1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-21 23:56:18 +04:00

Use uart16550 as serial in mipsel as well

This commit is contained in:
Jiajie Chen 2020-07-09 12:36:26 +08:00
parent 6906337068
commit 8942bb8eeb
15 changed files with 62 additions and 207 deletions

2
kernel/Cargo.lock generated
View File

@ -166,7 +166,7 @@ dependencies = [
[[package]]
name = "device_tree"
version = "1.0.3"
source = "git+https://github.com/rcore-os/device_tree-rs?rev=2fa8411c#2fa8411c421c6b4761992fd3d1a9b2427bf0cfc4"
source = "git+https://github.com/rcore-os/device_tree-rs?rev=eee2c23#eee2c23d50a2cdacb7777429d71e00691b361978"
[[package]]
name = "either"

View File

@ -48,7 +48,7 @@ bitvec = { version = "0.17", default-features = false, features = ["alloc"] }
bit_field = "0.10"
buddy_system_allocator = "0.4.0"
compression = { version = "0.1.4", default-features = false, features = ["gzip"] }
device_tree = { git = "https://github.com/rcore-os/device_tree-rs", rev = "2fa8411c" }
device_tree = { git = "https://github.com/rcore-os/device_tree-rs", rev = "eee2c23" }
executor = { git = "https://github.com/rcore-os/executor.git", rev = "a2d02ee9" }
isomorphic_drivers = { git = "https://github.com/rcore-os/isomorphic_drivers", rev = "fcf694d2", features = ["log"] }
lazy_static = { version = "1.4", features = ["spin_no_std"] }

View File

@ -25,12 +25,6 @@
reg = <0x00000000 0x10000000>;
};
uart0: serial@b80003f8 {
compatible = "ns16550a";
reg = <0xb80003f8 0x8>;
clock-frequency = <1843200>;
};
uart2: serial@bf000900 {
compatible = "ns16550a";
reg = <0xbf000900 0x40>;

View File

@ -1,11 +1,10 @@
use crate::drivers::block::ide;
use crate::drivers::bus::pci;
use crate::drivers::gpu::fb::{self, FramebufferInfo};
use crate::drivers::*;
use mips::registers::cp0;
pub mod consts;
#[path = "../../../../drivers/serial/ti_16c550c.rs"]
pub mod serial;
#[path = "../../../../drivers/gpu/qemu_stdvga.rs"]
pub mod vga;
@ -13,9 +12,7 @@ pub mod vga;
pub static DTB: &'static [u8] = include_bytes!("device.dtb");
/// Initialize serial port first
pub fn init_serial_early() {
// initialize serial driver
serial::init(0xbf000900);
pub fn early_init() {
// Enable serial interrupt
let mut status = cp0::status::read();
status.enable_hard_int2();
@ -24,8 +21,9 @@ pub fn init_serial_early() {
}
/// Initialize other board drivers
pub fn init_driver() {
pub fn init(dtb: usize) {
// TODO: add possibly more drivers
serial::uart16550::driver_init();
vga::init(0xbbe00000, 0xb2050000, 800, 600);
pci::init();
@ -44,4 +42,5 @@ pub fn init_driver() {
};
fb::init(fb_info);
ide::init();
device_tree::init(dtb);
}

View File

@ -1,11 +0,0 @@
//! mipsel drivers
use super::board;
pub use self::board::serial;
/// Initialize common drivers
pub fn init() {
board::init_driver();
crate::drivers::console::init();
}

View File

@ -4,10 +4,7 @@ pub fn is_page_fault(trap: usize) -> bool {
use cp0::cause::Exception as E;
let cause = cp0::cause::Cause { bits: trap as u32 };
match cause.cause() {
E::TLBModification | E::TLBLoadMiss | E::TLBStoreMiss => {
info!("{:#?}", cause.cause());
true
}
E::TLBModification | E::TLBLoadMiss | E::TLBStoreMiss => true,
_ => false,
}
}

View File

@ -23,12 +23,7 @@ pub fn init() {
status.enable_soft_int1();
// Enable clock interrupt
status.enable_hard_int5();
// status.enable_hard_int4();
// status.enable_hard_int3();
// status.enable_hard_int2();
// status.enable_hard_int1();
// status.enable_hard_int0();
// error!("{:#x?}", status);
cp0::status::write(status);
info!("interrupt: init end");
}
@ -100,7 +95,7 @@ fn interrupt_dispatcher(tf: &mut TrapFrame) {
fn external() {
// true means handled, false otherwise
let handlers = [try_process_serial, try_process_drivers];
let handlers = [try_process_drivers];
for handler in handlers.iter() {
if handler() == true {
break;
@ -108,17 +103,6 @@ fn external() {
}
}
fn try_process_serial() -> bool {
match super::io::getchar_option() {
Some(ch) => {
trace!("Get char {} from serial", ch);
crate::trap::serial(ch);
true
}
None => false,
}
}
fn try_process_drivers() -> bool {
IRQ_MANAGER.read().try_handle_interrupt(None)
}
@ -248,22 +232,6 @@ pub fn handle_user_page_fault(thread: &Arc<Thread>, addr: usize) -> bool {
} else {
tlb_entry.entry_lo1.valid()
};
// thread.vm.lock().handle_page_fault(addr);
// if !crate::memory::handle_page_fault(addr) {
// extern "C" {
// fn _copy_user_start();
// fn _copy_user_end();
// }
// let mut inner = thread.inner.lock();
// if let Some(tf) = &mut inner.context {
// let mut tf = &mut tf.user;
// if tf.epc >= _copy_user_start as usize && tf.epc < _copy_user_end as usize {
// debug!("fixup for addr {:x?}", addr);
// tf.epc = crate::memory::read_user_fixup as usize;
// return true;
// }
// }
// }
if !tlb_valid {
if !thread.vm.lock().handle_page_fault(addr) {
@ -352,5 +320,3 @@ pub fn wait_for_interrupt() {
cp0::status::enable_interrupt();
cp0::status::disable_interrupt();
}
//2ea84

View File

@ -1,22 +1,14 @@
//! Input/output for mipsel.
use super::driver::serial::*;
use crate::drivers::console::CONSOLE;
use crate::drivers::{console::CONSOLE, SERIAL_DRIVERS};
use core::fmt::{Arguments, Write};
pub fn getchar() -> u8 {
unsafe { SERIAL_PORT.force_unlock() }
SERIAL_PORT.lock().getchar()
}
pub fn getchar_option() -> Option<u8> {
unsafe { SERIAL_PORT.force_unlock() }
SERIAL_PORT.lock().getchar_option()
}
pub fn putfmt(fmt: Arguments) {
unsafe { SERIAL_PORT.force_unlock() }
SERIAL_PORT.lock().write_fmt(fmt).unwrap();
// output to serial
let mut drivers = SERIAL_DRIVERS.write();
if let Some(serial) = drivers.first_mut() {
serial.write(format!("{}", fmt).as_bytes());
}
unsafe { CONSOLE.force_unlock() }
if let Some(console) = CONSOLE.lock().as_mut() {

View File

@ -1,6 +1,5 @@
pub mod consts;
pub mod cpu;
pub mod driver;
pub mod fp;
pub mod interrupt;
pub mod io;
@ -36,13 +35,13 @@ pub extern "C" fn rust_main() -> ! {
memory::clear_bss();
}
board::init_serial_early();
board::early_init();
crate::logging::init();
interrupt::init();
memory::init();
timer::init();
driver::init();
board::init(dtb_start);
info!("Hello MIPS 32 from CPU {}, dtb @ {:#x}", cpu_id, dtb_start);

View File

@ -1,102 +0,0 @@
//! TI 16c550c serial adapter driver for malta board
#![allow(dead_code)]
use crate::sync::SpinLock as Mutex;
use crate::util::{read, write};
use core::fmt::{Arguments, Result, Write};
pub struct SerialPort {
base: usize,
}
impl SerialPort {
fn new() -> SerialPort {
SerialPort { base: 0 }
}
pub fn init(&mut self, base: usize) {
self.base = base;
// Turn off the FIFO
// write(self.base + COM_FCR, 0 as u8);
// Set speed; requires DLAB latch
// write(self.base + COM_LCR, COM_LCR_DLAB);
// write(self.base + COM_DLL, (115200 / 9600) as u8);
// write(self.base + COM_DLM, 0 as u8);
// 8 data bits, 1 stop bit, parity off; turn off DLAB latch
// write(self.base + COM_LCR, COM_LCR_WLEN8 & !COM_LCR_DLAB);
// No modem controls
// write(self.base + COM_MCR, 0 as u8);
// Enable rcv interrupts
write(self.base + COM_INT_EN, 0x1);
}
/// non-blocking version of putchar()
pub fn putchar(&mut self, c: u8) {
write(self.base + COM_TX, c);
}
/// blocking version of getchar()
pub fn getchar(&mut self) -> u8 {
loop {
if (read::<u8>(self.base + COM_LSR) & 0x01) == 0 {
break;
}
}
let c = read::<u8>(self.base + COM_RX);
match c {
255 => 0, // null
c => c,
}
}
/// non-blocking version of getchar()
pub fn getchar_option(&mut self) -> Option<u8> {
match read::<u8>(self.base + COM_LSR) & 0x01 {
0 => None,
_ => Some(read::<u8>(self.base + COM_RX) as u8),
}
}
pub fn putfmt(&mut self, fmt: Arguments) {
self.write_fmt(fmt).unwrap();
}
}
impl Write for SerialPort {
fn write_str(&mut self, s: &str) -> Result {
for c in s.bytes() {
match c {
127 => {
self.putchar(8);
self.putchar(b' ');
self.putchar(8);
}
b'\n' => {
self.putchar(b'\r');
self.putchar(b'\n');
}
c => {
self.putchar(c);
}
}
}
Ok(())
}
}
const COM_RX: usize = 0x00; // In: Receive buffer (DLAB=0)
const COM_TX: usize = 0x00; // Out: Transmit buffer (DLAB=0)
const COM_INT_EN: usize = 0x08; // In: Interrupt enable
const COM_INT_ID: usize = 0x10; // Out: Interrupt identification
const COM_LSR: usize = 0x28; // In: Line status register
lazy_static! {
pub static ref SERIAL_PORT: Mutex<SerialPort> = Mutex::new(SerialPort::new());
}
pub fn init(base: usize) {
SERIAL_PORT.lock().init(base);
}

View File

@ -16,6 +16,7 @@ use device_tree::Node;
pub struct SerialPort {
base: usize,
multiplier: usize,
}
impl Driver for SerialPort {
@ -38,8 +39,11 @@ impl Driver for SerialPort {
}
impl SerialPort {
fn new(base: usize) -> SerialPort {
let mut res = SerialPort { base: 0 };
fn new(base: usize, shift: usize) -> SerialPort {
let mut res = SerialPort {
base: 0,
multiplier: 1 << shift,
};
res.init(base);
res
}
@ -47,39 +51,42 @@ impl SerialPort {
pub fn init(&mut self, base: usize) {
self.base = base;
// Turn off the FIFO
write(self.base + COM_FCR, 0 as u8);
write(self.base + COM_FCR * self.multiplier, 0 as u8);
// Set speed; requires DLAB latch
write(self.base + COM_LCR, COM_LCR_DLAB);
write(self.base + COM_DLL, (115200 / 9600) as u8);
write(self.base + COM_DLM, 0 as u8);
write(self.base + COM_LCR * self.multiplier, COM_LCR_DLAB);
//write(self.base + COM_DLL * self.multiplier, (115200 / 9600) as u8);
//write(self.base + COM_DLM * self.multiplier, 0 as u8);
// 8 data bits, 1 stop bit, parity off; turn off DLAB latch
write(self.base + COM_LCR, COM_LCR_WLEN8 & !COM_LCR_DLAB);
write(
self.base + COM_LCR * self.multiplier,
COM_LCR_WLEN8 & !COM_LCR_DLAB,
);
// No modem controls
write(self.base + COM_MCR, 0 as u8);
write(self.base + COM_MCR * self.multiplier, 0 as u8);
// Enable rcv interrupts
write(self.base + COM_IER, COM_IER_RDI);
write(self.base + COM_IER * self.multiplier, COM_IER_RDI);
}
/// non-blocking version of putchar()
pub fn putchar(&self, c: u8) {
for _ in 0..100 {
if (read::<u8>(self.base + COM_LSR) & COM_LSR_TXRDY) == 0 {
if (read::<u8>(self.base + COM_LSR * self.multiplier) & COM_LSR_TXRDY) == 0 {
break;
}
}
write(self.base + COM_TX, c);
write(self.base + COM_TX * self.multiplier, c);
}
/// blocking version of getchar()
pub fn getchar(&mut self) -> u8 {
loop {
if (read::<u8>(self.base + COM_LSR) & COM_LSR_DATA) == 0 {
if (read::<u8>(self.base + COM_LSR * self.multiplier) & COM_LSR_DATA) == 0 {
break;
}
}
let c = read::<u8>(self.base + COM_RX);
let c = read::<u8>(self.base + COM_RX * self.multiplier);
match c {
255 => b'\0', // null
c => c,
@ -88,9 +95,9 @@ impl SerialPort {
/// non-blocking version of getchar()
pub fn getchar_option(&self) -> Option<u8> {
match read::<u8>(self.base + COM_LSR) & COM_LSR_DATA {
match read::<u8>(self.base + COM_LSR * self.multiplier) & COM_LSR_DATA {
0 => None,
_ => Some(read::<u8>(self.base + COM_RX) as u8),
_ => Some(read::<u8>(self.base + COM_RX * self.multiplier) as u8),
}
}
}
@ -128,10 +135,11 @@ const COM_LSR_TXRDY: u8 = 0x20; // Transmit buffer avail
const COM_LSR_TSRE: u8 = 0x40; // Transmitter off
pub fn init_dt(dt: &Node) {
let addr = dt.prop_u64("reg").unwrap() as usize;
let addr = dt.prop_usize("reg").unwrap();
let shift = dt.prop_u32("reg-shift").unwrap_or(0) as usize;
let base = phys_to_virt(addr);
info!("Init uart16550 at {:#x}", base);
let com = Arc::new(SerialPort::new(base));
let com = Arc::new(SerialPort::new(base, shift));
let mut found = false;
let irq_opt = dt.prop_u32("interrupts").ok().map(|irq| irq as usize);
DRIVERS.write().push(com.clone());

View File

@ -8,6 +8,7 @@
#![feature(negative_impls)]
#![feature(alloc_prelude)]
#![feature(const_fn)]
#![feature(const_if_match)]
#![feature(const_in_array_repeat_expressions)]
#![deny(unused_must_use)]
#![deny(stable_features)]

View File

@ -32,10 +32,22 @@ pub static FRAME_ALLOCATOR: SpinNoIrqLock<FrameAlloc> = SpinNoIrqLock::new(Frame
/// Convert physical address to virtual address
#[inline]
#[cfg(not(mipsel))]
pub const fn phys_to_virt(paddr: usize) -> usize {
PHYSICAL_MEMORY_OFFSET + paddr
}
/// MIPS is special
#[inline]
#[cfg(mipsel)]
pub const fn phys_to_virt(paddr: usize) -> usize {
if paddr <= PHYSICAL_MEMORY_OFFSET {
PHYSICAL_MEMORY_OFFSET + paddr
} else {
paddr
}
}
/// Convert virtual address to physical address
#[inline]
pub const fn virt_to_phys(vaddr: usize) -> usize {

View File

@ -55,7 +55,7 @@ use xmas_elf::{
pub type Tid = usize;
pub struct ThreadContext {
pub user: Box<UserContext>,
user: Box<UserContext>,
/// TODO: lazy fp
fp: Box<FpState>,
}
@ -65,7 +65,7 @@ pub struct ThreadContext {
pub struct ThreadInner {
/// user context
/// None when thread is running in user
pub context: Option<ThreadContext>,
context: Option<ThreadContext>,
/// Kernel performs futex wake when thread exits.
/// Ref: [http://man7.org/linux/man-pages/man2/set_tid_address.2.html]
pub clear_child_tid: usize,

View File

@ -664,11 +664,11 @@ impl Syscall<'_> {
let flags = AtFlags::from_bits_truncate(flags);
if !proc.pid.is_init() {
// we trust pid 0 process
info!(
"faccessat: dirfd: {}, path: {:?}, mode: {:#o}, flags: {:?}",
dirfd as isize, path, mode, flags
);
}
info!(
"faccessat: dirfd: {}, path: {:?}, mode: {:#o}, flags: {:?}",
dirfd as isize, path, mode, flags
);
let _inode =
proc.lookup_inode_at(dirfd, &path, !flags.contains(AtFlags::SYMLINK_NOFOLLOW))?;
Ok(0)