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