riscv: Introduce local_hart_init
When Sstc is available make sure that even if we enable timer
interrupts nothing will happen. This is necessary for cases where
the unit tests actually intend to use the SBI TIME extension and
aren't thinking about Sstc at all, like the SBI TIME test in
riscv/sbi where we can now remove the initialization.
We introduce local_hart_init() rather than something like
local_timer_init() for this since other non-timer-related CSRs will
also need to be set at init time in the future and we can just lump
them all together.
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
diff --git a/lib/riscv/asm/processor.h b/lib/riscv/asm/processor.h
index 4c9ad96..8f70ac8 100644
--- a/lib/riscv/asm/processor.h
+++ b/lib/riscv/asm/processor.h
@@ -36,6 +36,7 @@
void install_irq_handler(unsigned long cause, void (*handler)(struct pt_regs *));
void do_handle_exception(struct pt_regs *regs);
void thread_info_init(void);
+void local_hart_init(void);
void show_regs(struct pt_regs *regs);
diff --git a/lib/riscv/processor.c b/lib/riscv/processor.c
index 0dffadc..b055acc 100644
--- a/lib/riscv/processor.c
+++ b/lib/riscv/processor.c
@@ -3,10 +3,12 @@
* Copyright (C) 2023, Ventana Micro Systems Inc., Andrew Jones <ajones@ventanamicro.com>
*/
#include <libcflat.h>
+#include <limits.h>
#include <asm/csr.h>
#include <asm/isa.h>
#include <asm/processor.h>
#include <asm/setup.h>
+#include <asm/smp.h>
extern unsigned long ImageBase;
@@ -82,3 +84,12 @@
isa_init(&cpus[cpu]);
csr_write(CSR_SSCRATCH, &cpus[cpu]);
}
+
+void local_hart_init(void)
+{
+ if (cpu_has_extension(smp_processor_id(), ISA_SSTC)) {
+ csr_write(CSR_STIMECMP, ULONG_MAX);
+ if (__riscv_xlen == 32)
+ csr_write(CSR_STIMECMPH, ULONG_MAX);
+ }
+}
diff --git a/lib/riscv/setup.c b/lib/riscv/setup.c
index 9a16f00..495db04 100644
--- a/lib/riscv/setup.c
+++ b/lib/riscv/setup.c
@@ -210,6 +210,7 @@
cpu_init();
timer_get_frequency();
thread_info_init();
+ local_hart_init();
io_init();
ret = dt_get_bootargs(&bootargs);
@@ -276,6 +277,7 @@
cpu_init();
timer_get_frequency();
thread_info_init();
+ local_hart_init();
io_init();
initrd_setup();
diff --git a/lib/riscv/smp.c b/lib/riscv/smp.c
index 4d373e0..eb7061a 100644
--- a/lib/riscv/smp.c
+++ b/lib/riscv/smp.c
@@ -27,6 +27,7 @@
__mmu_enable(data->satp);
thread_info_init();
+ local_hart_init();
info = current_thread_info();
set_cpu_online(info->cpu, true);
smp_send_event();
diff --git a/riscv/sbi.c b/riscv/sbi.c
index 01697ae..0fe26f6 100644
--- a/riscv/sbi.c
+++ b/riscv/sbi.c
@@ -15,7 +15,6 @@
#include <asm/csr.h>
#include <asm/delay.h>
#include <asm/io.h>
-#include <asm/isa.h>
#include <asm/mmu.h>
#include <asm/processor.h>
#include <asm/sbi.h>
@@ -258,11 +257,6 @@
install_irq_handler(IRQ_S_TIMER, timer_irq_handler);
local_irq_enable();
- if (cpu_has_extension(smp_processor_id(), ISA_SSTC)) {
- csr_write(CSR_STIMECMP, ULONG_MAX);
- if (__riscv_xlen == 32)
- csr_write(CSR_STIMECMPH, ULONG_MAX);
- }
timer_irq_enable();
timer_check_set_timer(false);