qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 2/2] [RFC] ARMv7: Enable hardware management of acce


From: Bahadir Balban
Subject: [Qemu-devel] [PATCH 2/2] [RFC] ARMv7: Enable hardware management of access flags
Date: Sat, 23 Jan 2010 15:09:18 +0200

ARMv7 SCTLR bit 17 enables hardware management of access flags
where the hardware sets AP0 bit of a section or second level
table entry upon first access and does not generate a fault.

The issue is this had to introduce an extra ldl_phys_ptr call
that returns the pointer to page table entry for writing. A
better way to do it?

Signed-off-by: Bahadir Balban <address@hidden>
---
 cpu-common.h        |    1 +
 exec.c              |   16 ++++++++++++++++
 target-arm/helper.c |   13 ++++++++++---
 3 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/cpu-common.h b/cpu-common.h
index 6302372..96cf67d 100644
--- a/cpu-common.h
+++ b/cpu-common.h
@@ -64,6 +64,7 @@ void cpu_unregister_map_client(void *cookie);
 uint32_t ldub_phys(target_phys_addr_t addr);
 uint32_t lduw_phys(target_phys_addr_t addr);
 uint32_t ldl_phys(target_phys_addr_t addr);
+uint32_t *ldl_phys_ptr(target_phys_addr_t addr);
 uint64_t ldq_phys(target_phys_addr_t addr);
 void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val);
 void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val);
diff --git a/exec.c b/exec.c
index 1190591..cc19586 100644
--- a/exec.c
+++ b/exec.c
@@ -3346,6 +3346,22 @@ uint32_t ldl_phys(target_phys_addr_t addr)
     return val;
 }
 
+uint32_t *ldl_phys_ptr(target_phys_addr_t addr)
+{
+    unsigned long pd;
+    PhysPageDesc *p;
+
+    p = phys_page_find(addr >> TARGET_PAGE_BITS);
+    if (!p) {
+        pd = IO_MEM_UNASSIGNED;
+    } else {
+        pd = p->phys_offset;
+    }
+    /* RAM case */
+    return qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
+            (addr & ~TARGET_PAGE_MASK);
+}
+
 /* warning: addr must be aligned */
 uint64_t ldq_phys(target_phys_addr_t addr)
 {
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 0098053..5cebd8c 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1065,9 +1065,16 @@ static int get_phys_addr_v6(CPUState *env, uint32_t 
address, int access_type,
 
     /* The simplified model uses AP[0] as an access control bit.  */
     if ((env->cp15.c1_sys & (1 << 29)) && (ap & 1) == 0) {
-        /* Access flag fault.  */
-        code = (code == 15) ? 6 : 3;
-        goto do_fault;
+        /* Is hardware management enabled? */
+        if (!(env->cp15.c1_sys & (1 << 17))) {
+           /* No, access flag fault.  */
+           code = (code == 15) ? 6 : 3;
+           goto do_fault;
+       } else {
+            /* Set the access flag */
+           uint32_t *desc_ptr = ldl_phys_ptr(table);
+            *desc_ptr |= (1 << 10);
+       }
     }
     *prot = check_ap(env, ap, domain, access_type, is_user);
     if (!*prot) {
-- 
1.6.3.3





reply via email to

[Prev in Thread] Current Thread [Next in Thread]