Skip to content

Commit a4d55c7

Browse files
committed
uefi: Add integration test for PCI_ROOT_BRIDGE_IO_PROTOCOL
1 parent 895ae1f commit a4d55c7

File tree

8 files changed

+149
-0
lines changed

8 files changed

+149
-0
lines changed

ovmf-firmware-debugcon.log

Whitespace-only changes.

uefi-raw/src/protocol/hii/config.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// SPDX-License-Identifier: MIT OR Apache-2.0
2+
3+
//! Bindings for HII Configuration Keyword Handler protocol.
4+
5+
use crate::{Char16, Guid, Status, guid};
6+
7+
/// EFI_KEYWORD_HANDLER_PROTOCOL
8+
#[derive(Debug)]
9+
#[repr(C)]
10+
pub struct HiiKeywordHandlerProtocol {
11+
pub set_data: unsafe extern "efiapi" fn(
12+
this: *mut Self,
13+
keyword_string: *const Char16,
14+
progress: *mut *const Char16,
15+
progress_err: *mut u32,
16+
) -> Status,
17+
pub get_data: unsafe extern "efiapi" fn(
18+
this: *const Self,
19+
namespace_id: *const Char16,
20+
keyword_string: *const Char16,
21+
progress: *mut *const Char16,
22+
progress_err: *mut u32,
23+
results: *mut *const Char16,
24+
) -> Status,
25+
}
26+
27+
impl HiiKeywordHandlerProtocol {
28+
pub const GUID: Guid = guid!("0a8badd5-03b8-4d19-b128-7b8f0edaa596");
29+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
//! HII Protocols
44
5+
pub mod config;
56
pub mod database;
67

78
use crate::{Char16, Guid};

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub fn test() {
2020
loaded_image::test();
2121
media::test();
2222
network::test();
23+
pci::test();
2324
pi::test();
2425
rng::test();
2526
shell_params::test();
@@ -83,6 +84,7 @@ mod media;
8384
mod misc;
8485
mod network;
8586
mod nvme;
87+
mod pci;
8688
mod pi;
8789
mod rng;
8890
mod scsi;

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// SPDX-License-Identifier: MIT OR Apache-2.0
2+
3+
pub mod root_bridge;
4+
5+
pub fn test() {
6+
root_bridge::test();
7+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// SPDX-License-Identifier: MIT OR Apache-2.0
2+
3+
use core::mem;
4+
use uefi::Handle;
5+
use uefi::boot::{OpenProtocolAttributes, OpenProtocolParams, ScopedProtocol, image_handle};
6+
use uefi::proto::ProtocolPointer;
7+
use uefi::proto::pci::PciIoAddress;
8+
use uefi::proto::pci::root_bridge::PciRootBridgeIo;
9+
use uefi::proto::pci::{PciIoAddress, root_bridge::PciRootBridgeIo};
10+
11+
const RED_HAT_PCI_VENDOR_ID: u16 = 0x1AF4;
12+
const MASS_STORAGE_CTRL_CLASS_CODE: u8 = 0x1;
13+
const SATA_CTRL_SUBCLASS_CODE: u8 = 0x6;
14+
15+
const REG_SIZE: u8 = mem::size_of::<u32>() as u8;
16+
17+
pub fn test() {
18+
let pci_handles = uefi::boot::find_handles::<PciRootBridgeIo>().unwrap();
19+
20+
let mut red_hat_dev_cnt = 0;
21+
let mut mass_storage_ctrl_cnt = 0;
22+
let mut sata_ctrl_cnt = 0;
23+
24+
for pci_handle in pci_handles {
25+
let mut pci_proto = get_open_protocol::<PciRootBridgeIo>(pci_handle);
26+
27+
for bus in 0..=255 {
28+
for dev in 0..32 {
29+
for fun in 0..8 {
30+
let addr = PciIoAddress::new(bus, dev, fun);
31+
let Ok(reg0) = pci_proto.pci().read_one::<u32>(addr.with_register(0)) else {
32+
continue;
33+
};
34+
if reg0 == 0xFFFFFFFF {
35+
continue; // not a valid device
36+
}
37+
let reg1 = pci_proto
38+
.pci()
39+
.read_one::<u32>(addr.with_register(2 * REG_SIZE))
40+
.unwrap();
41+
42+
let vendor_id = (reg0 & 0xFFFF) as u16;
43+
let device_id = (reg0 >> 16) as u16;
44+
if vendor_id == RED_HAT_PCI_VENDOR_ID {
45+
red_hat_dev_cnt += 1;
46+
}
47+
48+
let class_code = (reg1 >> 24) as u8;
49+
let subclass_code = ((reg1 >> 16) & 0xFF) as u8;
50+
if class_code == MASS_STORAGE_CTRL_CLASS_CODE {
51+
mass_storage_ctrl_cnt += 1;
52+
53+
if subclass_code == SATA_CTRL_SUBCLASS_CODE {
54+
sata_ctrl_cnt += 1;
55+
}
56+
}
57+
58+
log::info!(
59+
"PCI Device: [{}, {}, {}]: vendor={:04X}, device={:04X}, class={:02X}, subclass={:02X}",
60+
bus,
61+
dev,
62+
fun,
63+
vendor_id,
64+
device_id,
65+
class_code,
66+
subclass_code
67+
);
68+
}
69+
}
70+
}
71+
}
72+
73+
assert!(red_hat_dev_cnt > 0);
74+
assert!(mass_storage_ctrl_cnt > 0);
75+
assert!(sata_ctrl_cnt > 0);
76+
}
77+
78+
fn get_open_protocol<P: ProtocolPointer + ?Sized>(handle: Handle) -> ScopedProtocol<P> {
79+
let open_opts = OpenProtocolParams {
80+
handle,
81+
agent: image_handle(),
82+
controller: None,
83+
};
84+
let open_attrs = OpenProtocolAttributes::GetProtocol;
85+
unsafe { uefi::boot::open_protocol(open_opts, open_attrs).unwrap() }
86+
}

uefi/src/proto/hii/config.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// SPDX-License-Identifier: MIT OR Apache-2.0
2+
3+
//! HII Configuration protocols.
4+
5+
use uefi_macros::unsafe_protocol;
6+
use uefi_raw::protocol::hii::config::HiiKeywordHandlerProtocol;
7+
8+
/// TODO
9+
#[derive(Debug)]
10+
#[repr(transparent)]
11+
#[unsafe_protocol(HiiKeywordHandlerProtocol::GUID)]
12+
pub struct HiiKeywordHandler(HiiKeywordHandlerProtocol);
13+
14+
impl HiiKeywordHandler {
15+
/// TODO REMOVE
16+
pub fn get_raw(&self) -> *const HiiKeywordHandlerProtocol {
17+
&self.0
18+
}
19+
}

uefi/src/proto/hii/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// SPDX-License-Identifier: MIT OR Apache-2.0
2+
3+
//! HII Protocols
4+
5+
pub mod config;

0 commit comments

Comments
 (0)