@@ -15,6 +15,7 @@ void hexagon_set_sys_pcycle_count(CPUHexagonState *env, uint64_t);
void hexagon_set_sys_pcycle_count_low(CPUHexagonState *env, uint32_t);
void hexagon_set_sys_pcycle_count_high(CPUHexagonState *env, uint32_t);
void hexagon_modify_ssr(CPUHexagonState *env, uint32_t new, uint32_t old);
+int get_cpu_mode(CPUHexagonState *env);
int get_exe_mode(CPUHexagonState *env);
void clear_wait_mode(CPUHexagonState *env);
void hexagon_ssr_set_cause(CPUHexagonState *env, uint32_t cause);
@@ -650,6 +650,28 @@ static const TCGCPUOps hexagon_tcg_ops = {
#endif /* !CONFIG_USER_ONLY */
};
+static int hexagon_cpu_mmu_index(CPUState *cs, bool ifetch)
+{
+#ifndef CONFIG_USER_ONLY
+ BQL_LOCK_GUARD();
+ CPUHexagonState *env = cpu_env(cs);
+ uint32_t syscfg = arch_get_system_reg(env, HEX_SREG_SYSCFG);
+ uint8_t mmuen = GET_SYSCFG_FIELD(SYSCFG_MMUEN, syscfg);
+ if (!mmuen) {
+ return MMU_KERNEL_IDX;
+ }
+
+ int cpu_mode = get_cpu_mode(env);
+ if (cpu_mode == HEX_CPU_MODE_MONITOR) {
+ return MMU_KERNEL_IDX;
+ } else if (cpu_mode == HEX_CPU_MODE_GUEST) {
+ return MMU_GUEST_IDX;
+ }
+#endif
+
+ return MMU_USER_IDX;
+}
+
static void hexagon_cpu_class_init(ObjectClass *c, void *data)
{
@@ -667,6 +689,7 @@ static void hexagon_cpu_class_init(ObjectClass *c, void *data)
cc->class_by_name = hexagon_cpu_class_by_name;
cc->has_work = hexagon_cpu_has_work;
+ cc->mmu_index = hexagon_cpu_mmu_index;
cc->dump_state = hexagon_dump_state;
cc->set_pc = hexagon_cpu_set_pc;
cc->get_pc = hexagon_cpu_get_pc;
@@ -394,4 +394,45 @@ void hexagon_stop_thread(CPUHexagonState *env)
}
}
+static int sys_in_monitor_mode_ssr(uint32_t ssr)
+{
+ if ((GET_SSR_FIELD(SSR_EX, ssr) != 0) ||
+ ((GET_SSR_FIELD(SSR_EX, ssr) == 0) && (GET_SSR_FIELD(SSR_UM, ssr) == 0)))
+ return 1;
+ return 0;
+}
+
+static int sys_in_guest_mode_ssr(uint32_t ssr)
+{
+ if ((GET_SSR_FIELD(SSR_EX, ssr) == 0) &&
+ (GET_SSR_FIELD(SSR_UM, ssr) != 0) &&
+ (GET_SSR_FIELD(SSR_GM, ssr) != 0))
+ return 1;
+ return 0;
+}
+
+static int sys_in_user_mode_ssr(uint32_t ssr)
+{
+ if ((GET_SSR_FIELD(SSR_EX, ssr) == 0) &&
+ (GET_SSR_FIELD(SSR_UM, ssr) != 0) &&
+ (GET_SSR_FIELD(SSR_GM, ssr) == 0))
+ return 1;
+ return 0;
+}
+
+int get_cpu_mode(CPUHexagonState *env)
+
+{
+ uint32_t ssr = arch_get_system_reg(env, HEX_SREG_SSR);
+
+ if (sys_in_monitor_mode_ssr(ssr)) {
+ return HEX_CPU_MODE_MONITOR;
+ } else if (sys_in_guest_mode_ssr(ssr)) {
+ return HEX_CPU_MODE_GUEST;
+ } else if (sys_in_user_mode_ssr(ssr)) {
+ return HEX_CPU_MODE_USER;
+ }
+ return HEX_CPU_MODE_MONITOR;
+}
+
#endif