Compare commits

..

No commits in common. "753515700fec975c0f49e708ad0e654e16109b8b" and "9b2cca3f699c955377d735ed8923f59de3538458" have entirely different histories.

4 changed files with 27 additions and 45 deletions

4
.vscode/launch.json vendored
View File

@ -9,7 +9,7 @@
"program": "${workspaceFolder}/target/test_exe",
"cwd": "${workspaceFolder}",
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb",
"miDebuggerPath": "/usr/bin/gdb-multiarch",
"miDebuggerServerAddress": "localhost:1234",
"setupCommands": [
{
@ -35,7 +35,7 @@
"program": "${workspaceFolder}/target/kernel_exe",
"cwd": "${workspaceFolder}",
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb",
"miDebuggerPath": "/usr/bin/gdb-multiarch",
"miDebuggerServerAddress": "localhost:1234",
"setupCommands": [
{

View File

@ -29,10 +29,7 @@ impl TrapOps for Trap {
// anyway, clear sscratch
riscv::register::sscratch::write(0);
// set trap_entry
unsafe { riscv::register::stvec::write(trap_entry as usize, TrapMode::Direct) };
// enable interrupt
unsafe { riscv::register::sie::set_ssoft() };
unsafe { riscv::register::sie::set_sext() };
unsafe { riscv::register::stvec::write(trap_entry as usize, TrapMode::Direct) }
}
}
@ -91,7 +88,6 @@ impl TrapContextOps for TrapContext {
},
T::Interrupt(I::SupervisorExternal) => {
// TODO: handle external interrupt, e.g. plic
panic_fatal!("Unhandled External Interrupt");
},
T::Exception(E::InstructionPageFault) | T::Exception(E::LoadPageFault) | T::Exception(E::StorePageFault) => {
if from_kernel {

View File

@ -1,12 +1,10 @@
use super::IrqDriver;
use crate::arch::layout::mmap_phys_to_virt;
use crate::drivers::Driver;
use crate::entry::HART_ID;
use crate::plat::irq::IrqController;
use core::sync::atomic::{AtomicPtr, Ordering};
use fdt::{node::FdtNode, Fdt};
use log::trace;
use utils::addr::PhysAddr;
const IRQ_OCCUPIED: usize = u32::MAX as usize; // OpenSBI will rewrite IRQ_M_EXT to this value
const IRQ_S_EXT: usize = 9;
@ -19,15 +17,21 @@ const PLIC_ENABLE_STRIDE: usize = 0x80;
const PLIC_CONTROL_OFFSET: usize = 0x200000;
const PLIC_CONTROL_STRIDE: usize = 0x1000;
#[repr(C, align(0x1000))]
#[derive(Debug)]
struct PlicCtrl {
threshold: *mut u32,
claim: *mut u32,
}
#[derive(Debug)]
pub struct IrqPlic
where IrqPlic: IrqDriver
{
priority: AtomicPtr<u32>,
pending: AtomicPtr<u32>,
enable: AtomicPtr<u32>,
threshold: AtomicPtr<u32>,
claim: AtomicPtr<u32>,
priority: AtomicPtr<u32>,
pending: AtomicPtr<u32>,
enable: AtomicPtr<u32>,
control: AtomicPtr<PlicCtrl>,
nr_irqs: usize,
}
@ -45,12 +49,8 @@ impl IrqPlic {
self.enable.load(Ordering::Relaxed)
}
fn threshold(&self) -> *mut u32 {
self.threshold.load(Ordering::Relaxed)
}
fn claim(&self) -> *mut u32 {
self.claim.load(Ordering::Relaxed)
fn control(&self) -> *mut PlicCtrl {
self.control.load(Ordering::Relaxed)
}
}
@ -65,9 +65,7 @@ impl Driver for IrqPlic {
.expect("no PLIC base address available")
.next()
.unwrap()
.starting_address;
let base_address = unsafe { mmap_phys_to_virt(PhysAddr::from(base_address)) };
let base_address: *mut u8 = base_address.into();
.starting_address as *mut u8;
let nr_irqs = node
.property("riscv,ndev")
@ -112,19 +110,14 @@ impl Driver for IrqPlic {
let priority = unsafe { base_address.add(PLIC_PRIORITY_OFFSET) as *mut u32 };
let pending = unsafe { base_address.add(PLIC_PENDING_OFFSET) as *mut u32 };
let enable = unsafe { base_address.add(PLIC_ENABLE_OFFSET + ctx_id * PLIC_ENABLE_STRIDE) as *mut u32 };
let threshold = unsafe { base_address.add(PLIC_CONTROL_OFFSET + ctx_id * PLIC_CONTROL_STRIDE) as *mut u32 };
let claim = unsafe { threshold.add(1) };
// Reset context threshold to 0
unsafe { threshold.write_volatile(0) };
let control = unsafe { (base_address.add(PLIC_CONTROL_OFFSET) as *mut PlicCtrl).add(ctx_id) };
Self {
priority: AtomicPtr::new(priority),
pending: AtomicPtr::new(pending),
enable: AtomicPtr::new(enable),
threshold: AtomicPtr::new(threshold),
claim: AtomicPtr::new(claim),
nr_irqs: nr_irqs.unwrap(),
priority: AtomicPtr::new(priority),
pending: AtomicPtr::new(pending),
enable: AtomicPtr::new(enable),
control: AtomicPtr::new(control),
nr_irqs: nr_irqs.unwrap(),
}
}
}
@ -135,12 +128,9 @@ impl IrqController for IrqPlic {
return;
}
// set priority = 1
unsafe { IrqPlic::priority(self).add(irq).write_volatile(1) };
// set enable = 1
let word = irq / 32;
let bit = irq % 32;
let val = unsafe { IrqPlic::enable(self).add(word).read_volatile() };
let val = val | (1 << bit);
unsafe { IrqPlic::enable(self).add(word).write_volatile(val) };
@ -151,15 +141,12 @@ impl IrqController for IrqPlic {
return;
}
// set enable = 0
let word = irq / 32;
let bit = irq % 32;
let val = unsafe { IrqPlic::enable(self).add(word).read_volatile() };
let val = val & !(1 << bit);
unsafe { IrqPlic::enable(self).add(word).write_volatile(val) };
// set priority = 0
unsafe { IrqPlic::priority(self).add(irq).write_volatile(0) };
}
fn is_pending(&mut self, irq: usize) -> bool {
@ -175,7 +162,7 @@ impl IrqController for IrqPlic {
}
fn claim(&mut self) -> Option<usize> {
let val = unsafe { IrqPlic::claim(self).read_volatile() };
let val = unsafe { IrqPlic::control(self).as_ref().unwrap().claim.read_volatile() };
if val > 0 {
Some(val as usize)
@ -190,7 +177,7 @@ impl IrqController for IrqPlic {
}
let val = irq as u32;
unsafe { IrqPlic::claim(self).write_volatile(val) };
unsafe { IrqPlic::control(self).as_ref().unwrap().claim.write_volatile(val) };
}
}

View File

@ -40,7 +40,6 @@ impl IrqController for DummyIrqDriver {
fn complete(&mut self, _: usize) {}
}
// TODO: per-core irq driver
static IRQ_DRIVER: Mutex<IrqDriver> = Mutex::new(IrqDriver::DummyIrqDriver(DummyIrqDriver));
pub fn set_irq_driver(driver: IrqDriver) {