1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-22 08:06:17 +04:00

Move serial to drivers completely

This commit is contained in:
Jiajie Chen 2020-06-20 15:43:39 +08:00
parent 7644694158
commit 9732f2148d
12 changed files with 38 additions and 121 deletions

View File

@ -1,25 +1,9 @@
pub mod keyboard;
pub mod serial;
use super::BootInfo;
pub fn init(_boot_info: &BootInfo) {
serial::init();
keyboard::init();
// Enable PCI Interrupts when necessary
// because they can be shared among devices
// including mouse and keyboard
/*
enable_irq(consts::PIRQA);
enable_irq(consts::PIRQB);
enable_irq(consts::PIRQC);
enable_irq(consts::PIRQD);
enable_irq(consts::PIRQE);
enable_irq(consts::PIRQF);
enable_irq(consts::PIRQG);
enable_irq(consts::PIRQH);
*/
}
pub fn init_graphic(boot_info: &BootInfo) {

View File

@ -1,15 +0,0 @@
use crate::sync::SpinNoIrqLock as Mutex;
use uart_16550::SerialPort;
use crate::arch::interrupt::{consts, enable_irq};
pub static COM1: Mutex<SerialPort> = Mutex::new(unsafe { SerialPort::new(0x3F8) });
pub static COM2: Mutex<SerialPort> = Mutex::new(unsafe { SerialPort::new(0x2F8) });
pub fn init() {
COM1.lock().init();
COM2.lock().init();
enable_irq(consts::COM1);
enable_irq(consts::COM2);
info!("serial: init end");
}

View File

@ -83,7 +83,6 @@ pub extern "C" fn trap_handler(tf: &mut TrapFrame) {
// Dispatch
match tf.trap_num {
Breakpoint => breakpoint(),
DoubleFault => double_fault(tf),
PageFault => page_fault(tf),
IRQ0..=63 => {
@ -99,8 +98,6 @@ pub extern "C" fn trap_handler(tf: &mut TrapFrame) {
*/
}
Keyboard => keyboard(),
COM1 => com1(),
COM2 => com2(),
_ => {
if IRQ_MANAGER.read().try_handle_interrupt(Some(irq)) {
debug!("driver processed interrupt");
@ -110,9 +107,6 @@ pub extern "C" fn trap_handler(tf: &mut TrapFrame) {
}
}
}
Syscall32 => syscall32(tf),
InvalidOpcode => invalid_opcode(tf),
DivideError | GeneralProtectionFault => error(tf),
IPIFuncCall => {
let irq = tf.trap_num - IRQ0;
super::ack(irq); // must ack before switching
@ -122,10 +116,6 @@ pub extern "C" fn trap_handler(tf: &mut TrapFrame) {
}
}
fn breakpoint() {
error!("\nEXCEPTION: Breakpoint");
}
fn double_fault(tf: &TrapFrame) {
error!("\nEXCEPTION: Double Fault\n{:#x?}", tf);
loop {}
@ -160,7 +150,7 @@ fn page_fault(tf: &mut TrapFrame) {
}
error!("\nEXCEPTION: Page Fault @ {:#x}, code: {:?}", addr, code);
error(tf);
loop {}
}
fn keyboard() {
@ -192,53 +182,3 @@ fn keyboard() {
}
}
}
fn com1() {
use crate::arch::driver::serial::*;
trace!("\nInterupt: COM1");
crate::trap::serial(COM1.lock().receive());
}
fn com2() {
use crate::arch::driver::serial::*;
trace!("\nInterupt: COM2");
COM2.lock().receive();
}
#[no_mangle]
pub extern "C" fn syscall(tf: &mut TrapFrame) {
trace!("\nInterupt: Syscall {:#x?}", tf.rax);
//let ret = crate::syscall::syscall(tf.rax, [tf.rdi, tf.rsi, tf.rdx, tf.r10, tf.r8, tf.r9], tf);
//tf.rax = ret as usize;
//do_signal(tf);
}
fn syscall32(tf: &mut TrapFrame) {
trace!("\nInterupt: Syscall {:#x?}", tf.rax);
//let ret = crate::syscall::syscall(tf.rax, [tf.rdx, tf.rcx, tf.rbx, tf.rdi, tf.rsi, 0], tf);
//tf.rax = ret as usize;
}
/// Support `syscall` instruction
fn invalid_opcode(tf: &mut TrapFrame) {
let opcode = unsafe { (tf.rip as *mut u16).read() };
const SYSCALL_OPCODE: u16 = 0x05_0f;
if opcode == SYSCALL_OPCODE {
tf.rip += 2; // must before syscall
syscall(tf);
} else {
todo!()
//crate::trap::error(tf);
}
}
fn error(tf: &TrapFrame) {
todo!()
//crate::trap::error(tf);
}
#[no_mangle]
pub unsafe extern "C" fn set_return_rsp(tf: *const TrapFrame) {
use crate::arch::gdt::Cpu;
Cpu::current().set_ring0_rsp(tf.add(1) as usize);
}

View File

@ -1,21 +1,13 @@
use super::driver::serial::*;
use crate::drivers::SERIAL_DRIVERS;
use core::fmt::{Arguments, Write};
pub fn getchar() -> char {
unsafe {
COM1.force_unlock();
}
COM1.lock().receive() as char
}
pub fn putfmt(fmt: Arguments) {
// output to serial
#[cfg(not(feature = "board_pc"))]
{
unsafe {
COM1.force_unlock();
}
COM1.lock().write_fmt(fmt).unwrap();
let mut drivers = SERIAL_DRIVERS.write();
let serial = drivers.first_mut().unwrap();
serial.write(format!("{}", fmt).as_bytes());
}
// print to graphic

View File

@ -24,7 +24,6 @@ static AP_CAN_INIT: AtomicBool = AtomicBool::new(false);
#[no_mangle] // don't mangle the name of this function
pub extern "C" fn _start(boot_info: &'static BootInfo) -> ! {
let cpu_id = cpu::id();
println!("Hello world! from CPU {}!", cpu_id);
if cpu_id != 0 {
while !AP_CAN_INIT.load(Ordering::Relaxed) {
@ -33,11 +32,17 @@ pub extern "C" fn _start(boot_info: &'static BootInfo) -> ! {
other_start();
}
// init log, heap and graphic output
// init log and heap
crate::logging::init();
crate::memory::init_heap();
// serial
crate::drivers::early_init();
// init graphic output
driver::init_graphic(boot_info);
println!("Hello world! from CPU {}!", cpu_id);
// check BootInfo from bootloader
info!("{:#x?}", boot_info);
assert_eq!(

View File

@ -1,4 +1,5 @@
use super::Driver;
use crate::arch::interrupt::enable_irq;
use alloc::collections::btree_map::Entry;
use alloc::collections::BTreeMap;
use alloc::sync::Arc;
@ -20,6 +21,7 @@ impl IrqManager {
}
pub fn register_irq(&mut self, irq: usize, driver: Arc<dyn Driver>) {
enable_irq(irq);
match self.mapping.entry(irq) {
Entry::Occupied(mut e) => {
e.get_mut().push(driver);

View File

@ -10,7 +10,7 @@ use spin::RwLock;
pub use block::BlockDriver;
pub use net::NetDriver;
pub use rtc::RtcDriver;
pub use tty::TtyDriver;
pub use serial::SerialDriver;
/// Block device
pub mod block;
@ -33,7 +33,7 @@ pub mod provider;
/// Real time clock
pub mod rtc;
/// Serial port
pub mod tty;
pub mod serial;
#[derive(Debug, Eq, PartialEq)]
pub enum DeviceType {
@ -42,7 +42,7 @@ pub enum DeviceType {
Input,
Block,
Rtc,
Tty,
Serial,
}
pub trait Driver: Send + Sync {
@ -79,7 +79,7 @@ lazy_static! {
pub static ref NET_DRIVERS: RwLock<Vec<Arc<dyn NetDriver>>> = RwLock::new(Vec::new());
pub static ref BLK_DRIVERS: RwLock<Vec<Arc<dyn BlockDriver>>> = RwLock::new(Vec::new());
pub static ref RTC_DRIVERS: RwLock<Vec<Arc<dyn RtcDriver>>> = RwLock::new(Vec::new());
pub static ref TTY_DRIVERS: RwLock<Vec<Arc<dyn TtyDriver>>> = RwLock::new(Vec::new());
pub static ref SERIAL_DRIVERS: RwLock<Vec<Arc<dyn SerialDriver>>> = RwLock::new(Vec::new());
pub static ref IRQ_MANAGER: RwLock<irq::IrqManager> = RwLock::new(irq::IrqManager::new());
}
@ -118,6 +118,12 @@ pub fn init(dtb: usize) {
#[cfg(target_arch = "x86_64")]
pub fn init() {
bus::pci::init();
rtc::rtc_cmos::init();
}
#[cfg(target_arch = "x86_64")]
pub fn early_init() {
serial::com::init();
}
lazy_static! {

View File

@ -1,7 +1,7 @@
//! COM ports in x86
use super::super::DRIVERS;
use super::super::IRQ_MANAGER;
use super::{super::TTY_DRIVERS, TtyDriver};
use super::{super::SERIAL_DRIVERS, SerialDriver};
use crate::{
drivers::{DeviceType, Driver},
sync::SpinNoIrqLock as Mutex,
@ -28,11 +28,13 @@ impl COM {
impl Driver for COM {
fn try_handle_interrupt(&self, irq: Option<usize>) -> bool {
false
let c = self.read();
crate::trap::serial(c);
true
}
fn device_type(&self) -> DeviceType {
DeviceType::Tty
DeviceType::Serial
}
fn get_id(&self) -> String {
@ -40,7 +42,7 @@ impl Driver for COM {
}
}
impl TtyDriver for COM {
impl SerialDriver for COM {
fn read(&self) -> u8 {
self.port.lock().receive()
}
@ -61,6 +63,6 @@ pub fn init() {
fn add(base: u16, irq: usize) {
let com = Arc::new(COM::new(base));
DRIVERS.write().push(com.clone());
TTY_DRIVERS.write().push(com.clone());
SERIAL_DRIVERS.write().push(com.clone());
IRQ_MANAGER.write().register_irq(irq, com);
}

View File

@ -1,10 +1,12 @@
use super::Driver;
use super::TTY_DRIVERS;
use super::SERIAL_DRIVERS;
use alloc::sync::Arc;
use core::fmt::{Result, Write};
#[cfg(target_arch = "x86_64")]
pub mod com;
pub trait TtyDriver: Driver {
pub trait SerialDriver: Driver {
// read one byte from tty
fn read(&self) -> u8;

View File

@ -156,7 +156,6 @@ pub fn init_heap() {
.lock()
.init(HEAP.as_ptr() as usize, HEAP_BLOCK * MACHINE_ALIGN);
}
info!("heap init end");
}
pub fn enlarge_heap(heap: &mut Heap) {

View File

@ -444,9 +444,9 @@ pub fn spawn(thread: Arc<Thread>) {
if trap_num == 0x20 {
crate::trap::timer();
} else if trap_num == 0x20 + 4 {
use crate::arch::driver::serial::*;
//use crate::arch::driver::serial::*;
info!("\nInterupt: COM1");
crate::trap::serial(COM1.lock().receive());
//crate::trap::serial(COM1.lock().receive());
}
}
0xe => {

View File

@ -1,5 +1,5 @@
use crate::arch::cpu;
use crate::arch::interrupt::{syscall, TrapFrame};
use crate::arch::interrupt::TrapFrame;
use crate::consts::INFORM_PER_MSEC;
use crate::process::*;
use crate::sync::SpinNoIrqLock as Mutex;