diff mbox series

[15/39] target/hexagon: Implement hex_tlb_entry_get_perm()

Message ID 20250301052845.1012069-16-brian.cain@oss.qualcomm.com (mailing list archive)
State New
Headers show
Series hexagon system emu, part 2/3 | expand

Commit Message

Brian Cain March 1, 2025, 5:28 a.m. UTC
From: Brian Cain <bcain@quicinc.com>

Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 target/hexagon/hex_mmu.c | 54 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 53 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/target/hexagon/hex_mmu.c b/target/hexagon/hex_mmu.c
index 54c4ba2dbf..d2297c036d 100644
--- a/target/hexagon/hex_mmu.c
+++ b/target/hexagon/hex_mmu.c
@@ -267,7 +267,59 @@  static inline void hex_tlb_entry_get_perm(CPUHexagonState *env, uint64_t entry,
                                           int mmu_idx, int *prot,
                                           int32_t *excp)
 {
-    g_assert_not_reached();
+    bool perm_x = GET_TLB_FIELD(entry, PTE_X);
+    bool perm_w = GET_TLB_FIELD(entry, PTE_W);
+    bool perm_r = GET_TLB_FIELD(entry, PTE_R);
+    bool perm_u = GET_TLB_FIELD(entry, PTE_U);
+    bool user_idx = mmu_idx == MMU_USER_IDX;
+
+    if (mmu_idx == MMU_KERNEL_IDX) {
+        *prot = PAGE_VALID | PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+        return;
+    }
+
+    *prot = PAGE_VALID;
+    switch (access_type) {
+    case MMU_INST_FETCH:
+        if (user_idx && !perm_u) {
+            *excp = HEX_EVENT_PRECISE;
+            env->cause_code = HEX_CAUSE_FETCH_NO_UPAGE;
+        } else if (!perm_x) {
+            *excp = HEX_EVENT_PRECISE;
+            env->cause_code = HEX_CAUSE_FETCH_NO_XPAGE;
+        }
+        break;
+    case MMU_DATA_LOAD:
+        if (user_idx && !perm_u) {
+            *excp = HEX_EVENT_PRECISE;
+            env->cause_code = HEX_CAUSE_PRIV_NO_UREAD;
+        } else if (!perm_r) {
+            *excp = HEX_EVENT_PRECISE;
+            env->cause_code = HEX_CAUSE_PRIV_NO_READ;
+        }
+        break;
+    case MMU_DATA_STORE:
+        if (user_idx && !perm_u) {
+            *excp = HEX_EVENT_PRECISE;
+            env->cause_code = HEX_CAUSE_PRIV_NO_UWRITE;
+        } else if (!perm_w) {
+            *excp = HEX_EVENT_PRECISE;
+            env->cause_code = HEX_CAUSE_PRIV_NO_WRITE;
+        }
+        break;
+    }
+
+    if (!user_idx || perm_u) {
+        if (perm_x) {
+            *prot |= PAGE_EXEC;
+        }
+        if (perm_r) {
+            *prot |= PAGE_READ;
+        }
+        if (perm_w) {
+            *prot |= PAGE_WRITE;
+        }
+    }
 }
 
 static inline bool hex_tlb_entry_match(CPUHexagonState *env, uint64_t entry,