Skip to content

Commit f5d401a

Browse files
committed
Provide write_all for Xous stdio
1 parent f0764b1 commit f5d401a

File tree

3 files changed

+55
-36
lines changed

3 files changed

+55
-36
lines changed

library/std/src/os/xous/services/log.rs

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ impl<'a> Into<[usize; 5]> for LogScalar<'a> {
4646
}
4747
}
4848

49+
#[derive(Clone, Copy)]
4950
pub(crate) enum LogLend {
5051
StandardOutput = 1,
5152
StandardError = 2,

library/std/src/sys/pal/xous/stdio.rs

+49-31
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::io;
2+
use crate::mem::MaybeUninit;
23
use crate::os::xous::ffi::{Connection, lend, try_lend, try_scalar};
34
use crate::os::xous::services::{LogLend, LogScalar, log_server, try_connect};
45

@@ -14,23 +15,16 @@ impl Stdout {
1415

1516
impl io::Write for Stdout {
1617
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
17-
#[repr(C, align(4096))]
18-
struct LendBuffer([u8; 4096]);
19-
let mut lend_buffer = LendBuffer([0u8; 4096]);
20-
let connection = log_server();
21-
for chunk in buf.chunks(lend_buffer.0.len()) {
22-
for (dest, src) in lend_buffer.0.iter_mut().zip(chunk) {
23-
*dest = *src;
24-
}
25-
lend(connection, LogLend::StandardOutput.into(), &lend_buffer.0, 0, chunk.len())
26-
.unwrap();
27-
}
28-
Ok(buf.len())
18+
write(LogLend::StandardOutput, buf)
2919
}
3020

3121
fn flush(&mut self) -> io::Result<()> {
3222
Ok(())
3323
}
24+
25+
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
26+
write_all(LogLend::StandardOutput, buf)
27+
}
3428
}
3529

3630
impl Stderr {
@@ -41,23 +35,51 @@ impl Stderr {
4135

4236
impl io::Write for Stderr {
4337
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
44-
#[repr(C, align(4096))]
45-
struct LendBuffer([u8; 4096]);
46-
let mut lend_buffer = LendBuffer([0u8; 4096]);
47-
let connection = log_server();
48-
for chunk in buf.chunks(lend_buffer.0.len()) {
49-
for (dest, src) in lend_buffer.0.iter_mut().zip(chunk) {
50-
*dest = *src;
51-
}
52-
lend(connection, LogLend::StandardError.into(), &lend_buffer.0, 0, chunk.len())
53-
.unwrap();
54-
}
55-
Ok(buf.len())
38+
write(LogLend::StandardError, buf)
5639
}
5740

5841
fn flush(&mut self) -> io::Result<()> {
5942
Ok(())
6043
}
44+
45+
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
46+
write_all(LogLend::StandardError, buf)
47+
}
48+
}
49+
50+
#[repr(C, align(4096))]
51+
struct AlignedBuffer([MaybeUninit<u8>; 4096]);
52+
53+
impl AlignedBuffer {
54+
#[inline]
55+
fn new() -> Self {
56+
AlignedBuffer([MaybeUninit::uninit(); 4096])
57+
}
58+
59+
#[inline]
60+
fn fill(&mut self, buf: &[u8]) -> &[u8] {
61+
let len = buf.len().min(self.0.len());
62+
self.0[..len].write_copy_of_slice(&buf[..len]);
63+
// SAFETY: This range was just initialized.
64+
unsafe { self.0[..len].assume_init_ref() }
65+
}
66+
}
67+
68+
fn write(opcode: LogLend, buf: &[u8]) -> io::Result<usize> {
69+
let mut aligned_buffer = AlignedBuffer::new();
70+
let aligned = aligned_buffer.fill(buf);
71+
lend(log_server(), opcode.into(), aligned, 0, aligned.len()).unwrap();
72+
Ok(aligned.len())
73+
}
74+
75+
fn write_all(opcode: LogLend, buf: &[u8]) -> io::Result<()> {
76+
let mut aligned_buffer = AlignedBuffer::new();
77+
let connection = log_server();
78+
for chunk in buf.chunks(aligned_buffer.0.len()) {
79+
let aligned = aligned_buffer.fill(chunk);
80+
lend(connection, opcode.into(), aligned, 0, aligned.len()).unwrap();
81+
}
82+
Ok(())
6183
}
6284

6385
pub const STDIN_BUF_SIZE: usize = super::unsupported_stdio::STDIN_BUF_SIZE;
@@ -86,13 +108,9 @@ impl io::Write for PanicWriter {
86108
// the data itself in the buffer. Typically several messages are require to
87109
// fully transmit the entire panic message.
88110
if let Some(gfx) = self.gfx {
89-
#[repr(C, align(4096))]
90-
struct Request([u8; 4096]);
91-
let mut request = Request([0u8; 4096]);
92-
for (&s, d) in s.iter().zip(request.0.iter_mut()) {
93-
*d = s;
94-
}
95-
try_lend(gfx, 0 /* AppendPanicText */, &request.0, 0, s.len()).ok();
111+
let mut request = AlignedBuffer::new();
112+
let request = request.fill(s);
113+
_ = try_lend(gfx, 0 /* AppendPanicText */, request, 0, request.len());
96114
}
97115
Ok(s.len())
98116
}

library/std/src/sys/pal/xous/thread.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,11 @@ impl Thread {
9494
asm!(
9595
"ecall",
9696
"ret",
97-
in("a0") Syscall::UnmapMemory as usize,
98-
in("a1") mapped_memory_base,
99-
in("a2") mapped_memory_length,
100-
in("ra") 0xff80_3000usize,
101-
options(nomem, nostack, noreturn)
97+
in("a0") Syscall::UnmapMemory as usize,
98+
in("a1") mapped_memory_base,
99+
in("a2") mapped_memory_length,
100+
in("ra") 0xff80_3000usize,
101+
options(nomem, nostack, noreturn)
102102
);
103103
}
104104
}

0 commit comments

Comments
 (0)