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:
parent
6906337068
commit
8942bb8eeb
2
kernel/Cargo.lock
generated
2
kernel/Cargo.lock
generated
@ -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"
|
||||
|
@ -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"] }
|
||||
|
@ -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>;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
@ -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());
|
||||
|
@ -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)]
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user