* [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).