Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 0d0966f

Browse files
Another pass of review on UEFI protocols (#69)
* Review the Simple Text Input protocol * Clean up data types and method order in text output protocol * Follow read-write method order convention in serial protocol * Add a FIXME regarding missing bits in the debug support protocol * Mark various APIs that take pointers as unsafe + prefer tuple struct * Only specific combinations of file modes are allowed, so an enum makes more sense * Clarify the API of the Media Access protocol * Generalize notion of 'GUID-bearer' from Protocol * Add support for UEFI's time-keeping functionality * Interface EFI_FILE_INFO * Update runtime service module * Implement support for all file info supported by UEFI * Comment clarification * Apply rustfmt * Add UEFI entry points for get/set info * Implement public entry points for get/set_info * Attaching a GUID to a type is unsafe * Implement first-class Directory support * Add forgotten open entry point * Add a bunch of derives * Reuse the Identify trait that we already have * Split the File module into smaller parts * Run cargo fmt
1 parent b8ce767 commit 0d0966f

File tree

16 files changed

+1208
-399
lines changed

16 files changed

+1208
-399
lines changed

‎src/data_types/guid.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,14 @@ impl fmt::Display for Guid {
5555
)
5656
}
5757
}
58+
59+
/// Several entities in the UEFI specification can be referred to by their GUID,
60+
/// this trait is a building block to interface them in uefi-rs.
61+
///
62+
/// Implementing it is unsafe, because attaching an incorrect GUID to a type can
63+
/// lead to type unsafety on both the Rust and UEFI side.
64+
///
65+
pub unsafe trait Identify {
66+
/// Unique protocol identifier.
67+
const GUID: Guid;
68+
}

‎src/data_types/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub struct Handle(*mut c_void);
1515
pub struct Event(*mut c_void);
1616

1717
mod guid;
18-
pub use self::guid::Guid;
18+
pub use self::guid::{Guid,Identify};
1919

2020
pub mod chars;
2121
pub use self::chars::{Char16, Char8};

‎src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333

3434
#[macro_use]
3535
pub mod data_types;
36-
pub use self::data_types::{CStr16, CStr8, Char16, Char8, Event, Guid, Handle};
36+
pub use self::data_types::{CStr16, CStr8, Char16, Char8, Event, Guid, Handle,Identify};
3737

3838
mod error;
3939
pub use self::error::{Completion, Result, ResultExt, Status};

‎src/proto/console/gop.rs

Lines changed: 105 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pub struct GraphicsOutput<'boot> {
4343
set_mode: extern "win64" fn(&mut GraphicsOutput, mode: u32) -> Status,
4444
// Clippy correctly complains that this is too complicated, but we can't change the spec.
4545
#[allow(clippy::type_complexity)]
46-
blt: extern "win64" fn(
46+
blt: unsafeextern "win64" fn(
4747
this: &mut GraphicsOutput,
4848
buffer: *mut BltPixel,
4949
op: u32,
@@ -97,80 +97,18 @@ impl<'boot> GraphicsOutput<'boot> {
9797
/// Every operation requires different parameters.
9898
pub fn blt(&mut self, op: BltOp) -> Result<()> {
9999
// Demultiplex the operation type.
100-
match op {
101-
BltOp::VideoFill {
102-
color,
103-
dest: (dest_x, dest_y),
104-
dims: (width, height),
105-
} => {
106-
self.check_framebuffer_region((dest_x, dest_y), (width, height));
107-
(self.blt)(
108-
self,
109-
&color as *const _ as *mut _,
110-
0,
111-
0,
112-
0,
113-
dest_x,
114-
dest_y,
115-
width,
116-
height,
117-
0,
118-
)
119-
.into()
120-
}
121-
BltOp::VideoToBltBuffer {
122-
buffer,
123-
src: (src_x, src_y),
124-
dest: dest_region,
125-
dims: (width, height),
126-
} => {
127-
self.check_framebuffer_region((src_x, src_y), (width, height));
128-
self.check_blt_buffer_region(dest_region, (width, height), buffer.len());
129-
match dest_region {
130-
BltRegion::Full => (self.blt)(
100+
unsafe {
101+
match op {
102+
BltOp::VideoFill {
103+
color,
104+
dest: (dest_x, dest_y),
105+
dims: (width, height),
106+
} => {
107+
self.check_framebuffer_region((dest_x, dest_y), (width, height));
108+
(self.blt)(
131109
self,
132-
buffer.as_mut_ptr(),
133-
1,
134-
src_x,
135-
src_y,
136-
0,
137-
0,
138-
width,
139-
height,
110+
&color as *const _ as *mut _,
140111
0,
141-
)
142-
.into(),
143-
BltRegion::SubRectangle {
144-
coords: (dest_x, dest_y),
145-
px_stride,
146-
} => (self.blt)(
147-
self,
148-
buffer.as_mut_ptr(),
149-
1,
150-
src_x,
151-
src_y,
152-
dest_x,
153-
dest_y,
154-
width,
155-
height,
156-
px_stride * core::mem::size_of::<BltPixel>(),
157-
)
158-
.into(),
159-
}
160-
}
161-
BltOp::BufferToVideo {
162-
buffer,
163-
src: src_region,
164-
dest: (dest_x, dest_y),
165-
dims: (width, height),
166-
} => {
167-
self.check_blt_buffer_region(src_region, (width, height), buffer.len());
168-
self.check_framebuffer_region((dest_x, dest_y), (width, height));
169-
match src_region {
170-
BltRegion::Full => (self.blt)(
171-
self,
172-
buffer.as_ptr() as *mut _,
173-
2,
174112
0,
175113
0,
176114
dest_x,
@@ -179,46 +117,110 @@ impl<'boot> GraphicsOutput<'boot> {
179117
height,
180118
0,
181119
)
182-
.into(),
183-
BltRegion::SubRectangle {
184-
coords: (src_x, src_y),
185-
px_stride,
186-
} => (self.blt)(
120+
.into()
121+
}
122+
BltOp::VideoToBltBuffer {
123+
buffer,
124+
src: (src_x, src_y),
125+
dest: dest_region,
126+
dims: (width, height),
127+
} => {
128+
self.check_framebuffer_region((src_x, src_y), (width, height));
129+
self.check_blt_buffer_region(dest_region, (width, height), buffer.len());
130+
match dest_region {
131+
BltRegion::Full => (self.blt)(
132+
self,
133+
buffer.as_mut_ptr(),
134+
1,
135+
src_x,
136+
src_y,
137+
0,
138+
0,
139+
width,
140+
height,
141+
0,
142+
)
143+
.into(),
144+
BltRegion::SubRectangle {
145+
coords: (dest_x, dest_y),
146+
px_stride,
147+
} => (self.blt)(
148+
self,
149+
buffer.as_mut_ptr(),
150+
1,
151+
src_x,
152+
src_y,
153+
dest_x,
154+
dest_y,
155+
width,
156+
height,
157+
px_stride * core::mem::size_of::<BltPixel>(),
158+
)
159+
.into(),
160+
}
161+
}
162+
BltOp::BufferToVideo {
163+
buffer,
164+
src: src_region,
165+
dest: (dest_x, dest_y),
166+
dims: (width, height),
167+
} => {
168+
self.check_blt_buffer_region(src_region, (width, height), buffer.len());
169+
self.check_framebuffer_region((dest_x, dest_y), (width, height));
170+
match src_region {
171+
BltRegion::Full => (self.blt)(
172+
self,
173+
buffer.as_ptr() as *mut _,
174+
2,
175+
0,
176+
0,
177+
dest_x,
178+
dest_y,
179+
width,
180+
height,
181+
0,
182+
)
183+
.into(),
184+
BltRegion::SubRectangle {
185+
coords: (src_x, src_y),
186+
px_stride,
187+
} => (self.blt)(
188+
self,
189+
buffer.as_ptr() as *mut _,
190+
2,
191+
src_x,
192+
src_y,
193+
dest_x,
194+
dest_y,
195+
width,
196+
height,
197+
px_stride * core::mem::size_of::<BltPixel>(),
198+
)
199+
.into(),
200+
}
201+
}
202+
BltOp::VideoToVideo {
203+
src: (src_x, src_y),
204+
dest: (dest_x, dest_y),
205+
dims: (width, height),
206+
} => {
207+
self.check_framebuffer_region((src_x, src_y), (width, height));
208+
self.check_framebuffer_region((dest_x, dest_y), (width, height));
209+
(self.blt)(
187210
self,
188-
buffer.as_ptr()as*mut_,
189-
2,
211+
ptr::null_mut(),
212+
3,
190213
src_x,
191214
src_y,
192215
dest_x,
193216
dest_y,
194217
width,
195218
height,
196-
px_stride * core::mem::size_of::<BltPixel>(),
219+
0,
197220
)
198-
.into(),
221+
.into()
199222
}
200223
}
201-
BltOp::VideoToVideo {
202-
src: (src_x, src_y),
203-
dest: (dest_x, dest_y),
204-
dims: (width, height),
205-
} => {
206-
self.check_framebuffer_region((src_x, src_y), (width, height));
207-
self.check_framebuffer_region((dest_x, dest_y), (width, height));
208-
(self.blt)(
209-
self,
210-
ptr::null_mut(),
211-
3,
212-
src_x,
213-
src_y,
214-
dest_x,
215-
dest_y,
216-
width,
217-
height,
218-
0,
219-
)
220-
.into()
221-
}
222224
}
223225
}
224226

‎src/proto/console/serial.rs

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ pub struct Serial<'boot> {
2727
) -> Status,
2828
set_control_bits: extern "win64" fn(&mut Serial, ControlBits) -> Status,
2929
get_control_bits: extern "win64" fn(&Serial, &mut ControlBits) -> Status,
30-
write: extern "win64" fn(&mut Serial, &mut usize, *const u8) -> Status,
31-
read: extern "win64" fn(&mut Serial, &mut usize, *mut u8) -> Status,
30+
write: unsafeextern "win64" fn(&mut Serial, &mut usize, *const u8) -> Status,
31+
read: unsafeextern "win64" fn(&mut Serial, &mut usize, *mut u8) -> Status,
3232
io_mode: &'boot IoMode,
3333
}
3434

@@ -38,6 +38,11 @@ impl<'boot> Serial<'boot> {
3838
(self.reset)(self).into()
3939
}
4040

41+
/// Returns the current I/O mode.
42+
pub fn io_mode(&self) -> &IoMode {
43+
self.io_mode
44+
}
45+
4146
/// Sets the device's new attributes.
4247
///
4348
/// The given `IoMode` will become the device's new `IoMode`,
@@ -64,6 +69,12 @@ impl<'boot> Serial<'boot> {
6469
.into()
6570
}
6671

72+
/// Retrieve the device's current control bits.
73+
pub fn get_control_bits(&self) -> Result<ControlBits> {
74+
let mut bits = ControlBits::empty();
75+
(self.get_control_bits)(self, &mut bits).into_with(|| bits)
76+
}
77+
6778
/// Sets the device's new control bits.
6879
///
6980
/// Not all bits can be modified with this function. A mask of the allowed
@@ -72,48 +83,37 @@ impl<'boot> Serial<'boot> {
7283
(self.set_control_bits)(self, bits).into()
7384
}
7485

75-
/// Retrieve the device's current control bits.
76-
pub fn get_control_bits(&self) -> Result<ControlBits> {
77-
let mut bits = ControlBits::empty();
78-
(self.get_control_bits)(self, &mut bits).into_with(|| bits)
79-
}
80-
81-
/// Writes data to this device.
86+
/// Reads data from this device.
8287
///
83-
/// Returns the number of bytes actually written to the device.
84-
/// In the case of a timeout, this number will be smaller than
85-
/// the buffer's size.
88+
/// Returns the number of bytes actually read from the device.
89+
/// In the case of a timeout or buffer overrun, this number will be smaller
90+
/// than the buffer's size.
8691
///
8792
/// Unlike UEFI, we handle timeouts as warnings, not errors
88-
pub fn write(&mut self, data: &[u8]) -> Result<usize> {
93+
pub fn read(&mut self, data: &mut[u8]) -> Result<usize> {
8994
let mut buffer_size = data.len();
9095

91-
match (self.write)(self, &mut buffer_size, data.as_ptr()) {
96+
match unsafe{(self.read)(self, &mut buffer_size, data.as_mut_ptr())} {
9297
s @ Status::TIMEOUT => Ok(Completion::Warning(buffer_size, s)),
9398
other => other.into_with(|| buffer_size),
9499
}
95100
}
96101

97-
/// Reads data from this device.
102+
/// Writes data to this device.
98103
///
99-
/// Returns the number of bytes actually read from the device.
100-
/// In the case of a timeout or buffer overrun, this number will be smaller
101-
/// than the buffer's size.
104+
/// Returns the number of bytes actually written to the device.
105+
/// In the case of a timeout, this number will be smaller than
106+
/// the buffer's size.
102107
///
103108
/// Unlike UEFI, we handle timeouts as warnings, not errors
104-
pub fn read(&mut self, data: &mut[u8]) -> Result<usize> {
109+
pub fn write(&mut self, data: &[u8]) -> Result<usize> {
105110
let mut buffer_size = data.len();
106111

107-
match (self.read)(self, &mut buffer_size, data.as_mut_ptr()) {
112+
match unsafe{(self.write)(self, &mut buffer_size, data.as_ptr())} {
108113
s @ Status::TIMEOUT => Ok(Completion::Warning(buffer_size, s)),
109114
other => other.into_with(|| buffer_size),
110115
}
111116
}
112-
113-
/// Returns the current I/O mode.
114-
pub fn io_mode(&self) -> &IoMode {
115-
self.io_mode
116-
}
117117
}
118118

119119
impl_proto! {

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /