qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/3] sparc64: improve mmu context handling
@ 2010-05-03  7:29 Igor V. Kovalenko
  2010-05-03  7:29 ` [Qemu-devel] [PATCH 1/3] sparc64: more ultrasparc asi extensions for disassembler Igor V. Kovalenko
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Igor V. Kovalenko @ 2010-05-03  7:29 UTC (permalink / raw)
  To: qemu-devel

The following series implements more sparc64 MMU bits.

We now support secondary and nucleus contexts referenced by
alternate space access instructions, and handle global MMU
translation entries.

---

Igor V. Kovalenko (3):
      sparc64: more ultrasparc asi extensions for disassembler
      sparc64: implement global translation table entries
      sparc64: handle asi referencing nucleus and secondary MMU contexts


 softmmu_exec.h           |   25 ++++
 sparc-dis.c              |   22 ++++
 target-sparc/cpu.h       |   31 +++++
 target-sparc/exec.h      |    4 +
 target-sparc/helper.c    |   71 +++++++----
 target-sparc/op_helper.c |  287 ++++++++++++++++++++++++++++++++++------------
 6 files changed, 336 insertions(+), 104 deletions(-)

-- 
Kind regards,
Igor V. Kovalenko

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH 1/3] sparc64: more ultrasparc asi extensions for disassembler
  2010-05-03  7:29 [Qemu-devel] [PATCH 0/3] sparc64: improve mmu context handling Igor V. Kovalenko
@ 2010-05-03  7:29 ` Igor V. Kovalenko
  2010-05-03  7:29 ` [Qemu-devel] [PATCH 2/3] sparc64: implement global translation table entries Igor V. Kovalenko
  2010-05-03  7:29 ` [Qemu-devel] [PATCH 3/3] sparc64: handle asi referencing nucleus and secondary MMU contexts Igor V. Kovalenko
  2 siblings, 0 replies; 8+ messages in thread
From: Igor V. Kovalenko @ 2010-05-03  7:29 UTC (permalink / raw)
  To: qemu-devel

From: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>

Signed-off-by: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>
---
 sparc-dis.c |   22 ++++++++++++++++++++++
 1 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/sparc-dis.c b/sparc-dis.c
index 611e74f..cdd337a 100644
--- a/sparc-dis.c
+++ b/sparc-dis.c
@@ -2153,6 +2153,28 @@ static const arg asi_table_v9[] =
   { 0x8a, "#ASI_PRIMARY_NOFAULT_LITTLE" },
   { 0x8b, "#ASI_SECONDARY_NOFAULT_LITTLE" },
   /* These are UltraSPARC extensions.  */
+  { 0x14, "#ASI_PHYS_USE_EC"},
+  { 0x15, "#ASI_PHYS_BYPASS_EC_WITH_EBIT"},
+  { 0x45, "#ASI_LSU_CONTROL_REG"},
+  { 0x47, "#ASI_DCACHE_TAG"},
+  { 0x4a, "#ASI_UPA_CONFIG_REG"},
+  { 0x50, "#ASI_IMMU" },
+  { 0x51, "#ASI_IMMU_TSB_8KB_PTR_REG" },
+  { 0x52, "#ASI_IMMU_TSB_64KB_PTR_REG" },
+  /*{ 0x53, "#reserved?" },*/
+  { 0x54, "#ASI_ITLB_DATA_IN_REG" },
+  { 0x55, "#ASI_ITLB_DATA_ACCESS_REG" },
+  { 0x56, "#ASI_ITLB_TAG_READ_REG" },
+  { 0x57, "#ASI_IMMU_DEMAP" },
+  { 0x58, "#ASI_DMMU" },
+  { 0x59, "#ASI_DMMU_TSB_8KB_PTR_REG" },
+  { 0x5a, "#ASI_DMMU_TSB_64KB_PTR_REG" },
+  { 0x5b, "#ASI_DMMU_TSB_DIRECT_PTR_REG" },
+  { 0x5c, "#ASI_DTLB_DATA_IN_REG" },
+  { 0x5d, "#ASI_DTLB_DATA_ACCESS_REG" },
+  { 0x5e, "#ASI_DTLB_TAG_READ_REG" },
+  { 0x5f, "#ASI_DMMU_DEMAP" },
+  { 0x67, "#ASI_IC_TAG"},
   /* FIXME: There are dozens of them.  Not sure we want them all.
      Most are for kernel building but some are for vis type stuff.  */
   { 0, NULL }

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH 2/3] sparc64: implement global translation table entries
  2010-05-03  7:29 [Qemu-devel] [PATCH 0/3] sparc64: improve mmu context handling Igor V. Kovalenko
  2010-05-03  7:29 ` [Qemu-devel] [PATCH 1/3] sparc64: more ultrasparc asi extensions for disassembler Igor V. Kovalenko
@ 2010-05-03  7:29 ` Igor V. Kovalenko
  2010-05-03 20:06   ` Blue Swirl
  2010-05-03  7:29 ` [Qemu-devel] [PATCH 3/3] sparc64: handle asi referencing nucleus and secondary MMU contexts Igor V. Kovalenko
  2 siblings, 1 reply; 8+ messages in thread
From: Igor V. Kovalenko @ 2010-05-03  7:29 UTC (permalink / raw)
  To: qemu-devel

From: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>

- match global tte against any context
- show global tte in MMU dump

Signed-off-by: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>
---
 target-sparc/cpu.h       |   18 ++++++++++++++++
 target-sparc/helper.c    |   33 ++++++++++++-----------------
 target-sparc/op_helper.c |   52 ++++++++++++++++++++++++++++++++++++++--------
 3 files changed, 75 insertions(+), 28 deletions(-)

diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 0e7f390..b705728 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -513,6 +513,24 @@ static inline void cpu_set_cwp(CPUSPARCState *env1, int new_cwp)
 /* sun4m.c, sun4u.c */
 void cpu_check_irqs(CPUSPARCState *env);
 
+#if defined (TARGET_SPARC64)
+
+static inline int compare_masked(uint64_t x, uint64_t y, uint64_t mask)
+{
+    return (x & mask) == (y & mask);
+}
+
+#define MMU_CONTEXT_BITS 13
+#define MMU_CONTEXT_MASK ((1 << MMU_CONTEXT_BITS) - 1)
+
+static inline int tlb_compare_context(const SparcTLBEntry *tlb,
+                                      uint64_t context)
+{
+    return compare_masked(context, tlb->tag, MMU_CONTEXT_MASK);
+}
+
+#endif
+
 static inline void PUT_PSR(CPUSPARCState *env1, target_ulong val)
 {
     env1->psr = val & PSR_ICC;
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index 1f0f7d4..4ece01b 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -381,17 +381,11 @@ static inline target_phys_addr_t ultrasparc_truncate_physical(uint64_t x)
  * UltraSparc IIi I/DMMUs
  */
 
-static inline int compare_masked(uint64_t x, uint64_t y, uint64_t mask)
-{
-    return (x & mask) == (y & mask);
-}
-
 // Returns true if TTE tag is valid and matches virtual address value in context
 // requires virtual address mask value calculated from TTE entry size
 static inline int ultrasparc_tag_match(SparcTLBEntry *tlb,
                                        uint64_t address, uint64_t context,
-                                       target_phys_addr_t *physical,
-                                       int is_nucleus)
+                                       target_phys_addr_t *physical)
 {
     uint64_t mask;
 
@@ -413,8 +407,7 @@ static inline int ultrasparc_tag_match(SparcTLBEntry *tlb,
 
     // valid, context match, virtual address match?
     if (TTE_IS_VALID(tlb->tte) &&
-        ((is_nucleus && compare_masked(0, tlb->tag, 0x1fff))
-         || TTE_IS_GLOBAL(tlb->tte) || compare_masked(context, tlb->tag, 0x1fff))
+        (TTE_IS_GLOBAL(tlb->tte) || tlb_compare_context(tlb, context))
         && compare_masked(address, tlb->tag, mask))
     {
         // decode physical address
@@ -431,7 +424,6 @@ static int get_physical_address_data(CPUState *env,
 {
     unsigned int i;
     uint64_t context;
-    int is_nucleus;
 
     if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */
         *physical = ultrasparc_truncate_physical(address);
@@ -439,14 +431,16 @@ static int get_physical_address_data(CPUState *env,
         return 0;
     }
 
-    context = env->dmmu.mmu_primary_context & 0x1fff;
-    is_nucleus = env->tl > 0;
+    if (env->tl == 0) {
+        context = env->dmmu.mmu_primary_context & 0x1fff;
+    } else {
+        context = 0;
+    }
 
     for (i = 0; i < 64; i++) {
         // ctx match, vaddr match, valid?
         if (ultrasparc_tag_match(&env->dtlb[i],
-                                 address, context, physical,
-                                 is_nucleus)) {
+                                 address, context, physical)) {
             // access ok?
             if (((env->dtlb[i].tte & 0x4) && is_user) ||
                 (!(env->dtlb[i].tte & 0x2) && (rw == 1))) {
@@ -492,7 +486,6 @@ static int get_physical_address_code(CPUState *env,
 {
     unsigned int i;
     uint64_t context;
-    int is_nucleus;
 
     if ((env->lsu & IMMU_E) == 0 || (env->pstate & PS_RED) != 0) {
         /* IMMU disabled */
@@ -501,14 +494,16 @@ static int get_physical_address_code(CPUState *env,
         return 0;
     }
 
-    context = env->dmmu.mmu_primary_context & 0x1fff;
-    is_nucleus = env->tl > 0;
+    if (env->tl == 0) {
+        context = env->dmmu.mmu_primary_context & 0x1fff;
+    } else {
+        context = 0;
+    }
 
     for (i = 0; i < 64; i++) {
         // ctx match, vaddr match, valid?
         if (ultrasparc_tag_match(&env->itlb[i],
-                                 address, context, physical,
-                                 is_nucleus)) {
+                                 address, context, physical)) {
             // access ok?
             if ((env->itlb[i].tte & 0x4) && is_user) {
                 if (env->immu.sfsr) /* Fault status register */
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index b27778b..e048845 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -129,24 +129,58 @@ static void demap_tlb(SparcTLBEntry *tlb, target_ulong demap_addr,
 {
     unsigned int i;
     target_ulong mask;
+    uint64_t context;
+
+    int is_demap_context = (demap_addr >> 6) & 1;
+
+    // demap context
+    switch ((demap_addr >> 4) & 3) {
+    case 0: // primary
+        context = env1->dmmu.mmu_primary_context;
+        break;
+    case 1: // secondary
+        context = env1->dmmu.mmu_secondary_context;
+        break;
+    case 2: // nucleus
+        context = 0;
+        break;
+    case 3: // reserved
+        return;
+    }
 
     for (i = 0; i < 64; i++) {
         if (TTE_IS_VALID(tlb[i].tte)) {
 
-            mask = 0xffffffffffffe000ULL;
-            mask <<= 3 * ((tlb[i].tte >> 61) & 3);
+            if (is_demap_context) {
+                // will remove non-global entries matching context value
+                if (TTE_IS_GLOBAL(tlb[i].tte) ||
+                    !tlb_compare_context(&tlb[i], context)) {
+                    continue;
+                }
+            } else {
+                // demap page
+                // will remove any entry matching VA
+                mask = 0xffffffffffffe000ULL;
+                mask <<= 3 * ((tlb[i].tte >> 61) & 3);
+
+                if (!compare_masked(demap_addr, tlb[i].tag, mask)) {
+                    continue;
+                }
+
+                // entry should be global or matching context value
+                if (!TTE_IS_GLOBAL(tlb[i].tte) &&
+                    !tlb_compare_context(&tlb[i], context)) {
+                    continue;
+                }
+            }
 
-            if ((demap_addr & mask) == (tlb[i].tag & mask)) {
-                replace_tlb_entry(&tlb[i], 0, 0, env1);
+            replace_tlb_entry(&tlb[i], 0, 0, env1);
 #ifdef DEBUG_MMU
-                DPRINTF_MMU("%s demap invalidated entry [%02u]\n", strmmu, i);
-                dump_mmu(env1);
+            DPRINTF_MMU("%s demap invalidated entry [%02u]\n", strmmu, i);
+            dump_mmu(env1);
 #endif
-            }
-            //return;
         }
     }
-
 }
 
 static void replace_tlb_1bit_lru(SparcTLBEntry *tlb,

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH 3/3] sparc64: handle asi referencing nucleus and secondary MMU contexts
  2010-05-03  7:29 [Qemu-devel] [PATCH 0/3] sparc64: improve mmu context handling Igor V. Kovalenko
  2010-05-03  7:29 ` [Qemu-devel] [PATCH 1/3] sparc64: more ultrasparc asi extensions for disassembler Igor V. Kovalenko
  2010-05-03  7:29 ` [Qemu-devel] [PATCH 2/3] sparc64: implement global translation table entries Igor V. Kovalenko
@ 2010-05-03  7:29 ` Igor V. Kovalenko
  2 siblings, 0 replies; 8+ messages in thread
From: Igor V. Kovalenko @ 2010-05-03  7:29 UTC (permalink / raw)
  To: qemu-devel

From: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>

- increase max supported MMU modes to 6
- handle nucleus context asi
- handle secondary context asi
- handle non-faulting loads from secondary context

Signed-off-by: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>
---
 softmmu_exec.h           |   25 ++++-
 target-sparc/cpu.h       |   13 ++-
 target-sparc/exec.h      |    4 +
 target-sparc/helper.c    |   42 ++++++--
 target-sparc/op_helper.c |  235 ++++++++++++++++++++++++++++++++++------------
 5 files changed, 241 insertions(+), 78 deletions(-)

diff --git a/softmmu_exec.h b/softmmu_exec.h
index a43e621..28d1d53 100644
--- a/softmmu_exec.h
+++ b/softmmu_exec.h
@@ -100,9 +100,28 @@
 #undef MEMSUFFIX
 #endif /* (NB_MMU_MODES >= 5) */
 
-#if (NB_MMU_MODES > 5)
-#error "NB_MMU_MODES > 5 is not supported for now"
-#endif /* (NB_MMU_MODES > 5) */
+#if (NB_MMU_MODES >= 6)
+
+#define ACCESS_TYPE 5
+#define MEMSUFFIX MMU_MODE5_SUFFIX
+#define DATA_SIZE 1
+#include "softmmu_header.h"
+
+#define DATA_SIZE 2
+#include "softmmu_header.h"
+
+#define DATA_SIZE 4
+#include "softmmu_header.h"
+
+#define DATA_SIZE 8
+#include "softmmu_header.h"
+#undef ACCESS_TYPE
+#undef MEMSUFFIX
+#endif /* (NB_MMU_MODES >= 6) */
+
+#if (NB_MMU_MODES > 6)
+#error "NB_MMU_MODES > 6 is not supported for now"
+#endif /* (NB_MMU_MODES > 6) */
 
 /* these access are slower, they must be as rare as possible */
 #define ACCESS_TYPE (NB_MMU_MODES)
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index b705728..b679333 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -224,7 +224,7 @@ enum {
 #if !defined(TARGET_SPARC64)
 #define NB_MMU_MODES 2
 #else
-#define NB_MMU_MODES 3
+#define NB_MMU_MODES 6
 typedef struct trap_state {
     uint64_t tpc;
     uint64_t tnpc;
@@ -571,6 +571,9 @@ static inline void PUT_CWP64(CPUSPARCState *env1, int cwp)
 #if !defined(CONFIG_USER_ONLY)
 void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
                           int is_asi, int size);
+target_phys_addr_t cpu_get_phys_page_nofault(CPUState *env, target_ulong addr,
+                                           int mmu_idx);
+
 #endif
 int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);
 
@@ -587,10 +590,18 @@ int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);
 #define MMU_MODE1_SUFFIX _kernel
 #ifdef TARGET_SPARC64
 #define MMU_MODE2_SUFFIX _hypv
+#define MMU_MODE3_SUFFIX _nucleus
+#define MMU_MODE4_SUFFIX _user_secondary
+#define MMU_MODE5_SUFFIX _kernel_secondary
 #endif
 #define MMU_USER_IDX   0
 #define MMU_KERNEL_IDX 1
 #define MMU_HYPV_IDX   2
+#ifdef TARGET_SPARC64
+#define MMU_NUCLEUS_IDX 3
+#define MMU_USER_SECONDARY_IDX   4
+#define MMU_KERNEL_SECONDARY_IDX 5
+#endif
 
 static inline int cpu_mmu_index(CPUState *env1)
 {
diff --git a/target-sparc/exec.h b/target-sparc/exec.h
index 70df828..1e9de82 100644
--- a/target-sparc/exec.h
+++ b/target-sparc/exec.h
@@ -13,6 +13,10 @@ register struct CPUSPARCState *env asm(AREG0);
 #include "cpu.h"
 #include "exec-all.h"
 
+#if !defined(CONFIG_USER_ONLY)
+#include "softmmu_exec.h"
+#endif /* !defined(CONFIG_USER_ONLY) */
+
 /* op_helper.c */
 void do_interrupt(CPUState *env);
 
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index 4ece01b..cac6cad 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -420,21 +420,32 @@ static inline int ultrasparc_tag_match(SparcTLBEntry *tlb,
 
 static int get_physical_address_data(CPUState *env,
                                      target_phys_addr_t *physical, int *prot,
-                                     target_ulong address, int rw, int is_user)
+                                     target_ulong address, int rw, int mmu_idx)
 {
     unsigned int i;
     uint64_t context;
 
+    int is_user = (mmu_idx == MMU_USER_IDX ||
+                   mmu_idx == MMU_USER_SECONDARY_IDX);
+
     if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */
         *physical = ultrasparc_truncate_physical(address);
         *prot = PAGE_READ | PAGE_WRITE;
         return 0;
     }
 
-    if (env->tl == 0) {
+    switch(mmu_idx) {
+    case MMU_USER_IDX:
+    case MMU_KERNEL_IDX:
         context = env->dmmu.mmu_primary_context & 0x1fff;
-    } else {
+        break;
+    case MMU_USER_SECONDARY_IDX:
+    case MMU_KERNEL_SECONDARY_IDX:
+        context = env->dmmu.mmu_secondary_context & 0x1fff;
+        break;
+    case MMU_NUCLEUS_IDX:
         context = 0;
+        break;
     }
 
     for (i = 0; i < 64; i++) {
@@ -482,11 +493,14 @@ static int get_physical_address_data(CPUState *env,
 
 static int get_physical_address_code(CPUState *env,
                                      target_phys_addr_t *physical, int *prot,
-                                     target_ulong address, int is_user)
+                                     target_ulong address, int mmu_idx)
 {
     unsigned int i;
     uint64_t context;
 
+    int is_user = (mmu_idx == MMU_USER_IDX ||
+                   mmu_idx == MMU_USER_SECONDARY_IDX);
+
     if ((env->lsu & IMMU_E) == 0 || (env->pstate & PS_RED) != 0) {
         /* IMMU disabled */
         *physical = ultrasparc_truncate_physical(address);
@@ -495,8 +509,10 @@ static int get_physical_address_code(CPUState *env,
     }
 
     if (env->tl == 0) {
+        /* PRIMARY context */
         context = env->dmmu.mmu_primary_context & 0x1fff;
     } else {
+        /* NUCLEUS context */
         context = 0;
     }
 
@@ -535,17 +551,15 @@ static int get_physical_address(CPUState *env, target_phys_addr_t *physical,
                                 target_ulong address, int rw, int mmu_idx,
                                 target_ulong *page_size)
 {
-    int is_user = mmu_idx == MMU_USER_IDX;
-
     /* ??? We treat everything as a small page, then explicitly flush
        everything when an entry is evicted.  */
     *page_size = TARGET_PAGE_SIZE;
     if (rw == 2)
         return get_physical_address_code(env, physical, prot, address,
-                                         is_user);
+                                         mmu_idx);
     else
         return get_physical_address_data(env, physical, prot, address, rw,
-                                         is_user);
+                                         mmu_idx);
 }
 
 /* Perform address translation */
@@ -659,21 +673,27 @@ void dump_mmu(CPUState *env)
 
 
 #if !defined(CONFIG_USER_ONLY)
-target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
+target_phys_addr_t cpu_get_phys_page_nofault(CPUState *env, target_ulong addr,
+                                           int mmu_idx)
 {
     target_phys_addr_t phys_addr;
     target_ulong page_size;
     int prot, access_index;
 
     if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2,
-                             MMU_KERNEL_IDX, &page_size) != 0)
+                             mmu_idx, &page_size) != 0)
         if (get_physical_address(env, &phys_addr, &prot, &access_index, addr,
-                                 0, MMU_KERNEL_IDX, &page_size) != 0)
+                                 0, mmu_idx, &page_size) != 0)
             return -1;
     if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED)
         return -1;
     return phys_addr;
 }
+
+target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
+{
+    return cpu_get_phys_page_nofault(env, addr, MMU_KERNEL_IDX);
+}
 #endif
 
 void cpu_reset(CPUSPARCState *env)
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index e048845..0388646 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -1,9 +1,6 @@
 #include "exec.h"
 #include "host-utils.h"
 #include "helper.h"
-#if !defined(CONFIG_USER_ONLY)
-#include "softmmu_exec.h"
-#endif /* !defined(CONFIG_USER_ONLY) */
 
 //#define DEBUG_MMU
 //#define DEBUG_MXCC
@@ -2141,17 +2138,29 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
     switch (asi) {
     case 0x82: // Primary no-fault
     case 0x8a: // Primary no-fault LE
-        if (cpu_get_phys_page_debug(env, addr) == -1ULL) {
+    case 0x83: // Secondary no-fault
+    case 0x8b: // Secondary no-fault LE
+        {
+            /* secondary space access has lowest asi bit equal to 1 */
+            int access_mmu_idx = ( asi & 1 ) ? MMU_KERNEL_IDX
+                                             : MMU_KERNEL_SECONDARY_IDX;
+
+            if (cpu_get_phys_page_nofault(env, addr, access_mmu_idx) == -1ULL) {
 #ifdef DEBUG_ASI
-            dump_asi("read ", last_addr, asi, size, ret);
+                dump_asi("read ", last_addr, asi, size, ret);
 #endif
-            return 0;
+                return 0;
+            }
         }
         // Fall through
     case 0x10: // As if user primary
+    case 0x11: // As if user secondary
     case 0x18: // As if user primary LE
+    case 0x19: // As if user secondary LE
     case 0x80: // Primary
+    case 0x81: // Secondary
     case 0x88: // Primary LE
+    case 0x89: // Secondary LE
     case 0xe2: // UA2007 Primary block init
     case 0xe3: // UA2007 Secondary block init
         if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
@@ -2173,37 +2182,75 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
                     break;
                 }
             } else {
+                /* secondary space access has lowest asi bit equal to 1 */
+                if (asi & 1) {
+                    switch(size) {
+                    case 1:
+                        ret = ldub_kernel_secondary(addr);
+                        break;
+                    case 2:
+                        ret = lduw_kernel_secondary(addr);
+                        break;
+                    case 4:
+                        ret = ldl_kernel_secondary(addr);
+                        break;
+                    default:
+                    case 8:
+                        ret = ldq_kernel_secondary(addr);
+                        break;
+                    }
+                } else {
+                    switch(size) {
+                    case 1:
+                        ret = ldub_kernel(addr);
+                        break;
+                    case 2:
+                        ret = lduw_kernel(addr);
+                        break;
+                    case 4:
+                        ret = ldl_kernel(addr);
+                        break;
+                    default:
+                    case 8:
+                        ret = ldq_kernel(addr);
+                        break;
+                    }
+                }
+            }
+        } else {
+            /* secondary space access has lowest asi bit equal to 1 */
+            if (asi & 1) {
                 switch(size) {
                 case 1:
-                    ret = ldub_kernel(addr);
+                    ret = ldub_user_secondary(addr);
                     break;
                 case 2:
-                    ret = lduw_kernel(addr);
+                    ret = lduw_user_secondary(addr);
                     break;
                 case 4:
-                    ret = ldl_kernel(addr);
+                    ret = ldl_user_secondary(addr);
                     break;
                 default:
                 case 8:
-                    ret = ldq_kernel(addr);
+                    ret = ldq_user_secondary(addr);
+                    break;
+                }
+            } else {
+                switch(size) {
+                case 1:
+                    ret = ldub_user(addr);
+                    break;
+                case 2:
+                    ret = lduw_user(addr);
+                    break;
+                case 4:
+                    ret = ldl_user(addr);
+                    break;
+                default:
+                case 8:
+                    ret = ldq_user(addr);
                     break;
                 }
-            }
-        } else {
-            switch(size) {
-            case 1:
-                ret = ldub_user(addr);
-                break;
-            case 2:
-                ret = lduw_user(addr);
-                break;
-            case 4:
-                ret = ldl_user(addr);
-                break;
-            default:
-            case 8:
-                ret = ldq_user(addr);
-                break;
             }
         }
         break;
@@ -2234,22 +2281,27 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
         //  Only ldda allowed
         raise_exception(TT_ILL_INSN);
         return 0;
-    case 0x83: // Secondary no-fault
-    case 0x8b: // Secondary no-fault LE
-        if (cpu_get_phys_page_debug(env, addr) == -1ULL) {
-#ifdef DEBUG_ASI
-            dump_asi("read ", last_addr, asi, size, ret);
-#endif
-            return 0;
-        }
-        // Fall through
     case 0x04: // Nucleus
     case 0x0c: // Nucleus Little Endian (LE)
-    case 0x11: // As if user secondary
-    case 0x19: // As if user secondary LE
+    {
+        switch(size) {
+        case 1:
+            ret = ldub_nucleus(addr);
+            break;
+        case 2:
+            ret = lduw_nucleus(addr);
+            break;
+        case 4:
+            ret = ldl_nucleus(addr);
+            break;
+        default:
+        case 8:
+            ret = ldq_nucleus(addr);
+            break;
+        }
+        break;
+    }
     case 0x4a: // UPA config
-    case 0x81: // Secondary
-    case 0x89: // Secondary LE
         // XXX
         break;
     case 0x45: // LSU
@@ -2463,9 +2515,13 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
 
     switch(asi) {
     case 0x10: // As if user primary
+    case 0x11: // As if user secondary
     case 0x18: // As if user primary LE
+    case 0x19: // As if user secondary LE
     case 0x80: // Primary
+    case 0x81: // Secondary
     case 0x88: // Primary LE
+    case 0x89: // Secondary LE
     case 0xe2: // UA2007 Primary block init
     case 0xe3: // UA2007 Secondary block init
         if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
@@ -2487,37 +2543,75 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
                     break;
                 }
             } else {
+                /* secondary space access has lowest asi bit equal to 1 */
+                if (asi & 1) {
+                    switch(size) {
+                    case 1:
+                        stb_kernel_secondary(addr, val);
+                        break;
+                    case 2:
+                        stw_kernel_secondary(addr, val);
+                        break;
+                    case 4:
+                        stl_kernel_secondary(addr, val);
+                        break;
+                    case 8:
+                    default:
+                        stq_kernel_secondary(addr, val);
+                        break;
+                    }
+                } else {
+                    switch(size) {
+                    case 1:
+                        stb_kernel(addr, val);
+                        break;
+                    case 2:
+                        stw_kernel(addr, val);
+                        break;
+                    case 4:
+                        stl_kernel(addr, val);
+                        break;
+                    case 8:
+                    default:
+                        stq_kernel(addr, val);
+                        break;
+                    }
+                }
+            }
+        } else {
+            /* secondary space access has lowest asi bit equal to 1 */
+            if (asi & 1) {
                 switch(size) {
                 case 1:
-                    stb_kernel(addr, val);
+                    stb_user_secondary(addr, val);
                     break;
                 case 2:
-                    stw_kernel(addr, val);
+                    stw_user_secondary(addr, val);
                     break;
                 case 4:
-                    stl_kernel(addr, val);
+                    stl_user_secondary(addr, val);
                     break;
                 case 8:
                 default:
-                    stq_kernel(addr, val);
+                    stq_user_secondary(addr, val);
+                    break;
+                }
+            } else {
+                switch(size) {
+                case 1:
+                    stb_user(addr, val);
+                    break;
+                case 2:
+                    stw_user(addr, val);
+                    break;
+                case 4:
+                    stl_user(addr, val);
+                    break;
+                case 8:
+                default:
+                    stq_user(addr, val);
                     break;
                 }
-            }
-        } else {
-            switch(size) {
-            case 1:
-                stb_user(addr, val);
-                break;
-            case 2:
-                stw_user(addr, val);
-                break;
-            case 4:
-                stl_user(addr, val);
-                break;
-            case 8:
-            default:
-                stq_user(addr, val);
-                break;
             }
         }
         break;
@@ -2550,11 +2644,26 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
         return;
     case 0x04: // Nucleus
     case 0x0c: // Nucleus Little Endian (LE)
-    case 0x11: // As if user secondary
-    case 0x19: // As if user secondary LE
+    {
+        switch(size) {
+        case 1:
+            stb_nucleus(addr, val);
+            break;
+        case 2:
+            stw_nucleus(addr, val);
+            break;
+        case 4:
+            stl_nucleus(addr, val);
+            break;
+        default:
+        case 8:
+            stq_nucleus(addr, val);
+            break;
+        }
+        break;
+    }
+
     case 0x4a: // UPA config
-    case 0x81: // Secondary
-    case 0x89: // Secondary LE
         // XXX
         return;
     case 0x45: // LSU

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] sparc64: implement global translation table entries
  2010-05-03  7:29 ` [Qemu-devel] [PATCH 2/3] sparc64: implement global translation table entries Igor V. Kovalenko
@ 2010-05-03 20:06   ` Blue Swirl
  2010-05-03 20:21     ` Igor Kovalenko
  0 siblings, 1 reply; 8+ messages in thread
From: Blue Swirl @ 2010-05-03 20:06 UTC (permalink / raw)
  To: Igor V. Kovalenko; +Cc: qemu-devel

On 5/3/10, Igor V. Kovalenko <igor.v.kovalenko@gmail.com> wrote:
> From: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>
>
>  - match global tte against any context
>  - show global tte in MMU dump
>
>  Signed-off-by: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>

I get this error:
  CC    sparc64-softmmu/op_helper.o
cc1: warnings being treated as errors
/src/qemu/target-sparc/op_helper.c: In function 'demap_tlb':
/src/qemu/target-sparc/op_helper.c:129: error: 'context' may be used
uninitialized in this function

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] sparc64: implement global translation table entries
  2010-05-03 20:06   ` Blue Swirl
@ 2010-05-03 20:21     ` Igor Kovalenko
  2010-05-03 20:29       ` Blue Swirl
  0 siblings, 1 reply; 8+ messages in thread
From: Igor Kovalenko @ 2010-05-03 20:21 UTC (permalink / raw)
  To: Blue Swirl; +Cc: qemu-devel

On Tue, May 4, 2010 at 12:06 AM, Blue Swirl <blauwirbel@gmail.com> wrote:
> On 5/3/10, Igor V. Kovalenko <igor.v.kovalenko@gmail.com> wrote:
>> From: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>
>>
>>  - match global tte against any context
>>  - show global tte in MMU dump
>>
>>  Signed-off-by: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>
>
> I get this error:
>  CC    sparc64-softmmu/op_helper.o
> cc1: warnings being treated as errors
> /src/qemu/target-sparc/op_helper.c: In function 'demap_tlb':
> /src/qemu/target-sparc/op_helper.c:129: error: 'context' may be used
> uninitialized in this function
>

My gcc (Gentoo 4.4.3-r2 p1.2) is silent, and looking at the change all
4 possible cases are handled in switch statement.
It should initializes context in 3 usable cases and returns from the
4th which is reserved.
How do we fix this issue?

-- 
Kind regards,
Igor V. Kovalenko

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] sparc64: implement global translation table entries
  2010-05-03 20:21     ` Igor Kovalenko
@ 2010-05-03 20:29       ` Blue Swirl
  2010-05-04 19:12         ` Igor Kovalenko
  0 siblings, 1 reply; 8+ messages in thread
From: Blue Swirl @ 2010-05-03 20:29 UTC (permalink / raw)
  To: Igor Kovalenko; +Cc: qemu-devel

On 5/3/10, Igor Kovalenko <igor.v.kovalenko@gmail.com> wrote:
> On Tue, May 4, 2010 at 12:06 AM, Blue Swirl <blauwirbel@gmail.com> wrote:
>  > On 5/3/10, Igor V. Kovalenko <igor.v.kovalenko@gmail.com> wrote:
>  >> From: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>
>  >>
>  >>  - match global tte against any context
>  >>  - show global tte in MMU dump
>  >>
>  >>  Signed-off-by: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>
>  >
>  > I get this error:
>  >  CC    sparc64-softmmu/op_helper.o
>  > cc1: warnings being treated as errors
>  > /src/qemu/target-sparc/op_helper.c: In function 'demap_tlb':
>  > /src/qemu/target-sparc/op_helper.c:129: error: 'context' may be used
>  > uninitialized in this function
>  >
>
>
> My gcc (Gentoo 4.4.3-r2 p1.2) is silent, and looking at the change all
>  4 possible cases are handled in switch statement.

I think gcc is not intelligent enough to know that x & 3 has only 4
possible cases. :-)

>  It should initializes context in 3 usable cases and returns from the
>  4th which is reserved.
>  How do we fix this issue?

I'd add a default case to one of the cases. Another possibility is to
initialize the context with 0 and then make one of the cases empty.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] [PATCH 2/3] sparc64: implement global translation table entries
  2010-05-03 20:29       ` Blue Swirl
@ 2010-05-04 19:12         ` Igor Kovalenko
  0 siblings, 0 replies; 8+ messages in thread
From: Igor Kovalenko @ 2010-05-04 19:12 UTC (permalink / raw)
  To: Blue Swirl; +Cc: qemu-devel

On Tue, May 4, 2010 at 12:29 AM, Blue Swirl <blauwirbel@gmail.com> wrote:
> On 5/3/10, Igor Kovalenko <igor.v.kovalenko@gmail.com> wrote:
>> On Tue, May 4, 2010 at 12:06 AM, Blue Swirl <blauwirbel@gmail.com> wrote:
>>  > On 5/3/10, Igor V. Kovalenko <igor.v.kovalenko@gmail.com> wrote:
>>  >> From: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>
>>  >>
>>  >>  - match global tte against any context
>>  >>  - show global tte in MMU dump
>>  >>
>>  >>  Signed-off-by: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>
>>  >
>>  > I get this error:
>>  >  CC    sparc64-softmmu/op_helper.o
>>  > cc1: warnings being treated as errors
>>  > /src/qemu/target-sparc/op_helper.c: In function 'demap_tlb':
>>  > /src/qemu/target-sparc/op_helper.c:129: error: 'context' may be used
>>  > uninitialized in this function
>>  >
>>
>>
>> My gcc (Gentoo 4.4.3-r2 p1.2) is silent, and looking at the change all
>>  4 possible cases are handled in switch statement.
>
> I think gcc is not intelligent enough to know that x & 3 has only 4
> possible cases. :-)
>
>>  It should initializes context in 3 usable cases and returns from the
>>  4th which is reserved.
>>  How do we fix this issue?
>
> I'd add a default case to one of the cases. Another possibility is to
> initialize the context with 0 and then make one of the cases empty.
>

Added default case, resent this patch only.

-- 
Kind regards,
Igor V. Kovalenko

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2010-05-04 19:12 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-03  7:29 [Qemu-devel] [PATCH 0/3] sparc64: improve mmu context handling Igor V. Kovalenko
2010-05-03  7:29 ` [Qemu-devel] [PATCH 1/3] sparc64: more ultrasparc asi extensions for disassembler Igor V. Kovalenko
2010-05-03  7:29 ` [Qemu-devel] [PATCH 2/3] sparc64: implement global translation table entries Igor V. Kovalenko
2010-05-03 20:06   ` Blue Swirl
2010-05-03 20:21     ` Igor Kovalenko
2010-05-03 20:29       ` Blue Swirl
2010-05-04 19:12         ` Igor Kovalenko
2010-05-03  7:29 ` [Qemu-devel] [PATCH 3/3] sparc64: handle asi referencing nucleus and secondary MMU contexts Igor V. Kovalenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).