kernel/riscv: timer freq calculation, interrupt handling fixes

Change-Id: Ibe8b260a49c1b6e51df06f82b6c3a066c44accb1
Reviewed-on: https://review.haiku-os.org/c/haiku/+/6219
Reviewed-by: X512 <[email protected]>
Reviewed-by: Alex von Gluck IV <[email protected]>
This commit is contained in:
X512
2023-03-20 16:52:27 +00:00
committed by Alex von Gluck IV
parent 604b6f7e9b
commit 5865e68ef2
2 changed files with 19 additions and 11 deletions
+2 -2
View File
@@ -504,14 +504,14 @@ STrap(iframe* frame)
return; return;
} }
case causeInterrupt + sSoftInt: { case causeInterrupt + sSoftInt: {
SetSip(Sip() & ~(1 << sSoftInt)); ClearBitsSip(1 << sSoftInt);
// dprintf("sSoftInt(%" B_PRId32 ")\n", smp_get_current_cpu()); // dprintf("sSoftInt(%" B_PRId32 ")\n", smp_get_current_cpu());
smp_intercpu_int_handler(smp_get_current_cpu()); smp_intercpu_int_handler(smp_get_current_cpu());
AfterInterrupt(); AfterInterrupt();
return; return;
} }
case causeInterrupt + sTimerInt: { case causeInterrupt + sTimerInt: {
// SetSie(Sie() & ~(1 << sTimerInt)); ClearBitsSie(1 << sTimerInt);
// dprintf("sTimerInt(%" B_PRId32 ")\n", smp_get_current_cpu()); // dprintf("sTimerInt(%" B_PRId32 ")\n", smp_get_current_cpu());
timer_interrupt(); timer_interrupt();
AfterInterrupt(); AfterInterrupt();
+17 -9
View File
@@ -22,41 +22,47 @@
extern uint32 gPlatform; extern uint32 gPlatform;
static uint64 sTimerConversionFactor;
void void
arch_timer_set_hardware_timer(bigtime_t timeout) arch_timer_set_hardware_timer(bigtime_t timeout)
{ {
// dprintf("arch_timer_set_hardware_timer(%" B_PRIu64 "), cpu: %" B_PRId32 "\n", timeout, smp_get_current_cpu()); /*
dprintf("arch_timer_set_hardware_timer(%" B_PRIu64 "), cpu: %" B_PRId32 "\n", timeout,
smp_get_current_cpu());
*/
uint64 scaledTimeout = (static_cast<__uint128_t>(timeout) * sTimerConversionFactor) >> 32;
SetBitsSie(1 << sTimerInt);
// TODO: Read timer frequency from FDT
switch (gPlatform) { switch (gPlatform) {
case kPlatformMNative: case kPlatformMNative:
MSyscall(kMSyscallSetTimer, true, MSyscall(kMSyscallSetTimer, true, gClintRegs->mtime + scaledTimeout);
gClintRegs->mtime + timeout * 10);
break; break;
case kPlatformSbi: { case kPlatformSbi: {
sbi_set_timer(CpuTime() + timeout); sbi_set_timer(CpuTime() + scaledTimeout);
break; break;
} }
default: default:
; ;
} }
// SetSie(Sie() | (1 << sTimerInt));
} }
void void
arch_timer_clear_hardware_timer() arch_timer_clear_hardware_timer()
{ {
// SetSie(Sie() & ~(1 << sTimerInt)); ClearBitsSie(1 << sTimerInt);
switch (gPlatform) { switch (gPlatform) {
case kPlatformMNative: case kPlatformMNative:
MSyscall(kMSyscallSetTimer, false); MSyscall(kMSyscallSetTimer, false);
break; break;
case kPlatformSbi: { case kPlatformSbi: {
sbi_set_timer(CpuTime() + (uint64)10000000 * 3600); // Do nothing, it is not possible to clear SBI timer, so we only disable supervisor
// timer interrupt. SBI timer still can be triggered, but its interrupt will be not
// delivered to kernel.
break; break;
} }
default: default:
@@ -68,5 +74,7 @@ arch_timer_clear_hardware_timer()
int int
arch_init_timer(kernel_args *args) arch_init_timer(kernel_args *args)
{ {
sTimerConversionFactor = (1LL << 32) * args->arch_args.timerFrequency / 1000000LL;
return B_OK; return B_OK;
} }