Skip to content

Commit 545899b

Browse files
committed
Improve Pipe Protocol
1. Add function pointers to Protocol 2. Using different function pointers for Null Pipes Signed-off-by: Ayush Singh <ayushsingh1325@gmail.com>
1 parent 3df71e6 commit 545899b

File tree

1 file changed

+128
-35
lines changed

1 file changed

+128
-35
lines changed

library/std/src/sys/uefi/pipe.rs

Lines changed: 128 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! An implementation of Pipes using UEFI variables
1+
//! An implementation of Pipes for UEFI
22
33
use super::common;
44
use crate::io::{self, IoSlice, IoSliceMut};
@@ -47,13 +47,36 @@ impl AnonPipe {
4747
}
4848

4949
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
50-
let protocol = common::open_protocol(self.handle, uefi_pipe_protocol::PROTOCOL_GUID)?;
51-
unsafe { uefi_pipe_protocol::Protocol::read(protocol.as_ptr(), buf) }
50+
let protocol = common::open_protocol::<uefi_pipe_protocol::Protocol>(
51+
self.handle,
52+
uefi_pipe_protocol::PROTOCOL_GUID,
53+
)?;
54+
let mut buf_size = buf.len();
55+
let r = unsafe {
56+
((*protocol.as_ptr()).read)(protocol.as_ptr(), &mut buf_size, buf.as_mut_ptr())
57+
};
58+
if r.is_error() { Err(common::status_to_io_error(r)) } else { Ok(buf_size) }
5259
}
5360

5461
pub(crate) fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
55-
let protocol = common::open_protocol(self.handle, uefi_pipe_protocol::PROTOCOL_GUID)?;
56-
unsafe { uefi_pipe_protocol::Protocol::read_to_end(protocol.as_ptr(), buf) }
62+
let protocol = common::open_protocol::<uefi_pipe_protocol::Protocol>(
63+
self.handle,
64+
uefi_pipe_protocol::PROTOCOL_GUID,
65+
)?;
66+
let buf_size = unsafe { ((*protocol.as_ptr()).size)(protocol.as_ptr()) };
67+
buf.reserve_exact(buf_size);
68+
let mut buf_size = buf.capacity();
69+
let r = unsafe {
70+
((*protocol.as_ptr()).read)(protocol.as_ptr(), &mut buf_size, buf.as_mut_ptr())
71+
};
72+
if r.is_error() {
73+
Err(common::status_to_io_error(r))
74+
} else {
75+
unsafe {
76+
buf.set_len(buf.len() + buf_size);
77+
}
78+
Ok(buf_size)
79+
}
5780
}
5881

5982
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
@@ -66,8 +89,14 @@ impl AnonPipe {
6689
}
6790

6891
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
69-
let protocol = common::open_protocol(self.handle, uefi_pipe_protocol::PROTOCOL_GUID)?;
70-
unsafe { uefi_pipe_protocol::Protocol::write(protocol.as_ptr(), buf) }
92+
let protocol = common::open_protocol::<uefi_pipe_protocol::Protocol>(
93+
self.handle,
94+
uefi_pipe_protocol::PROTOCOL_GUID,
95+
)?;
96+
let mut buf_size = buf.len();
97+
let r =
98+
unsafe { ((*protocol.as_ptr()).write)(protocol.as_ptr(), &mut buf_size, buf.as_ptr()) };
99+
if r.is_error() { Err(common::status_to_io_error(r)) } else { Ok(buf_size) }
71100
}
72101

73102
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
@@ -96,6 +125,7 @@ pub(crate) mod uefi_pipe_protocol {
96125
use crate::sys::uefi::common;
97126
use io::{Read, Write};
98127
use r_efi::efi::Guid;
128+
use r_efi::{eficall, eficall_abi};
99129

100130
pub(crate) const PROTOCOL_GUID: Guid = Guid::from_fields(
101131
0x3c4acb49,
@@ -120,26 +150,30 @@ pub(crate) mod uefi_pipe_protocol {
120150
}
121151

122152
#[inline]
123-
pub(crate) unsafe fn read(data: *mut Pipedata, buf: &mut [u8]) -> io::Result<usize> {
153+
unsafe fn read(data: *mut Pipedata, buf: &mut [u8]) -> io::Result<usize> {
124154
unsafe { (*data).data.read(buf) }
125155
}
126156

127157
#[inline]
128-
pub(crate) unsafe fn read_to_end(
129-
data: *mut Pipedata,
130-
buf: &mut Vec<u8>,
131-
) -> io::Result<usize> {
132-
unsafe { (*data).data.read_to_end(buf) }
158+
unsafe fn write(data: *mut Pipedata, buf: &[u8]) -> io::Result<usize> {
159+
unsafe { (*data).data.write(buf) }
133160
}
134161

135162
#[inline]
136-
pub(crate) unsafe fn write(data: *mut Pipedata, buf: &[u8]) -> io::Result<usize> {
137-
unsafe { (*data).data.write(buf) }
163+
unsafe fn size(data: *mut Pipedata) -> usize {
164+
unsafe { (*data).data.len() }
138165
}
139166
}
140167

168+
type WriteSignature = eficall! {fn(*mut Protocol, *mut usize, *const u8) -> r_efi::efi::Status};
169+
type ReadSignature = eficall! {fn(*mut Protocol, *mut usize, *mut u8) -> r_efi::efi::Status};
170+
type SizeSignature = eficall! {fn(*mut Protocol) -> usize};
171+
141172
#[repr(C)]
142173
pub(crate) struct Protocol {
174+
pub read: ReadSignature,
175+
pub write: WriteSignature,
176+
pub size: SizeSignature,
143177
data: *mut Pipedata,
144178
}
145179

@@ -150,39 +184,98 @@ pub(crate) mod uefi_pipe_protocol {
150184
impl Protocol {
151185
#[inline]
152186
pub(crate) fn with_data(data: &mut Pipedata) -> Self {
153-
Self { data }
187+
Self {
188+
data,
189+
read: pipe_protocol_read,
190+
write: pipe_protocol_write,
191+
size: pipe_protocol_size,
192+
}
154193
}
155194

156195
#[inline]
157196
pub(crate) fn null() -> Self {
158-
Self { data: crate::ptr::null_mut() }
197+
Self {
198+
data: crate::ptr::null_mut(),
199+
read: pipe_protocol_null_read,
200+
write: pipe_protocol_null_write,
201+
size: pipe_protocol_null_size,
202+
}
203+
}
204+
205+
unsafe fn read(protocol: *mut Protocol, buf: &mut [u8]) -> io::Result<usize> {
206+
unsafe {
207+
assert!(!(*protocol).data.is_null());
208+
Pipedata::read((*protocol).data, buf)
209+
}
159210
}
160211

161-
pub(crate) unsafe fn read(protocol: *mut Protocol, buf: &mut [u8]) -> io::Result<usize> {
162-
if unsafe { (*protocol).data.is_null() } {
163-
Ok(0)
164-
} else {
165-
unsafe { Pipedata::read((*protocol).data, buf) }
212+
unsafe fn write(protocol: *mut Protocol, buf: &[u8]) -> io::Result<usize> {
213+
unsafe {
214+
assert!(!(*protocol).data.is_null());
215+
Pipedata::write((*protocol).data, buf)
166216
}
167217
}
168218

169-
pub(crate) unsafe fn read_to_end(
170-
protocol: *mut Protocol,
171-
buf: &mut Vec<u8>,
172-
) -> io::Result<usize> {
173-
if unsafe { (*protocol).data.is_null() } {
174-
Ok(0)
175-
} else {
176-
unsafe { Pipedata::read_to_end((*protocol).data, buf) }
219+
unsafe fn size(protocol: *mut Protocol) -> usize {
220+
unsafe {
221+
assert!(!(*protocol).data.is_null());
222+
Pipedata::size((*protocol).data)
177223
}
178224
}
225+
}
179226

180-
pub(crate) unsafe fn write(protocol: *mut Protocol, buf: &[u8]) -> io::Result<usize> {
181-
if unsafe { (*protocol).data.is_null() } {
182-
Ok(buf.len())
183-
} else {
184-
unsafe { Pipedata::write((*protocol).data, buf) }
227+
extern "efiapi" fn pipe_protocol_read(
228+
protocol: *mut Protocol,
229+
buf_size: *mut usize,
230+
buf: *mut u8,
231+
) -> r_efi::efi::Status {
232+
let buffer = unsafe { crate::slice::from_raw_parts_mut(buf, buf_size.read()) };
233+
match unsafe { Protocol::read(protocol, buffer) } {
234+
Ok(x) => {
235+
unsafe { buf_size.write(x) };
236+
r_efi::efi::Status::SUCCESS
185237
}
238+
Err(_) => r_efi::efi::Status::ABORTED,
186239
}
187240
}
241+
242+
extern "efiapi" fn pipe_protocol_write(
243+
protocol: *mut Protocol,
244+
buf_size: *mut usize,
245+
buf: *const u8,
246+
) -> r_efi::efi::Status {
247+
let buffer = unsafe { crate::slice::from_raw_parts(buf, buf_size.read()) };
248+
match unsafe { Protocol::write(protocol, buffer) } {
249+
Ok(x) => {
250+
unsafe { buf_size.write(x) };
251+
r_efi::efi::Status::SUCCESS
252+
}
253+
Err(_) => r_efi::efi::Status::ABORTED,
254+
}
255+
}
256+
257+
extern "efiapi" fn pipe_protocol_size(protocol: *mut Protocol) -> usize {
258+
unsafe { Protocol::size(protocol) }
259+
}
260+
261+
extern "efiapi" fn pipe_protocol_null_write(
262+
_protocol: *mut Protocol,
263+
_buf_size: *mut usize,
264+
_buf: *const u8,
265+
) -> r_efi::efi::Status {
266+
r_efi::efi::Status::SUCCESS
267+
}
268+
269+
extern "efiapi" fn pipe_protocol_null_read(
270+
_protocol: *mut Protocol,
271+
buf_size: *mut usize,
272+
_buf: *mut u8,
273+
) -> r_efi::efi::Status {
274+
unsafe { buf_size.write(0) };
275+
r_efi::efi::Status::SUCCESS
276+
}
277+
278+
extern "efiapi" fn pipe_protocol_null_size(_protocol: *mut Protocol) -> usize {
279+
0
280+
}
188281
}

0 commit comments

Comments
 (0)