Skip to content

Commit 36237f3

Browse files
committed
Implement write_all for Xous stdio
1 parent 9e73a17 commit 36237f3

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/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
}

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

+49-31
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
mod unsupported_stdio;
44

55
use crate::io;
6+
use crate::mem::MaybeUninit;
67
use crate::os::xous::ffi::{Connection, lend, try_lend, try_scalar};
78
use crate::os::xous::services::{LogLend, LogScalar, log_server, try_connect};
89

@@ -18,23 +19,16 @@ impl Stdout {
1819

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

3525
fn flush(&mut self) -> io::Result<()> {
3626
Ok(())
3727
}
28+
29+
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
30+
write_all(LogLend::StandardOutput, buf)
31+
}
3832
}
3933

4034
impl Stderr {
@@ -45,23 +39,51 @@ impl Stderr {
4539

4640
impl io::Write for Stderr {
4741
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
48-
#[repr(C, align(4096))]
49-
struct LendBuffer([u8; 4096]);
50-
let mut lend_buffer = LendBuffer([0u8; 4096]);
51-
let connection = log_server();
52-
for chunk in buf.chunks(lend_buffer.0.len()) {
53-
for (dest, src) in lend_buffer.0.iter_mut().zip(chunk) {
54-
*dest = *src;
55-
}
56-
lend(connection, LogLend::StandardError.into(), &lend_buffer.0, 0, chunk.len())
57-
.unwrap();
58-
}
59-
Ok(buf.len())
42+
write(LogLend::StandardError, buf)
6043
}
6144

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

6789
pub const STDIN_BUF_SIZE: usize = unsupported_stdio::STDIN_BUF_SIZE;
@@ -90,13 +112,9 @@ impl io::Write for PanicWriter {
90112
// the data itself in the buffer. Typically several messages are require to
91113
// fully transmit the entire panic message.
92114
if let Some(gfx) = self.gfx {
93-
#[repr(C, align(4096))]
94-
struct Request([u8; 4096]);
95-
let mut request = Request([0u8; 4096]);
96-
for (&s, d) in s.iter().zip(request.0.iter_mut()) {
97-
*d = s;
98-
}
99-
try_lend(gfx, 0 /* AppendPanicText */, &request.0, 0, s.len()).ok();
115+
let mut request = AlignedBuffer::new();
116+
let request = request.fill(s);
117+
_ = try_lend(gfx, 0 /* AppendPanicText */, request, 0, request.len());
100118
}
101119
Ok(s.len())
102120
}

0 commit comments

Comments
 (0)