@@ -739,7 +739,24 @@ static void hexagon_cpu_class_init(ObjectClass *c, void *data)
#ifndef CONFIG_USER_ONLY
uint32_t hexagon_greg_read(CPUHexagonState *env, uint32_t reg)
{
- g_assert_not_reached();
+ target_ulong ssr = arch_get_system_reg(env, HEX_SREG_SSR);
+ int ssr_ce = GET_SSR_FIELD(SSR_CE, ssr);
+
+ if (reg <= HEX_GREG_G3) {
+ return env->greg[reg];
+ }
+ switch (reg) {
+ case HEX_GREG_GPCYCLELO:
+ return ssr_ce ? hexagon_get_sys_pcycle_count_low(env) : 0;
+
+ case HEX_GREG_GPCYCLEHI:
+ return ssr_ce ? hexagon_get_sys_pcycle_count_high(env) : 0;
+
+ default:
+ qemu_log_mask(LOG_UNIMP, "reading greg %" PRId32
+ " not yet supported.\n", reg);
+ return 0;
+ }
}
#endif
@@ -1877,13 +1877,28 @@ uint64_t HELPER(sreg_read_pair)(CPUHexagonState *env, uint32_t reg)
}
uint32_t HELPER(greg_read)(CPUHexagonState *env, uint32_t reg)
+
{
- g_assert_not_reached();
+ return hexagon_greg_read(env, reg);
}
uint64_t HELPER(greg_read_pair)(CPUHexagonState *env, uint32_t reg)
+
{
- g_assert_not_reached();
+ if (reg == HEX_GREG_G0 || reg == HEX_GREG_G2) {
+ return (uint64_t)(env->greg[reg]) |
+ (((uint64_t)(env->greg[reg + 1])) << 32);
+ }
+ switch (reg) {
+ case HEX_GREG_GPCYCLELO: {
+ target_ulong ssr = arch_get_system_reg(env, HEX_SREG_SSR);
+ int ssr_ce = GET_SSR_FIELD(SSR_CE, ssr);
+ return ssr_ce ? hexagon_get_sys_pcycle_count(env) : 0;
+ }
+ default:
+ return (uint64_t)hexagon_greg_read(env, reg) |
+ ((uint64_t)(hexagon_greg_read(env, reg + 1)) << 32);
+ }
}
void HELPER(setprio)(CPUHexagonState *env, uint32_t thread, uint32_t prio)