run in qemu -bios none ENV
This commit is contained in:
parent
8947b7e4c3
commit
58bf26222f
7 changed files with 858 additions and 9 deletions
|
@ -2,7 +2,7 @@ pub const CLOCK_FREQ: usize = 12500000;
|
|||
|
||||
pub const MMIO: &[(usize, usize)] = &[
|
||||
(0x0010_0000, 0x00_2000), // VIRT_TEST/RTC in virt machine
|
||||
(0x2000000, 0x10000),
|
||||
(0x2000000, 0x10000), // core local interrupter (CLINT)
|
||||
(0xc000000, 0x210000), // VIRT_PLIC in virt machine
|
||||
(0x10000000, 0x9000), // VIRT_UART0 with GPU in virt machine
|
||||
];
|
||||
|
@ -53,6 +53,57 @@ pub fn irq_handler() {
|
|||
plic.complete(0, IntrTargetPriority::Supervisor, intr_src_id);
|
||||
}
|
||||
|
||||
|
||||
// core local interrupter (CLINT), which contains the timer
|
||||
pub const CLINT: usize = 0x2000000;
|
||||
pub const fn clint_mtimecmp(hartid: usize) -> usize {
|
||||
CLINT + 0x4000 + 8 * hartid
|
||||
}
|
||||
pub const CLINT_MTIME: usize = CLINT + 0xBFF8; // Cycles since boot.
|
||||
|
||||
#[naked]
|
||||
#[repr(align(16))] // if miss this alignment, a load access fault will occur.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn timervec() -> ! {
|
||||
// start.rs has set up the memory that mscratch points to:
|
||||
// scratch[0,8,16] : register save area.
|
||||
// scratch[24] : address of CLINT's MTIMECMP register.
|
||||
// scratch[32] : desired interval between interrupts.
|
||||
|
||||
// Now, mscrach has a pointer to an additional scratch space.
|
||||
// to aboid overwriting the contents of the integer registers,
|
||||
// the prologue of an interrupts handler usually begins by swapping
|
||||
// an integer register(say a0) with mscratch CSR.
|
||||
// The interrupt handler stores the integer registers
|
||||
// used for processing in this scratch space.
|
||||
// a0 saved in mscrach, a1 ~ a3 saved in scratch space.
|
||||
//loop {}
|
||||
asm!(
|
||||
"csrrw a0, mscratch, a0",
|
||||
"sd a1, 0(a0)",
|
||||
"sd a2, 8(a0)",
|
||||
"sd a3, 16(a0)",
|
||||
// schedule the next timer interrupt
|
||||
// by adding interval to mtimecmp.
|
||||
"ld a1, 24(a0)", // CLINT_MTIMECMP(hartid) contents
|
||||
"ld a2, 32(a0)", // interval
|
||||
"ld a3, 0(a1)",
|
||||
"add a3, a3, a2",
|
||||
"sd a3, 0(a1)",
|
||||
// raise a supervisor software interrupt.
|
||||
"li a1, 2",
|
||||
"csrw sip, a1",
|
||||
// restore and return
|
||||
"ld a3, 16(a0)",
|
||||
"ld a2, 8(a0)",
|
||||
"ld a1, 0(a0)",
|
||||
"csrrw a0, mscratch, a0",
|
||||
"mret",
|
||||
options(noreturn)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//ref:: https://github.com/andre-richter/qemu-exit
|
||||
use core::arch::asm;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue