* [Qemu-devel] [PATCH 0/5] allow HelenOS to start userspace tasks under qemu-system-sparc64
@ 2010-05-22 10:52 Igor V. Kovalenko
2010-05-22 10:52 ` [Qemu-devel] [PATCH 1/5] sparc64: generate data access exception on RW violation Igor V. Kovalenko
` (5 more replies)
0 siblings, 6 replies; 10+ messages in thread
From: Igor V. Kovalenko @ 2010-05-22 10:52 UTC (permalink / raw)
To: qemu-devel
The following series addresses a few issues found in current sparc64 mmu
implementation.
With these changes HelenOS-0.4.2-sparc64-us2.iso can progress to executing
userspace tasks (verified by looking for 40b0 addresses in in_asm debug trace)
---
Igor V. Kovalenko (5):
sparc64: generate data access exception on RW violation
sparc64: fix pstate privilege bits
sparc64: fix dump_mmu to look for global bit in tte value instead of tag
sparc64: fix mmu context at trap levels above zero
sparc64: flush translations on mmu context change
target-sparc/cpu.h | 73 +++++++++++++++++++--------
target-sparc/helper.c | 126 +++++++++++++++++++++++++++++++---------------
target-sparc/op_helper.c | 30 ++++++-----
target-sparc/translate.c | 14 +++--
4 files changed, 161 insertions(+), 82 deletions(-)
--
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 1/5] sparc64: generate data access exception on RW violation
2010-05-22 10:52 [Qemu-devel] [PATCH 0/5] allow HelenOS to start userspace tasks under qemu-system-sparc64 Igor V. Kovalenko
@ 2010-05-22 10:52 ` Igor V. Kovalenko
2010-05-22 10:52 ` [Qemu-devel] [PATCH 2/5] sparc64: fix pstate privilege bits Igor V. Kovalenko
` (4 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Igor V. Kovalenko @ 2010-05-22 10:52 UTC (permalink / raw)
To: qemu-devel
From: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>
- separate PRIV and PROT handling
- DPRINTF_MMU macro to clean up debug code
- dump mmu_idx, trap level and mmu context registers
along with address translation values
Signed-off-by: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>
---
target-sparc/helper.c | 99 +++++++++++++++++++++++++++++++------------------
1 files changed, 62 insertions(+), 37 deletions(-)
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index 2fbbbbf..4a494de 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -30,6 +30,13 @@
//#define DEBUG_MMU
//#define DEBUG_FEATURES
+#ifdef DEBUG_MMU
+#define DPRINTF_MMU(fmt, ...) \
+ do { printf("MMU: " fmt , ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF_MMU(fmt, ...) do {} while (0)
+#endif
+
static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model);
/* Sparc MMU emulation */
@@ -451,42 +458,50 @@ static int get_physical_address_data(CPUState *env,
for (i = 0; i < 64; i++) {
// ctx match, vaddr match, valid?
- if (ultrasparc_tag_match(&env->dtlb[i],
- address, context, physical)) {
+ if (ultrasparc_tag_match(&env->dtlb[i], address, context, physical)) {
+
+ uint8_t fault_type = 0;
+
// access ok?
- if (((env->dtlb[i].tte & 0x4) && is_user) ||
- (!(env->dtlb[i].tte & 0x2) && (rw == 1))) {
- uint8_t fault_type = 0;
+ if ((env->dtlb[i].tte & 0x4) && is_user) {
+ fault_type |= 1; /* privilege violation */
+ env->exception_index = TT_DFAULT;
- if ((env->dtlb[i].tte & 0x4) && is_user) {
- fault_type |= 1; /* privilege violation */
- }
+ DPRINTF_MMU("DFAULT at %" PRIx64 " context %" PRIx64
+ " mmu_idx=%d tl=%d\n",
+ address, context, mmu_idx, env->tl);
+ } else if (!(env->dtlb[i].tte & 0x2) && (rw == 1)) {
+ env->exception_index = TT_DPROT;
- if (env->dmmu.sfsr & 1) /* Fault status register */
- env->dmmu.sfsr = 2; /* overflow (not read before
+ DPRINTF_MMU("DPROT at %" PRIx64 " context %" PRIx64
+ " mmu_idx=%d tl=%d\n",
+ address, context, mmu_idx, env->tl);
+ } else {
+ *prot = PAGE_READ;
+ if (env->dtlb[i].tte & 0x2)
+ *prot |= PAGE_WRITE;
+
+ TTE_SET_USED(env->dtlb[i].tte);
+
+ return 0;
+ }
+
+ if (env->dmmu.sfsr & 1) /* Fault status register */
+ env->dmmu.sfsr = 2; /* overflow (not read before
another fault) */
- env->dmmu.sfsr |= (is_user << 3) | ((rw == 1) << 2) | 1;
+ env->dmmu.sfsr |= (is_user << 3) | ((rw == 1) << 2) | 1;
- env->dmmu.sfsr |= (fault_type << 7);
+ env->dmmu.sfsr |= (fault_type << 7);
- env->dmmu.sfar = address; /* Fault address register */
- env->exception_index = TT_DFAULT;
-#ifdef DEBUG_MMU
- printf("DFAULT at 0x%" PRIx64 "\n", address);
-#endif
- return 1;
- }
- *prot = PAGE_READ;
- if (env->dtlb[i].tte & 0x2)
- *prot |= PAGE_WRITE;
- TTE_SET_USED(env->dtlb[i].tte);
- return 0;
+ env->dmmu.sfar = address; /* Fault address register */
+ return 1;
}
}
-#ifdef DEBUG_MMU
- printf("DMISS at 0x%" PRIx64 "\n", address);
-#endif
+
+ DPRINTF_MMU("DMISS at %" PRIx64 " context %" PRIx64 "\n",
+ address, context);
+
env->dmmu.tag_access = (address & ~0x1fffULL) | context;
env->exception_index = TT_DMISS;
return 1;
@@ -528,9 +543,10 @@ static int get_physical_address_code(CPUState *env,
another fault) */
env->immu.sfsr |= (is_user << 3) | 1;
env->exception_index = TT_TFAULT;
-#ifdef DEBUG_MMU
- printf("TFAULT at 0x%" PRIx64 "\n", address);
-#endif
+
+ DPRINTF_MMU("TFAULT at %" PRIx64 " context %" PRIx64 "\n",
+ address, context);
+
return 1;
}
*prot = PAGE_EXEC;
@@ -538,9 +554,10 @@ static int get_physical_address_code(CPUState *env,
return 0;
}
}
-#ifdef DEBUG_MMU
- printf("TMISS at 0x%" PRIx64 "\n", address);
-#endif
+
+ DPRINTF_MMU("TMISS at %" PRIx64 " context %" PRIx64 "\n",
+ address, context);
+
/* Context is stored in DMMU (dmmuregs[1]) also for IMMU */
env->immu.tag_access = (address & ~0x1fffULL) | context;
env->exception_index = TT_TMISS;
@@ -578,10 +595,18 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
virt_addr = address & TARGET_PAGE_MASK;
vaddr = virt_addr + ((address & TARGET_PAGE_MASK) &
(TARGET_PAGE_SIZE - 1));
-#ifdef DEBUG_MMU
- printf("Translate at 0x%" PRIx64 " -> 0x%" PRIx64 ", vaddr 0x%" PRIx64
- "\n", address, paddr, vaddr);
-#endif
+
+ DPRINTF_MMU("Translate at %" PRIx64 " -> %" PRIx64 ","
+ " vaddr %" PRIx64
+ " mmu_idx=%d"
+ " tl=%d"
+ " primary context=%" PRIx64
+ " secondary context=%" PRIx64
+ "\n",
+ address, paddr, vaddr, mmu_idx, env->tl,
+ env->dmmu.mmu_primary_context,
+ env->dmmu.mmu_secondary_context);
+
tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size);
return 0;
}
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 2/5] sparc64: fix pstate privilege bits
2010-05-22 10:52 [Qemu-devel] [PATCH 0/5] allow HelenOS to start userspace tasks under qemu-system-sparc64 Igor V. Kovalenko
2010-05-22 10:52 ` [Qemu-devel] [PATCH 1/5] sparc64: generate data access exception on RW violation Igor V. Kovalenko
@ 2010-05-22 10:52 ` Igor V. Kovalenko
2010-05-22 10:52 ` [Qemu-devel] [PATCH 3/5] sparc64: fix dump_mmu to look for global bit in tte value instead of tag Igor V. Kovalenko
` (3 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Igor V. Kovalenko @ 2010-05-22 10:52 UTC (permalink / raw)
To: qemu-devel
From: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>
- refactor code to handle hpstate only if available for current cpu
- conditionally set hypervisor bit in hpstate register
- reorder softmmu indices so user accessable ones go first, translation context
macros supervisor() and hypervisor() adjusted as well
- disable sparcv8 registers for TARGET_SPARC64
- fix cpu_mmu_index to use sparcv9 bits only
Signed-off-by: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>
---
target-sparc/cpu.h | 61 ++++++++++++++++++++++++++++++++--------------
target-sparc/helper.c | 4 ++-
target-sparc/op_helper.c | 24 ++++++++----------
target-sparc/translate.c | 4 ++-
4 files changed, 57 insertions(+), 36 deletions(-)
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 27b020b..4fd58e9 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -92,12 +92,14 @@
#define PSR_CARRY_SHIFT 20
#define PSR_CARRY (1 << PSR_CARRY_SHIFT)
#define PSR_ICC (PSR_NEG|PSR_ZERO|PSR_OVF|PSR_CARRY)
+#if !defined(TARGET_SPARC64)
#define PSR_EF (1<<12)
#define PSR_PIL 0xf00
#define PSR_S (1<<7)
#define PSR_PS (1<<6)
#define PSR_ET (1<<5)
#define PSR_CWP 0x1f
+#endif
#define CC_SRC (env->cc_src)
#define CC_SRC2 (env->cc_src2)
@@ -341,14 +343,16 @@ typedef struct CPUSPARCState {
uint32_t wim; /* window invalid mask */
#endif
target_ulong tbr; /* trap base register */
+#if !defined(TARGET_SPARC64)
int psrs; /* supervisor mode (extracted from PSR) */
int psrps; /* previous supervisor mode */
-#if !defined(TARGET_SPARC64)
int psret; /* enable traps */
#endif
uint32_t psrpil; /* interrupt blocking level */
uint32_t pil_in; /* incoming interrupt level bitmap */
+#if !defined(TARGET_SPARC64)
int psref; /* enable fpu */
+#endif
target_ulong version;
int interrupt_index;
uint32_t nwindows;
@@ -508,21 +512,41 @@ int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);
#define CPU_SAVE_VERSION 6
/* MMU modes definitions */
+#if defined (TARGET_SPARC64)
+#define MMU_USER_IDX 0
#define MMU_MODE0_SUFFIX _user
-#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_SECONDARY_IDX 1
+#define MMU_MODE1_SUFFIX _user_secondary
+#define MMU_KERNEL_IDX 2
+#define MMU_MODE2_SUFFIX _kernel
+#define MMU_KERNEL_SECONDARY_IDX 3
+#define MMU_MODE3_SUFFIX _kernel_secondary
+#define MMU_NUCLEUS_IDX 4
+#define MMU_MODE4_SUFFIX _nucleus
+#define MMU_HYPV_IDX 5
+#define MMU_MODE5_SUFFIX _hypv
+#else
#define MMU_USER_IDX 0
+#define MMU_MODE0_SUFFIX _user
#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
+#define MMU_MODE1_SUFFIX _kernel
+#endif
+
+#if defined (TARGET_SPARC64)
+static inline int cpu_has_hypervisor(CPUState *env1)
+{
+ return env1->def->features & CPU_FEATURE_HYPV;
+}
+
+static inline int cpu_hypervisor_mode(CPUState *env1)
+{
+ return cpu_has_hypervisor(env1) && (env1->hpstate & HS_PRIV);
+}
+
+static inline int cpu_supervisor_mode(CPUState *env1)
+{
+ return env1->pstate & PS_PRIV;
+}
#endif
static inline int cpu_mmu_index(CPUState *env1)
@@ -532,12 +556,13 @@ static inline int cpu_mmu_index(CPUState *env1)
#elif !defined(TARGET_SPARC64)
return env1->psrs;
#else
- if (!env1->psrs)
- return MMU_USER_IDX;
- else if ((env1->hpstate & HS_PRIV) == 0)
- return MMU_KERNEL_IDX;
- else
+ if (cpu_hypervisor_mode(env1)) {
return MMU_HYPV_IDX;
+ } else if (cpu_supervisor_mode(env1)) {
+ return MMU_KERNEL_IDX;
+ } else {
+ return MMU_USER_IDX;
+ }
#endif
}
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index 4a494de..538795f 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -746,12 +746,12 @@ void cpu_reset(CPUSPARCState *env)
#else
#if !defined(TARGET_SPARC64)
env->psret = 0;
-#endif
env->psrs = 1;
env->psrps = 1;
+#endif
#ifdef TARGET_SPARC64
env->pstate = PS_PRIV|PS_RED|PS_PEF|PS_AG;
- env->hpstate = HS_PRIV;
+ env->hpstate = cpu_has_hypervisor(env) ? HS_PRIV : 0;
env->tl = env->maxtl;
cpu_tsptr(env)->tt = TT_POWER_ON_RESET;
env->lsu = 0;
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index d0bc277..28224b2 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -1404,11 +1404,7 @@ static target_ulong get_psr(void)
(env->psrps? PSR_PS : 0) |
(env->psret? PSR_ET : 0) | env->cwp;
#else
- return env->version | (env->psr & PSR_ICC) |
- (env->psref? PSR_EF : 0) |
- (env->psrpil << 8) |
- (env->psrs? PSR_S : 0) |
- (env->psrps? PSR_PS : 0) | env->cwp;
+ return env->psr & PSR_ICC;
#endif
}
@@ -1427,17 +1423,19 @@ target_ulong cpu_get_psr(CPUState *env1)
static void put_psr(target_ulong val)
{
env->psr = val & PSR_ICC;
+#if !defined (TARGET_SPARC64)
env->psref = (val & PSR_EF)? 1 : 0;
env->psrpil = (val & PSR_PIL) >> 8;
+#endif
#if ((!defined (TARGET_SPARC64)) && !defined(CONFIG_USER_ONLY))
cpu_check_irqs(env);
#endif
+#if !defined (TARGET_SPARC64)
env->psrs = (val & PSR_S)? 1 : 0;
env->psrps = (val & PSR_PS)? 1 : 0;
-#if !defined (TARGET_SPARC64)
env->psret = (val & PSR_ET)? 1 : 0;
-#endif
set_cwp(val & PSR_CWP);
+#endif
env->cc_op = CC_OP_FLAGS;
}
@@ -2326,7 +2324,7 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
asi &= 0xff;
if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
- || ((env->def->features & CPU_FEATURE_HYPV)
+ || (cpu_has_hypervisor(env)
&& asi >= 0x30 && asi < 0x80
&& !(env->hpstate & HS_PRIV)))
raise_exception(TT_PRIV_ACT);
@@ -2361,8 +2359,7 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
case 0xe2: // UA2007 Primary block init
case 0xe3: // UA2007 Secondary block init
if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
- if ((env->def->features & CPU_FEATURE_HYPV)
- && env->hpstate & HS_PRIV) {
+ if (cpu_hypervisor_mode(env)) {
switch(size) {
case 1:
ret = ldub_hypv(addr);
@@ -2678,7 +2675,7 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
asi &= 0xff;
if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
- || ((env->def->features & CPU_FEATURE_HYPV)
+ || (cpu_has_hypervisor(env)
&& asi >= 0x30 && asi < 0x80
&& !(env->hpstate & HS_PRIV)))
raise_exception(TT_PRIV_ACT);
@@ -2722,8 +2719,7 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
case 0xe2: // UA2007 Primary block init
case 0xe3: // UA2007 Secondary block init
if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
- if ((env->def->features & CPU_FEATURE_HYPV)
- && env->hpstate & HS_PRIV) {
+ if (cpu_hypervisor_mode(env)) {
switch(size) {
case 1:
stb_hypv(addr, val);
@@ -3048,7 +3044,7 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
void helper_ldda_asi(target_ulong addr, int asi, int rd)
{
if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
- || ((env->def->features & CPU_FEATURE_HYPV)
+ || (cpu_has_hypervisor(env)
&& asi >= 0x30 && asi < 0x80
&& !(env->hpstate & HS_PRIV)))
raise_exception(TT_PRIV_ACT);
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 8129b79..86096d2 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -183,9 +183,9 @@ static void gen_op_store_QT0_fpr(unsigned int dst)
#define hypervisor(dc) 0
#endif
#else
-#define supervisor(dc) (dc->mem_idx >= 1)
+#define supervisor(dc) (dc->mem_idx >= MMU_KERNEL_IDX)
#ifdef TARGET_SPARC64
-#define hypervisor(dc) (dc->mem_idx == 2)
+#define hypervisor(dc) (dc->mem_idx == MMU_HYPV_IDX)
#else
#endif
#endif
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 3/5] sparc64: fix dump_mmu to look for global bit in tte value instead of tag
2010-05-22 10:52 [Qemu-devel] [PATCH 0/5] allow HelenOS to start userspace tasks under qemu-system-sparc64 Igor V. Kovalenko
2010-05-22 10:52 ` [Qemu-devel] [PATCH 1/5] sparc64: generate data access exception on RW violation Igor V. Kovalenko
2010-05-22 10:52 ` [Qemu-devel] [PATCH 2/5] sparc64: fix pstate privilege bits Igor V. Kovalenko
@ 2010-05-22 10:52 ` Igor V. Kovalenko
2010-05-22 10:52 ` [Qemu-devel] [PATCH 4/5] sparc64: fix mmu context at trap levels above zero Igor V. Kovalenko
` (2 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Igor V. Kovalenko @ 2010-05-22 10:52 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>
---
target-sparc/helper.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index 538795f..1045c31 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -653,7 +653,7 @@ void dump_mmu(CPUState *env)
env->dtlb[i].tte & 0x2? "RW": "RO",
env->dtlb[i].tte & 0x40? "locked": "unlocked",
env->dtlb[i].tag & (uint64_t)0x1fffULL,
- TTE_IS_GLOBAL(env->dtlb[i].tag)? "global" : "local");
+ TTE_IS_GLOBAL(env->dtlb[i].tte)? "global" : "local");
}
}
}
@@ -687,7 +687,7 @@ void dump_mmu(CPUState *env)
env->itlb[i].tte & 0x4? "priv": "user",
env->itlb[i].tte & 0x40? "locked": "unlocked",
env->itlb[i].tag & (uint64_t)0x1fffULL,
- TTE_IS_GLOBAL(env->itlb[i].tag)? "global" : "local");
+ TTE_IS_GLOBAL(env->itlb[i].tte)? "global" : "local");
}
}
}
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 4/5] sparc64: fix mmu context at trap levels above zero
2010-05-22 10:52 [Qemu-devel] [PATCH 0/5] allow HelenOS to start userspace tasks under qemu-system-sparc64 Igor V. Kovalenko
` (2 preceding siblings ...)
2010-05-22 10:52 ` [Qemu-devel] [PATCH 3/5] sparc64: fix dump_mmu to look for global bit in tte value instead of tag Igor V. Kovalenko
@ 2010-05-22 10:52 ` Igor V. Kovalenko
2011-04-04 17:25 ` Artyom Tarasenko
2010-05-22 10:52 ` [Qemu-devel] [PATCH 5/5] sparc64: flush translations on mmu context change Igor V. Kovalenko
2010-05-22 13:16 ` [Qemu-devel] [PATCH 0/5] allow HelenOS to start userspace tasks under qemu-system-sparc64 Blue Swirl
5 siblings, 1 reply; 10+ messages in thread
From: Igor V. Kovalenko @ 2010-05-22 10:52 UTC (permalink / raw)
To: qemu-devel
From: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>
- cpu_mmu_index return MMU_NUCLEUS_IDX if trap level is not zero
- cpu_get_tb_cpu_state: store trap level and primary context in flags
this allows to restart code translation when address translation is changed
- stop translation block after writing to pstate and tl registers
- stop translation block after writing to alternate space
this can be optimized to stop only if address translation can be changed
by write operation (e.g. by comparing with MMU ASI values)
Signed-off-by: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>
---
target-sparc/cpu.h | 14 ++++++++++----
target-sparc/helper.c | 19 ++++++++++++++++++-
target-sparc/translate.c | 10 +++++++---
3 files changed, 35 insertions(+), 8 deletions(-)
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 4fd58e9..8f0484b 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -556,7 +556,9 @@ static inline int cpu_mmu_index(CPUState *env1)
#elif !defined(TARGET_SPARC64)
return env1->psrs;
#else
- if (cpu_hypervisor_mode(env1)) {
+ if (env1->tl > 0) {
+ return MMU_NUCLEUS_IDX;
+ } else if (cpu_hypervisor_mode(env1)) {
return MMU_HYPV_IDX;
} else if (cpu_supervisor_mode(env1)) {
return MMU_KERNEL_IDX;
@@ -636,9 +638,13 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
*cs_base = env->npc;
#ifdef TARGET_SPARC64
// AM . Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled
- *flags = ((env->pstate & PS_AM) << 2)
- | (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2))
- | (env->pstate & PS_PRIV) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2);
+ *flags = ((env->pstate & PS_AM) << 2) /* 5 */
+ | (((env->pstate & PS_PEF) >> 1) /* 3 */
+ | ((env->fprs & FPRS_FEF) << 2)) /* 4 */
+ | (env->pstate & PS_PRIV) /* 2 */
+ | ((env->lsu & (DMMU_E | IMMU_E)) >> 2) /* 1, 0 */
+ | ((env->tl & 0xff) << 8)
+ | (env->dmmu.mmu_primary_context << 16); /* 16... */
#else
// FPU enable . Supervisor
*flags = (env->psref << 4) | env->psrs;
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index 1045c31..96a22f3 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -572,6 +572,23 @@ static int get_physical_address(CPUState *env, target_phys_addr_t *physical,
/* ??? We treat everything as a small page, then explicitly flush
everything when an entry is evicted. */
*page_size = TARGET_PAGE_SIZE;
+
+#if defined (DEBUG_MMU)
+ /* safety net to catch wrong softmmu index use from dynamic code */
+ if (env->tl > 0 && mmu_idx != MMU_NUCLEUS_IDX) {
+ DPRINTF_MMU("get_physical_address %s tl=%d mmu_idx=%d"
+ " primary context=%" PRIx64
+ " secondary context=%" PRIx64
+ " address=%" PRIx64
+ "\n",
+ (rw == 2 ? "CODE" : "DATA"),
+ env->tl, mmu_idx,
+ env->dmmu.mmu_primary_context,
+ env->dmmu.mmu_secondary_context,
+ address);
+ }
+#endif
+
if (rw == 2)
return get_physical_address_code(env, physical, prot, address,
mmu_idx);
@@ -718,7 +735,7 @@ target_phys_addr_t cpu_get_phys_page_nofault(CPUState *env, target_ulong 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);
+ return cpu_get_phys_page_nofault(env, addr, cpu_mmu_index(env));
}
#endif
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 86096d2..72ca0b4 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -3484,14 +3484,14 @@ static void disas_sparc_insn(DisasContext * dc)
case 6: // pstate
save_state(dc, cpu_cond);
gen_helper_wrpstate(cpu_tmp0);
- gen_op_next_insn();
- tcg_gen_exit_tb(0);
- dc->is_br = 1;
+ dc->npc = DYNAMIC_PC;
break;
case 7: // tl
+ save_state(dc, cpu_cond);
tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
tcg_gen_st_i32(cpu_tmp32, cpu_env,
offsetof(CPUSPARCState, tl));
+ dc->npc = DYNAMIC_PC;
break;
case 8: // pil
gen_helper_wrpil(cpu_tmp0);
@@ -4550,6 +4550,7 @@ static void disas_sparc_insn(DisasContext * dc)
#endif
save_state(dc, cpu_cond);
gen_st_asi(cpu_val, cpu_addr, insn, 4);
+ dc->npc = DYNAMIC_PC;
break;
case 0x15: /* stba, store byte alternate */
#ifndef TARGET_SPARC64
@@ -4560,6 +4561,7 @@ static void disas_sparc_insn(DisasContext * dc)
#endif
save_state(dc, cpu_cond);
gen_st_asi(cpu_val, cpu_addr, insn, 1);
+ dc->npc = DYNAMIC_PC;
break;
case 0x16: /* stha, store halfword alternate */
#ifndef TARGET_SPARC64
@@ -4570,6 +4572,7 @@ static void disas_sparc_insn(DisasContext * dc)
#endif
save_state(dc, cpu_cond);
gen_st_asi(cpu_val, cpu_addr, insn, 2);
+ dc->npc = DYNAMIC_PC;
break;
case 0x17: /* stda, store double word alternate */
#ifndef TARGET_SPARC64
@@ -4594,6 +4597,7 @@ static void disas_sparc_insn(DisasContext * dc)
case 0x1e: /* V9 stxa */
save_state(dc, cpu_cond);
gen_st_asi(cpu_val, cpu_addr, insn, 8);
+ dc->npc = DYNAMIC_PC;
break;
#endif
default:
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH 5/5] sparc64: flush translations on mmu context change
2010-05-22 10:52 [Qemu-devel] [PATCH 0/5] allow HelenOS to start userspace tasks under qemu-system-sparc64 Igor V. Kovalenko
` (3 preceding siblings ...)
2010-05-22 10:52 ` [Qemu-devel] [PATCH 4/5] sparc64: fix mmu context at trap levels above zero Igor V. Kovalenko
@ 2010-05-22 10:52 ` Igor V. Kovalenko
2010-05-22 13:16 ` [Qemu-devel] [PATCH 0/5] allow HelenOS to start userspace tasks under qemu-system-sparc64 Blue Swirl
5 siblings, 0 replies; 10+ messages in thread
From: Igor V. Kovalenko @ 2010-05-22 10:52 UTC (permalink / raw)
To: qemu-devel
From: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>
- two pairs of softmmu indexes bind softmmu tlb to cpu tlb in fault handlers
using value of DMMU primary and secondary context registers, so we need to
flush softmmu translations when context registers are changed
Signed-off-by: Igor V. Kovalenko <igor.v.kovalenko@gmail.com>
---
target-sparc/op_helper.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index 28224b2..edeeb44 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -2959,9 +2959,15 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
break;
case 1: // Primary context
env->dmmu.mmu_primary_context = val;
+ /* can be optimized to only flush MMU_USER_IDX
+ and MMU_KERNEL_IDX entries */
+ tlb_flush(env, 1);
break;
case 2: // Secondary context
env->dmmu.mmu_secondary_context = val;
+ /* can be optimized to only flush MMU_USER_SECONDARY_IDX
+ and MMU_KERNEL_SECONDARY_IDX entries */
+ tlb_flush(env, 1);
break;
case 5: // TSB access
DPRINTF_MMU("dmmu TSB write: 0x%016" PRIx64 " -> 0x%016"
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH 0/5] allow HelenOS to start userspace tasks under qemu-system-sparc64
2010-05-22 10:52 [Qemu-devel] [PATCH 0/5] allow HelenOS to start userspace tasks under qemu-system-sparc64 Igor V. Kovalenko
` (4 preceding siblings ...)
2010-05-22 10:52 ` [Qemu-devel] [PATCH 5/5] sparc64: flush translations on mmu context change Igor V. Kovalenko
@ 2010-05-22 13:16 ` Blue Swirl
5 siblings, 0 replies; 10+ messages in thread
From: Blue Swirl @ 2010-05-22 13:16 UTC (permalink / raw)
To: Igor V. Kovalenko; +Cc: qemu-devel
Thanks, applied all.
On Sat, May 22, 2010 at 10:52 AM, Igor V. Kovalenko
<igor.v.kovalenko@gmail.com> wrote:
> The following series addresses a few issues found in current sparc64 mmu
> implementation.
>
> With these changes HelenOS-0.4.2-sparc64-us2.iso can progress to executing
> userspace tasks (verified by looking for 40b0 addresses in in_asm debug trace)
>
> ---
>
> Igor V. Kovalenko (5):
> sparc64: generate data access exception on RW violation
> sparc64: fix pstate privilege bits
> sparc64: fix dump_mmu to look for global bit in tte value instead of tag
> sparc64: fix mmu context at trap levels above zero
> sparc64: flush translations on mmu context change
>
>
> target-sparc/cpu.h | 73 +++++++++++++++++++--------
> target-sparc/helper.c | 126 +++++++++++++++++++++++++++++++---------------
> target-sparc/op_helper.c | 30 ++++++-----
> target-sparc/translate.c | 14 +++--
> 4 files changed, 161 insertions(+), 82 deletions(-)
>
> --
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH 4/5] sparc64: fix mmu context at trap levels above zero
2010-05-22 10:52 ` [Qemu-devel] [PATCH 4/5] sparc64: fix mmu context at trap levels above zero Igor V. Kovalenko
@ 2011-04-04 17:25 ` Artyom Tarasenko
2011-04-04 18:37 ` Blue Swirl
0 siblings, 1 reply; 10+ messages in thread
From: Artyom Tarasenko @ 2011-04-04 17:25 UTC (permalink / raw)
To: Igor V. Kovalenko, Blue Swirl; +Cc: qemu-devel
On Sat, May 22, 2010 at 12:52 PM, Igor V. Kovalenko
<igor.v.kovalenko@gmail.com> wrote:
> --- a/target-sparc/helper.c
> +++ b/target-sparc/helper.c
> @@ -572,6 +572,23 @@ static int get_physical_address(CPUState *env, target_phys_addr_t *physical,
> /* ??? We treat everything as a small page, then explicitly flush
> everything when an entry is evicted. */
> *page_size = TARGET_PAGE_SIZE;
> +
> +#if defined (DEBUG_MMU)
> + /* safety net to catch wrong softmmu index use from dynamic code */
What does "wrong softmmu index" mean? Is it an error or an indication
that something is not implemented?
I'm hitting this net with the following message:
get_physical_address DATA tl=1 mmu_idx=2 primary context=0 secondary
context=0 address=fffb5f40
> + if (env->tl > 0 && mmu_idx != MMU_NUCLEUS_IDX) {
> + DPRINTF_MMU("get_physical_address %s tl=%d mmu_idx=%d"
> + " primary context=%" PRIx64
> + " secondary context=%" PRIx64
> + " address=%" PRIx64
> + "\n",
> + (rw == 2 ? "CODE" : "DATA"),
> + env->tl, mmu_idx,
> + env->dmmu.mmu_primary_context,
> + env->dmmu.mmu_secondary_context,
> + address);
> + }
> +#endif
Artyom
--
Regards,
Artyom Tarasenko
solaris/sparc under qemu blog: http://tyom.blogspot.com/
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH 4/5] sparc64: fix mmu context at trap levels above zero
2011-04-04 17:25 ` Artyom Tarasenko
@ 2011-04-04 18:37 ` Blue Swirl
2011-04-04 19:12 ` Igor Kovalenko
0 siblings, 1 reply; 10+ messages in thread
From: Blue Swirl @ 2011-04-04 18:37 UTC (permalink / raw)
To: Artyom Tarasenko; +Cc: qemu-devel
On Mon, Apr 4, 2011 at 8:25 PM, Artyom Tarasenko <atar4qemu@gmail.com> wrote:
> On Sat, May 22, 2010 at 12:52 PM, Igor V. Kovalenko
> <igor.v.kovalenko@gmail.com> wrote:
>> --- a/target-sparc/helper.c
>> +++ b/target-sparc/helper.c
>> @@ -572,6 +572,23 @@ static int get_physical_address(CPUState *env, target_phys_addr_t *physical,
>> /* ??? We treat everything as a small page, then explicitly flush
>> everything when an entry is evicted. */
>> *page_size = TARGET_PAGE_SIZE;
>> +
>> +#if defined (DEBUG_MMU)
>> + /* safety net to catch wrong softmmu index use from dynamic code */
>
> What does "wrong softmmu index" mean? Is it an error or an indication
> that something is not implemented?
> I'm hitting this net with the following message:
The warning is not correct for CPUs without hypervisor mode. On T1/T2,
the default access mode when TL > 1 is hypervisor or nucleus mode.
Even then, the hypervisor could perform some accesses with kernel or
user ASIs.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH 4/5] sparc64: fix mmu context at trap levels above zero
2011-04-04 18:37 ` Blue Swirl
@ 2011-04-04 19:12 ` Igor Kovalenko
0 siblings, 0 replies; 10+ messages in thread
From: Igor Kovalenko @ 2011-04-04 19:12 UTC (permalink / raw)
To: Blue Swirl; +Cc: qemu-devel, Artyom Tarasenko
On Mon, Apr 4, 2011 at 10:37 PM, Blue Swirl <blauwirbel@gmail.com> wrote:
> On Mon, Apr 4, 2011 at 8:25 PM, Artyom Tarasenko <atar4qemu@gmail.com> wrote:
>> On Sat, May 22, 2010 at 12:52 PM, Igor V. Kovalenko
>> <igor.v.kovalenko@gmail.com> wrote:
>>> --- a/target-sparc/helper.c
>>> +++ b/target-sparc/helper.c
>>> @@ -572,6 +572,23 @@ static int get_physical_address(CPUState *env, target_phys_addr_t *physical,
>>> /* ??? We treat everything as a small page, then explicitly flush
>>> everything when an entry is evicted. */
>>> *page_size = TARGET_PAGE_SIZE;
>>> +
>>> +#if defined (DEBUG_MMU)
>>> + /* safety net to catch wrong softmmu index use from dynamic code */
>>
>> What does "wrong softmmu index" mean? Is it an error or an indication
>> that something is not implemented?
>> I'm hitting this net with the following message:
>
> The warning is not correct for CPUs without hypervisor mode. On T1/T2,
> the default access mode when TL > 1 is hypervisor or nucleus mode.
> Even then, the hypervisor could perform some accesses with kernel or
> user ASIs.
Right.
The warning is still good for CODE access. Check itself was intended
to catch reusing translated block of user or kernel mode after
entering trap so it must be corrected.
--
Kind regards,
Igor V. Kovalenko
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2011-04-04 19:12 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-22 10:52 [Qemu-devel] [PATCH 0/5] allow HelenOS to start userspace tasks under qemu-system-sparc64 Igor V. Kovalenko
2010-05-22 10:52 ` [Qemu-devel] [PATCH 1/5] sparc64: generate data access exception on RW violation Igor V. Kovalenko
2010-05-22 10:52 ` [Qemu-devel] [PATCH 2/5] sparc64: fix pstate privilege bits Igor V. Kovalenko
2010-05-22 10:52 ` [Qemu-devel] [PATCH 3/5] sparc64: fix dump_mmu to look for global bit in tte value instead of tag Igor V. Kovalenko
2010-05-22 10:52 ` [Qemu-devel] [PATCH 4/5] sparc64: fix mmu context at trap levels above zero Igor V. Kovalenko
2011-04-04 17:25 ` Artyom Tarasenko
2011-04-04 18:37 ` Blue Swirl
2011-04-04 19:12 ` Igor Kovalenko
2010-05-22 10:52 ` [Qemu-devel] [PATCH 5/5] sparc64: flush translations on mmu context change Igor V. Kovalenko
2010-05-22 13:16 ` [Qemu-devel] [PATCH 0/5] allow HelenOS to start userspace tasks under qemu-system-sparc64 Blue Swirl
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).