Skip to content

Commit b334e5b

Browse files
committed
kernel: Split debug shell and uart driver.
I've added a `platform` module to store all platform specific code, (not architecture specific) as some platforms will require custom drivers, e.g. for debug output and for the random number generation code. The platform code is in charge of mapping any peripherals needed to work, also to initialize any other parts of the kernel that require drivers, for example the debug shell. Signed-off-by: Jean-Pierre De Jesus DIAZ <[email protected]>
1 parent 4f9e6f1 commit b334e5b

File tree

8 files changed

+431
-350
lines changed

8 files changed

+431
-350
lines changed

kernel/src/debug/macros.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// SPDX-FileCopyrightText: 2020 Sean Cross <[email protected]>
2+
// SPDX-FileCopyrightText: 2022 Foundation Devices, Inc. <[email protected]>
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
/// Prints to the debug output directly.
6+
#[cfg(baremetal)]
7+
#[macro_export]
8+
macro_rules! print {
9+
($($args:tt)+) => {{
10+
#[allow(unused_unsafe)]
11+
unsafe {
12+
use core::fmt::Write;
13+
if let Some(stream) = crate::debug::shell::OUTPUT.as_mut() {
14+
write!(stream, $($args)+).unwrap();
15+
}
16+
}
17+
}};
18+
}
19+
20+
/// Prints to the debug output directly, with a newline.
21+
#[cfg(baremetal)]
22+
#[macro_export]
23+
macro_rules! println {
24+
() => ({
25+
print!("\r\n")
26+
});
27+
($fmt:expr) => ({
28+
print!(concat!($fmt, "\r\n"))
29+
});
30+
($fmt:expr, $($args:tt)+) => ({
31+
print!(concat!($fmt, "\r\n"), $($args)+)
32+
});
33+
}
34+
35+
#[cfg(feature = "debug-print")]
36+
#[macro_export]
37+
macro_rules! klog {
38+
() => ({
39+
print!(" [{}:{}]", file!(), line!())
40+
});
41+
($fmt:expr) => ({
42+
print!(concat!(" [{}:{} ", $fmt, "]"), file!(), line!())
43+
});
44+
($fmt:expr, $($args:tt)+) => ({
45+
print!(concat!(" [{}:{} ", $fmt, "]"), file!(), line!(), $($args)+)
46+
});
47+
}
48+
49+
#[cfg(not(feature = "debug-print"))]
50+
#[macro_export]
51+
macro_rules! klog {
52+
($($args:tt)+) => {{}};
53+
}

kernel/src/debug/mod.rs

Lines changed: 2 additions & 313 deletions
Original file line numberDiff line numberDiff line change
@@ -1,318 +1,7 @@
11
// SPDX-FileCopyrightText: 2020 Sean Cross <[email protected]>
22
// SPDX-License-Identifier: Apache-2.0
33

4-
#[cfg(baremetal)]
5-
use core::fmt::{Error, Write};
6-
#[cfg(baremetal)]
7-
use utralib::generated::*;
8-
9-
#[cfg(baremetal)]
10-
pub static mut DEBUG_OUTPUT: Option<&'static mut dyn Write> = None;
11-
12-
pub use crate::arch::process::Process as ArchProcess;
13-
144
#[macro_use]
15-
#[cfg(all(
16-
not(test),
17-
baremetal,
18-
any(feature = "debug-print", feature = "print-panics")
19-
))]
20-
pub mod debug_print_hardware {
21-
// the HW device mapping is done in main.rs/init(); the virtual address has to be in the top 4MiB as it is the only page shared among all processes
22-
pub const SUPERVISOR_UART_ADDR: *mut usize = 0xffcf_0000 as *mut usize; // see https://github.com/betrusted-io/xous-core/blob/master/docs/memory.md
23-
}
24-
#[cfg(all(
25-
not(test),
26-
baremetal,
27-
any(feature = "debug-print", feature = "print-panics")
28-
))]
29-
pub use crate::debug::debug_print_hardware::SUPERVISOR_UART_ADDR;
30-
31-
#[cfg(baremetal)]
32-
#[macro_export]
33-
macro_rules! print {
34-
($($args:tt)+) => {{
35-
#[allow(unused_unsafe)]
36-
unsafe {
37-
if let Some(mut stream) = crate::debug::DEBUG_OUTPUT.as_mut() {
38-
write!(&mut stream, $($args)+).unwrap();
39-
}
40-
}
41-
}};
42-
}
43-
44-
#[cfg(baremetal)]
45-
#[macro_export]
46-
macro_rules! println
47-
{
48-
() => ({
49-
print!("\r\n")
50-
});
51-
($fmt:expr) => ({
52-
print!(concat!($fmt, "\r\n"))
53-
});
54-
($fmt:expr, $($args:tt)+) => ({
55-
print!(concat!($fmt, "\r\n"), $($args)+)
56-
});
57-
}
58-
59-
#[cfg(baremetal)]
60-
pub struct Uart {}
5+
mod macros;
616
#[cfg(baremetal)]
62-
pub static mut UART: Uart = Uart {};
63-
64-
#[cfg(all(baremetal, feature = "wrap-print"))]
65-
static mut CHAR_COUNT: usize = 0;
66-
67-
#[cfg(baremetal)]
68-
impl Uart {
69-
#[allow(dead_code)]
70-
pub fn init(self) {
71-
unsafe { DEBUG_OUTPUT = Some(&mut UART) };
72-
let mut uart_csr = CSR::new(crate::debug::SUPERVISOR_UART_ADDR as *mut u32);
73-
uart_csr.rmwf(utra::uart::EV_ENABLE_RX, 1);
74-
}
75-
76-
pub fn putc(&self, c: u8) {
77-
if unsafe { DEBUG_OUTPUT.is_none() } {
78-
return;
79-
}
80-
81-
let mut uart_csr = CSR::new(crate::debug::SUPERVISOR_UART_ADDR as *mut u32);
82-
// Wait until TXFULL is `0`
83-
while uart_csr.r(utra::uart::TXFULL) != 0 {}
84-
#[cfg(feature = "wrap-print")]
85-
unsafe {
86-
if c == b'\n' {
87-
CHAR_COUNT = 0;
88-
} else if CHAR_COUNT > 80 {
89-
CHAR_COUNT = 0;
90-
self.putc(b'\n');
91-
self.putc(b'\r');
92-
self.putc(b' ');
93-
self.putc(b' ');
94-
self.putc(b' ');
95-
self.putc(b' ');
96-
} else {
97-
CHAR_COUNT += 1;
98-
}
99-
}
100-
uart_csr.wfo(utra::uart::RXTX_RXTX, c as u32);
101-
}
102-
103-
#[allow(dead_code)]
104-
pub fn getc(&self) -> Option<u8> {
105-
if unsafe { DEBUG_OUTPUT.is_none() } {
106-
return None;
107-
}
108-
let mut uart_csr = CSR::new(crate::debug::SUPERVISOR_UART_ADDR as *mut u32);
109-
// If EV_PENDING_RX is 1, return the pending character.
110-
// Otherwise, return None.
111-
match uart_csr.rf(utra::uart::EV_PENDING_RX) {
112-
0 => None,
113-
_ => {
114-
let ret = Some(uart_csr.r(utra::uart::RXTX) as u8);
115-
uart_csr.wfo(utra::uart::EV_PENDING_RX, 1);
116-
ret
117-
}
118-
}
119-
}
120-
}
121-
122-
#[cfg(all(
123-
baremetal,
124-
not(test),
125-
any(feature = "debug-print", feature = "print-panics")
126-
))]
127-
pub fn irq(_irq_number: usize, _arg: *mut usize) {
128-
let uart = Uart {};
129-
while let Some(b) = uart.getc() {
130-
process_irq_character(b);
131-
}
132-
// uart.acknowledge_irq();
133-
}
134-
135-
#[cfg(all(
136-
baremetal,
137-
not(test),
138-
any(feature = "debug-print", feature = "print-panics")
139-
))]
140-
fn process_irq_character(b: u8) {
141-
match b {
142-
b'i' => {
143-
println!("Interrupt handlers:");
144-
println!(" IRQ | Process | Handler | Argument");
145-
crate::services::SystemServices::with(|system_services| {
146-
crate::irq::for_each_irq(|irq, pid, address, arg| {
147-
println!(
148-
" {}: {} @ {:x?} {:x?}",
149-
irq,
150-
system_services.process_name(*pid).unwrap_or(""),
151-
address,
152-
arg
153-
);
154-
});
155-
});
156-
}
157-
b'm' => {
158-
println!("Printing memory page tables");
159-
crate::services::SystemServices::with(|system_services| {
160-
let current_pid = system_services.current_pid();
161-
for process in &system_services.processes {
162-
if !process.free() {
163-
println!(
164-
"PID {} {}:",
165-
process.pid,
166-
system_services.process_name(process.pid).unwrap_or("")
167-
);
168-
process.activate().unwrap();
169-
crate::arch::mem::MemoryMapping::current().print_map();
170-
println!();
171-
}
172-
}
173-
system_services
174-
.get_process(current_pid)
175-
.unwrap()
176-
.activate()
177-
.unwrap();
178-
});
179-
}
180-
b'p' => {
181-
println!("Printing processes");
182-
crate::services::SystemServices::with(|system_services| {
183-
let current_pid = system_services.current_pid();
184-
for process in &system_services.processes {
185-
if !process.free() {
186-
process.activate().unwrap();
187-
let mut connection_count = 0;
188-
ArchProcess::with_inner(|process_inner| {
189-
for conn in &process_inner.connection_map {
190-
if conn.is_some() {
191-
connection_count += 1;
192-
}
193-
}
194-
});
195-
println!(
196-
"{:?} conns:{}/32 {}",
197-
process,
198-
connection_count,
199-
system_services.process_name(process.pid).unwrap_or("")
200-
);
201-
}
202-
}
203-
system_services
204-
.get_process(current_pid)
205-
.unwrap()
206-
.activate()
207-
.unwrap();
208-
});
209-
}
210-
b'P' => {
211-
println!("Printing processes and threads");
212-
crate::services::SystemServices::with(|system_services| {
213-
let current_pid = system_services.current_pid();
214-
for process in &system_services.processes {
215-
if !process.free() {
216-
println!(
217-
"{:?} {}:",
218-
process,
219-
system_services.process_name(process.pid).unwrap_or("")
220-
);
221-
process.activate().unwrap();
222-
crate::arch::process::Process::with_current_mut(|arch_process| {
223-
arch_process.print_all_threads()
224-
});
225-
println!();
226-
}
227-
}
228-
system_services
229-
.get_process(current_pid)
230-
.unwrap()
231-
.activate()
232-
.unwrap();
233-
});
234-
}
235-
b'r' => {
236-
println!("RAM usage:");
237-
let mut total_bytes = 0;
238-
crate::services::SystemServices::with(|system_services| {
239-
crate::mem::MemoryManager::with(|mm| {
240-
for process in &system_services.processes {
241-
if !process.free() {
242-
let bytes_used = mm.ram_used_by(process.pid);
243-
total_bytes += bytes_used;
244-
println!(
245-
" PID {:>3}: {:>4} k {}",
246-
process.pid,
247-
bytes_used / 1024,
248-
system_services.process_name(process.pid).unwrap_or("")
249-
);
250-
}
251-
}
252-
});
253-
});
254-
println!("{} k total", total_bytes / 1024);
255-
}
256-
b's' => {
257-
println!("Servers in use:");
258-
crate::services::SystemServices::with(|system_services| {
259-
println!(" idx | pid | process | sid");
260-
println!(" --- + --- + -------------------- | ------------------");
261-
for (idx, server) in system_services.servers.iter().enumerate() {
262-
if let Some(s) = server {
263-
println!(
264-
" {:3} | {:3} | {:20} | {:x?}",
265-
idx,
266-
s.pid,
267-
system_services.process_name(s.pid).unwrap_or(""),
268-
s.sid
269-
);
270-
}
271-
}
272-
});
273-
}
274-
b'h' => {
275-
println!("Xous Kernel Debug");
276-
println!("key | command");
277-
println!("--- + -----------------------");
278-
println!(" i | print irq handlers");
279-
println!(" m | print MMU page tables of all processes");
280-
println!(" p | print all processes");
281-
println!(" P | print all processes and threads");
282-
println!(" r | report RAM usage of all processes");
283-
println!(" s | print all allocated servers");
284-
}
285-
_ => {}
286-
}
287-
}
288-
289-
#[cfg(baremetal)]
290-
impl Write for Uart {
291-
fn write_str(&mut self, s: &str) -> Result<(), Error> {
292-
for c in s.bytes() {
293-
self.putc(c);
294-
}
295-
Ok(())
296-
}
297-
}
298-
299-
#[cfg(feature = "debug-print")]
300-
#[macro_export]
301-
macro_rules! klog
302-
{
303-
() => ({
304-
print!(" [{}:{}]", file!(), line!())
305-
});
306-
($fmt:expr) => ({
307-
print!(concat!(" [{}:{} ", $fmt, "]"), file!(), line!())
308-
});
309-
($fmt:expr, $($args:tt)+) => ({
310-
print!(concat!(" [{}:{} ", $fmt, "]"), file!(), line!(), $($args)+)
311-
});
312-
}
313-
314-
#[cfg(not(feature = "debug-print"))]
315-
#[macro_export]
316-
macro_rules! klog {
317-
($($args:tt)+) => {{}};
318-
}
7+
pub mod shell;

0 commit comments

Comments
 (0)