diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c index c6034b89ce93..8c1bbea380a8 100644 --- a/target/hexagon/op_helper.c +++ b/target/hexagon/op_helper.c @@ -17,6 +17,7 @@ #include "qemu/osdep.h" #include "qemu/log.h" +#include "qemu/timer.h" #include "exec/exec-all.h" #include "exec/cpu_ldst.h" #include "exec/helper-proto.h" @@ -2663,6 +2664,12 @@ uint32_t HELPER(creg_read)(CPUHexagonState *env, uint32_t reg) { /* These are handled directly by gen_read_ctrl_reg(). */ g_assert(reg != HEX_REG_UPCYCLELO && reg != HEX_REG_UPCYCLEHI); + + if (reg == HEX_REG_UTIMERHI) { + return cpu_get_host_ticks() >> 32; + } else if (reg == HEX_REG_UTIMERLO) { + return extract32(cpu_get_host_ticks(), 0, 32); + } return 0; } @@ -2672,6 +2679,9 @@ uint64_t HELPER(creg_read_pair)(CPUHexagonState *env, uint32_t reg) /* Pretend SSR[CE] is always set. */ return hexagon_get_sys_pcycle_count(env); } + if (reg == HEX_REG_UTIMERLO) { + return cpu_get_host_ticks(); + } return 0; } #endif diff --git a/tests/tcg/hexagon/Makefile.target b/tests/tcg/hexagon/Makefile.target index 605f15d45269..9b2e34eb05ec 100644 --- a/tests/tcg/hexagon/Makefile.target +++ b/tests/tcg/hexagon/Makefile.target @@ -54,6 +54,7 @@ HEX_TESTS += invalid-slots HEX_TESTS += unaligned_pc HEX_TESTS += unaligned_pc_multi_cof HEX_TESTS += multiple-writes +HEX_TESTS += utimer run-unaligned_pc: unaligned_pc run-unaligned_pc_multi_cof: unaligned_pc_multi_cof @@ -125,6 +126,7 @@ overflow: overflow.c hex_test.h preg_alias: preg_alias.c hex_test.h read_write_overlap: read_write_overlap.c hex_test.h reg_mut: reg_mut.c hex_test.h +utimer: utimer.c hex_test.h # This test has to be compiled for the -mv67t target usr: usr.c hex_test.h diff --git a/tests/tcg/hexagon/utimer.c b/tests/tcg/hexagon/utimer.c new file mode 100644 index 000000000000..ae3bca320192 --- /dev/null +++ b/tests/tcg/hexagon/utimer.c @@ -0,0 +1,50 @@ +/* + * Copyright(c) 2022-2023 Qualcomm Innovation Center, Inc. All Rights Reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +static int err; + +#include "hex_test.h" + +static uint64_t get_time() +{ + uint64_t time; + asm volatile("%0 = utimer\n\t" + : "=r"(time) + : + : + ); + return time; +} + +static uint64_t get_time_from_regs() +{ + uint32_t time_low; + uint32_t time_high; + asm volatile("%0 = utimerhi\n\t" + "%1 = utimerlo\n\t" + : "=r"(time_high), "=r"(time_low) + : + : + ); + return ((uint64_t)time_high << 32) | (uint64_t)time_low; +} + + +int main() +{ + err = 0; + + uint64_t t0 = get_time(); + check64_ne(t0, 0); + + uint64_t t1 = get_time_from_regs(); + check64_ne(t1, 0); + + puts(err ? "FAIL" : "PASS"); + return err; +}