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:
parent
7644694158
commit
9732f2148d
@ -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) {
|
||||
|
@ -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");
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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!(
|
||||
|
@ -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);
|
||||
|
@ -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! {
|
||||
|
@ -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);
|
||||
}
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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 => {
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user