Skip to content

Commit 03bfa12

Browse files
authored
Merge pull request #909 from nicholasbishop/bishop-raw-blockio
Add block I/O protocol to `uefi-raw` and use it in `uefi`
2 parents 7549b11 + 8a62ad4 commit 03bfa12

File tree

3 files changed

+97
-64
lines changed

3 files changed

+97
-64
lines changed

uefi-raw/src/protocol/block.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
use crate::{guid, Guid, Status};
2+
use core::ffi::c_void;
3+
4+
/// Logical block address.
5+
pub type Lba = u64;
6+
7+
/// Media information structure
8+
#[repr(C)]
9+
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
10+
pub struct BlockIoMedia {
11+
pub media_id: u32,
12+
pub removable_media: bool,
13+
pub media_present: bool,
14+
pub logical_partition: bool,
15+
pub read_only: bool,
16+
pub write_caching: bool,
17+
pub block_size: u32,
18+
pub io_align: u32,
19+
pub last_block: Lba,
20+
21+
// Added in revision 2.
22+
pub lowest_aligned_lba: Lba,
23+
pub logical_blocks_per_physical_block: u32,
24+
25+
// Added in revision 3.
26+
pub optimal_transfer_length_granularity: u32,
27+
}
28+
29+
#[repr(C)]
30+
pub struct BlockIo {
31+
pub revision: u64,
32+
pub media: *const BlockIoMedia,
33+
pub reset: unsafe extern "efiapi" fn(this: *mut Self, extended_verification: bool) -> Status,
34+
pub read_blocks: unsafe extern "efiapi" fn(
35+
this: *const Self,
36+
media_id: u32,
37+
lba: Lba,
38+
buffer_size: usize,
39+
buffer: *mut c_void,
40+
) -> Status,
41+
pub write_blocks: unsafe extern "efiapi" fn(
42+
this: *mut Self,
43+
media_id: u32,
44+
lba: Lba,
45+
buffer_size: usize,
46+
buffer: *const c_void,
47+
) -> Status,
48+
pub flush_blocks: unsafe extern "efiapi" fn(this: *mut Self) -> Status,
49+
}
50+
51+
impl BlockIo {
52+
pub const GUID: Guid = guid!("964e5b21-6459-11d2-8e39-00a0c969723b");
53+
}

uefi-raw/src/protocol/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//! ID. They can be implemented by a UEFI driver or occasionally by a
55
//! UEFI application.
66
7+
pub mod block;
78
pub mod console;
89
pub mod device_path;
910
pub mod disk;

uefi/src/proto/media/block.rs

Lines changed: 43 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,20 @@
11
//! Block I/O protocols.
22
33
use crate::proto::unsafe_protocol;
4-
use crate::{Result, Status, StatusExt};
4+
use crate::{Result, StatusExt};
5+
6+
pub use uefi_raw::protocol::block::Lba;
57

68
/// The Block I/O protocol.
7-
#[repr(C)]
8-
#[unsafe_protocol("964e5b21-6459-11d2-8e39-00a0c969723b")]
9-
pub struct BlockIO {
10-
revision: u64,
11-
media: *const BlockIOMedia,
12-
13-
reset: extern "efiapi" fn(this: &BlockIO, extended_verification: bool) -> Status,
14-
read_blocks: extern "efiapi" fn(
15-
this: &BlockIO,
16-
media_id: u32,
17-
lba: Lba,
18-
buffer_size: usize,
19-
buffer: *mut u8,
20-
) -> Status,
21-
write_blocks: extern "efiapi" fn(
22-
this: &BlockIO,
23-
media_id: u32,
24-
lba: Lba,
25-
buffer_size: usize,
26-
buffer: *const u8,
27-
) -> Status,
28-
flush_blocks: extern "efiapi" fn(this: &BlockIO) -> Status,
29-
}
9+
#[repr(transparent)]
10+
#[unsafe_protocol(uefi_raw::protocol::block::BlockIo::GUID)]
11+
pub struct BlockIO(uefi_raw::protocol::block::BlockIo);
3012

3113
impl BlockIO {
3214
/// Pointer for block IO media.
3315
#[must_use]
3416
pub const fn media(&self) -> &BlockIOMedia {
35-
unsafe { &*self.media }
17+
unsafe { &*self.0.media.cast::<BlockIOMedia>() }
3618
}
3719

3820
/// Resets the block device hardware.
@@ -44,7 +26,7 @@ impl BlockIO {
4426
/// # Errors
4527
/// * `uefi::Status::DEVICE_ERROR` The block device is not functioning correctly and could not be reset.
4628
pub fn reset(&mut self, extended_verification: bool) -> Result {
47-
(self.reset)(self, extended_verification).to_result()
29+
unsafe { (self.0.reset)(&mut self.0, extended_verification) }.to_result()
4830
}
4931

5032
/// Read the requested number of blocks from the device.
@@ -65,7 +47,16 @@ impl BlockIO {
6547
/// proper alignment.
6648
pub fn read_blocks(&self, media_id: u32, lba: Lba, buffer: &mut [u8]) -> Result {
6749
let buffer_size = buffer.len();
68-
(self.read_blocks)(self, media_id, lba, buffer_size, buffer.as_mut_ptr()).to_result()
50+
unsafe {
51+
(self.0.read_blocks)(
52+
&self.0,
53+
media_id,
54+
lba,
55+
buffer_size,
56+
buffer.as_mut_ptr().cast(),
57+
)
58+
}
59+
.to_result()
6960
}
7061

7162
/// Writes the requested number of blocks to the device.
@@ -87,7 +78,16 @@ impl BlockIO {
8778
/// on proper alignment.
8879
pub fn write_blocks(&mut self, media_id: u32, lba: Lba, buffer: &[u8]) -> Result {
8980
let buffer_size = buffer.len();
90-
(self.write_blocks)(self, media_id, lba, buffer_size, buffer.as_ptr()).to_result()
81+
unsafe {
82+
(self.0.write_blocks)(
83+
&mut self.0,
84+
media_id,
85+
lba,
86+
buffer_size,
87+
buffer.as_ptr().cast(),
88+
)
89+
}
90+
.to_result()
9191
}
9292

9393
/// Flushes all modified data to a physical block device.
@@ -96,108 +96,87 @@ impl BlockIO {
9696
/// * `uefi::Status::DEVICE_ERROR` The device reported an error while attempting to write data.
9797
/// * `uefi::Status::NO_MEDIA` There is no media in the device.
9898
pub fn flush_blocks(&mut self) -> Result {
99-
(self.flush_blocks)(self).to_result()
99+
unsafe { (self.0.flush_blocks)(&mut self.0) }.to_result()
100100
}
101101
}
102102

103-
/// EFI LBA type
104-
pub type Lba = u64;
105-
106103
/// Media information structure
107-
#[repr(C)]
104+
#[repr(transparent)]
108105
#[derive(Debug)]
109-
pub struct BlockIOMedia {
110-
media_id: u32,
111-
removable_media: bool,
112-
media_present: bool,
113-
logical_partition: bool,
114-
read_only: bool,
115-
write_caching: bool,
116-
117-
block_size: u32,
118-
io_align: u32,
119-
last_block: Lba,
120-
121-
// Revision 2
122-
lowest_aligned_lba: Lba,
123-
logical_blocks_per_physical_block: u32,
124-
125-
// Revision 3
126-
optimal_transfer_length_granularity: u32,
127-
}
106+
pub struct BlockIOMedia(uefi_raw::protocol::block::BlockIoMedia);
128107

129108
impl BlockIOMedia {
130109
/// The current media ID.
131110
#[must_use]
132111
pub const fn media_id(&self) -> u32 {
133-
self.media_id
112+
self.0.media_id
134113
}
135114

136115
/// True if the media is removable.
137116
#[must_use]
138117
pub const fn is_removable_media(&self) -> bool {
139-
self.removable_media
118+
self.0.removable_media
140119
}
141120

142121
/// True if there is a media currently present in the device.
143122
#[must_use]
144123
pub const fn is_media_present(&self) -> bool {
145-
self.media_present
124+
self.0.media_present
146125
}
147126

148127
/// True if block IO was produced to abstract partition structure.
149128
#[must_use]
150129
pub const fn is_logical_partition(&self) -> bool {
151-
self.logical_partition
130+
self.0.logical_partition
152131
}
153132

154133
/// True if the media is marked read-only.
155134
#[must_use]
156135
pub const fn is_read_only(&self) -> bool {
157-
self.read_only
136+
self.0.read_only
158137
}
159138

160139
/// True if `writeBlocks` function writes data.
161140
#[must_use]
162141
pub const fn is_write_caching(&self) -> bool {
163-
self.write_caching
142+
self.0.write_caching
164143
}
165144

166145
/// The intrinsic block size of the device.
167146
///
168147
/// If the media changes, then this field is updated. Returns the number of bytes per logical block.
169148
#[must_use]
170149
pub const fn block_size(&self) -> u32 {
171-
self.block_size
150+
self.0.block_size
172151
}
173152

174153
/// Supplies the alignment requirement for any buffer used in a data transfer.
175154
#[must_use]
176155
pub const fn io_align(&self) -> u32 {
177-
self.io_align
156+
self.0.io_align
178157
}
179158

180159
/// The last LBA on the device. If the media changes, then this field is updated.
181160
#[must_use]
182161
pub const fn last_block(&self) -> Lba {
183-
self.last_block
162+
self.0.last_block
184163
}
185164

186165
/// Returns the first LBA that is aligned to a physical block boundary.
187166
#[must_use]
188167
pub const fn lowest_aligned_lba(&self) -> Lba {
189-
self.lowest_aligned_lba
168+
self.0.lowest_aligned_lba
190169
}
191170

192171
/// Returns the number of logical blocks per physical block.
193172
#[must_use]
194173
pub const fn logical_blocks_per_physical_block(&self) -> u32 {
195-
self.logical_blocks_per_physical_block
174+
self.0.logical_blocks_per_physical_block
196175
}
197176

198177
/// Returns the optimal transfer length granularity as a number of logical blocks.
199178
#[must_use]
200179
pub const fn optimal_transfer_length_granularity(&self) -> u32 {
201-
self.optimal_transfer_length_granularity
180+
self.0.optimal_transfer_length_granularity
202181
}
203182
}

0 commit comments

Comments
 (0)