1 /* 2 * Copyright 2019-2021, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Adrien Destugues <pulkomandy@pulkomandy.tk> 7 */ 8 9 10 #include <arch_cpu_defs.h> 11 #include <arch_int.h> 12 #include <arch/timer.h> 13 #include <boot/kernel_args.h> 14 #include <debug.h> 15 #include <kernel.h> 16 #include <platform/sbi/sbi_syscalls.h> 17 #include <timer.h> 18 #include <Clint.h> 19 20 #include <smp.h> 21 22 23 extern uint32 gPlatform; 24 25 static uint64 sTimerConversionFactor; 26 27 28 void 29 arch_timer_set_hardware_timer(bigtime_t timeout) 30 { 31 /* 32 dprintf("arch_timer_set_hardware_timer(%" B_PRIu64 "), cpu: %" B_PRId32 "\n", timeout, 33 smp_get_current_cpu()); 34 */ 35 uint64 scaledTimeout = (static_cast<__uint128_t>(timeout) * sTimerConversionFactor) >> 32; 36 37 SetBitsSie(1 << sTimerInt); 38 39 switch (gPlatform) { 40 case kPlatformMNative: 41 MSyscall(kMSyscallSetTimer, true, gClintRegs->mtime + scaledTimeout); 42 break; 43 case kPlatformSbi: { 44 sbi_set_timer(CpuTime() + scaledTimeout); 45 break; 46 } 47 default: 48 ; 49 } 50 } 51 52 53 void 54 arch_timer_clear_hardware_timer() 55 { 56 ClearBitsSie(1 << sTimerInt); 57 58 switch (gPlatform) { 59 case kPlatformMNative: 60 MSyscall(kMSyscallSetTimer, false); 61 break; 62 case kPlatformSbi: { 63 // Do nothing, it is not possible to clear SBI timer, so we only disable supervisor 64 // timer interrupt. SBI timer still can be triggered, but its interrupt will be not 65 // delivered to kernel. 66 break; 67 } 68 default: 69 ; 70 } 71 } 72 73 74 int 75 arch_init_timer(kernel_args *args) 76 { 77 sTimerConversionFactor = (1LL << 32) * args->arch_args.timerFrequency / 1000000LL; 78 79 return B_OK; 80 } 81