1
0
mirror of https://github.com/rcore-os/rCore.git synced 2025-01-19 01:07:05 +04:00

Move COM1 to drivers

This commit is contained in:
Jiajie Chen 2020-06-20 15:13:52 +08:00
parent 5cc8e825ef
commit 7644694158
15 changed files with 123 additions and 24 deletions

View File

@ -102,7 +102,7 @@ pub extern "C" fn trap_handler(tf: &mut TrapFrame) {
COM1 => com1(),
COM2 => com2(),
_ => {
if IRQ_MANAGER.read().try_handle_interrupt(Some(irq as u32)) {
if IRQ_MANAGER.read().try_handle_interrupt(Some(irq)) {
debug!("driver processed interrupt");
return;
}

View File

@ -18,7 +18,7 @@ use super::{
pub struct AHCIDriver(Mutex<AHCI<Provider>>);
impl Driver for AHCIDriver {
fn try_handle_interrupt(&self, _irq: Option<u32>) -> bool {
fn try_handle_interrupt(&self, _irq: Option<usize>) -> bool {
false
}
@ -55,7 +55,7 @@ impl BlockDriver for AHCIDriver {
}
}
pub fn init(_irq: Option<u32>, header: usize, size: usize) -> Option<Arc<AHCIDriver>> {
pub fn init(_irq: Option<usize>, header: usize, size: usize) -> Option<Arc<AHCIDriver>> {
if let Some(ahci) = AHCI::new(header, size) {
let driver = Arc::new(AHCIDriver(Mutex::new(ahci)));
DRIVERS.write().push(driver.clone());

View File

@ -12,7 +12,7 @@ use crate::{drivers::NetDriver, sync::SpinNoIrqLock as Mutex};
struct VirtIOBlkDriver(Mutex<VirtIOBlk<'static>>);
impl Driver for VirtIOBlkDriver {
fn try_handle_interrupt(&self, _irq: Option<u32>) -> bool {
fn try_handle_interrupt(&self, _irq: Option<usize>) -> bool {
self.0.lock().ack_interrupt()
}

View File

@ -77,7 +77,7 @@ impl PortOps for PortOpsImpl {
/// Enable the pci device and its interrupt
/// Return assigned MSI interrupt number when applicable
unsafe fn enable(loc: Location) -> Option<u32> {
unsafe fn enable(loc: Location) -> Option<usize> {
let ops = &PortOpsImpl;
let am = CSpaceAccessMethod::IO;
@ -101,7 +101,7 @@ unsafe fn enable(loc: Location) -> Option<u32> {
am.write32(ops, loc, cap_ptr + PCI_MSI_ADDR, 0xfee00000 | (0 << 12));
MSI_IRQ += 1;
let irq = MSI_IRQ;
assigned_irq = Some(irq);
assigned_irq = Some(irq as usize);
// we offset all our irq numbers by 32
if (orig_ctrl >> 16) & (1 << 7) != 0 {
// 64bit

View File

@ -13,7 +13,7 @@ use crate::{
struct VirtIOGpuDriver(Mutex<VirtIOGpu<'static>>);
impl Driver for VirtIOGpuDriver {
fn try_handle_interrupt(&self, _irq: Option<u32>) -> bool {
fn try_handle_interrupt(&self, _irq: Option<usize>) -> bool {
self.0.lock().ack_interrupt()
}

View File

@ -14,7 +14,7 @@ use crate::{
struct VirtIOInputDriver(Mutex<VirtIOInput<'static>>);
impl Driver for VirtIOInputDriver {
fn try_handle_interrupt(&self, _irq: Option<u32>) -> bool {
fn try_handle_interrupt(&self, _irq: Option<usize>) -> bool {
let mut input = self.0.lock();
let ack = input.ack_interrupt().expect("failed to ack interrupt");
if ack {

View File

@ -6,7 +6,7 @@ use alloc::vec::Vec;
pub struct IrqManager {
// drivers that only respond to specific irq
mapping: BTreeMap<u32, Vec<Arc<dyn Driver>>>,
mapping: BTreeMap<usize, Vec<Arc<dyn Driver>>>,
// drivers that respond to all irqs
all: Vec<Arc<dyn Driver>>,
}
@ -19,7 +19,7 @@ impl IrqManager {
}
}
pub fn register_irq(&mut self, irq: u32, driver: Arc<dyn Driver>) {
pub fn register_irq(&mut self, irq: usize, driver: Arc<dyn Driver>) {
match self.mapping.entry(irq) {
Entry::Occupied(mut e) => {
e.get_mut().push(driver);
@ -36,7 +36,7 @@ impl IrqManager {
self.all.push(driver);
}
pub fn register_opt(&mut self, irq_opt: Option<u32>, driver: Arc<dyn Driver>) {
pub fn register_opt(&mut self, irq_opt: Option<usize>, driver: Arc<dyn Driver>) {
if let Some(irq) = irq_opt {
self.register_irq(irq, driver);
} else {
@ -44,7 +44,7 @@ impl IrqManager {
}
}
pub fn deregister_irq(&mut self, irq: u32, driver: Arc<dyn Driver>) {
pub fn deregister_irq(&mut self, irq: usize, driver: Arc<dyn Driver>) {
if let Some(e) = self.mapping.get_mut(&irq) {
e.retain(|d| !Arc::ptr_eq(&d, &driver));
}
@ -54,7 +54,7 @@ impl IrqManager {
self.all.retain(|d| !Arc::ptr_eq(&d, &driver));
}
pub fn try_handle_interrupt(&self, irq_opt: Option<u32>) -> bool {
pub fn try_handle_interrupt(&self, irq_opt: Option<usize>) -> bool {
if let Some(irq) = irq_opt {
if let Some(e) = self.mapping.get(&irq) {
for dri in e.iter() {

View File

@ -9,18 +9,31 @@ use spin::RwLock;
pub use block::BlockDriver;
pub use net::NetDriver;
use rtc::RtcDriver;
pub use rtc::RtcDriver;
pub use tty::TtyDriver;
/// Block device
pub mod block;
/// Bus controller
pub mod bus;
/// Character console
pub mod console;
/// Device tree
pub mod device_tree;
/// Display controller
pub mod gpu;
/// Mouse device
pub mod input;
/// Interrupt controller
pub mod irq;
/// Network controller
pub mod net;
/// For isomorphic_drivers
pub mod provider;
/// Real time clock
pub mod rtc;
/// Serial port
pub mod tty;
#[derive(Debug, Eq, PartialEq)]
pub enum DeviceType {
@ -29,6 +42,7 @@ pub enum DeviceType {
Input,
Block,
Rtc,
Tty,
}
pub trait Driver: Send + Sync {
@ -36,7 +50,7 @@ pub trait Driver: Send + Sync {
// return false otherwise
// irq number is provided when available
// driver should skip handling when irq number is mismatched
fn try_handle_interrupt(&self, irq: Option<u32>) -> bool;
fn try_handle_interrupt(&self, irq: Option<usize>) -> bool;
// return the correspondent device type, see DeviceType
fn device_type(&self) -> DeviceType;
@ -49,9 +63,14 @@ pub trait Driver: Send + Sync {
fn as_net(&self) -> Option<&dyn NetDriver> {
None
}
fn as_block(&self) -> Option<&dyn BlockDriver> {
None
}
fn as_rtc(&self) -> Option<&dyn RtcDriver> {
None
}
}
lazy_static! {
@ -60,6 +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 IRQ_MANAGER: RwLock<irq::IrqManager> = RwLock::new(irq::IrqManager::new());
}

View File

@ -32,11 +32,11 @@ pub struct E1000Interface {
iface: Mutex<EthernetInterface<'static, 'static, 'static, E1000Driver>>,
driver: E1000Driver,
name: String,
irq: Option<u32>,
irq: Option<usize>,
}
impl Driver for E1000Interface {
fn try_handle_interrupt(&self, irq: Option<u32>) -> bool {
fn try_handle_interrupt(&self, irq: Option<usize>) -> bool {
if irq.is_some() && self.irq.is_some() && irq != self.irq {
// not ours, skip it
return false;
@ -186,7 +186,7 @@ impl phy::TxToken for E1000TxToken {
}
// JudgeDuck-OS/kern/e1000.c
pub fn init(name: String, irq: Option<u32>, header: usize, size: usize, index: usize) {
pub fn init(name: String, irq: Option<usize>, header: usize, size: usize, index: usize) {
info!("Probing e1000 {}", name);
// randomly generated

View File

@ -38,12 +38,12 @@ pub struct IXGBEInterface {
iface: Mutex<EthernetInterface<'static, 'static, 'static, IXGBEDriver>>,
driver: IXGBEDriver,
ifname: String,
irq: Option<u32>,
irq: Option<usize>,
id: String,
}
impl Driver for IXGBEInterface {
fn try_handle_interrupt(&self, irq: Option<u32>) -> bool {
fn try_handle_interrupt(&self, irq: Option<usize>) -> bool {
if irq.is_some() && self.irq.is_some() && irq != self.irq {
// not ours, skip it
return false;
@ -196,7 +196,7 @@ impl phy::TxToken for IXGBETxToken {
pub fn ixgbe_init(
name: String,
irq: Option<u32>,
irq: Option<usize>,
header: usize,
size: usize,
index: usize,

View File

@ -147,7 +147,7 @@ pub struct RouterInterface {
}
impl Driver for RouterInterface {
fn try_handle_interrupt(&self, _irq: Option<u32>) -> bool {
fn try_handle_interrupt(&self, _irq: Option<usize>) -> bool {
let mut driver = self.driver.0.lock();
let isr = unsafe { AXI_STREAM_FIFO_ISR.read_volatile() };

View File

@ -36,7 +36,7 @@ impl NetDriver for VirtIONetDriver {
}
impl Driver for VirtIONetDriver {
fn try_handle_interrupt(&self, _irq: Option<u32>) -> bool {
fn try_handle_interrupt(&self, _irq: Option<usize>) -> bool {
self.0.lock().ack_interrupt()
}

View File

@ -35,7 +35,7 @@ fn bcd2bin(num: u64) -> u64 {
pub struct RtcCmos;
impl Driver for RtcCmos {
fn try_handle_interrupt(&self, irq: Option<u32>) -> bool {
fn try_handle_interrupt(&self, irq: Option<usize>) -> bool {
false
}

View File

@ -0,0 +1,66 @@
//! COM ports in x86
use super::super::DRIVERS;
use super::super::IRQ_MANAGER;
use super::{super::TTY_DRIVERS, TtyDriver};
use crate::{
drivers::{DeviceType, Driver},
sync::SpinNoIrqLock as Mutex,
};
use alloc::string::String;
use alloc::sync::Arc;
use uart_16550::SerialPort;
pub const COM2: usize = 3;
pub const COM1: usize = 4;
struct COM {
port: Mutex<SerialPort>,
base: u16,
}
impl COM {
fn new(base: u16) -> COM {
let port = Mutex::new(unsafe { SerialPort::new(base) });
port.lock().init();
COM { port, base }
}
}
impl Driver for COM {
fn try_handle_interrupt(&self, irq: Option<usize>) -> bool {
false
}
fn device_type(&self) -> DeviceType {
DeviceType::Tty
}
fn get_id(&self) -> String {
format!("com_{}", self.base)
}
}
impl TtyDriver for COM {
fn read(&self) -> u8 {
self.port.lock().receive()
}
fn write(&self, data: &[u8]) {
let mut port = self.port.lock();
for byte in data {
port.send(*byte);
}
}
}
pub fn init() {
add(0x3F8, COM1);
add(0x2F8, COM2);
}
fn add(base: u16, irq: usize) {
let com = Arc::new(COM::new(base));
DRIVERS.write().push(com.clone());
TTY_DRIVERS.write().push(com.clone());
IRQ_MANAGER.write().register_irq(irq, com);
}

View File

@ -0,0 +1,13 @@
use super::Driver;
use super::TTY_DRIVERS;
#[cfg(target_arch = "x86_64")]
pub mod com;
pub trait TtyDriver: Driver {
// read one byte from tty
fn read(&self) -> u8;
// write bytes to tty
fn write(&self, data: &[u8]);
}