pub struct Plic {
base_addr: usize,
max_interrupts: InterruptId,
max_cpus: CpuId,
s_mode_contexts: Option<Vec<usize>>,
}Expand description
RISC-V PLIC Implementation
Fields§
§base_addr: usizeBase address of the PLIC
max_interrupts: InterruptIdMaximum number of interrupts this PLIC supports
max_cpus: CpuIdMaximum number of CPUs (harts) this PLIC supports
s_mode_contexts: Option<Vec<usize>>S-mode context ID for each CPU (hart). Index = CPU ID, Value = PLIC context ID for S-mode external interrupt. If None, use the default formula: (cpu_id * 2) + 1
Implementations§
Source§impl Plic
impl Plic
Sourcepub fn new(
base_addr: usize,
max_interrupts: InterruptId,
max_cpus: CpuId,
) -> Self
pub fn new( base_addr: usize, max_interrupts: InterruptId, max_cpus: CpuId, ) -> Self
Create a new PLIC instance
§Arguments
base_addr- Physical base address of the PLICmax_interrupts- Maximum interrupt ID supported (1-based)max_cpus- Maximum number of CPUs supported
Sourcepub fn with_contexts(
base_addr: usize,
max_interrupts: InterruptId,
s_mode_context_ids: Vec<usize>,
) -> Self
pub fn with_contexts( base_addr: usize, max_interrupts: InterruptId, s_mode_context_ids: Vec<usize>, ) -> Self
Create a new PLIC instance with explicit S-mode context mapping
§Arguments
base_addr- Physical base address of the PLICmax_interrupts- Maximum interrupt ID supported (1-based)s_mode_context_ids- Vector mapping CPU ID -> PLIC context ID for S-mode
Sourcefn context_id_for_cpu(&self, cpu_id: CpuId) -> usize
fn context_id_for_cpu(&self, cpu_id: CpuId) -> usize
Convert CPU ID to PLIC context ID for Supervisor mode. If explicit mapping exists, use it; otherwise Hart 0 S-Mode -> Context 1, etc.
Sourcefn priority_addr(&self, interrupt_id: InterruptId) -> usize
fn priority_addr(&self, interrupt_id: InterruptId) -> usize
Get the address of a priority register for an interrupt
Sourcefn pending_addr(&self, interrupt_id: InterruptId) -> usize
fn pending_addr(&self, interrupt_id: InterruptId) -> usize
Get the address of a pending register for an interrupt
Sourcefn enable_addr(&self, cpu_id: CpuId, interrupt_id: InterruptId) -> usize
fn enable_addr(&self, cpu_id: CpuId, interrupt_id: InterruptId) -> usize
Get the address of an enable register for a CPU and interrupt
Sourcefn threshold_addr(&self, cpu_id: CpuId) -> usize
fn threshold_addr(&self, cpu_id: CpuId) -> usize
Get the address of a threshold register for a CPU
Sourcefn claim_addr(&self, cpu_id: CpuId) -> usize
fn claim_addr(&self, cpu_id: CpuId) -> usize
Get the address of a claim register for a CPU
Sourcefn validate_interrupt_id(
&self,
interrupt_id: InterruptId,
) -> InterruptResult<()>
fn validate_interrupt_id( &self, interrupt_id: InterruptId, ) -> InterruptResult<()>
Validate interrupt ID
Sourcefn validate_cpu_id(&self, cpu_id: CpuId) -> InterruptResult<()>
fn validate_cpu_id(&self, cpu_id: CpuId) -> InterruptResult<()>
Validate CPU ID
Sourcefn mmio_write32_with_readback(addr: usize, value: u32) -> u32
fn mmio_write32_with_readback(addr: usize, value: u32) -> u32
MMIO write with readback verification
Trait Implementations§
Source§impl ExternalInterruptController for Plic
impl ExternalInterruptController for Plic
Source§fn init(&mut self) -> InterruptResult<()>
fn init(&mut self) -> InterruptResult<()>
Initialize the PLIC
Source§fn enable_interrupt(
&mut self,
interrupt_id: InterruptId,
cpu_id: CpuId,
) -> InterruptResult<()>
fn enable_interrupt( &mut self, interrupt_id: InterruptId, cpu_id: CpuId, ) -> InterruptResult<()>
Enable a specific interrupt for a CPU
Source§fn disable_interrupt(
&mut self,
interrupt_id: InterruptId,
cpu_id: CpuId,
) -> InterruptResult<()>
fn disable_interrupt( &mut self, interrupt_id: InterruptId, cpu_id: CpuId, ) -> InterruptResult<()>
Disable a specific interrupt for a CPU
Source§fn set_priority(
&mut self,
interrupt_id: InterruptId,
priority: Priority,
) -> InterruptResult<()>
fn set_priority( &mut self, interrupt_id: InterruptId, priority: Priority, ) -> InterruptResult<()>
Set priority for a specific interrupt
Source§fn get_priority(&self, interrupt_id: InterruptId) -> InterruptResult<Priority>
fn get_priority(&self, interrupt_id: InterruptId) -> InterruptResult<Priority>
Get priority for a specific interrupt
Source§fn set_threshold(
&mut self,
cpu_id: CpuId,
threshold: Priority,
) -> InterruptResult<()>
fn set_threshold( &mut self, cpu_id: CpuId, threshold: Priority, ) -> InterruptResult<()>
Set priority threshold for a CPU
Source§fn get_threshold(&self, cpu_id: CpuId) -> InterruptResult<Priority>
fn get_threshold(&self, cpu_id: CpuId) -> InterruptResult<Priority>
Get priority threshold for a CPU
Source§fn claim_interrupt(
&mut self,
cpu_id: CpuId,
) -> InterruptResult<Option<InterruptId>>
fn claim_interrupt( &mut self, cpu_id: CpuId, ) -> InterruptResult<Option<InterruptId>>
Claim an interrupt (acknowledge and get the interrupt ID)
Source§fn complete_interrupt(
&mut self,
cpu_id: CpuId,
interrupt_id: InterruptId,
) -> InterruptResult<()>
fn complete_interrupt( &mut self, cpu_id: CpuId, interrupt_id: InterruptId, ) -> InterruptResult<()>
Complete an interrupt (signal that handling is finished)
Source§fn is_pending(&self, interrupt_id: InterruptId) -> bool
fn is_pending(&self, interrupt_id: InterruptId) -> bool
Check if a specific interrupt is pending
Source§fn max_interrupts(&self) -> InterruptId
fn max_interrupts(&self) -> InterruptId
Get the maximum number of interrupts supported