• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2024 Google LLC
4  * Author: Vincent Donnefort <vdonnefort@google.com>
5  */
6 
7 #include <nvhe/clock.h>
8 
9 #include <asm/arch_timer.h>
10 #include <asm/div64.h>
11 
12 static struct clock_data {
13 	struct {
14 		u32 mult;
15 		u32 shift;
16 		u64 epoch_ns;
17 		u64 epoch_cyc;
18 	} data[2];
19 	u64 cur;
20 } trace_clock_data;
21 
22 /* Does not guarantee no reader on the modified bank. */
trace_clock_update(u32 mult,u32 shift,u64 epoch_ns,u64 epoch_cyc)23 void trace_clock_update(u32 mult, u32 shift, u64 epoch_ns, u64 epoch_cyc)
24 {
25 	struct clock_data *clock = &trace_clock_data;
26 	u64 bank = clock->cur ^ 1;
27 
28 	clock->data[bank].mult		= mult;
29 	clock->data[bank].shift		= shift;
30 	clock->data[bank].epoch_ns	= epoch_ns;
31 	clock->data[bank].epoch_cyc	= epoch_cyc;
32 
33 	smp_store_release(&clock->cur, bank);
34 }
35 
36 /* Using host provided data. Do not use for anything else than debugging. */
trace_clock(void)37 u64 __attribute__((patchable_function_entry(0, 0))) trace_clock(void)
38 {
39 	struct clock_data *clock = &trace_clock_data;
40 	u64 bank = smp_load_acquire(&clock->cur);
41 	u64 cyc, ns;
42 
43 	cyc = __arch_counter_get_cntpct() - clock->data[bank].epoch_cyc;
44 
45 	ns = cyc * clock->data[bank].mult;
46 	ns >>= clock->data[bank].shift;
47 
48 	return (u64)ns + clock->data[bank].epoch_ns;
49 }
50