mirror of
https://github.com/rcore-os/rCore.git
synced 2025-01-19 01:07:05 +04:00
Split Driver trait
This commit is contained in:
parent
d9234ccb4a
commit
c8573436e9
2
kernel/Cargo.lock
generated
2
kernel/Cargo.lock
generated
@ -721,7 +721,7 @@ checksum = "3a385d94f3f62e60445a0adb9ff8d9621faa272234530d4c0f848ec98f88e316"
|
||||
[[package]]
|
||||
name = "trapframe"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/rcore-os/trapframe-rs?rev=12a73f6#12a73f6974859d9b7d93332771d28adc178f28db"
|
||||
source = "git+https://github.com/rcore-os/trapframe-rs?rev=cd828e1#cd828e1457e57eeb6bddf65325cb9b72448d9b5e"
|
||||
dependencies = [
|
||||
"log",
|
||||
"raw-cpuid",
|
||||
|
@ -74,7 +74,7 @@ rcore-fs-devfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "517af47"
|
||||
rlibc = "1.0"
|
||||
smoltcp = { git = "https://github.com/rcore-os/smoltcp", rev = "5bd87c7c", default-features = false, features = ["alloc", "log", "ethernet", "proto-ipv4", "proto-igmp", "socket-icmp", "socket-udp", "socket-tcp", "socket-raw"] }
|
||||
spin = "0.5"
|
||||
trapframe = { git = "https://github.com/rcore-os/trapframe-rs", rev = "12a73f6" }
|
||||
trapframe = { git = "https://github.com/rcore-os/trapframe-rs", rev = "cd828e1" }
|
||||
virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "dfa70e14" }
|
||||
volatile = "0.2"
|
||||
woke = "0.0.2"
|
||||
|
@ -7,10 +7,13 @@ use alloc::sync::Arc;
|
||||
|
||||
use isomorphic_drivers::block::ahci::{AHCI, BLOCK_SIZE};
|
||||
|
||||
use crate::drivers::provider::Provider;
|
||||
use crate::drivers::{provider::Provider, NetDriver};
|
||||
use crate::sync::SpinNoIrqLock as Mutex;
|
||||
|
||||
use super::super::{DeviceType, Driver, BLK_DRIVERS, DRIVERS};
|
||||
use super::{
|
||||
super::{DeviceType, Driver, BLK_DRIVERS, DRIVERS},
|
||||
BlockDriver,
|
||||
};
|
||||
|
||||
pub struct AHCIDriver(Mutex<AHCI<Provider>>);
|
||||
|
||||
@ -27,6 +30,15 @@ impl Driver for AHCIDriver {
|
||||
format!("ahci")
|
||||
}
|
||||
|
||||
fn as_block(&self) -> Option<&dyn BlockDriver> {
|
||||
Some(self)
|
||||
}
|
||||
|
||||
fn as_net(&self) -> Option<&dyn NetDriver> {
|
||||
None
|
||||
}
|
||||
}
|
||||
impl BlockDriver for AHCIDriver {
|
||||
fn read_block(&self, block_id: usize, buf: &mut [u8]) -> bool {
|
||||
let mut driver = self.0.lock();
|
||||
driver.read_block(block_id, buf);
|
||||
|
@ -1,2 +1,14 @@
|
||||
use super::Driver;
|
||||
|
||||
pub mod ahci;
|
||||
pub mod virtio_blk;
|
||||
|
||||
pub trait BlockDriver: Driver {
|
||||
fn read_block(&self, _block_id: usize, _buf: &mut [u8]) -> bool {
|
||||
unimplemented!("not a block driver")
|
||||
}
|
||||
|
||||
fn write_block(&self, _block_id: usize, _buf: &[u8]) -> bool {
|
||||
unimplemented!("not a block driver")
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,11 @@ use alloc::sync::Arc;
|
||||
|
||||
use virtio_drivers::{VirtIOBlk, VirtIOHeader};
|
||||
|
||||
use super::super::{DeviceType, Driver, BLK_DRIVERS, DRIVERS, IRQ_MANAGER};
|
||||
use crate::sync::SpinNoIrqLock as Mutex;
|
||||
use super::{
|
||||
super::{DeviceType, Driver, BLK_DRIVERS, DRIVERS, IRQ_MANAGER},
|
||||
BlockDriver,
|
||||
};
|
||||
use crate::{drivers::NetDriver, sync::SpinNoIrqLock as Mutex};
|
||||
|
||||
struct VirtIOBlkDriver(Mutex<VirtIOBlk<'static>>);
|
||||
|
||||
@ -21,6 +24,16 @@ impl Driver for VirtIOBlkDriver {
|
||||
format!("virtio_block")
|
||||
}
|
||||
|
||||
fn as_block(&self) -> Option<&dyn BlockDriver> {
|
||||
None
|
||||
}
|
||||
|
||||
fn as_net(&self) -> Option<&dyn NetDriver> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl BlockDriver for VirtIOBlkDriver {
|
||||
fn read_block(&self, block_id: usize, buf: &mut [u8]) -> bool {
|
||||
self.0.lock().read_block(block_id, buf).is_ok()
|
||||
}
|
||||
|
@ -5,7 +5,10 @@ use virtio_drivers::{VirtIOGpu, VirtIOHeader};
|
||||
|
||||
use super::super::{DeviceType, Driver, DRIVERS, IRQ_MANAGER};
|
||||
use crate::memory::virt_to_phys;
|
||||
use crate::sync::SpinNoIrqLock as Mutex;
|
||||
use crate::{
|
||||
drivers::{BlockDriver, NetDriver},
|
||||
sync::SpinNoIrqLock as Mutex,
|
||||
};
|
||||
|
||||
struct VirtIOGpuDriver(Mutex<VirtIOGpu<'static>>);
|
||||
|
||||
@ -21,6 +24,14 @@ impl Driver for VirtIOGpuDriver {
|
||||
fn get_id(&self) -> String {
|
||||
format!("virtio_gpu")
|
||||
}
|
||||
|
||||
fn as_block(&self) -> Option<&dyn BlockDriver> {
|
||||
None
|
||||
}
|
||||
|
||||
fn as_net(&self) -> Option<&dyn NetDriver> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(header: &'static mut VirtIOHeader) {
|
||||
|
@ -6,7 +6,10 @@ use log::*;
|
||||
use virtio_drivers::{VirtIOHeader, VirtIOInput};
|
||||
|
||||
use super::super::{DeviceType, Driver, DRIVERS, IRQ_MANAGER};
|
||||
use crate::sync::SpinNoIrqLock as Mutex;
|
||||
use crate::{
|
||||
drivers::{BlockDriver, NetDriver},
|
||||
sync::SpinNoIrqLock as Mutex,
|
||||
};
|
||||
|
||||
struct VirtIOInputDriver(Mutex<VirtIOInput<'static>>);
|
||||
|
||||
@ -27,6 +30,14 @@ impl Driver for VirtIOInputDriver {
|
||||
fn get_id(&self) -> String {
|
||||
String::from("virtio_input")
|
||||
}
|
||||
|
||||
fn as_net(&self) -> Option<&dyn NetDriver> {
|
||||
None
|
||||
}
|
||||
|
||||
fn as_block(&self) -> Option<&dyn BlockDriver> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(header: &'static mut VirtIOHeader) {
|
||||
|
@ -1,29 +1,24 @@
|
||||
use crate::sync::Condvar;
|
||||
use alloc::string::String;
|
||||
use alloc::sync::Arc;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use rcore_fs::dev::{self, BlockDevice, DevError};
|
||||
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr, Ipv4Address};
|
||||
use spin::RwLock;
|
||||
|
||||
use crate::sync::Condvar;
|
||||
use rcore_fs::dev::{self, BlockDevice, DevError};
|
||||
pub use block::BlockDriver;
|
||||
pub use net::NetDriver;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub mod block;
|
||||
#[allow(dead_code)]
|
||||
pub mod bus;
|
||||
pub mod console;
|
||||
#[allow(dead_code)]
|
||||
mod device_tree;
|
||||
#[allow(dead_code)]
|
||||
pub mod device_tree;
|
||||
pub mod gpu;
|
||||
#[allow(dead_code)]
|
||||
mod input;
|
||||
pub mod input;
|
||||
pub mod irq;
|
||||
#[allow(dead_code)]
|
||||
pub mod net;
|
||||
mod provider;
|
||||
pub mod provider;
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub enum DeviceType {
|
||||
@ -47,64 +42,22 @@ pub trait Driver: Send + Sync {
|
||||
// should be different for each instance
|
||||
fn get_id(&self) -> String;
|
||||
|
||||
// Rust trait is still too restricted...
|
||||
// network related drivers should implement these
|
||||
// get mac address for this device
|
||||
fn get_mac(&self) -> EthernetAddress {
|
||||
unimplemented!("not a net driver")
|
||||
}
|
||||
|
||||
// get interface name for this device
|
||||
fn get_ifname(&self) -> String {
|
||||
unimplemented!("not a net driver")
|
||||
}
|
||||
|
||||
// get ip addresses
|
||||
fn get_ip_addresses(&self) -> Vec<IpCidr> {
|
||||
unimplemented!("not a net driver")
|
||||
}
|
||||
|
||||
// get ipv4 address
|
||||
fn ipv4_address(&self) -> Option<Ipv4Address> {
|
||||
unimplemented!("not a net driver")
|
||||
}
|
||||
|
||||
// manually trigger a poll, use it after sending packets
|
||||
fn poll(&self) {
|
||||
unimplemented!("not a net driver")
|
||||
}
|
||||
|
||||
// send an ethernet frame, only use it when necessary
|
||||
fn send(&self, _data: &[u8]) -> Option<usize> {
|
||||
unimplemented!("not a net driver")
|
||||
}
|
||||
|
||||
// get mac address from ip address in arp table
|
||||
fn get_arp(&self, _ip: IpAddress) -> Option<EthernetAddress> {
|
||||
unimplemented!("not a net driver")
|
||||
}
|
||||
|
||||
// block related drivers should implement these
|
||||
fn read_block(&self, _block_id: usize, _buf: &mut [u8]) -> bool {
|
||||
unimplemented!("not a block driver")
|
||||
}
|
||||
|
||||
fn write_block(&self, _block_id: usize, _buf: &[u8]) -> bool {
|
||||
unimplemented!("not a block driver")
|
||||
}
|
||||
// trait casting
|
||||
fn as_net(&self) -> Option<&dyn NetDriver>;
|
||||
fn as_block(&self) -> Option<&dyn BlockDriver>;
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
// NOTE: RwLock only write when initializing drivers
|
||||
pub static ref DRIVERS: RwLock<Vec<Arc<dyn Driver>>> = RwLock::new(Vec::new());
|
||||
pub static ref NET_DRIVERS: RwLock<Vec<Arc<dyn Driver>>> = RwLock::new(Vec::new());
|
||||
pub static ref BLK_DRIVERS: RwLock<Vec<Arc<dyn Driver>>> = RwLock::new(Vec::new());
|
||||
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 IRQ_MANAGER: RwLock<irq::IrqManager> = RwLock::new(irq::IrqManager::new());
|
||||
}
|
||||
|
||||
pub struct BlockDriver(pub Arc<dyn Driver>);
|
||||
pub struct BlockDriverWrapper(pub Arc<dyn BlockDriver>);
|
||||
|
||||
impl BlockDevice for BlockDriver {
|
||||
impl BlockDevice for BlockDriverWrapper {
|
||||
const BLOCK_SIZE_LOG2: u8 = 9; // 512
|
||||
fn read_at(&self, block_id: usize, buf: &mut [u8]) -> dev::Result<()> {
|
||||
match self.0.read_block(block_id, buf) {
|
||||
|
@ -16,11 +16,14 @@ use isomorphic_drivers::net::ethernet::intel::e1000::E1000;
|
||||
use isomorphic_drivers::net::ethernet::structs::EthernetAddress as DriverEthernetAddress;
|
||||
use rcore_memory::PAGE_SIZE;
|
||||
|
||||
use crate::drivers::provider::Provider;
|
||||
use crate::drivers::{provider::Provider, BlockDriver};
|
||||
use crate::net::SOCKETS;
|
||||
use crate::sync::SpinNoIrqLock as Mutex;
|
||||
|
||||
use super::super::{DeviceType, Driver, DRIVERS, IRQ_MANAGER, NET_DRIVERS, SOCKET_ACTIVITY};
|
||||
use super::{
|
||||
super::{DeviceType, Driver, DRIVERS, IRQ_MANAGER, NET_DRIVERS, SOCKET_ACTIVITY},
|
||||
NetDriver,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct E1000Driver(Arc<Mutex<E1000<Provider>>>);
|
||||
@ -65,6 +68,16 @@ impl Driver for E1000Interface {
|
||||
String::from("e1000")
|
||||
}
|
||||
|
||||
fn as_net(&self) -> Option<&dyn NetDriver> {
|
||||
Some(self)
|
||||
}
|
||||
|
||||
fn as_block(&self) -> Option<&dyn BlockDriver> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl NetDriver for E1000Interface {
|
||||
fn get_mac(&self) -> EthernetAddress {
|
||||
self.iface.lock().ethernet_addr()
|
||||
}
|
||||
|
@ -17,10 +17,13 @@ use smoltcp::Result;
|
||||
|
||||
use crate::net::SOCKETS;
|
||||
use crate::sync::FlagsGuard;
|
||||
use crate::sync::SpinNoIrqLock as Mutex;
|
||||
use crate::{drivers::BlockDriver, sync::SpinNoIrqLock as Mutex};
|
||||
|
||||
use super::super::{
|
||||
provider::Provider, DeviceType, Driver, DRIVERS, IRQ_MANAGER, NET_DRIVERS, SOCKET_ACTIVITY,
|
||||
use super::{
|
||||
super::{
|
||||
provider::Provider, DeviceType, Driver, DRIVERS, IRQ_MANAGER, NET_DRIVERS, SOCKET_ACTIVITY,
|
||||
},
|
||||
NetDriver,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -75,6 +78,16 @@ impl Driver for IXGBEInterface {
|
||||
self.ifname.clone()
|
||||
}
|
||||
|
||||
fn as_net(&self) -> Option<&dyn NetDriver> {
|
||||
Some(self)
|
||||
}
|
||||
|
||||
fn as_block(&self) -> Option<&dyn BlockDriver> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl NetDriver for IXGBEInterface {
|
||||
fn get_mac(&self) -> EthernetAddress {
|
||||
self.iface.lock().ethernet_addr()
|
||||
}
|
||||
|
@ -1,4 +1,46 @@
|
||||
use super::Driver;
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr, Ipv4Address};
|
||||
|
||||
pub mod e1000;
|
||||
pub mod ixgbe;
|
||||
pub mod router;
|
||||
pub mod virtio_net;
|
||||
|
||||
pub trait NetDriver: Driver {
|
||||
// get mac address for this device
|
||||
fn get_mac(&self) -> EthernetAddress {
|
||||
unimplemented!("not a net driver")
|
||||
}
|
||||
|
||||
// get interface name for this device
|
||||
fn get_ifname(&self) -> String {
|
||||
unimplemented!("not a net driver")
|
||||
}
|
||||
|
||||
// get ip addresses
|
||||
fn get_ip_addresses(&self) -> Vec<IpCidr> {
|
||||
unimplemented!("not a net driver")
|
||||
}
|
||||
|
||||
// get ipv4 address
|
||||
fn ipv4_address(&self) -> Option<Ipv4Address> {
|
||||
unimplemented!("not a net driver")
|
||||
}
|
||||
|
||||
// manually trigger a poll, use it after sending packets
|
||||
fn poll(&self) {
|
||||
unimplemented!("not a net driver")
|
||||
}
|
||||
|
||||
// send an ethernet frame, only use it when necessary
|
||||
fn send(&self, _data: &[u8]) -> Option<usize> {
|
||||
unimplemented!("not a net driver")
|
||||
}
|
||||
|
||||
// get mac address from ip address in arp table
|
||||
fn get_arp(&self, _ip: IpAddress) -> Option<EthernetAddress> {
|
||||
unimplemented!("not a net driver")
|
||||
}
|
||||
}
|
||||
|
@ -15,8 +15,11 @@ use smoltcp::Result;
|
||||
use crate::net::SOCKETS;
|
||||
use crate::sync::SpinNoIrqLock as Mutex;
|
||||
|
||||
use super::super::{DeviceType, Driver, DRIVERS, IRQ_MANAGER, NET_DRIVERS, SOCKET_ACTIVITY};
|
||||
use crate::memory::phys_to_virt;
|
||||
use super::{
|
||||
super::{DeviceType, Driver, DRIVERS, IRQ_MANAGER, NET_DRIVERS, SOCKET_ACTIVITY},
|
||||
NetDriver,
|
||||
};
|
||||
use crate::{drivers::BlockDriver, memory::phys_to_virt};
|
||||
|
||||
const AXI_STREAM_FIFO_ISR: *mut u32 = phys_to_virt(0x64A0_0000) as *mut u32;
|
||||
const AXI_STREAM_FIFO_IER: *mut u32 = phys_to_virt(0x64A0_0004) as *mut u32;
|
||||
@ -199,6 +202,16 @@ impl Driver for RouterInterface {
|
||||
format!("router")
|
||||
}
|
||||
|
||||
fn as_net(&self) -> Option<&dyn NetDriver> {
|
||||
Some(self)
|
||||
}
|
||||
|
||||
fn as_block(&self) -> Option<&dyn BlockDriver> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl NetDriver for RouterInterface {
|
||||
fn get_mac(&self) -> EthernetAddress {
|
||||
unimplemented!()
|
||||
}
|
||||
|
@ -8,25 +8,16 @@ use smoltcp::wire::{EthernetAddress, Ipv4Address};
|
||||
use smoltcp::Result;
|
||||
use virtio_drivers::{VirtIOHeader, VirtIONet};
|
||||
|
||||
use super::super::{DeviceType, Driver, DRIVERS, IRQ_MANAGER, NET_DRIVERS};
|
||||
use crate::sync::SpinNoIrqLock as Mutex;
|
||||
use super::{
|
||||
super::{DeviceType, Driver, DRIVERS, IRQ_MANAGER, NET_DRIVERS},
|
||||
NetDriver,
|
||||
};
|
||||
use crate::{drivers::BlockDriver, sync::SpinNoIrqLock as Mutex};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct VirtIONetDriver(Arc<Mutex<VirtIONet<'static>>>);
|
||||
|
||||
impl Driver for VirtIONetDriver {
|
||||
fn try_handle_interrupt(&self, _irq: Option<u32>) -> bool {
|
||||
self.0.lock().ack_interrupt()
|
||||
}
|
||||
|
||||
fn device_type(&self) -> DeviceType {
|
||||
DeviceType::Net
|
||||
}
|
||||
|
||||
fn get_id(&self) -> String {
|
||||
format!("virtio_net")
|
||||
}
|
||||
|
||||
impl NetDriver for VirtIONetDriver {
|
||||
fn get_mac(&self) -> EthernetAddress {
|
||||
EthernetAddress(self.0.lock().mac())
|
||||
}
|
||||
@ -44,6 +35,28 @@ impl Driver for VirtIONetDriver {
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for VirtIONetDriver {
|
||||
fn try_handle_interrupt(&self, _irq: Option<u32>) -> bool {
|
||||
self.0.lock().ack_interrupt()
|
||||
}
|
||||
|
||||
fn device_type(&self) -> DeviceType {
|
||||
DeviceType::Net
|
||||
}
|
||||
|
||||
fn get_id(&self) -> String {
|
||||
format!("virtio_net")
|
||||
}
|
||||
|
||||
fn as_net(&self) -> Option<&dyn NetDriver> {
|
||||
Some(self)
|
||||
}
|
||||
|
||||
fn as_block(&self) -> Option<&dyn BlockDriver> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl phy::Device<'_> for VirtIONetDriver {
|
||||
type RxToken = VirtIONetDriver;
|
||||
type TxToken = VirtIONetDriver;
|
||||
|
@ -16,6 +16,7 @@ pub use self::file::*;
|
||||
pub use self::file_like::*;
|
||||
pub use self::pipe::Pipe;
|
||||
pub use self::pseudo::*;
|
||||
use crate::drivers::BlockDriverWrapper;
|
||||
|
||||
mod devfs;
|
||||
mod device;
|
||||
@ -51,7 +52,7 @@ lazy_static! {
|
||||
{
|
||||
use crate::drivers::BlockDriver;
|
||||
use rcore_fs::dev::block_cache::BlockCache;
|
||||
let driver = BlockDriver(
|
||||
let driver = BlockDriverWrapper(
|
||||
crate::drivers::BLK_DRIVERS
|
||||
.read().iter()
|
||||
.next().expect("Block device not found")
|
||||
|
@ -278,7 +278,8 @@ impl Thread {
|
||||
let mut context = UserContext::default();
|
||||
context.set_ip(entry_addr);
|
||||
context.set_sp(ustack_top);
|
||||
if cfg!(target_arch = "x86_64") {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
if true {
|
||||
context.general.rflags = 0x3202;
|
||||
}
|
||||
|
||||
@ -429,7 +430,7 @@ pub fn spawn(thread: Arc<Thread>) {
|
||||
trace!("go to user: {:#x?}", cx);
|
||||
cx.run();
|
||||
trace!("back from user: {:#x?}", cx);
|
||||
let mut trap_num = 0;
|
||||
let mut trap_num: usize = 0;
|
||||
if cfg!(target_arch = "x86_64") {
|
||||
trap_num = cx.trap_num;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user