/* * Copyright 2019-2021, Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Adrien Destugues */ #include #include #include #include #include #include #include #include #include #include extern uint32 gPlatform; static uint64 sTimerConversionFactor; void 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()); */ uint64 scaledTimeout = (static_cast<__uint128_t>(timeout) * sTimerConversionFactor) >> 32; SetBitsSie(1 << sTimerInt); switch (gPlatform) { case kPlatformMNative: MSyscall(kMSyscallSetTimer, true, gClintRegs->mtime + scaledTimeout); break; case kPlatformSbi: { sbi_set_timer(CpuTime() + scaledTimeout); break; } default: ; } } void arch_timer_clear_hardware_timer() { ClearBitsSie(1 << sTimerInt); switch (gPlatform) { case kPlatformMNative: MSyscall(kMSyscallSetTimer, false); break; case kPlatformSbi: { // 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; } default: ; } } int arch_init_timer(kernel_args *args) { sTimerConversionFactor = (1LL << 32) * args->arch_args.timerFrequency / 1000000LL; return B_OK; }