Skip to content

Commit 6edf49d

Browse files
committed
uefi: Remove GhostCell and implement PciRootBridgeIo::configuration
1 parent 16f6fe7 commit 6edf49d

File tree

15 files changed

+708
-335
lines changed

15 files changed

+708
-335
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ bitflags = "2.0.0"
2424
log = { version = "0.4.5", default-features = false }
2525
ptr_meta = { version = "0.3.0", default-features = false, features = ["derive"] }
2626
uguid = "2.2.1"
27-
ghost-cell = "0.2.6"
27+
static_assertions = "1.1.0"
2828

2929
[patch.crates-io]
3030
uefi = { path = "uefi" }

uefi-raw/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ rust-version = "1.85.1"
2121
[dependencies]
2222
bitflags.workspace = true
2323
uguid.workspace = true
24+
static_assertions.workspace = true
2425

2526
[package.metadata.docs.rs]
2627
rustdoc-args = ["--cfg", "docsrs"]

uefi-raw/src/protocol/pci/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
// SPDX-License-Identifier: MIT OR Apache-2.0
22

3+
pub mod resource;
34
pub mod root_bridge;

uefi-raw/src/protocol/pci/resource.rs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
use bitflags::bitflags;
2+
use static_assertions::assert_eq_size;
3+
4+
/// Descriptor for current PCI root bridge's configuration space.
5+
/// Specification:
6+
/// https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/06_Device_Configuration/Device_Configuration.html#qword-address-space-descriptor
7+
#[repr(C, packed)]
8+
#[derive(Debug)]
9+
pub struct QWordAddressSpaceDescriptor {
10+
tag: u8,
11+
descriptor_length: u16,
12+
pub resource_type: ResourceType,
13+
pub flags: GeneralFlags,
14+
pub type_flags: u8,
15+
pub address_granularity: u64,
16+
pub range_min: u64,
17+
pub range_max: u64, // inclusive
18+
pub translation_offset: u64,
19+
pub address_length: u64,
20+
}
21+
assert_eq_size!(QWordAddressSpaceDescriptor, [u8; 0x2E]);
22+
23+
newtype_enum! {
24+
/// Indicates which type of resource this descriptor describes.
25+
pub enum ResourceType: u8 => {
26+
/// This resource describes range of memory.
27+
MEMORY = 0,
28+
29+
/// This resource describes range of I/O ports.
30+
IO = 1,
31+
32+
/// This resource describes range of Bus numbers.
33+
BUS = 2,
34+
}
35+
}
36+
37+
bitflags! {
38+
#[repr(transparent)]
39+
#[derive(Debug, Copy, Clone)]
40+
pub struct GeneralFlags: u8 {
41+
/// Indicates maximum address is fixed.
42+
const MAX_ADDRESS_FIXED = 0b1000;
43+
44+
/// Indicates minimum address is fixed.
45+
const MIN_ADDRESS_FIXED = 0b0100;
46+
47+
/// Indicates if this bridge would subtract or positively decode address.
48+
/// 1 This bridge subtractively decodes this address (top level bridges only)
49+
/// 0 This bridge positively decodes this address
50+
const DECODE_TYPE = 0b0010;
51+
}
52+
}
53+
54+
impl QWordAddressSpaceDescriptor {
55+
/// Verifies if given descriptor is valid according to specification.
56+
/// This also checks if all reserved bit fields which are supposed to be 0 are actually 0.
57+
pub fn verify(&self) {
58+
let tag = self.tag;
59+
if tag != 0x8A {
60+
panic!("Tag value for QWordAddressSpaceDescriptor should be 0x8A, not {}", tag);
61+
}
62+
63+
let length = self.descriptor_length;
64+
if self.descriptor_length != 0x2B {
65+
panic!("Length value for QWordAddressSpaceDescriptor should be 0x2B, not {}", length);
66+
}
67+
68+
if self.flags.bits() & 0b11110000 != 0 {
69+
panic!("Reserved bits for GeneralFlags are 1")
70+
}
71+
72+
let type_flags = self.type_flags;
73+
match self.resource_type {
74+
ResourceType::MEMORY => {
75+
if type_flags & 0b11000000 != 0 {
76+
panic!("Reserved bits for Memory Type Flags are 1");
77+
}
78+
}
79+
ResourceType::IO => {
80+
if type_flags & 0b11001100 != 0 {
81+
panic!("Reserved bits for IO Type Flags are 1");
82+
}
83+
}
84+
ResourceType::BUS => {
85+
if type_flags != 0 {
86+
panic!("Bus type flags should be 0, not {}", type_flags);
87+
}
88+
}
89+
ResourceType(3..=191) => panic!("Invalid resource type: {}", self.resource_type.0),
90+
ResourceType(192..) => {} // Hardware defined range
91+
}
92+
93+
let min = self.range_min;
94+
let max = self.range_max;
95+
if max < min {
96+
panic!("Address range is invalid. Max(0x{:X}) is smaller than Min(0x{:X}).", max, min);
97+
}
98+
}
99+
}

uefi-raw/src/protocol/pci/root_bridge.rs

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -42,21 +42,22 @@ bitflags! {
4242
/// Describes PCI I/O Protocol Attribute bitflags specified in UEFI specification.
4343
///. https://uefi.org/specs/UEFI/2.10_A/14_Protocols_PCI_Bus_Support.html
4444
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
45+
#[repr(transparent)]
4546
pub struct PciRootBridgeIoProtocolAttribute: u64 {
46-
const PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO = 0x0001;
47-
const PCI_ATTRIBUTE_ISA_IO = 0x0002;
48-
const PCI_ATTRIBUTE_VGA_PALETTE_IO = 0x0004;
49-
const PCI_ATTRIBUTE_VGA_MEMORY = 0x0008;
50-
const PCI_ATTRIBUTE_VGA_IO = 0x0010;
51-
const PCI_ATTRIBUTE_IDE_PRIMARY_IO = 0x0020;
52-
const PCI_ATTRIBUTE_IDE_SECONDARY_IO = 0x0040;
53-
const PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE = 0x0080;
54-
const PCI_ATTRIBUTE_MEMORY_CACHED = 0x0800;
55-
const PCI_ATTRIBUTE_MEMORY_DISABLE = 0x1000;
56-
const PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE = 0x8000;
57-
const PCI_ATTRIBUTE_ISA_IO_16 = 0x10000;
58-
const PCI_ATTRIBUTE_VGA_PALETTE_IO_16 = 0x20000;
59-
const PCI_ATTRIBUTE_VGA_IO_16 = 0x40000;
47+
const ISA_MOTHERBOARD_IO = 0x0001;
48+
const ISA_IO = 0x0002;
49+
const VGA_PALETTE_IO = 0x0004;
50+
const VGA_MEMORY = 0x0008;
51+
const VGA_IO = 0x0010;
52+
const IDE_PRIMARY_IO = 0x0020;
53+
const IDE_SECONDARY_IO = 0x0040;
54+
const MEMORY_WRITE_COMBINE = 0x0080;
55+
const MEMORY_CACHED = 0x0800;
56+
const MEMORY_DISABLE = 0x1000;
57+
const DUAL_ADDRESS_CYCLE = 0x8000;
58+
const ISA_IO_16 = 0x10000;
59+
const VGA_PALETTE_IO_16 = 0x20000;
60+
const VGA_IO_16 = 0x40000;
6061
}
6162
}
6263

@@ -157,18 +158,10 @@ impl PciRootBridgeIoProtocol {
157158
impl PciRootBridgeIoProtocolWidth {
158159
pub fn size(self) -> usize {
159160
match self {
160-
Self::UINT8 |
161-
Self::FIFO_UINT8 |
162-
Self::FILL_UINT8 => 1,
163-
Self::UINT16 |
164-
Self::FIFO_UINT16 |
165-
Self::FILL_UINT16 => 2,
166-
Self::UINT32 |
167-
Self::FIFO_UINT32 |
168-
Self::FILL_UINT32 => 4,
169-
Self::UINT64 |
170-
Self::FIFO_UINT64 |
171-
Self::FILL_UINT64 => 8,
161+
Self::UINT8 | Self::FIFO_UINT8 | Self::FILL_UINT8 => 1,
162+
Self::UINT16 | Self::FIFO_UINT16 | Self::FILL_UINT16 => 2,
163+
Self::UINT32 | Self::FIFO_UINT32 | Self::FILL_UINT32 => 4,
164+
Self::UINT64 | Self::FIFO_UINT64 | Self::FILL_UINT64 => 8,
172165
_ => unreachable!(),
173166
}
174167
}

uefi-test-runner/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ edition = "2024"
99
uefi-raw = { path = "../uefi-raw" }
1010
uefi = { path = "../uefi", features = ["alloc", "global_allocator", "panic_handler", "logger", "qemu", "log-debugcon"] }
1111
smoltcp = { version = "0.12.0", default-features = false, features = ["medium-ethernet", "proto-ipv4", "socket-udp"] }
12-
ghost-cell.workspace = true
1312

1413
log.workspace = true
1514

uefi-test-runner/src/proto/pci/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ pub fn test() {
77
root_bridge::test_buffer();
88
root_bridge::test_mapping();
99
root_bridge::test_copy();
10+
root_bridge::test_config();
1011
}

0 commit comments

Comments
 (0)