riscv64: integrate minimal flattened devicetree reader and switch timer to time CSR
Punch list §25 item 0.3 NOT complete. - Added `starkernel/fdt.h` and `fdt.c` for minimal read-only devicetree parsing: sufficient for boot-time lookups such as `timebase-frequency`. - Bootloader now captures the devicetree blob (DTB) from `EFI_DTB_TABLE_GUID` into `BootInfo::dtb`. - RISC-V timer subsystem now uses the `time` CSR as the primary timestamp source, abandoning the hardcoded `cycle` frequency assumption. - Timer rate is read from `timebase-frequency` in the DTB when accessible; otherwise, a fallback value is used with a RELATIVE trust level. - Integrated the SBI TIME extension for one-shot timer deadlines, ensuring re-arming occurs after each tick to avoid missing heartbeats. Verified: riscv64 builds clean, boots to the ok> prompt with no regression; `riscv64/timer.c` reports accurate frequencies on QEMU's default firmware. Signed-off-by: Robert Allan James <robert.allan.james@gmail.com>
This commit is contained in:
@@ -17,6 +17,12 @@ volatile const char *g_sk_fault_word = (void *)0;
|
||||
|
||||
extern void riscv64_install_vectors(void);
|
||||
|
||||
/* Defined in arch/riscv64/apic.c. Declared here rather than in the shared
|
||||
* starkernel/apic.h because re-arming is specific to the one-shot SBI timer
|
||||
* and has no meaning for the amd64 periodic APIC timer. Same extern-in-place
|
||||
* convention as riscv64_install_vectors above. */
|
||||
extern void riscv64_timer_rearm(void);
|
||||
|
||||
/* scause cause codes for supervisor-mode interrupts (RISC-V Privileged Spec
|
||||
* §4.1.9, Table "Supervisor cause register values"). Only the timer is used;
|
||||
* software (1) and external (9) interrupts are not enabled. */
|
||||
@@ -30,11 +36,11 @@ extern void riscv64_install_vectors(void);
|
||||
* Unlike @c riscv64_exception_handler() this **returns** — the trap entry
|
||||
* restores the caller-saved register set and issues @c SRET.
|
||||
*
|
||||
* Supervisor timer (cause 5) is routed to @c heartbeat_tick(). No timer is
|
||||
* armed yet: arming via the SBI TIME extension, enabling @c sie.STIE, and the
|
||||
* mandatory per-tick re-arm are punch-list item 0.3. Until then this path is
|
||||
* unreachable, which is why item 0.2 accepts on "boots with no regression"
|
||||
* rather than on having observed an interrupt.
|
||||
* Supervisor timer (cause 5) re-arms the one-shot SBI timer and then accounts
|
||||
* the tick. **Re-arm comes first**: the SBI timer fires once per programmed
|
||||
* deadline, so any return path that skips the re-arm stops the heartbeat
|
||||
* permanently and silently. Ordering it ahead of @c heartbeat_tick() means a
|
||||
* fault in the bookkeeping cannot also cost the next tick.
|
||||
*
|
||||
* Any other cause is ignored rather than fatal: an unexpected-but-harmless
|
||||
* asynchronous interrupt should not take the kernel down, and none are
|
||||
@@ -47,6 +53,7 @@ void riscv64_interrupt_handler(uint64_t scause)
|
||||
uint64_t cause = scause & ~SCAUSE_INTERRUPT_BIT;
|
||||
|
||||
if (cause == SCAUSE_S_TIMER) {
|
||||
riscv64_timer_rearm();
|
||||
heartbeat_tick();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user