All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.