1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
#![allow(non_snake_case)]
use tock_registers::registers::{ReadOnly, ReadWrite};
/// RISC-V Platform-Level Interrupt Controller
///
/// <https://github.com/riscv/riscv-plic-spec/blob/master/riscv-plic.adoc>
#[repr(C)]
pub struct Plic {
// +0x000000
/// The interrupt priority for each interrupt source.
///
/// > If PLIC supports Interrupt Priorities, then each PLIC interrupt source
/// > can be assigned a priority by writing to its 32-bit memory-mapped
/// > priority register. A priority value of 0 is reserved to mean ''never
/// > interrupt'' and effectively disables the interrupt. Priority 1 is the
/// > lowest active priority while the maximun level of priority depends on
/// > PLIC implementation. Ties between global interrupts of the same
/// > priority are broken by the Interrupt ID; interrupts with the lowest ID
/// > have the highest effective priority.
/// >
/// > The base address of Interrupt Source Priority block within PLIC Memory
/// > Map region is fixed at 0x000000.
pub interrupt_priority: [ReadWrite<u32, ()>; 1024],
// +0x001000
/// The interrupt pending status of each interrupt source.
///
/// > The current status of the interrupt source pending bits in the PLIC
/// > core can be read from the pending array, organized as 32-bit register.
/// > The pending bit for interrupt ID N is stored in bit (N mod 32) of word
/// > (N/32). Bit 0 of word 0, which represents the non-existent interrupt
/// > source 0, is hardwired to zero.
/// >
/// > A pending bit in the PLIC core can be cleared by setting the
/// > associated enable bit then performing a claim.
/// > The base address of Interrupt Pending Bits block within PLIC Memory
/// > Map region is fixed at 0x001000.
pub interrupt_pending: [ReadOnly<u32, ()>; 1024 / 32],
_reserved1: [u32; 1024 - 1024 / 32],
// +0x002000
/// The enablement of interrupt source of each context.
///
/// > Each global interrupt can be enabled by setting the corresponding bit
/// > in the enables register. The enables registers are accessed as a
/// > contiguous array of 32-bit registers, packed the same way as the
/// > pending bits. Bit 0 of enable register 0 represents the non-existent
/// > interrupt ID 0 and is hardwired to 0. PLIC has 15872 Interrupt Enable
/// > blocks for the contexts. The context is referred to the specific
/// > privilege mode in the specific Hart of specific RISC-V processor
/// > instance. How PLIC organizes interrupts for the contexts (Hart and
/// > privilege mode) is out of RISC-V PLIC specification scope, however it
/// > must be spec-out in vendor’s PLIC specification.
/// >
/// > The base address of Interrupt Enable Bits block within PLIC Memory Map
/// > region is fixed at 0x002000.
pub interrupt_enable: [[ReadWrite<u32, ()>; 1024 / 32]; 15872],
_reserved2: [u32; (0x200000 - 0x1f2000) / 4],
// +0x200000
pub ctxs: [PlicCtx; 15872],
}
#[repr(C)]
pub struct PlicCtx {
/// The interrupt priority threshold of each context.
///
/// > PLIC provides context based threshold register for the settings of a
/// > interrupt priority threshold of each context. The threshold register
/// > is a WARL field. The PLIC will mask all PLIC interrupts of a priority
/// > less than or equal to threshold. For example, a`threshold` value of
/// > zero permits all interrupts with non-zero priority.
/// >
/// > The base address of Priority Thresholds register block is located at
/// > 4K alignement starts from offset 0x200000.
pub priority_threshold: ReadWrite<u32, ()>,
/// The claim/complete register.
///
/// > # Interrupt Claim Process
/// >
/// > The PLIC can perform an interrupt claim by reading the
/// > `claim/complete` register, which returns the ID of the highest
/// > priority pending interrupt or zero if there is no pending interrupt. A
/// > successful claim will also atomically clear the corresponding pending
/// > bit on the interrupt source.
/// >
/// > The PLIC can perform a claim at any time and the claim operation is
/// > not affected by the setting of the priority threshold register.
/// > The Interrupt Claim Process register is context based and is located
/// > at (4K alignement + 4) starts from offset 0x200000.
/// >
/// > # Interrupt Completion
/// >
/// > The PLIC signals it has completed executing an interrupt handler by
/// > writing the interrupt ID it received from the claim to the
/// > `claim/complete` register. The PLIC does not check whether the
/// > completion ID is the same as the last claim ID for that target. If the
/// > completion ID does not match an interrupt source that is currently
/// > enabled for the target, the completion is silently ignored.
/// > The Interrupt Completion registers are context based and located at
/// > the same address with Interrupt Claim Process register, which is at
/// > (4K alignement + 4) starts from offset 0x200000.
pub claim_complete: ReadWrite<u32, ()>,
_reserved: [u32; 0x400 - 2],
}