Skip to content

Commit c34a0d2

Browse files
committed
initial commit
0 parents  commit c34a0d2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+4053
-0
lines changed

.github/dependabot.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "cargo"
4+
directory: "/"
5+
schedule:
6+
interval: "monthly"
7+
open-pull-requests-limit: 3
8+
groups:
9+
all-dependencies:
10+
patterns:
11+
- "*"
12+
13+
- package-ecosystem: "github-actions"
14+
directory: "/"
15+
schedule:
16+
interval: "monthly"

.github/workflows/ci.yml

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
name: ci
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
env:
10+
CARGO_TERM_COLOR: always
11+
12+
jobs:
13+
test:
14+
name: cargo test
15+
runs-on: ubuntu-latest
16+
strategy:
17+
fail-fast: false
18+
matrix:
19+
rust: [stable, beta, nightly, 1.80.0] # stable, beta, nightly, and MSRV
20+
mode: ["", "--release"]
21+
steps:
22+
- name: checkout code
23+
uses: actions/checkout@v5
24+
25+
- name: install rust toolchain
26+
uses: dtolnay/rust-toolchain@master
27+
with:
28+
toolchain: ${{ matrix.rust }}
29+
30+
- name: cache rust toolchain
31+
uses: Swatinem/rust-cache@v2
32+
33+
- name: cargo test
34+
run: cargo test ${{ matrix.mode }}
35+
36+
deny:
37+
name: cargo deny
38+
runs-on: ubuntu-latest
39+
steps:
40+
- name: checkout code
41+
uses: actions/checkout@v5
42+
43+
- name: cargo deny
44+
uses: EmbarkStudios/cargo-deny-action@v2
45+
46+
fmt:
47+
name: cargo fmt
48+
runs-on: ubuntu-latest
49+
steps:
50+
- name: checkout code
51+
uses: actions/checkout@v5
52+
53+
- name: install rust toolchain
54+
uses: dtolnay/rust-toolchain@stable
55+
with:
56+
components: rustfmt
57+
58+
- name: cargo fmt
59+
run: cargo fmt --all -- --check
60+
61+
doc:
62+
name: cargo doc
63+
runs-on: ubuntu-latest
64+
steps:
65+
- name: checkout code
66+
uses: actions/checkout@v5
67+
68+
- name: install rust toolchain
69+
uses: dtolnay/rust-toolchain@stable
70+
71+
- name: cargo doc
72+
run: cargo doc --no-deps
73+
74+
clippy:
75+
name: cargo clippy
76+
runs-on: ubuntu-latest
77+
steps:
78+
- name: checkout code
79+
uses: actions/checkout@v5
80+
81+
- name: install rust toolchain
82+
uses: dtolnay/rust-toolchain@stable
83+
with:
84+
components: clippy
85+
86+
- name: cargo clippy
87+
run: cargo clippy --bins -- -D warnings

.github/workflows/release.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
release:
13+
name: release
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: checkout code
17+
uses: actions/checkout@v5
18+
19+
- name: install rust toolchain
20+
uses: dtolnay/rust-toolchain@stable
21+
with:
22+
targets: x86_64-unknown-linux-musl
23+
24+
- name: cache rust toolchain
25+
uses: Swatinem/rust-cache@v2
26+
27+
- name: install musl-tools
28+
run: sudo apt-get update && sudo apt-get install -y musl-tools
29+
30+
- name: cargo build
31+
run: cargo build --release --target x86_64-unknown-linux-musl
32+
33+
- name: create release
34+
env:
35+
GH_TOKEN: ${{ github.token }}
36+
run: |
37+
gh release delete --yes ${{ github.ref_name }} || true
38+
gh release create --generate-notes ${{ github.ref_name }} target/x86_64-unknown-linux-musl/release/beacon

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
target/

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "devpath"
3+
version = "0.1.0"
4+
edition = "2021"
5+
description = "UEFI Device Path parsing library"
6+
license = "MIT OR Apache-2.0"
7+
repository = "https://github.com/AMDEPYC/snpcert"
8+
readme = "README.md"
9+
keywords = ["uefi", "device-path", "firmware", "boot", "efi"]
10+
categories = ["embedded", "hardware-support", "parsing"]
11+
rust-version = "1.80"

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Advanced Micro Devices
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# devpath
2+
3+
[![CI](https://github.com/AMDEPYC/devpath/workflows/ci/badge.svg)](https://github.com/AMDEPYC/devpath/actions/workflows/ci.yml)
4+
[![Crates.io](https://img.shields.io/crates/v/devpath.svg)](https://crates.io/crates/devpath)
5+
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6+
[![Rust](https://img.shields.io/badge/rust-1.80%2B-blue.svg)](https://www.rust-lang.org)
7+
8+
A `no_std` Rust library for parsing and manipulating UEFI device paths as defined in the UEFI 2.11 specification.
9+
10+
## Usage
11+
12+
Add this to your `Cargo.toml`:
13+
14+
```toml
15+
[dependencies]
16+
devpath = "0.1"
17+
```
18+
19+
### Basic Example
20+
21+
```rust
22+
use devpath::{Paths, FromBytes};
23+
24+
// Parse device paths from raw bytes
25+
let raw_bytes = &[
26+
0x02, 0x01, 0x0c, 0x00, // ACPI device path
27+
0xd0, 0x41, 0x03, 0x0a, // HID: PNP0A03 (PCI Root Bridge)
28+
0x00, 0x00, 0x00, 0x00, // UID: 0
29+
0x01, 0x01, 0x06, 0x00, // PCI device path
30+
0x00, 0x1f, // Function: 0, Device: 31
31+
0x7f, 0xff, 0x04, 0x00, // End of device path
32+
];
33+
34+
let paths = Paths::from_bytes(raw_bytes)?;
35+
println!("Parsed {} device path(s)", paths.len());
36+
```
37+
38+
## Features
39+
40+
- **Complete UEFI 2.11 Support** - All device path types: Hardware, ACPI, Messaging, Media, and BIOS
41+
- **Type-Safe Parsing** - Structured representation of device path nodes
42+
- **no_std Compatible** - Works in embedded and firmware environments
43+
- **Zero Unsafe Code** - Memory-safe parsing with comprehensive error handling
44+
45+
## Device Path Types
46+
47+
- **Hardware** - PCI, memory-mapped devices, controllers
48+
- **ACPI** - ACPI namespace devices, _ADR devices
49+
- **Messaging** - USB, SATA, NVMe, network protocols, Bluetooth
50+
- **Media** - Hard drives, file paths, CD-ROM, RAM disks
51+
- **BIOS** - Legacy BIOS boot specification devices
52+
53+
## Documentation
54+
55+
Full API documentation is available on [docs.rs](https://docs.rs/devpath).
56+
57+
## License
58+
59+
This project is licensed under the [MIT License](LICENSE).

STYLE.md

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# Code Style Guide
2+
3+
## Module Organization
4+
5+
- **Module names**: Shortened, clear (e.g., `bluetooth_le``btle`, `device_logical_unit``dlu`)
6+
- **Module structure**: One primary struct per sub-type, implementation in same file
7+
- **File naming**: Match shortened module names
8+
9+
## Import Grouping
10+
11+
```rust
12+
// 1. External crates (if any)
13+
use core::net::Ipv4Addr;
14+
15+
// 2. Internal crate imports
16+
use crate::{Error, Head};
17+
use crate::parser::{ByteOrder, Parser};
18+
19+
// 3. Relative imports
20+
use super::ipv4::Protocol;
21+
```
22+
23+
## Field Naming
24+
25+
- **Brief names**: `vendor_id``vid`, `mac_address``mac`, `baud_rate``baud`
26+
- **Documentation**: Add doc comments for any ambiguous shortened names
27+
- **Standard abbreviations**: `nsid`, `lun`, `wwn`, `eui`, `vid`, `pid`, `hba_port`, `pm_port`
28+
29+
## Data Types
30+
31+
### String Handling
32+
- **UTF-8 strings**: Use `&CStr` for null-terminated UTF-8 strings
33+
- **UTF-16 strings**: Use `String` for UTF-16 strings (converted from parser)
34+
- **Raw strings**: Use `&str` for non-null-terminated UTF-8 strings (rare)
35+
36+
### Newtypes
37+
- **Single field structs**: Use newtype pattern
38+
```rust
39+
pub struct Vlan(pub u16);
40+
pub struct Protocol(pub u16);
41+
```
42+
43+
### Enums
44+
- **Small known value sets**: Use proper enums (no repr guarantees)
45+
- **Parser trait**: Implement for validation
46+
```rust
47+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
48+
pub enum Origin {
49+
Manual = 0x00,
50+
StatelessAutoConfiguration = 0x01,
51+
}
52+
```
53+
54+
### Structs
55+
- **Multi-field types**: Regular structs with brief field names
56+
- **Derive**: Always include `Debug, Clone, Copy, PartialEq, Eq, Hash`
57+
58+
## Reserved Fields
59+
60+
- **Storage**: Do NOT store reserved fields in structs
61+
- **Validation**: Parse and validate in `TryFrom` implementation
62+
- **Pattern**: `let _reserved: u32 = node.data.parse(ByteOrder::Little)?;`
63+
64+
## Error Handling
65+
66+
- **Invalid values**: Return `Error::Invalid` for spec violations
67+
- **Validation**: Check reserved field values, invalid NSIDs, etc.
68+
69+
## Documentation
70+
71+
- **Struct docs**: Include UEFI sub-type number and byte length
72+
- **Field docs**: Required for abbreviated field names
73+
- **Example**:
74+
```rust
75+
/// SATA Device Path (SubType 0x12)
76+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
77+
pub struct Sata {
78+
/// HBA port number
79+
pub hba_port: u16,
80+
/// Port multiplier port number
81+
pub pm_port: u16,
82+
pub lun: u16,
83+
}
84+
```
85+
86+
## Implementation Patterns
87+
88+
### Parse Order
89+
- **Last field**: Always use `finish()` method to guarantee end of data
90+
- **Earlier fields**: Use regular `parse()` method
91+
92+
### TryFrom Implementation
93+
```rust
94+
impl<'a> TryFrom<Head<'a>> for TypeName<'a> {
95+
type Error = Error;
96+
97+
fn try_from(mut node: Head<'a>) -> Result<Self, Self::Error> {
98+
// Parse reserved fields (don't store)
99+
let _reserved: u32 = node.data.parse(ByteOrder::Little)?;
100+
101+
// Parse fields (use finish() for last field)
102+
let field1 = node.data.parse(ByteOrder::Little)?;
103+
let utf8_string = node.data.finish(())?; // &CStr for UTF-8
104+
105+
Ok(TypeName { field1, utf8_string })
106+
}
107+
}
108+
```
109+
110+
### Byte Order
111+
- **Multi-byte integers**: Always specify `ByteOrder::Little`
112+
- **Single bytes**: Use `()` argument
113+
- **Arrays**: Use `()` argument
114+
115+
## Constants
116+
117+
- **Protocol numbers**: Define as associated constants
118+
- **Magic values**: Use descriptive constant names
119+
- **Grouping**: Related constants together with docs

deny.toml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[licenses]
2+
confidence-threshold = 0.8
3+
allow = [
4+
"MIT",
5+
"Apache-2.0",
6+
]
7+
8+
[bans]
9+
multiple-versions = "warn"
10+
11+
[sources]
12+
allow-registry = ["https://github.com/rust-lang/crates.io-index"]
13+
unknown-registry = "deny"
14+
unknown-git = "deny"

0 commit comments

Comments
 (0)