Fix malta drivers

Signed-off-by: Harry Chen <i@harrychen.xyz>
master
Harry Chen 6 years ago
parent 8dff9f1b14
commit 015cc72aa4

@ -13,7 +13,9 @@ authors = [
"chenqiuhao <haohao0924@126.com>", "chenqiuhao <haohao0924@126.com>",
"maoyuchaxue <wangjt15@mails.tsinghua.edu.cn>", "maoyuchaxue <wangjt15@mails.tsinghua.edu.cn>",
"Jiajie Chen <jiegec@qq.com>", "Jiajie Chen <jiegec@qq.com>",
"chyyuu <yuchen@mail.tsinghua.edu.cn>" "chyyuu <yuchen@mail.tsinghua.edu.cn>",
"Shengqi Chen <harry-chen@outlok.com>",
"Yuhao Zhou <miskcoo@gmail.com>"
] ]
[features] [features]
@ -26,6 +28,8 @@ board_raspi3 = ["bcm2837", "link_user"]
raspi3_use_generic_timer = ["bcm2837/use_generic_timer"] raspi3_use_generic_timer = ["bcm2837/use_generic_timer"]
# for mipsel qemu malta machine # for mipsel qemu malta machine
board_malta = [] board_malta = []
# for thinpad
board_thinpad = []
# Hard link user program # Hard link user program
link_user = [] link_user = []
# Run cmdline instead of user shell, useful for automatic testing # Run cmdline instead of user shell, useful for automatic testing

@ -113,11 +113,13 @@ qemu_opts += \
-kernel $(kernel_img) -kernel $(kernel_img)
else ifeq ($(arch), mipsel) else ifeq ($(arch), mipsel)
ifeq ($(board), malta)
qemu_opts += \ qemu_opts += \
-machine $(board) \ -machine $(board) \
-serial null -serial null -serial mon:stdio \ -serial none -serial none -serial mon:stdio \
-kernel $(kernel_img) -kernel $(kernel_img)
endif endif
endif
ifdef d ifdef d
qemu_opts += -d $(d) qemu_opts += -d $(d)

@ -2,6 +2,8 @@ lazy_static! {
pub static ref FRAME_BUFFER: Mutex<Option<Framebuffer>> = Mutex::new(None); pub static ref FRAME_BUFFER: Mutex<Option<Framebuffer>> = Mutex::new(None);
} }
pub struct Framebuffer {}
pub struct FramebufferInfo {} pub struct FramebufferInfo {}
pub enum ColorDepth {} pub enum ColorDepth {}

@ -8,7 +8,7 @@ pub mod console;
/// Initialize serial port first /// Initialize serial port first
pub fn init_serial_early() { pub fn init_serial_early() {
assert_has_not_been_called!("board::init must be called only once"); assert_has_not_been_called!("board::init must be called only once");
serial::init(); serial::init(0xbf000900);
println!("Hello QEMU Malta!"); println!("Hello QEMU Malta!");
} }

@ -1,88 +1,91 @@
use core::fmt::{Write, Result, Arguments}; use core::fmt::{Write, Result, Arguments};
use core::ptr::{read_volatile, write_volatile}; use core::ptr::{read_volatile, write_volatile};
struct SerialPort {}; struct SerialPort {
base: usize
}
impl SerialPort { impl SerialPort {
fn new() -> SerialPort { fn new() -> SerialPort {
SerialPort { } SerialPort { }
} }
}
impl Write for SerialPort { pub fn init(&mut self, base: usize) {
fn write_str(&mut self, s: &str) -> Result { self.base = base;
for c in s.bytes() { // Turn off the FIFO
if c == 127 { write(self.base + COM_FCR, 0 as u8);
putchar(8); // Set speed; requires DLAB latch
putchar(b' '); write(self.base + COM_LCR, COM_LCR_DLAB);
putchar(8); write(self.base + COM_DLL, (115200 / 9600) as u8);
} else { write(self.base + COM_DLM, 0 as u8);
putchar(c);
}
}
Ok(())
}
}
fn write<T>(addr: usize, content: T) { // 8 data bits, 1 stop bit, parity off; turn off DLAB latch
let cell = (addr) as *mut T; write(self.base + COM_LCR, COM_LCR_WLEN8 & !COM_LCR_DLAB);
write_volatile(cell, content);
}
fn read<T>(addr: usize) -> T { // No modem controls
let cell = (addr) as *const T; write(self.base + COM_MCR, 0 as u8);
read_volatile(cell); // Enable rcv interrupts
} write(self.base + COM_IER, COM_IER_RDI);
}
/// non-blocking version of putchar() /// non-blocking version of putchar()
fn putchar(c: u8) { fn putchar(&mut self, c: u8) {
write(COM1 + COM_TX, c); write(self.base + COM_TX, c);
} }
/// blocking version of getchar() /// blocking version of getchar()
pub fn getchar() -> char { pub fn getchar(&mut self) -> char {
loop { loop {
if (read::<u8>(COM1 + COM_LSR) & COM_LSR_DATA) == 0 { if (read::<u8>(self.base + COM_LSR) & COM_LSR_DATA) == 0 {
break; break;
} }
} }
let c = read::<u8>(COM1 + COM_RX); let c = read::<u8>(self.base + COM_RX);
match c { match c {
255 => '\0', // null 255 => '\0', // null
c => c as char, c => c as char,
} }
} }
/// non-blocking version of getchar() /// non-blocking version of getchar()
pub fn getchar_option() -> Option<char> { pub fn getchar_option(&mut self) -> Option<char> {
match read::<u8>(COM1 + COM_LSR) & COM_LSR_DATA { match read::<u8>(self.base + COM_LSR) & COM_LSR_DATA {
0 => None, 0 => None,
else => Some(read::<u8>(COM1 + COM_RX) as u8 as char), _ => Some(read::<u8>(self.base + COM_RX) as u8 as char),
}
}
pub fn putfmt(&mut self, fmt: Arguments) {
self.write_fmt(fmt).unwrap();
} }
}
pub fn putfmt(fmt: Arguments) {
SerialPort.write_fmt(fmt).unwrap();
} }
pub fn init() { impl Write for SerialPort {
// Turn off the FIFO fn write_str(&mut self, s: &str) -> Result {
write(COM1 + COM_FCR, 0 as u8); for c in s.bytes() {
// Set speed; requires DLAB latch if c == 127 {
write(COM1 + COM_LCR, COM_LCR_DLAB); self.putchar(8);
write(COM1 + COM_DLL, (115200 / 9600) as u8); self.putchar(b' ');
write(COM1 + COM_DLM, 0 as u8); self.putchar(8);
} else {
self.putchar(c);
}
}
Ok(())
}
}
// 8 data bits, 1 stop bit, parity off; turn off DLAB latch fn write<T>(addr: usize, content: T) {
write(COM1 + COM_LCR, COM_LCR_WLEN8 & !COM_LCR_DLAB); let cell = (addr) as *mut T;
write_volatile(cell, content);
}
// No modem controls fn read<T>(addr: usize) -> T {
write(COM1 + COM_MCR, 0 as u8); let cell = (addr) as *const T;
// Enable rcv interrupts read_volatile(cell);
write(COM1 + COM_IER, COM_IER_RDI);
} }
const COM1 :usize = 0xbf000900; // 16550 Base Address
const COM_RX :usize = 0; // In: Receive buffer (DLAB=0) const COM_RX :usize = 0; // In: Receive buffer (DLAB=0)
const COM_TX :usize = 0; // Out: Transmit buffer (DLAB=0) const COM_TX :usize = 0; // Out: Transmit buffer (DLAB=0)
@ -109,6 +112,6 @@ lazy_static! {
pub static ref SERIAL_PORT: Mutex<SerialPort> = Mutex::new(SerialPort::new()); pub static ref SERIAL_PORT: Mutex<SerialPort> = Mutex::new(SerialPort::new());
} }
pub fn init() { pub fn init(base: usize) {
SERIAL_PORT.lock().init(); SERIAL_PORT.lock().init(base);
} }
Loading…
Cancel
Save