Skip to content

Commit

Permalink
feat: add irq support for aarch64 and x86_64
Browse files Browse the repository at this point in the history
  • Loading branch information
yfblock committed May 29, 2024
1 parent 3ad67de commit 4df1ebc
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 24 deletions.
22 changes: 16 additions & 6 deletions src/aarch64/gic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use arm_gic::{translate_irq, InterruptType};
use irq_safety::MutexIrqSafe;

use crate::addr::PhysAddr;
use crate::irq::IRQ;

/// The maximum number of IRQs.
#[allow(dead_code)]
Expand All @@ -24,12 +25,6 @@ static GICD: MutexIrqSafe<GicDistributor> =
// per-CPU, no lock
static GICC: GicCpuInterface = GicCpuInterface::new(GICC_BASE.get_mut_ptr());

/// Enables or disables the given IRQ.
pub fn set_enable(irq_num: usize, enabled: bool) {
trace!("GICD set enable: {} {}", irq_num, enabled);
GICD.lock().set_enable(irq_num as _, enabled);
}

/// Initializes GICD, GICC on the primary CPU.
pub(crate) fn init() {
info!("Initialize GICv2...");
Expand All @@ -44,3 +39,18 @@ where
{
GICC.handle_irq(f)
}

/// Implement IRQ operations for the IRQ interface.
impl IRQ {
/// Enable irq for the given IRQ number.
#[inline]
pub fn enable(irq_num: usize) {
GICD.lock().set_enable(irq_num, true);
}

/// Disable irq for the given IRQ number.
#[inline]
pub fn disable(irq_num: usize) {
GICD.lock().set_enable(irq_num, false);
}
}
5 changes: 3 additions & 2 deletions src/aarch64/timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use aarch64_cpu::registers::{CNTFRQ_EL0, CNTPCT_EL0, CNTP_CTL_EL0, CNTP_TVAL_EL0};
use tock_registers::interfaces::{Readable, Writeable};

use crate::time::Time;
use crate::{irq::IRQ, time::Time};

impl Time {
#[inline]
Expand All @@ -27,6 +27,7 @@ pub fn init() {
debug!("freq: {}", freq);
CNTP_CTL_EL0.write(CNTP_CTL_EL0::ENABLE::SET);
CNTP_TVAL_EL0.set(0);
super::gic::set_enable(super::gic::TIMER_IRQ_NUM, true);
// Enable the timer irq.
IRQ::enable(super::gic::TIMER_IRQ_NUM);
set_next_timer();
}
17 changes: 17 additions & 0 deletions src/loongarch64/timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use loongArch64::register::tcfg;
use loongArch64::time::{get_timer_freq, Time};
use spin::Lazy;

use crate::irq::IRQ;

// static mut FREQ: usize = 0;
static FREQ: Lazy<usize> = Lazy::new(|| get_timer_freq());

Expand Down Expand Up @@ -32,3 +34,18 @@ pub fn init_timer() {
| LineBasedInterrupt::HWI0;
ecfg::set_lie(inter);
}

/// Implement IRQ operations for the IRQ interface.
impl IRQ {
/// Enable irq for the given IRQ number.
#[inline]
pub fn enable(_irq_num: usize) {
log::warn!("irq not implemented in loongarch64 platform yet");
}

/// Disable irq for the given IRQ number.
#[inline]
pub fn disable(_irq_num: usize) {
log::warn!("irq not implemented in loongarch64 platform yet");
}
}
5 changes: 3 additions & 2 deletions src/loongarch64/trap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,8 +349,9 @@ fn loongarch64_trap_handler(tf: &mut TrapFrame) -> TrapType {
// TrapType::Un
TrapType::StorePageFault(badv::read().vaddr())
}
Trap::Exception(Exception::FetchPageFault)
| Trap::Exception(Exception::LoadPageFault) => TrapType::LoadPageFault(badv::read().vaddr()),
Trap::Exception(Exception::FetchPageFault) | Trap::Exception(Exception::LoadPageFault) => {
TrapType::LoadPageFault(badv::read().vaddr())
}
_ => {
panic!(
"Unhandled trap {:?} @ {:#x} BADV: {:#x}:\n{:#x?}",
Expand Down
16 changes: 16 additions & 0 deletions src/riscv64/irq.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use crate::irq::IRQ;

/// Implement IRQ operations for the IRQ interface.
impl IRQ {
/// Enable irq for the given IRQ number.
#[inline]
pub fn enable(_irq_num: usize) {
log::warn!("irq not implemented in riscv platform yet");
}

/// Disable irq for the given IRQ number.
#[inline]
pub fn disable(_irq_num: usize) {
log::warn!("irq not implemented in riscv platform yet");
}
}
1 change: 1 addition & 0 deletions src/riscv64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod consts;
mod context;
mod entry;
mod interrupt;
mod irq;
#[cfg(feature = "kcontext")]
mod kcontext;
mod page_table;
Expand Down
40 changes: 26 additions & 14 deletions src/x86_64/apic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use x2apic::lapic::{xapic_base, LocalApic, LocalApicBuilder};
use x86_64::instructions::port::Port;

use self::vectors::*;
use crate::irq::IRQ;
use crate::VIRT_ADDR_START;

pub(super) mod vectors {
Expand All @@ -27,20 +28,6 @@ static mut LOCAL_APIC: Option<LocalApic> = None;
static mut IS_X2APIC: bool = false;
static IO_APIC: Once<MutexIrqSafe<IoApic>> = Once::new();

/// Enables or disables the given IRQ.
pub fn set_enable(vector: usize, enabled: bool) {
// should not affect LAPIC interrupts
if vector < APIC_TIMER_VECTOR as _ {
unsafe {
if enabled {
IO_APIC.get_unchecked().lock().enable_irq(vector as u8);
} else {
IO_APIC.get_unchecked().lock().disable_irq(vector as u8);
}
}
}
}

/// Registers an IRQ handler for the given IRQ.
///
/// It also enables the IRQ if the registration succeeds. It returns `false` if
Expand Down Expand Up @@ -112,3 +99,28 @@ pub(super) fn init() {
let io_apic = unsafe { IoApic::new(IO_APIC_BASE) };
IO_APIC.call_once(|| MutexIrqSafe::new(io_apic));
}

/// Implement IRQ operations for the IRQ interface.
impl IRQ {
/// Enable irq for the given IRQ number.
#[inline]
pub fn enable(irq_num: usize) {
// should not affect LAPIC interrupts
if irq_num < APIC_TIMER_VECTOR as _ {
unsafe {
IO_APIC.get_unchecked().lock().enable_irq(irq_num as _);
}
}
}

/// Disable irq for the given IRQ number.
#[inline]
pub fn disable(irq_num: usize) {
// should not affect LAPIC interrupts
if irq_num < APIC_TIMER_VECTOR as _ {
unsafe {
IO_APIC.get_unchecked().lock().disable_irq(irq_num as _);
}
}
}
}

0 comments on commit 4df1ebc

Please sign in to comment.