3
3
mod unsupported_stdio;
4
4
5
5
use crate :: io;
6
+ use crate :: mem:: MaybeUninit ;
6
7
use crate :: os:: xous:: ffi:: { Connection , lend, try_lend, try_scalar} ;
7
8
use crate :: os:: xous:: services:: { LogLend , LogScalar , log_server, try_connect} ;
8
9
@@ -18,23 +19,16 @@ impl Stdout {
18
19
19
20
impl io:: Write for Stdout {
20
21
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)
33
23
}
34
24
35
25
fn flush ( & mut self ) -> io:: Result < ( ) > {
36
26
Ok ( ( ) )
37
27
}
28
+
29
+ fn write_all ( & mut self , buf : & [ u8 ] ) -> io:: Result < ( ) > {
30
+ write_all ( LogLend :: StandardOutput , buf)
31
+ }
38
32
}
39
33
40
34
impl Stderr {
@@ -45,23 +39,51 @@ impl Stderr {
45
39
46
40
impl io:: Write for Stderr {
47
41
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)
60
43
}
61
44
62
45
fn flush ( & mut self ) -> io:: Result < ( ) > {
63
46
Ok ( ( ) )
64
47
}
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 ( ( ) )
65
87
}
66
88
67
89
pub const STDIN_BUF_SIZE : usize = unsupported_stdio:: STDIN_BUF_SIZE ;
@@ -90,13 +112,9 @@ impl io::Write for PanicWriter {
90
112
// the data itself in the buffer. Typically several messages are require to
91
113
// fully transmit the entire panic message.
92
114
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 ( ) ) ;
100
118
}
101
119
Ok ( s. len ( ) )
102
120
}
0 commit comments