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)23void 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)37u64 __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