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