xref: /haiku/src/system/kernel/arch/riscv64/arch_timer.cpp (revision 5865e68ef24e849e1ce3971f16a63377e2d0644e)
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