Skip to content

Commit 6b787c3

Browse files
committed
uefi: Add integration test for the USB I/O protocol
1 parent e5b16ee commit 6b787c3

File tree

4 files changed

+89
-0
lines changed

4 files changed

+89
-0
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub fn test() {
2424
rng::test();
2525
shell_params::test();
2626
string::test();
27+
usb::test();
2728
misc::test();
2829

2930
// disable the ATA test on aarch64 for now. The aarch64 UEFI Firmware does not yet seem
@@ -96,3 +97,4 @@ mod shell_params;
9697
mod shim;
9798
mod string;
9899
mod tcg;
100+
mod usb;

uefi-test-runner/src/proto/usb/io.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// SPDX-License-Identifier: MIT OR Apache-2.0
2+
3+
use core::mem;
4+
use uefi::proto::usb::DeviceDescriptor;
5+
use uefi::proto::usb::io::{ControlTransfer, UsbIo};
6+
use uefi::{Status, boot};
7+
8+
pub fn test() {
9+
info!("Testing USB I/O protocol");
10+
11+
let handles = boot::locate_handle_buffer(boot::SearchType::from_proto::<UsbIo>())
12+
.expect("failed to acquire USB I/O handles");
13+
14+
for handle in handles.iter().copied() {
15+
let mut io = boot::open_protocol_exclusive::<UsbIo>(handle)
16+
.expect("failed to open USB I/O protocol");
17+
18+
let device = io
19+
.device_descriptor()
20+
.expect("failed to acquire USB device descriptor");
21+
io.config_descriptor()
22+
.expect("failed to acquire USB config descriptor");
23+
io.interface_descriptor()
24+
.expect("failed to acquire USB interface descriptor");
25+
26+
for endpoint_index in 0..16 {
27+
let result = io.endpoint_descriptor(endpoint_index);
28+
if result
29+
.as_ref()
30+
.is_err_and(|error| error.status() == Status::NOT_FOUND)
31+
{
32+
continue;
33+
}
34+
35+
result.expect("failed to acquire USB endpoint descriptor");
36+
}
37+
38+
let supported_languages = io
39+
.supported_languages()
40+
.expect("failed to acquire supported language list");
41+
let test_language = supported_languages[0];
42+
43+
for string_index in 0..=u8::MAX {
44+
let result = io.string_descriptor(test_language, string_index);
45+
if result
46+
.as_ref()
47+
.is_err_and(|error| error.status() == Status::NOT_FOUND)
48+
{
49+
continue;
50+
}
51+
52+
result.expect("failed to acquire string descriptor");
53+
}
54+
55+
let mut buffer = [0u8; mem::size_of::<DeviceDescriptor>()];
56+
57+
io.control_transfer(
58+
0b1000_0000,
59+
6,
60+
1u16 << 8,
61+
0,
62+
ControlTransfer::DataIn(&mut buffer[..mem::size_of::<DeviceDescriptor>()]),
63+
0,
64+
)
65+
.expect("failed control transfer");
66+
unsafe {
67+
assert_eq!(
68+
device,
69+
buffer.as_ptr().cast::<DeviceDescriptor>().read_unaligned()
70+
)
71+
}
72+
}
73+
}

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// SPDX-License-Identifier: MIT OR Apache-2.0
2+
3+
pub fn test() {
4+
info!("Testing USB protocols");
5+
6+
io::test();
7+
}
8+
9+
mod io;

xtask/src/qemu.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,11 @@ pub fn run_qemu(arch: UefiArch, opt: &QemuOpt) -> Result<()> {
438438
cmd.args(["-display", "none"]);
439439
}
440440

441+
// Configure USB
442+
cmd.args(["-device", "qemu-xhci"]);
443+
444+
cmd.args(["-device", "usb-net"]);
445+
441446
// Second (FAT) disk
442447
let test_disk = tmp_dir.join("test_disk.fat.img");
443448
create_mbr_test_disk(&test_disk)?;

0 commit comments

Comments
 (0)