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:
@@ -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();
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user