All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation
@ 2016-10-01 10:05 Artyom Tarasenko
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 01/29] target-sparc: don't trap on MMU-fault if MMU is disabled Artyom Tarasenko
                   ` (30 more replies)
  0 siblings, 31 replies; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

This patch series adds a Niagara OpenSPARC T1 sun4v machine.
The most important new feature: it can boot Solaris 10 / sparc64.
The machine uses a firmware released by Sun as a part of the OpenSPARC project.

The series are available under:
https://github.com/artyom-tarasenko/qemu/tree/sun4v-for-upstream

The command line for booting Solaris 10 / sparc:

sparc64-softmmu/qemu-system-sparc64 -M Niagara -L /path/to/S10image/ -nographic -m 256 -drive if=pflash,readonly=on,file=/path/to/S10image/disk.s10hw2

More info under
http://tyom.blogspot.de/2016/10/qemu-sun4vniagara-target-went-public.html

Artyom Tarasenko (29):
  target-sparc: don't trap on MMU-fault if MMU is disabled
  target-sparc: use explicit mmu register pointers
  target-sparc: add UA2005 TTE bit #defines
  target-sparc: add UltraSPARC T1 TLB #defines
  target-sparc: on UA2005 don't deliver Interrupt_level_n IRQs in
    hypervisor mode
  target-sparc: simplify replace_tlb_entry by using TTE_PGSIZE
  target-sparc: implement UA2005 scratchpad registers
  target-sparc: implement UltraSPARC-T1 Strand status ASR
  target-sparc: hypervisor mode takes over nucleus mode
  target-sparc: implement UA2005 hypervisor traps
  target-sparc: implement UA2005 GL register
  target-sparc: implement UA2005 rdhpstate and wrhpstate instructions
  target-sparc: fix immediate UA2005 traps
  target-sparc: use direct address translation in hyperprivileged mode
  target-sparc: allow priveleged ASIs in hyperprivileged mode
  target-sparc: ignore writes to UA2005 CPU mondo queue register
  target-sparc: replace the last tlb entry when no free entries left
  target-sparc: use SparcV9MMU type for sparc64 I/D-MMUs
  target-sparc: implement UA2005 TSB Pointers
  target-sparc: simplify ultrasparc_tsb_pointer
  target-sparc: allow 256M sized pages
  target-sparc: implement auto-demapping for UA2005 CPUs
  target-sparc: implement ST_BLKINIT_ ASIs
  target-sparc: add more registers to dump_mmu
  target-sparc: implement UA2005 ASI_MMU (0x21)
  target-sparc: store the UA2005 entries in sun4u format
  target-sparc: implement sun4v RTC
  target-sparc: move common cpu initialisation routines to sparc64.c
  target-sparc: fix up Niagara machine

 MAINTAINERS                         |   6 +
 default-configs/sparc64-softmmu.mak |   2 +
 hw/sparc64/Makefile.objs            |   2 +
 hw/sparc64/niagara.c                | 177 ++++++++++++++++
 hw/sparc64/sparc64.c                | 378 +++++++++++++++++++++++++++++++++++
 hw/sparc64/sun4u.c                  | 382 +----------------------------------
 hw/timer/Makefile.objs              |   2 +
 hw/timer/sun4v-rtc.c                | 103 ++++++++++
 include/hw/sparc/sparc64.h          |   5 +
 include/hw/timer/sun4v-rtc.h        |   1 +
 target-sparc/asi.h                  |   1 +
 target-sparc/cpu.c                  |  13 +-
 target-sparc/cpu.h                  |  79 +++++---
 target-sparc/helper.h               |   1 +
 target-sparc/int64_helper.c         |  42 +++-
 target-sparc/ldst_helper.c          | 388 ++++++++++++++++++++++++++++--------
 target-sparc/machine.c              |   4 +-
 target-sparc/mmu_helper.c           |  28 +--
 target-sparc/translate.c            |  42 +++-
 target-sparc/win_helper.c           |  46 ++++-
 20 files changed, 1171 insertions(+), 531 deletions(-)
 create mode 100644 hw/sparc64/niagara.c
 create mode 100644 hw/sparc64/sparc64.c
 create mode 100644 hw/timer/sun4v-rtc.c
 create mode 100644 include/hw/sparc/sparc64.h
 create mode 100644 include/hw/timer/sun4v-rtc.h

-- 
2.7.2

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

* [Qemu-devel] [PATCH 01/29] target-sparc: don't trap on MMU-fault if MMU is disabled
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-10 21:14   ` Richard Henderson
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 02/29] target-sparc: use explicit mmu register pointers Artyom Tarasenko
                   ` (29 subsequent siblings)
  30 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/ldst_helper.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index 6ce5ccc..f17ac9b 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -2341,9 +2341,13 @@ void sparc_cpu_unassigned_access(CPUState *cs, hwaddr addr,
 #endif
 
     if (is_exec) {
-        helper_raise_exception(env, TT_CODE_ACCESS);
+        if (env->lsu & (IMMU_E)) {
+            helper_raise_exception(env, TT_CODE_ACCESS);
+        }
     } else {
-        helper_raise_exception(env, TT_DATA_ACCESS);
+        if (env->lsu & (DMMU_E)) {
+                helper_raise_exception(env, TT_DATA_ACCESS);
+        }
     }
 }
 #endif
-- 
2.7.2

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

* [Qemu-devel] [PATCH 02/29] target-sparc: use explicit mmu register pointers
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 01/29] target-sparc: don't trap on MMU-fault if MMU is disabled Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-10 21:18   ` Richard Henderson
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 03/29] target-sparc: add UA2005 TTE bit #defines Artyom Tarasenko
                   ` (28 subsequent siblings)
  30 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Use explicit register pointers while accessing D/I-MMU registers.
Trap on access to missing registers.

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/cpu.h         |  4 +++
 target-sparc/ldst_helper.c | 66 +++++++++++++++++++++++++++++++++++++---------
 2 files changed, 58 insertions(+), 12 deletions(-)

diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index a3d64a4..238ebf2 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -436,6 +436,8 @@ struct CPUSPARCState {
             uint64_t sfar;
             uint64_t tsb;
             uint64_t tag_access;
+            uint64_t virtual_watchpoint;
+            uint64_t physical_watchpoint;
         } immu;
     };
     union {
@@ -448,6 +450,8 @@ struct CPUSPARCState {
             uint64_t sfar;
             uint64_t tsb;
             uint64_t tag_access;
+            uint64_t virtual_watchpoint;
+            uint64_t physical_watchpoint;
         } dmmu;
     };
     SparcTLBEntry itlb[64];
diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index f17ac9b..74708f2 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -1479,14 +1479,25 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
     case ASI_IMMU: /* I-MMU regs */
         {
             int reg = (addr >> 3) & 0xf;
-
-            if (reg == 0) {
-                /* I-TSB Tag Target register */
+            switch (reg) {
+            case 0:
+                /* 0x00 I-TSB Tag Target register */
                 ret = ultrasparc_tag_target(env->immu.tag_access);
-            } else {
-                ret = env->immuregs[reg];
+                break;
+            case 3: /* SFSR */
+                ret = env->immu.sfsr;
+                break;
+            case 5: /* TSB access */
+                ret = env->immu.tsb;
+                break;
+            case 6:
+                /* 0x30 I-TSB Tag Access register */
+                ret = env->immu.tag_access;
+                break;
+            default:
+                cpu_unassigned_access(cs, addr, false, false, 1, size);
+                ret = 0;
             }
-
             break;
         }
     case ASI_IMMU_TSB_8KB_PTR: /* I-MMU 8k TSB pointer */
@@ -1522,12 +1533,38 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
     case ASI_DMMU: /* D-MMU regs */
         {
             int reg = (addr >> 3) & 0xf;
-
-            if (reg == 0) {
-                /* D-TSB Tag Target register */
+            switch (reg) {
+            case 0:
+                /* 0x00 D-TSB Tag Target register */
                 ret = ultrasparc_tag_target(env->dmmu.tag_access);
-            } else {
-                ret = env->dmmuregs[reg];
+                break;
+            case 1: /* 0x08 Primary Context */
+                ret = env->dmmu.mmu_primary_context;
+                break;
+            case 2: /* 0x10 Secondary Context */
+                ret = env->dmmu.mmu_secondary_context;
+                break;
+            case 3: /* SFSR */
+                ret = env->dmmu.sfsr;
+                break;
+            case 4: /* 0x20 SFAR */
+                ret = env->dmmu.sfar;
+                break;
+            case 5: /* 0x28 TSB access */
+                ret = env->dmmu.tsb;
+                break;
+            case 6: /* 0x30 D-TSB Tag Access register */
+                ret = env->dmmu.tag_access;
+                break;
+            case 7:
+                ret = env->dmmu.virtual_watchpoint;
+                break;
+            case 8:
+                ret = env->dmmu.physical_watchpoint;
+                break;
+            default:
+                cpu_unassigned_access(cs, addr, false, false, 1, size);
+                ret = 0;
             }
             break;
         }
@@ -1910,6 +1947,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
             case 8:
                 return;
             default:
+                cpu_unassigned_access(cs, addr, true, false, 1, size);
                 break;
             }
 
@@ -1980,9 +2018,13 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
                 env->dmmu.tag_access = val;
                 break;
             case 7: /* Virtual Watchpoint */
+                env->dmmu.virtual_watchpoint = val;
+                break;
             case 8: /* Physical Watchpoint */
+                env->dmmu.physical_watchpoint = val;
+                break;
             default:
-                env->dmmuregs[reg] = val;
+                cpu_unassigned_access(cs, addr, true, false, 1, size);
                 break;
             }
 
-- 
2.7.2

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

* [Qemu-devel] [PATCH 03/29] target-sparc: add UA2005 TTE bit #defines
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 01/29] target-sparc: don't trap on MMU-fault if MMU is disabled Artyom Tarasenko
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 02/29] target-sparc: use explicit mmu register pointers Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-10 21:22   ` Richard Henderson
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 04/29] target-sparc: add UltraSPARC T1 TLB #defines Artyom Tarasenko
                   ` (27 subsequent siblings)
  30 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/cpu.h | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 238ebf2..2c169e1 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -290,11 +290,17 @@ enum {
 
 #define TTE_VALID_BIT       (1ULL << 63)
 #define TTE_NFO_BIT         (1ULL << 60)
+#define TTE_NFO_BIT_UA2005  (1ULL << 62)
 #define TTE_USED_BIT        (1ULL << 41)
+#define TTE_USED_BIT_UA2005 (1ULL << 47)
 #define TTE_LOCKED_BIT      (1ULL <<  6)
+#define TTE_LOCKED_BIT_UA2005 (1ULL <<  61)
 #define TTE_SIDEEFFECT_BIT  (1ULL <<  3)
+#define TTE_SIDEEFFECT_BIT_UA2005 (1ULL <<  11)
 #define TTE_PRIV_BIT        (1ULL <<  2)
+#define TTE_PRIV_BIT_UA2005 (1ULL <<  8)
 #define TTE_W_OK_BIT        (1ULL <<  1)
+#define TTE_W_OK_BIT_UA2005 (1ULL <<  6)
 #define TTE_GLOBAL_BIT      (1ULL <<  0)
 
 #define TTE_IS_VALID(tte)   ((tte) & TTE_VALID_BIT)
@@ -302,14 +308,24 @@ enum {
 #define TTE_IS_USED(tte)    ((tte) & TTE_USED_BIT)
 #define TTE_IS_LOCKED(tte)  ((tte) & TTE_LOCKED_BIT)
 #define TTE_IS_SIDEEFFECT(tte) ((tte) & TTE_SIDEEFFECT_BIT)
+#define TTE_IS_SIDEEFFECT_UA2005(tte) ((tte) & TTE_SIDEEFFECT_BIT_UA2005)
 #define TTE_IS_PRIV(tte)    ((tte) & TTE_PRIV_BIT)
 #define TTE_IS_W_OK(tte)    ((tte) & TTE_W_OK_BIT)
+
+#define TTE_IS_NFO_UA2005(tte)     ((tte) & TTE_NFO_BIT_UA2005)
+#define TTE_IS_USED_UA2005(tte)    ((tte) & TTE_USED_BIT_UA2005)
+#define TTE_IS_LOCKED_UA2005(tte)  ((tte) & TTE_LOCKED_BIT_UA2005)
+#define TTE_IS_SIDEEFFECT_UA2005(tte) ((tte) & TTE_SIDEEFFECT_BIT_UA2005)
+#define TTE_IS_PRIV_UA2005(tte)    ((tte) & TTE_PRIV_BIT_UA2005)
+#define TTE_IS_W_OK_UA2005(tte)    ((tte) & TTE_W_OK_BIT_UA2005)
+
 #define TTE_IS_GLOBAL(tte)  ((tte) & TTE_GLOBAL_BIT)
 
 #define TTE_SET_USED(tte)   ((tte) |= TTE_USED_BIT)
 #define TTE_SET_UNUSED(tte) ((tte) &= ~TTE_USED_BIT)
 
 #define TTE_PGSIZE(tte)     (((tte) >> 61) & 3ULL)
+#define TTE_PGSIZE_UA2005(tte)     ((tte) & 7ULL)
 #define TTE_PA(tte)         ((tte) & 0x1ffffffe000ULL)
 
 #define SFSR_NF_BIT         (1ULL << 24)   /* JPS1 NoFault */
-- 
2.7.2

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

* [Qemu-devel] [PATCH 04/29] target-sparc: add UltraSPARC T1 TLB #defines
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (2 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 03/29] target-sparc: add UA2005 TTE bit #defines Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 05/29] target-sparc: on UA2005 don't deliver Interrupt_level_n IRQs in hypervisor mode Artyom Tarasenko
                   ` (26 subsequent siblings)
  30 siblings, 0 replies; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/cpu.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 2c169e1..bafa8d9 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -328,6 +328,10 @@ enum {
 #define TTE_PGSIZE_UA2005(tte)     ((tte) & 7ULL)
 #define TTE_PA(tte)         ((tte) & 0x1ffffffe000ULL)
 
+/* UltraSPARC T1 specific */
+#define TLB_UST1_IS_REAL_BIT   (1ULL << 9)  /* Real translation entry */
+#define TLB_UST1_IS_SUN4V_BIT  (1ULL << 10) /* sun4u/sun4v TTE format switch */
+
 #define SFSR_NF_BIT         (1ULL << 24)   /* JPS1 NoFault */
 #define SFSR_TM_BIT         (1ULL << 15)   /* JPS1 TLB Miss */
 #define SFSR_FT_VA_IMMU_BIT (1ULL << 13)   /* USIIi VA out of range (IMMU) */
-- 
2.7.2

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

* [Qemu-devel] [PATCH 05/29] target-sparc: on UA2005 don't deliver Interrupt_level_n IRQs in hypervisor mode
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (3 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 04/29] target-sparc: add UltraSPARC T1 TLB #defines Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-10 21:23   ` Richard Henderson
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 06/29] target-sparc: simplify replace_tlb_entry by using TTE_PGSIZE Artyom Tarasenko
                   ` (25 subsequent siblings)
  30 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

As described in Chapter 5.7.6 of the UltraSPARC Architecture 2005,
outstanding disrupting exceptions that are destined for privileged mode can only
cause a trap when the virtual processor is in nonprivileged or privileged mode and
PSTATE.ie = 1. At all other times, they are held pending.

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/cpu.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index bafa8d9..ff2e053 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -716,8 +716,9 @@ static inline int cpu_interrupts_enabled(CPUSPARCState *env1)
     if (env1->psret != 0)
         return 1;
 #else
-    if (env1->pstate & PS_IE)
+    if ((env1->pstate & PS_IE) && !cpu_hypervisor_mode(env1)) {
         return 1;
+    }
 #endif
 
     return 0;
-- 
2.7.2

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

* [Qemu-devel] [PATCH 06/29] target-sparc: simplify replace_tlb_entry by using TTE_PGSIZE
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (4 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 05/29] target-sparc: on UA2005 don't deliver Interrupt_level_n IRQs in hypervisor mode Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-10 21:25   ` Richard Henderson
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 07/29] target-sparc: implement UA2005 scratchpad registers Artyom Tarasenko
                   ` (24 subsequent siblings)
  30 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/ldst_helper.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index 74708f2..7607128 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -127,9 +127,8 @@ static void replace_tlb_entry(SparcTLBEntry *tlb,
     if (TTE_IS_VALID(tlb->tte)) {
         CPUState *cs = CPU(sparc_env_get_cpu(env1));
 
-        mask = 0xffffffffffffe000ULL;
-        mask <<= 3 * ((tlb->tte >> 61) & 3);
-        size = ~mask + 1;
+        size = 8192ULL << 3 * TTE_PGSIZE(tlb->tte);
+        mask = 1ULL + ~size;
 
         va = tlb->tag & mask;
 
-- 
2.7.2

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

* [Qemu-devel] [PATCH 07/29] target-sparc: implement UA2005 scratchpad registers
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (5 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 06/29] target-sparc: simplify replace_tlb_entry by using TTE_PGSIZE Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-10 21:37   ` Richard Henderson
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 08/29] target-sparc: implement UltraSPARC-T1 Strand status ASR Artyom Tarasenko
                   ` (23 subsequent siblings)
  30 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/asi.h         |  1 +
 target-sparc/cpu.h         |  1 +
 target-sparc/ldst_helper.c | 28 ++++++++++++++++++++++++++++
 3 files changed, 30 insertions(+)

diff --git a/target-sparc/asi.h b/target-sparc/asi.h
index c9a1849..d8d6284 100644
--- a/target-sparc/asi.h
+++ b/target-sparc/asi.h
@@ -211,6 +211,7 @@
 #define ASI_AFSR		0x4c /* Async fault status register	*/
 #define ASI_AFAR		0x4d /* Async fault address register	*/
 #define ASI_EC_TAG_DATA		0x4e /* E-cache tag/valid ram diag acc	*/
+#define ASI_HYP_SCRATCHPAD	0x4f /* (4V) Hypervisor scratchpad	*/
 #define ASI_IMMU		0x50 /* Insn-MMU main register space	*/
 #define ASI_IMMU_TSB_8KB_PTR	0x51 /* Insn-MMU 8KB TSB pointer reg	*/
 #define ASI_IMMU_TSB_64KB_PTR	0x52 /* Insn-MMU 64KB TSB pointer reg	*/
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index ff2e053..0b5c79f 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -512,6 +512,7 @@ struct CPUSPARCState {
     uint32_t gl; // UA2005
     /* UA 2005 hyperprivileged registers */
     uint64_t hpstate, htstate[MAXTL_MAX], hintp, htba, hver, hstick_cmpr, ssr;
+    uint64_t scratch[8];
     CPUTimer *hstick; // UA 2005
     /* Interrupt vector registers */
     uint64_t ivec_status;
diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index 7607128..5fb9024 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -1610,6 +1610,18 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
             }
             break;
         }
+    case ASI_SCRATCHPAD: /* UA2005 privileged scratchpad */
+        if (unlikely((addr >= 0x20) && (addr < 0x30))) {
+            /* Hyperprivileged access only */
+            cpu_unassigned_access(cs, addr, false, false, 1, size);
+        }
+        /* fall through */
+    case ASI_HYP_SCRATCHPAD: /* UA2005 hyperprivileged scratchpad */
+        {
+            unsigned int i = (addr >> 3) & 0x7;
+            ret = env->scratch[i];
+            break;
+        }
     case ASI_DCACHE_DATA:     /* D-cache data */
     case ASI_DCACHE_TAG:      /* D-cache tag access */
     case ASI_ESTATE_ERROR_EN: /* E-cache error enable */
@@ -2056,6 +2068,9 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
         return;
     case ASI_INTR_RECEIVE: /* Interrupt data receive */
         env->ivec_status = val & 0x20;
+        if (!env->ivec_status) {
+            cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
+        }
         return;
     case ASI_NUCLEUS_QUAD_LDD:   /* Nucleus quad LDD 128 bit atomic */
     case ASI_NUCLEUS_QUAD_LDD_L: /* Nucleus quad LDD 128 bit atomic LE */
@@ -2075,6 +2090,19 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
         /* Only stda allowed */
         helper_raise_exception(env, TT_ILL_INSN);
         return;
+    case ASI_SCRATCHPAD: /* UA2005 privileged scratchpad */
+        if (unlikely((addr >= 0x20) && (addr < 0x30))) {
+            /* Hyperprivileged access only */
+            cpu_unassigned_access(cs, addr, true, false, 1, size);
+        }
+        /* fall through */
+    case ASI_HYP_SCRATCHPAD: /* UA2005 hyperprivileged scratchpad */
+        {
+            unsigned int i = (addr >> 3) & 0x7;
+            env->scratch[i] = val;
+            return;
+        }
+
     case ASI_DCACHE_DATA: /* D-cache data */
     case ASI_DCACHE_TAG: /* D-cache tag access */
     case ASI_ESTATE_ERROR_EN: /* E-cache error enable */
-- 
2.7.2

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

* [Qemu-devel] [PATCH 08/29] target-sparc: implement UltraSPARC-T1 Strand status ASR
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (6 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 07/29] target-sparc: implement UA2005 scratchpad registers Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-10 21:38   ` Richard Henderson
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 09/29] target-sparc: hypervisor mode takes over nucleus mode Artyom Tarasenko
                   ` (22 subsequent siblings)
  30 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/translate.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index e7691e4..b9c749c 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -3278,6 +3278,17 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                 case 0x19: /* System tick compare */
                     gen_store_gpr(dc, rd, cpu_stick_cmpr);
                     break;
+                case 0x1a: /* UltraSPARC-T1 Strand status */
+                    /* XXX HYPV check maybe not enough, UA2005 & UA2007 describe
+                     * this ASR as impl. dep
+                     */
+                    CHECK_IU_FEATURE(dc, HYPV);
+                    {
+                        TCGv t = gen_dest_gpr(dc, rd);
+                        tcg_gen_movi_tl(t, 1UL);
+                        gen_store_gpr(dc, rd, t);
+                    }
+                    break;
                 case 0x10: /* Performance Control */
                 case 0x11: /* Performance Instrumentation Counter */
                 case 0x12: /* Dispatch Control */
-- 
2.7.2

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

* [Qemu-devel] [PATCH 09/29] target-sparc: hypervisor mode takes over nucleus mode
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (7 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 08/29] target-sparc: implement UltraSPARC-T1 Strand status ASR Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-10 21:41   ` Richard Henderson
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 10/29] target-sparc: implement UA2005 hypervisor traps Artyom Tarasenko
                   ` (21 subsequent siblings)
  30 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/cpu.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 0b5c79f..fbeb8d7 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -699,10 +699,10 @@ static inline int cpu_mmu_index(CPUSPARCState *env1, bool ifetch)
 #elif !defined(TARGET_SPARC64)
     return env1->psrs;
 #else
-    if (env1->tl > 0) {
-        return MMU_NUCLEUS_IDX;
-    } else if (cpu_hypervisor_mode(env1)) {
+    if (cpu_hypervisor_mode(env1)) {
         return MMU_HYPV_IDX;
+    } else if (env1->tl > 0) {
+        return MMU_NUCLEUS_IDX;
     } else if (cpu_supervisor_mode(env1)) {
         return MMU_KERNEL_IDX;
     } else {
-- 
2.7.2

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

* [Qemu-devel] [PATCH 10/29] target-sparc: implement UA2005 hypervisor traps
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (8 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 09/29] target-sparc: hypervisor mode takes over nucleus mode Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 11/29] target-sparc: implement UA2005 GL register Artyom Tarasenko
                   ` (20 subsequent siblings)
  30 siblings, 0 replies; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/cpu.h          |  1 +
 target-sparc/int64_helper.c | 36 +++++++++++++++++++++++++++++++-----
 target-sparc/win_helper.c   |  6 ++++++
 3 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index fbeb8d7..763feb1 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -77,6 +77,7 @@
 #define TT_FILL     0xc0
 #define TT_WOTHER   (1 << 5)
 #define TT_TRAP     0x100
+#define TT_HTRAP    0x180
 #endif
 
 #define PSR_NEG_SHIFT 23
diff --git a/target-sparc/int64_helper.c b/target-sparc/int64_helper.c
index 29360fa..c5a0609 100644
--- a/target-sparc/int64_helper.c
+++ b/target-sparc/int64_helper.c
@@ -78,8 +78,10 @@ void sparc_cpu_do_interrupt(CPUState *cs)
         static int count;
         const char *name;
 
-        if (intno < 0 || intno >= 0x180) {
+        if (intno < 0 || intno >= 0x1ff) {
             name = "Unknown";
+        } else if (intno >= 0x180) {
+            name = "Hyperprivileged Trap Instruction";
         } else if (intno >= 0x100) {
             name = "Trap Instruction";
         } else if (intno >= 0xc0) {
@@ -135,16 +137,35 @@ void sparc_cpu_do_interrupt(CPUState *cs)
     tsptr->tnpc = env->npc;
     tsptr->tt = intno;
 
+    if (cpu_has_hypervisor(env)) {
+        env->htstate[env->tl] = env->hpstate;
+        /* XXX OpenSPARC T1 - UltraSPARC T3 have MAXPTL=2
+           but this may change in the future */
+        if (env->tl > 2) {
+            env->hpstate |= HS_PRIV;
+        }
+    }
+
     switch (intno) {
     case TT_IVEC:
-        cpu_change_pstate(env, PS_PEF | PS_PRIV | PS_IG);
+        if (!cpu_has_hypervisor(env)) {
+            cpu_change_pstate(env, PS_PEF | PS_PRIV | PS_IG);
+        }
         break;
     case TT_TFAULT:
     case TT_DFAULT:
     case TT_TMISS ... TT_TMISS + 3:
     case TT_DMISS ... TT_DMISS + 3:
     case TT_DPROT ... TT_DPROT + 3:
-        cpu_change_pstate(env, PS_PEF | PS_PRIV | PS_MG);
+        if (cpu_has_hypervisor(env)) {
+            env->hpstate |= HS_PRIV;
+            env->pstate = PS_PEF | PS_PRIV;
+        } else {
+            cpu_change_pstate(env, PS_PEF | PS_PRIV | PS_MG);
+        }
+        break;
+    case TT_HTRAP ... TT_HTRAP + 127:
+        env->hpstate |= HS_PRIV;
         break;
     default:
         cpu_change_pstate(env, PS_PEF | PS_PRIV | PS_AG);
@@ -158,8 +179,13 @@ void sparc_cpu_do_interrupt(CPUState *cs)
     } else if ((intno & 0x1c0) == TT_FILL) {
         cpu_set_cwp(env, cpu_cwp_inc(env, env->cwp + 1));
     }
-    env->pc = env->tbr  & ~0x7fffULL;
-    env->pc |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
+
+    if (cpu_hypervisor_mode(env)) {
+        env->pc = (env->htba & ~0x3fffULL) | (intno << 5);
+    } else {
+        env->pc = env->tbr  & ~0x7fffULL;
+        env->pc |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
+    }
     env->npc = env->pc + 4;
     cs->exception_index = -1;
 }
diff --git a/target-sparc/win_helper.c b/target-sparc/win_helper.c
index a8a6c0c..61e849e 100644
--- a/target-sparc/win_helper.c
+++ b/target-sparc/win_helper.c
@@ -365,6 +365,9 @@ void helper_done(CPUSPARCState *env)
     env->asi = (tsptr->tstate >> 24) & 0xff;
     cpu_change_pstate(env, (tsptr->tstate >> 8) & 0xf3f);
     cpu_put_cwp64(env, tsptr->tstate & 0xff);
+    if (cpu_has_hypervisor(env)) {
+        env->hpstate = env->htstate[env->tl];
+    }
     env->tl--;
 
     trace_win_helper_done(env->tl);
@@ -386,6 +389,9 @@ void helper_retry(CPUSPARCState *env)
     env->asi = (tsptr->tstate >> 24) & 0xff;
     cpu_change_pstate(env, (tsptr->tstate >> 8) & 0xf3f);
     cpu_put_cwp64(env, tsptr->tstate & 0xff);
+    if (cpu_has_hypervisor(env)) {
+        env->hpstate = env->htstate[env->tl];
+    }
     env->tl--;
 
     trace_win_helper_retry(env->tl);
-- 
2.7.2

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

* [Qemu-devel] [PATCH 11/29] target-sparc: implement UA2005 GL register
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (9 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 10/29] target-sparc: implement UA2005 hypervisor traps Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-10 21:45   ` Richard Henderson
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 12/29] target-sparc: implement UA2005 rdhpstate and wrhpstate instructions Artyom Tarasenko
                   ` (19 subsequent siblings)
  30 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/cpu.c          | 13 ++++++++++---
 target-sparc/cpu.h          |  2 ++
 target-sparc/helper.h       |  1 +
 target-sparc/int64_helper.c |  6 ++++++
 target-sparc/translate.c    |  5 +++--
 target-sparc/win_helper.c   | 40 ++++++++++++++++++++++++++++++++++++++--
 6 files changed, 60 insertions(+), 7 deletions(-)

diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index 800a25a..0bd3993 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -58,9 +58,13 @@ static void sparc_cpu_reset(CPUState *s)
     env->psrps = 1;
 #endif
 #ifdef TARGET_SPARC64
-    env->pstate = PS_PRIV|PS_RED|PS_PEF|PS_AG;
+    env->pstate = PS_PRIV | PS_RED | PS_PEF;
+    if (!cpu_has_hypervisor(env)) {
+        env->pstate |= PS_AG;
+    }
     env->hpstate = cpu_has_hypervisor(env) ? HS_PRIV : 0;
     env->tl = env->maxtl;
+    env->gl = 2;
     cpu_tsptr(env)->tt = TT_POWER_ON_RESET;
     env->lsu = 0;
 #else
@@ -745,14 +749,17 @@ void sparc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
     cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << PSR_CARRY_SHIFT);
     cpu_fprintf(f, " xcc: ");
     cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << (PSR_CARRY_SHIFT - 4));
-    cpu_fprintf(f, ") asi: %02x tl: %d pil: %x\n", env->asi, env->tl,
-                env->psrpil);
+    cpu_fprintf(f, ") asi: %02x tl: %d pil: %x gl: %d\n", env->asi, env->tl,
+                env->psrpil, env->gl);
+    cpu_fprintf(f, "tbr: " TARGET_FMT_lx " hpstate: " TARGET_FMT_lx " htba: "
+                TARGET_FMT_lx "\n", env->tbr, env->hpstate, env->htba);
     cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate: %d "
                 "cleanwin: %d cwp: %d\n",
                 env->cansave, env->canrestore, env->otherwin, env->wstate,
                 env->cleanwin, env->nwindows - 1 - env->cwp);
     cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx " fprs: "
                 TARGET_FMT_lx "\n", env->fsr, env->y, env->fprs);
+
 #else
     cpu_fprintf(f, "psr: %08x (icc: ", cpu_get_psr(env));
     cpu_print_cc(f, cpu_fprintf, cpu_get_psr(env));
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 763feb1..41002af 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -504,6 +504,7 @@ struct CPUSPARCState {
     uint64_t bgregs[8]; /* backup for normal global registers */
     uint64_t igregs[8]; /* interrupt general registers */
     uint64_t mgregs[8]; /* mmu general registers */
+    uint64_t glregs[8 * MAXTL_MAX];
     uint64_t fprs;
     uint64_t tick_cmpr, stick_cmpr;
     CPUTimer *tick, *stick;
@@ -603,6 +604,7 @@ void cpu_put_ccr(CPUSPARCState *env1, target_ulong val);
 target_ulong cpu_get_cwp64(CPUSPARCState *env1);
 void cpu_put_cwp64(CPUSPARCState *env1, int cwp);
 void cpu_change_pstate(CPUSPARCState *env1, uint32_t new_pstate);
+void cpu_gl_switch_gregs(CPUSPARCState *env, uint32_t new_gl);
 #endif
 int cpu_cwp_inc(CPUSPARCState *env1, int cwp);
 int cpu_cwp_dec(CPUSPARCState *env1, int cwp);
diff --git a/target-sparc/helper.h b/target-sparc/helper.h
index caa2a89..b8f39ff 100644
--- a/target-sparc/helper.h
+++ b/target-sparc/helper.h
@@ -5,6 +5,7 @@ DEF_HELPER_1(rdpsr, tl, env)
 DEF_HELPER_1(power_down, void, env)
 #else
 DEF_HELPER_FLAGS_2(wrpil, TCG_CALL_NO_RWG, void, env, tl)
+DEF_HELPER_2(wrgl, void, env, tl)
 DEF_HELPER_2(wrpstate, void, env, tl)
 DEF_HELPER_1(done, void, env)
 DEF_HELPER_1(retry, void, env)
diff --git a/target-sparc/int64_helper.c b/target-sparc/int64_helper.c
index c5a0609..5cdb861 100644
--- a/target-sparc/int64_helper.c
+++ b/target-sparc/int64_helper.c
@@ -146,6 +146,12 @@ void sparc_cpu_do_interrupt(CPUState *cs)
         }
     }
 
+    if (env->def->features & CPU_FEATURE_GL) {
+        tsptr->tstate |= (env->gl & 7UL) << 40;
+        cpu_gl_switch_gregs(env, env->gl + 1);
+        env->gl++;
+    }
+
     switch (intno) {
     case TT_IVEC:
         if (!cpu_has_hypervisor(env)) {
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index b9c749c..6c461b1 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -4404,8 +4404,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                                 break;
                             case 16: // UA2005 gl
                                 CHECK_IU_FEATURE(dc, GL);
-                                tcg_gen_st32_tl(cpu_tmp0, cpu_env,
-                                                offsetof(CPUSPARCState, gl));
+                                save_state(dc);
+                                gen_helper_wrgl(cpu_env, cpu_tmp0);
+                                dc->npc = DYNAMIC_PC;
                                 break;
                             case 26: // UA2005 strand status
                                 CHECK_IU_FEATURE(dc, HYPV);
diff --git a/target-sparc/win_helper.c b/target-sparc/win_helper.c
index 61e849e..6e67565 100644
--- a/target-sparc/win_helper.c
+++ b/target-sparc/win_helper.c
@@ -289,6 +289,10 @@ void helper_wrcwp(CPUSPARCState *env, target_ulong new_cwp)
 
 static inline uint64_t *get_gregset(CPUSPARCState *env, uint32_t pstate)
 {
+    if (env->def->features & CPU_FEATURE_GL) {
+        return env->glregs + (env->gl & 7) * 8;
+    }
+
     switch (pstate) {
     default:
         trace_win_helper_gregset_error(pstate);
@@ -304,14 +308,40 @@ static inline uint64_t *get_gregset(CPUSPARCState *env, uint32_t pstate)
     }
 }
 
+static inline uint64_t *get_gl_gregset(CPUSPARCState *env, uint32_t gl)
+{
+    return env->glregs + (gl & 7) * 8;
+}
+
+/* Switch global register bank */
+void cpu_gl_switch_gregs(CPUSPARCState *env, uint32_t new_gl)
+{
+    uint64_t *src, *dst;
+    src = get_gl_gregset(env, new_gl);
+    dst = get_gl_gregset(env, env->gl);
+
+    if (src != dst) {
+        memcpy32(dst, env->gregs);
+        memcpy32(env->gregs, src);
+    }
+}
+
+void helper_wrgl(CPUSPARCState *env, target_ulong new_gl)
+{
+    cpu_gl_switch_gregs(env, new_gl & 7);
+    env->gl = new_gl & 7;
+}
+
 void cpu_change_pstate(CPUSPARCState *env, uint32_t new_pstate)
 {
     uint32_t pstate_regs, new_pstate_regs;
     uint64_t *src, *dst;
 
     if (env->def->features & CPU_FEATURE_GL) {
-        /* PS_AG is not implemented in this case */
-        new_pstate &= ~PS_AG;
+        /* PS_AG, IG and MG are not implemented in this case */
+        new_pstate &= ~(PS_AG | PS_IG | PS_MG);
+        env->pstate = new_pstate;
+        return;
     }
 
     pstate_regs = env->pstate & 0xc01;
@@ -366,7 +396,10 @@ void helper_done(CPUSPARCState *env)
     cpu_change_pstate(env, (tsptr->tstate >> 8) & 0xf3f);
     cpu_put_cwp64(env, tsptr->tstate & 0xff);
     if (cpu_has_hypervisor(env)) {
+        uint32_t new_gl = (tsptr->tstate >> 40) & 7;
         env->hpstate = env->htstate[env->tl];
+        cpu_gl_switch_gregs(env, new_gl);
+        env->gl = new_gl;
     }
     env->tl--;
 
@@ -390,7 +423,10 @@ void helper_retry(CPUSPARCState *env)
     cpu_change_pstate(env, (tsptr->tstate >> 8) & 0xf3f);
     cpu_put_cwp64(env, tsptr->tstate & 0xff);
     if (cpu_has_hypervisor(env)) {
+        uint32_t new_gl = (tsptr->tstate >> 40) & 7;
         env->hpstate = env->htstate[env->tl];
+        cpu_gl_switch_gregs(env, new_gl);
+        env->gl = new_gl;
     }
     env->tl--;
 
-- 
2.7.2

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

* [Qemu-devel] [PATCH 12/29] target-sparc: implement UA2005 rdhpstate and wrhpstate instructions
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (10 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 11/29] target-sparc: implement UA2005 GL register Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-10 21:46   ` Richard Henderson
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 13/29] target-sparc: fix immediate UA2005 traps Artyom Tarasenko
                   ` (18 subsequent siblings)
  30 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/translate.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 6c461b1..19ffb23 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -3313,7 +3313,8 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                 rs1 = GET_FIELD(insn, 13, 17);
                 switch (rs1) {
                 case 0: // hpstate
-                    // gen_op_rdhpstate();
+                    tcg_gen_ld_i64(cpu_dst, cpu_env,
+                                   offsetof(CPUSPARCState, hpstate));
                     break;
                 case 1: // htstate
                     // gen_op_rdhtstate();
@@ -4440,7 +4441,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                             tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
                             switch (rd) {
                             case 0: // hpstate
-                                // XXX gen_op_wrhpstate();
+                                tcg_gen_st_i64(cpu_tmp0, cpu_env,
+                                               offsetof(CPUSPARCState,
+                                                        hpstate));
                                 save_state(dc);
                                 gen_op_next_insn();
                                 tcg_gen_exit_tb(0);
-- 
2.7.2

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

* [Qemu-devel] [PATCH 13/29] target-sparc: fix immediate UA2005 traps
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (11 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 12/29] target-sparc: implement UA2005 rdhpstate and wrhpstate instructions Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 14/29] target-sparc: use direct address translation in hyperprivileged mode Artyom Tarasenko
                   ` (17 subsequent siblings)
  30 siblings, 0 replies; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/translate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 19ffb23..6520bb3 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -3143,7 +3143,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
 
                 rs1 = GET_FIELD_SP(insn, 14, 18);
                 if (IS_IMM) {
-                    rs2 = GET_FIELD_SP(insn, 0, 6);
+                    rs2 = GET_FIELD_SP(insn, 0, 7);
                     if (rs1 == 0) {
                         tcg_gen_movi_i32(trap, (rs2 & mask) + TT_TRAP);
                         /* Signal that the trap value is fully constant.  */
-- 
2.7.2

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

* [Qemu-devel] [PATCH 14/29] target-sparc: use direct address translation in hyperprivileged mode
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (12 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 13/29] target-sparc: fix immediate UA2005 traps Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-11  5:55   ` Richard Henderson
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 15/29] target-sparc: allow priveleged ASIs " Artyom Tarasenko
                   ` (16 subsequent siblings)
  30 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Implement translation behavior described in the chapter 13.7 of
"UltraSPARC T1™ Supplement to the UltraSPARC Architecture 2005".

Please note that QEMU doesn't impelement Real->Physical address
translation. The "Real Address" is always the "Physical Address".

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/mmu_helper.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/target-sparc/mmu_helper.c b/target-sparc/mmu_helper.c
index 32b629f..bef63f8 100644
--- a/target-sparc/mmu_helper.c
+++ b/target-sparc/mmu_helper.c
@@ -498,7 +498,8 @@ static int get_physical_address_data(CPUSPARCState *env,
     int is_user = (mmu_idx == MMU_USER_IDX ||
                    mmu_idx == MMU_USER_SECONDARY_IDX);
 
-    if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */
+    if ((env->lsu & DMMU_E) == 0 || cpu_hypervisor_mode(env)) {
+        /* direct translation VA -> PA */
         *physical = ultrasparc_truncate_physical(address);
         *prot = PAGE_READ | PAGE_WRITE;
         return 0;
@@ -617,8 +618,9 @@ static int get_physical_address_code(CPUSPARCState *env,
     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 */
+    if (((env->lsu & IMMU_E) == 0) || (env->pstate & PS_RED) != 0
+        || cpu_hypervisor_mode(env)) {
+        /* direct translation VA -> PA */
         *physical = ultrasparc_truncate_physical(address);
         *prot = PAGE_EXEC;
         return 0;
-- 
2.7.2

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

* [Qemu-devel] [PATCH 15/29] target-sparc: allow priveleged ASIs in hyperprivileged mode
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (13 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 14/29] target-sparc: use direct address translation in hyperprivileged mode Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-11 13:57   ` Richard Henderson
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 16/29] target-sparc: ignore writes to UA2005 CPU mondo queue register Artyom Tarasenko
                   ` (15 subsequent siblings)
  30 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/ldst_helper.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index 5fb9024..70febcb 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -1295,10 +1295,9 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
 
     asi &= 0xff;
 
-    if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
-        || (cpu_has_hypervisor(env)
-            && asi >= 0x30 && asi < 0x80
-            && !(env->hpstate & HS_PRIV))) {
+    if (((!cpu_hypervisor_mode(env)) && asi < 0x80)
+        && (((env->pstate & PS_PRIV) == 0)
+        || (cpu_has_hypervisor(env) && asi >= 0x30))) {
         helper_raise_exception(env, TT_PRIV_ACT);
     }
 
@@ -1727,10 +1726,9 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
 
     asi &= 0xff;
 
-    if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
-        || (cpu_has_hypervisor(env)
-            && asi >= 0x30 && asi < 0x80
-            && !(env->hpstate & HS_PRIV))) {
+    if (((!cpu_hypervisor_mode(env)) && asi < 0x80)
+        && (((env->pstate & PS_PRIV) == 0)
+        || (cpu_has_hypervisor(env) && asi >= 0x30))) {
         helper_raise_exception(env, TT_PRIV_ACT);
     }
 
-- 
2.7.2

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

* [Qemu-devel] [PATCH 16/29] target-sparc: ignore writes to UA2005 CPU mondo queue register
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (14 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 15/29] target-sparc: allow priveleged ASIs " Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-11 13:57   ` Richard Henderson
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 17/29] target-sparc: replace the last tlb entry when no free entries left Artyom Tarasenko
                   ` (14 subsequent siblings)
  30 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/ldst_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index 70febcb..250c23f 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -2100,7 +2100,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
             env->scratch[i] = val;
             return;
         }
-
+    case ASI_QUEUE: /* UA2005 CPU mondo queue */
     case ASI_DCACHE_DATA: /* D-cache data */
     case ASI_DCACHE_TAG: /* D-cache tag access */
     case ASI_ESTATE_ERROR_EN: /* E-cache error enable */
-- 
2.7.2

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

* [Qemu-devel] [PATCH 17/29] target-sparc: replace the last tlb entry when no free entries left
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (15 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 16/29] target-sparc: ignore writes to UA2005 CPU mondo queue register Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 18/29] target-sparc: use SparcV9MMU type for sparc64 I/D-MMUs Artyom Tarasenko
                   ` (13 subsequent siblings)
  30 siblings, 0 replies; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Implement the behavior described in the chapter 13.9.11 of
UltraSPARC T1™ Supplement to the UltraSPARC Architecture 2005:

"If a TLB Data-In replacement is attempted with all TLB
entries locked and valid, the last TLB entry (entry 63) is
replaced."

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/ldst_helper.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index 250c23f..11ca74e 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -246,9 +246,11 @@ static void replace_tlb_1bit_lru(SparcTLBEntry *tlb,
     }
 
 #ifdef DEBUG_MMU
-    DPRINTF_MMU("%s lru replacement failed: no entries available\n", strmmu);
+    DPRINTF_MMU("%s lru replacement: no free entries available, "
+                "replacing the last one\n", strmmu);
 #endif
-    /* error state? */
+    /* corner case: the last entry is replaced anyway */
+    replace_tlb_entry(&tlb[63], tlb_tag, tlb_tte, env1);
 }
 
 #endif
-- 
2.7.2

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

* [Qemu-devel] [PATCH 18/29] target-sparc: use SparcV9MMU type for sparc64 I/D-MMUs
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (16 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 17/29] target-sparc: replace the last tlb entry when no free entries left Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-10 20:13   ` Richard Henderson
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 19/29] target-sparc: implement UA2005 TSB Pointers Artyom Tarasenko
                   ` (12 subsequent siblings)
  30 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/cpu.h         | 48 +++++++++++++++++-----------------------------
 target-sparc/ldst_helper.c |  8 ++++----
 target-sparc/machine.c     |  4 ++--
 3 files changed, 24 insertions(+), 36 deletions(-)

diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 41002af..7b77d26 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -396,7 +396,22 @@ struct CPUTimer
 typedef struct CPUTimer CPUTimer;
 
 typedef struct CPUSPARCState CPUSPARCState;
-
+#if defined(TARGET_SPARC64)
+typedef union {
+   uint64_t mmuregs[16];
+   struct {
+    uint64_t tsb_tag_target;
+    uint64_t mmu_primary_context;
+    uint64_t mmu_secondary_context;
+    uint64_t sfsr;
+    uint64_t sfar;
+    uint64_t tsb;
+    uint64_t tag_access;
+    uint64_t virtual_watchpoint;
+    uint64_t physical_watchpoint;
+   };
+} SparcV9MMU;
+#endif
 struct CPUSPARCState {
     target_ulong gregs[8]; /* general registers */
     target_ulong *regwptr; /* pointer to current register window */
@@ -446,35 +461,8 @@ struct CPUSPARCState {
     uint64_t lsu;
 #define DMMU_E 0x8
 #define IMMU_E 0x4
-    //typedef struct SparcMMU
-    union {
-        uint64_t immuregs[16];
-        struct {
-            uint64_t tsb_tag_target;
-            uint64_t unused_mmu_primary_context;   // use DMMU
-            uint64_t unused_mmu_secondary_context; // use DMMU
-            uint64_t sfsr;
-            uint64_t sfar;
-            uint64_t tsb;
-            uint64_t tag_access;
-            uint64_t virtual_watchpoint;
-            uint64_t physical_watchpoint;
-        } immu;
-    };
-    union {
-        uint64_t dmmuregs[16];
-        struct {
-            uint64_t tsb_tag_target;
-            uint64_t mmu_primary_context;
-            uint64_t mmu_secondary_context;
-            uint64_t sfsr;
-            uint64_t sfar;
-            uint64_t tsb;
-            uint64_t tag_access;
-            uint64_t virtual_watchpoint;
-            uint64_t physical_watchpoint;
-        } dmmu;
-    };
+    SparcV9MMU immu;
+    SparcV9MMU dmmu;
     SparcTLBEntry itlb[64];
     SparcTLBEntry dtlb[64];
     uint32_t mmu_version;
diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index 11ca74e..5e79627 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -1931,7 +1931,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
             int reg = (addr >> 3) & 0xf;
             uint64_t oldreg;
 
-            oldreg = env->immuregs[reg];
+            oldreg = env->immu.mmuregs[reg];
             switch (reg) {
             case 0: /* RO */
                 return;
@@ -1962,7 +1962,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
                 break;
             }
 
-            if (oldreg != env->immuregs[reg]) {
+            if (oldreg != env->immu.mmuregs[reg]) {
                 DPRINTF_MMU("immu change reg[%d]: 0x%016" PRIx64 " -> 0x%016"
                             PRIx64 "\n", reg, oldreg, env->immuregs[reg]);
             }
@@ -1996,7 +1996,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
             int reg = (addr >> 3) & 0xf;
             uint64_t oldreg;
 
-            oldreg = env->dmmuregs[reg];
+            oldreg = env->dmmu.mmuregs[reg];
             switch (reg) {
             case 0: /* RO */
             case 4:
@@ -2039,7 +2039,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
                 break;
             }
 
-            if (oldreg != env->dmmuregs[reg]) {
+            if (oldreg != env->dmmu.mmuregs[reg]) {
                 DPRINTF_MMU("dmmu change reg[%d]: 0x%016" PRIx64 " -> 0x%016"
                             PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]);
             }
diff --git a/target-sparc/machine.c b/target-sparc/machine.c
index 59c92f7..bd63841 100644
--- a/target-sparc/machine.c
+++ b/target-sparc/machine.c
@@ -151,8 +151,8 @@ const VMStateDescription vmstate_sparc_cpu = {
         VMSTATE_UINT64_ARRAY(env.mmubpregs, SPARCCPU, 4),
 #else
         VMSTATE_UINT64(env.lsu, SPARCCPU),
-        VMSTATE_UINT64_ARRAY(env.immuregs, SPARCCPU, 16),
-        VMSTATE_UINT64_ARRAY(env.dmmuregs, SPARCCPU, 16),
+        VMSTATE_UINT64_ARRAY(env.immu.mmuregs, SPARCCPU, 16),
+        VMSTATE_UINT64_ARRAY(env.dmmu.mmuregs, SPARCCPU, 16),
         VMSTATE_STRUCT_ARRAY(env.itlb, SPARCCPU, 64, 0,
                              vmstate_tlb_entry, SparcTLBEntry),
         VMSTATE_STRUCT_ARRAY(env.dtlb, SPARCCPU, 64, 0,
-- 
2.7.2

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

* [Qemu-devel] [PATCH 19/29] target-sparc: implement UA2005 TSB Pointers
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (17 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 18/29] target-sparc: use SparcV9MMU type for sparc64 I/D-MMUs Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 20/29] target-sparc: simplify ultrasparc_tsb_pointer Artyom Tarasenko
                   ` (11 subsequent siblings)
  30 siblings, 0 replies; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/cpu.h         |   2 +
 target-sparc/ldst_helper.c | 124 +++++++++++++++++++++++++++++++++++++--------
 2 files changed, 104 insertions(+), 22 deletions(-)

diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 7b77d26..54dade2 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -409,6 +409,8 @@ typedef union {
     uint64_t tag_access;
     uint64_t virtual_watchpoint;
     uint64_t physical_watchpoint;
+    uint64_t sun4v_ctx_config[2];
+    uint64_t sun4v_tsb_pointers[4];
    };
 } SparcV9MMU;
 #endif
diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index 5e79627..8d788fa 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -70,11 +70,29 @@
 #define QT1 (env->qt1)
 
 #if defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
-/* Calculates TSB pointer value for fault page size 8k or 64k */
-static uint64_t ultrasparc_tsb_pointer(uint64_t tsb_register,
+static uint64_t ultrasparc_tsb_pointer(CPUSPARCState *env, uint64_t tsb,
+                                       uint64_t *tsb_ptr,
                                        uint64_t tag_access_register,
-                                       int page_size)
+                                       int idx, uint64_t *cfg_ptr)
+/* Calculates TSB pointer value for fault page size
+ * UltraSPARC IIi has fixed sizes (8k or 64k) for the page pointers
+ * UA2005 holds the page size configuration in mmu_ctx registers */
 {
+    uint64_t tsb_register;
+    int page_size;
+    if (cpu_has_hypervisor(env)) {
+        int tsb_index = 0;
+        int ctx = tag_access_register & 0x1fffULL;
+        uint64_t ctx_register = cfg_ptr[ctx ? 1 : 0];
+        tsb_index = idx;
+        tsb_index |= ctx ? 2 : 0;
+        page_size = idx ? ctx_register >> 8 : ctx_register;
+        page_size &= 7;
+        tsb_register = tsb_ptr[tsb_index];
+    } else {
+        page_size = idx;
+        tsb_register = tsb;
+    }
     uint64_t tsb_base = tsb_register & ~0x1fffULL;
     int tsb_split = (tsb_register & 0x1000ULL) ? 1 : 0;
     int tsb_size  = tsb_register & 0xf;
@@ -87,21 +105,15 @@ static uint64_t ultrasparc_tsb_pointer(uint64_t tsb_register,
     uint64_t va = tag_access_va;
 
     /* move va bits to correct position */
-    if (page_size == 8*1024) {
-        va >>= 9;
-    } else if (page_size == 64*1024) {
-        va >>= 12;
-    }
+    va >>= 3 * page_size + 9;
 
-    if (tsb_size) {
-        tsb_base_mask <<= tsb_size;
-    }
+    tsb_base_mask <<= tsb_size;
 
     /* calculate tsb_base mask and adjust va if split is in use */
     if (tsb_split) {
-        if (page_size == 8*1024) {
+        if (idx == 0) {
             va &= ~(1ULL << (13 + tsb_size));
-        } else if (page_size == 64*1024) {
+        } else {
             va |= (1ULL << (13 + tsb_size));
         }
         tsb_base_mask <<= 1;
@@ -1504,16 +1516,20 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
         {
             /* env->immuregs[5] holds I-MMU TSB register value
                env->immuregs[6] holds I-MMU Tag Access register value */
-            ret = ultrasparc_tsb_pointer(env->immu.tsb, env->immu.tag_access,
-                                         8*1024);
+            ret = ultrasparc_tsb_pointer(env, env->immu.tsb,
+                                         env->immu.sun4v_tsb_pointers,
+                                         env->immu.tag_access,
+                                         0, env->immu.sun4v_ctx_config);
             break;
         }
     case ASI_IMMU_TSB_64KB_PTR: /* I-MMU 64k TSB pointer */
         {
             /* env->immuregs[5] holds I-MMU TSB register value
                env->immuregs[6] holds I-MMU Tag Access register value */
-            ret = ultrasparc_tsb_pointer(env->immu.tsb, env->immu.tag_access,
-                                         64*1024);
+            ret = ultrasparc_tsb_pointer(env, env->immu.tsb,
+                                         env->immu.sun4v_tsb_pointers,
+                                         env->immu.tag_access,
+                                         1, env->immu.sun4v_ctx_config);
             break;
         }
     case ASI_ITLB_DATA_ACCESS: /* I-MMU data access */
@@ -1572,16 +1588,20 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
         {
             /* env->dmmuregs[5] holds D-MMU TSB register value
                env->dmmuregs[6] holds D-MMU Tag Access register value */
-            ret = ultrasparc_tsb_pointer(env->dmmu.tsb, env->dmmu.tag_access,
-                                         8*1024);
+            ret = ultrasparc_tsb_pointer(env, env->dmmu.tsb,
+                                         env->dmmu.sun4v_tsb_pointers,
+                                         env->dmmu.tag_access,
+                                         0, env->dmmu.sun4v_ctx_config);
             break;
         }
     case ASI_DMMU_TSB_64KB_PTR: /* D-MMU 64k TSB pointer */
         {
             /* env->dmmuregs[5] holds D-MMU TSB register value
                env->dmmuregs[6] holds D-MMU Tag Access register value */
-            ret = ultrasparc_tsb_pointer(env->dmmu.tsb, env->dmmu.tag_access,
-                                         64*1024);
+            ret = ultrasparc_tsb_pointer(env, env->dmmu.tsb,
+                                         env->dmmu.sun4v_tsb_pointers,
+                                         env->dmmu.tag_access,
+                                         1, env->dmmu.sun4v_ctx_config);
             break;
         }
     case ASI_DTLB_DATA_ACCESS: /* D-MMU data access */
@@ -1904,7 +1924,67 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
             }
             break;
         }
-
+    /* these ASIs have different functions on UltraSPARC-IIIi
+     * and UA2005 CPUs. Use the explicit numbers to avoid confusion
+     */
+    case 0x31:
+    case 0x32:
+    case 0x39:
+    case 0x3a:
+        if (cpu_has_hypervisor(env)) {
+            /* UA2005
+             * ASI_DMMU_CTX_ZERO_TSB_BASE_PS0
+             * ASI_DMMU_CTX_ZERO_TSB_BASE_PS1
+             * ASI_DMMU_CTX_NONZERO_TSB_BASE_PS0
+             * ASI_DMMU_CTX_NONZERO_TSB_BASE_PS1
+             */
+            int idx = ((asi & 2) >> 1) | ((asi & 8) >> 2);
+            env->dmmu.sun4v_tsb_pointers[idx] = val;
+        } else {
+            helper_raise_exception(env, TT_ILL_INSN);
+        }
+        break;
+    case 0x33:
+    case 0x3b:
+        if (cpu_has_hypervisor(env)) {
+            /* UA2005
+             * ASI_DMMU_CTX_ZERO_CONFIG
+             * ASI_DMMU_CTX_NONZERO_CONFIG
+             */
+            env->dmmu.sun4v_ctx_config[(asi & 8) >> 3] = val;
+        } else {
+            helper_raise_exception(env, TT_ILL_INSN);
+        }
+        break;
+    case 0x35:
+    case 0x36:
+    case 0x3d:
+    case 0x3e:
+        if (cpu_has_hypervisor(env)) {
+            /* UA2005
+             * ASI_IMMU_CTX_ZERO_TSB_BASE_PS0
+             * ASI_IMMU_CTX_ZERO_TSB_BASE_PS1
+             * ASI_IMMU_CTX_NONZERO_TSB_BASE_PS0
+             * ASI_IMMU_CTX_NONZERO_TSB_BASE_PS1
+             */
+            int idx = ((asi & 2) >> 1) | ((asi & 8) >> 2);
+            env->immu.sun4v_tsb_pointers[idx] = val;
+        } else {
+            helper_raise_exception(env, TT_ILL_INSN);
+        }
+      break;
+    case 0x37:
+    case 0x3f:
+        if (cpu_has_hypervisor(env)) {
+            /* UA2005
+             * ASI_IMMU_CTX_ZERO_CONFIG
+             * ASI_IMMU_CTX_NONZERO_CONFIG
+             */
+            env->immu.sun4v_ctx_config[(asi & 8) >> 3] = val;
+        } else {
+          helper_raise_exception(env, TT_ILL_INSN);
+        }
+        break;
     case ASI_UPA_CONFIG: /* UPA config */
         /* XXX */
         return;
-- 
2.7.2

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

* [Qemu-devel] [PATCH 20/29] target-sparc: simplify ultrasparc_tsb_pointer
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (18 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 19/29] target-sparc: implement UA2005 TSB Pointers Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-11 14:05   ` Richard Henderson
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 21/29] target-sparc: allow 256M sized pages Artyom Tarasenko
                   ` (10 subsequent siblings)
  30 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/ldst_helper.c | 51 ++++++++++++++--------------------------------
 1 file changed, 15 insertions(+), 36 deletions(-)

diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index 8d788fa..a85552e 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -70,44 +70,35 @@
 #define QT1 (env->qt1)
 
 #if defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
-static uint64_t ultrasparc_tsb_pointer(CPUSPARCState *env, uint64_t tsb,
-                                       uint64_t *tsb_ptr,
-                                       uint64_t tag_access_register,
-                                       int idx, uint64_t *cfg_ptr)
 /* Calculates TSB pointer value for fault page size
  * UltraSPARC IIi has fixed sizes (8k or 64k) for the page pointers
  * UA2005 holds the page size configuration in mmu_ctx registers */
+static uint64_t ultrasparc_tsb_pointer(CPUSPARCState *env, SparcV9MMU mmu,
+                                       int idx)
 {
     uint64_t tsb_register;
     int page_size;
     if (cpu_has_hypervisor(env)) {
         int tsb_index = 0;
-        int ctx = tag_access_register & 0x1fffULL;
-        uint64_t ctx_register = cfg_ptr[ctx ? 1 : 0];
+        int ctx = mmu.tag_access & 0x1fffULL;
+        uint64_t ctx_register = mmu.sun4v_ctx_config[ctx ? 1 : 0];
         tsb_index = idx;
         tsb_index |= ctx ? 2 : 0;
         page_size = idx ? ctx_register >> 8 : ctx_register;
         page_size &= 7;
-        tsb_register = tsb_ptr[tsb_index];
+        tsb_register = mmu.sun4v_tsb_pointers[tsb_index];
     } else {
         page_size = idx;
-        tsb_register = tsb;
+        tsb_register = mmu.tsb;
     }
-    uint64_t tsb_base = tsb_register & ~0x1fffULL;
     int tsb_split = (tsb_register & 0x1000ULL) ? 1 : 0;
     int tsb_size  = tsb_register & 0xf;
 
-    /* discard lower 13 bits which hold tag access context */
-    uint64_t tag_access_va = tag_access_register & ~0x1fffULL;
+    uint64_t tsb_base_mask = (~0x1fffULL) << tsb_size;
 
-    /* now reorder bits */
-    uint64_t tsb_base_mask = ~0x1fffULL;
-    uint64_t va = tag_access_va;
-
-    /* move va bits to correct position */
-    va >>= 3 * page_size + 9;
-
-    tsb_base_mask <<= tsb_size;
+    /* move va bits to correct position,
+     * the context bits will be masked out later */
+    uint64_t va = mmu.tag_access >> (3 * page_size + 9);
 
     /* calculate tsb_base mask and adjust va if split is in use */
     if (tsb_split) {
@@ -119,7 +110,7 @@ static uint64_t ultrasparc_tsb_pointer(CPUSPARCState *env, uint64_t tsb,
         tsb_base_mask <<= 1;
     }
 
-    return ((tsb_base & tsb_base_mask) | (va & ~tsb_base_mask)) & ~0xfULL;
+    return ((tsb_register & tsb_base_mask) | (va & ~tsb_base_mask)) & ~0xfULL;
 }
 
 /* Calculates tag target register value by reordering bits
@@ -1516,20 +1507,14 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
         {
             /* env->immuregs[5] holds I-MMU TSB register value
                env->immuregs[6] holds I-MMU Tag Access register value */
-            ret = ultrasparc_tsb_pointer(env, env->immu.tsb,
-                                         env->immu.sun4v_tsb_pointers,
-                                         env->immu.tag_access,
-                                         0, env->immu.sun4v_ctx_config);
+            ret = ultrasparc_tsb_pointer(env, env->immu, 0);
             break;
         }
     case ASI_IMMU_TSB_64KB_PTR: /* I-MMU 64k TSB pointer */
         {
             /* env->immuregs[5] holds I-MMU TSB register value
                env->immuregs[6] holds I-MMU Tag Access register value */
-            ret = ultrasparc_tsb_pointer(env, env->immu.tsb,
-                                         env->immu.sun4v_tsb_pointers,
-                                         env->immu.tag_access,
-                                         1, env->immu.sun4v_ctx_config);
+            ret = ultrasparc_tsb_pointer(env, env->immu, 1);
             break;
         }
     case ASI_ITLB_DATA_ACCESS: /* I-MMU data access */
@@ -1588,20 +1573,14 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
         {
             /* env->dmmuregs[5] holds D-MMU TSB register value
                env->dmmuregs[6] holds D-MMU Tag Access register value */
-            ret = ultrasparc_tsb_pointer(env, env->dmmu.tsb,
-                                         env->dmmu.sun4v_tsb_pointers,
-                                         env->dmmu.tag_access,
-                                         0, env->dmmu.sun4v_ctx_config);
+            ret = ultrasparc_tsb_pointer(env, env->dmmu, 0);
             break;
         }
     case ASI_DMMU_TSB_64KB_PTR: /* D-MMU 64k TSB pointer */
         {
             /* env->dmmuregs[5] holds D-MMU TSB register value
                env->dmmuregs[6] holds D-MMU Tag Access register value */
-            ret = ultrasparc_tsb_pointer(env, env->dmmu.tsb,
-                                         env->dmmu.sun4v_tsb_pointers,
-                                         env->dmmu.tag_access,
-                                         1, env->dmmu.sun4v_ctx_config);
+            ret = ultrasparc_tsb_pointer(env, env->dmmu, 1);
             break;
         }
     case ASI_DTLB_DATA_ACCESS: /* D-MMU data access */
-- 
2.7.2

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

* [Qemu-devel] [PATCH 21/29] target-sparc: allow 256M sized pages
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (19 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 20/29] target-sparc: simplify ultrasparc_tsb_pointer Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-11 14:07   ` Richard Henderson
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 22/29] target-sparc: implement auto-demapping for UA2005 CPUs Artyom Tarasenko
                   ` (9 subsequent siblings)
  30 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/mmu_helper.c | 18 +-----------------
 1 file changed, 1 insertion(+), 17 deletions(-)

diff --git a/target-sparc/mmu_helper.c b/target-sparc/mmu_helper.c
index bef63f8..33b48eb 100644
--- a/target-sparc/mmu_helper.c
+++ b/target-sparc/mmu_helper.c
@@ -456,23 +456,7 @@ static inline int ultrasparc_tag_match(SparcTLBEntry *tlb,
                                        uint64_t address, uint64_t context,
                                        hwaddr *physical)
 {
-    uint64_t mask;
-
-    switch (TTE_PGSIZE(tlb->tte)) {
-    default:
-    case 0x0: /* 8k */
-        mask = 0xffffffffffffe000ULL;
-        break;
-    case 0x1: /* 64k */
-        mask = 0xffffffffffff0000ULL;
-        break;
-    case 0x2: /* 512k */
-        mask = 0xfffffffffff80000ULL;
-        break;
-    case 0x3: /* 4M */
-        mask = 0xffffffffffc00000ULL;
-        break;
-    }
+    uint64_t mask = 1ULL + ~(8192ULL << 3 * TTE_PGSIZE(tlb->tte));
 
     /* valid, context match, virtual address match? */
     if (TTE_IS_VALID(tlb->tte) &&
-- 
2.7.2

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

* [Qemu-devel] [PATCH 22/29] target-sparc: implement auto-demapping for UA2005 CPUs
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (20 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 21/29] target-sparc: allow 256M sized pages Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-11 14:17   ` Richard Henderson
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 23/29] target-sparc: implement ST_BLKINIT_ ASIs Artyom Tarasenko
                   ` (8 subsequent siblings)
  30 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/ldst_helper.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index a85552e..c27e668 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -210,6 +210,27 @@ static void replace_tlb_1bit_lru(SparcTLBEntry *tlb,
 {
     unsigned int i, replace_used;
 
+    if (cpu_has_hypervisor(env1)) {
+        uint64_t new_vaddr = tlb_tag & ~0x1fffULL;
+        uint64_t new_size = 1024ULL * (8 << 3 * TTE_PGSIZE(tlb_tte));
+        uint32_t new_ctx = tlb_tag & 0x1fffU;
+        for (i = 0; i < 64; i++) {
+            uint32_t ctx = tlb[i].tag & 0x1fffU;
+            /* check if new mapping overlaps an existing one */
+            if (new_ctx == ctx) {
+                uint64_t vaddr = tlb[i].tag & ~0x1fffULL;
+                uint64_t size = 1024ULL * (8 << 3 * TTE_PGSIZE(tlb[i].tte));
+                if ((new_vaddr == vaddr) || ((new_vaddr < (vaddr + size))
+                    && (vaddr < (new_vaddr + new_size)))) {
+                    DPRINTF_MMU("auto demap entry [%d] %lx->%lx\n", i, vaddr,
+                                new_vaddr);
+                    replace_tlb_entry(&tlb[i], tlb_tag, tlb_tte, env1);
+                    return;
+                }
+            }
+
+        }
+    }
     /* Try replacing invalid entry */
     for (i = 0; i < 64; i++) {
         if (!TTE_IS_VALID(tlb[i].tte)) {
-- 
2.7.2

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

* [Qemu-devel] [PATCH 23/29] target-sparc: implement ST_BLKINIT_ ASIs
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (21 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 22/29] target-sparc: implement auto-demapping for UA2005 CPUs Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-11 14:22   ` Richard Henderson
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 24/29] target-sparc: add more registers to dump_mmu Artyom Tarasenko
                   ` (7 subsequent siblings)
  30 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

In OpenSPARC T1+ TWINX ASIs in store instructions are aliased
with Block Initializing Store ASIs.

"UltraSPARC T1 Supplement Draft D2.1, 14 May 2007" describes them
in the chapter "5.9 Block Initializing Store ASIs"

Integer stores of all sizes are allowed with these ASIs.

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/ldst_helper.c | 22 +++++++++++-----------
 target-sparc/translate.c   | 17 ++++++++++++++---
 2 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index c27e668..f59293d 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -1766,6 +1766,9 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
     case ASI_REAL_IO_L: /* Bypass, non-cacheable LE */
     case ASI_PL: /* Primary LE */
     case ASI_SL: /* Secondary LE */
+    case ASI_TWINX_AIUS_L: /* 0x2b, ASI_STBI_AIUS_L */
+    case ASI_TWINX_PL: /* 0xea ASI_ST_BLKINIT_PRIMARY_LITTLE */
+    case ASI_TWINX_SL: /* 0xeb ASI_ST_BLKINIT_SECONDARY_LITTLE */
         switch (size) {
         case 2:
             val = bswap16(val);
@@ -1784,6 +1787,14 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
     }
 
     switch (asi) {
+    case ASI_TWINX_AIUP: /* 0x22 ASI_STBI_AIUP */
+    case ASI_TWINX_AIUP_L: /* 0x2a ASI_STBI_AIUPL_L */
+    case ASI_TWINX_AIUS: /* 0x23 ASI_STBI_AIUS */
+    case ASI_TWINX_AIUS_L: /* 0x2b ASI_STBI_AIUS_L */
+    case ASI_BLK_INIT_QUAD_LDD_P: /* 0xe2 Primary block init */
+    case ASI_BLK_INIT_QUAD_LDD_S: /* 0xe3 Secondary block init */
+    case ASI_TWINX_PL: /* 0xea ASI_ST_BLKINIT_PRIMARY_LITTLE */
+    case ASI_TWINX_SL: /* 0xeb ASI_ST_BLKINIT_SECONDARY_LITTLE */
     case ASI_AIUP:  /* As if user primary */
     case ASI_AIUS:  /* As if user secondary */
     case ASI_AIUPL: /* As if user primary LE */
@@ -2154,19 +2165,8 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
         return;
     case ASI_NUCLEUS_QUAD_LDD:   /* Nucleus quad LDD 128 bit atomic */
     case ASI_NUCLEUS_QUAD_LDD_L: /* Nucleus quad LDD 128 bit atomic LE */
-    case ASI_TWINX_AIUP:   /* As if user primary, twinx */
-    case ASI_TWINX_AIUS:   /* As if user secondary, twinx */
     case ASI_TWINX_REAL:   /* Real address, twinx */
-    case ASI_TWINX_AIUP_L: /* As if user primary, twinx, LE */
-    case ASI_TWINX_AIUS_L: /* As if user secondary, twinx, LE */
     case ASI_TWINX_REAL_L: /* Real address, twinx, LE */
-    case ASI_TWINX_N:  /* Nucleus, twinx */
-    case ASI_TWINX_NL: /* Nucleus, twinx, LE */
-    /* ??? From the UA2011 document; overlaps BLK_INIT_QUAD_LDD_* */
-    case ASI_TWINX_P:  /* Primary, twinx */
-    case ASI_TWINX_PL: /* Primary, twinx, LE */
-    case ASI_TWINX_S:  /* Secondary, twinx */
-    case ASI_TWINX_SL: /* Secondary, twinx, LE */
         /* Only stda allowed */
         helper_raise_exception(env, TT_ILL_INSN);
         return;
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 6520bb3..c7fbcbc 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -2234,13 +2234,24 @@ static void gen_st_asi(DisasContext *dc, TCGv src, TCGv addr,
     switch (da.type) {
     case GET_ASI_EXCP:
         break;
-    case GET_ASI_DTWINX: /* Reserved for stda.  */
-        gen_exception(dc, TT_ILL_INSN);
-        break;
     case GET_ASI_DIRECT:
         gen_address_mask(dc, addr);
         tcg_gen_qemu_st_tl(src, addr, da.mem_idx, da.memop);
         break;
+    case GET_ASI_DTWINX:
+#ifndef TARGET_SPARC64
+        gen_exception(dc, TT_ILL_INSN);
+        break;
+#else
+        if (!(dc->def->features & CPU_FEATURE_HYPV)) {
+            /* Pre OpenSPARC CPUs don't have these */
+            gen_exception(dc, TT_ILL_INSN);
+            return;
+        }
+        /* in OpenSPARC T1+ CPUs TWINX ASIs in store instructions
+         * are ST_BLKINIT_ ASIs */
+        /* fall through */
+#endif
     default:
         {
             TCGv_i32 r_asi = tcg_const_i32(da.asi);
-- 
2.7.2

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

* [Qemu-devel] [PATCH 24/29] target-sparc: add more registers to dump_mmu
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (22 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 23/29] target-sparc: implement ST_BLKINIT_ ASIs Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-11 14:22   ` Richard Henderson
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 25/29] target-sparc: implement UA2005 ASI_MMU (0x21) Artyom Tarasenko
                   ` (6 subsequent siblings)
  30 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/mmu_helper.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/target-sparc/mmu_helper.c b/target-sparc/mmu_helper.c
index 33b48eb..e6558eb 100644
--- a/target-sparc/mmu_helper.c
+++ b/target-sparc/mmu_helper.c
@@ -732,6 +732,8 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env)
                    PRId64 "\n",
                    env->dmmu.mmu_primary_context,
                    env->dmmu.mmu_secondary_context);
+    (*cpu_fprintf)(f, "DMMU Tag Access: %" PRIx64 ", TSB Tag Target: %" PRIx64
+                   "\n", env->dmmu.tag_access, env->dmmu.tsb_tag_target);
     if ((env->lsu & DMMU_E) == 0) {
         (*cpu_fprintf)(f, "DMMU disabled\n");
     } else {
-- 
2.7.2

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

* [Qemu-devel] [PATCH 25/29] target-sparc: implement UA2005 ASI_MMU (0x21)
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (23 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 24/29] target-sparc: add more registers to dump_mmu Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-11 14:25   ` Richard Henderson
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 26/29] target-sparc: store the UA2005 entries in sun4u format Artyom Tarasenko
                   ` (5 subsequent siblings)
  30 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/ldst_helper.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index f59293d..efdbabc 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -1643,6 +1643,18 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
             ret = env->scratch[i];
             break;
         }
+    case ASI_MMU: /* UA2005 Context ID registers */
+        switch ((addr >> 3) & 0x3) {
+        case 1:
+            ret = env->dmmu.mmu_primary_context;
+            break;
+        case 2:
+            ret = env->dmmu.mmu_secondary_context;
+            break;
+        default:
+          cpu_unassigned_access(cs, addr, true, false, 1, size);
+        }
+        break;
     case ASI_DCACHE_DATA:     /* D-cache data */
     case ASI_DCACHE_TAG:      /* D-cache tag access */
     case ASI_ESTATE_ERROR_EN: /* E-cache error enable */
@@ -2182,6 +2194,28 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
             env->scratch[i] = val;
             return;
         }
+    case ASI_MMU: /* UA2005 Context ID registers */
+        {
+          switch ((addr >> 3) & 0x3) {
+          case 1:
+              env->dmmu.mmu_primary_context = val;
+              env->immu.mmu_primary_context = val;
+              /* can be optimized to only flush MMU_USER_PRIMARY_IDX
+                 and MMU_KERNEL_PRIMARY_IDX entries */
+              tlb_flush(CPU(cpu), 1);
+              break;
+          case 2:
+              env->dmmu.mmu_secondary_context = val;
+              env->immu.mmu_secondary_context = val;
+              /* can be optimized to only flush MMU_USER_SECONDARY_IDX
+                 and MMU_KERNEL_SECONDARY_IDX entries */
+              tlb_flush(CPU(cpu), 1);
+              break;
+          default:
+              cpu_unassigned_access(cs, addr, true, false, 1, size);
+          }
+        }
+        return;
     case ASI_QUEUE: /* UA2005 CPU mondo queue */
     case ASI_DCACHE_DATA: /* D-cache data */
     case ASI_DCACHE_TAG: /* D-cache tag access */
-- 
2.7.2

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

* [Qemu-devel] [PATCH 26/29] target-sparc: store the UA2005 entries in sun4u format
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (24 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 25/29] target-sparc: implement UA2005 ASI_MMU (0x21) Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-11 14:31   ` Richard Henderson
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 27/29] target-sparc: implement sun4v RTC Artyom Tarasenko
                   ` (4 subsequent siblings)
  30 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

According to chapter 13.3 of the
UltraSPARC T1 Supplement to the UltraSPARC Architecture 2005,
only the sun4u format is available for data-access loads.

Store UA2005 entries in the sun4u format to simplify processing.

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target-sparc/ldst_helper.c | 51 ++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 43 insertions(+), 8 deletions(-)

diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index efdbabc..e267195 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -204,12 +204,33 @@ static void demap_tlb(SparcTLBEntry *tlb, target_ulong demap_addr,
     }
 }
 
+static uint64_t sun4v_tte_to_sun4u(CPUSPARCState *env, uint64_t tag,
+                                   uint64_t sun4v_tte)
+{
+    uint64_t sun4u_tte;
+    if (!(cpu_has_hypervisor(env) && (tag & TLB_UST1_IS_SUN4V_BIT))) {
+        /* is already in the sun4u format */
+        return sun4v_tte;
+    }
+    sun4u_tte = TTE_PA(sun4v_tte) | (sun4v_tte & TTE_VALID_BIT);
+    sun4u_tte |= (sun4v_tte & 3ULL) << 61;
+    sun4u_tte |= (sun4v_tte & TTE_NFO_BIT_UA2005) >> 2;
+    sun4u_tte |= (sun4v_tte & TTE_USED_BIT_UA2005) >> 6;
+    sun4u_tte |= (sun4v_tte & TTE_W_OK_BIT_UA2005) >> 5;
+    sun4u_tte |= (sun4v_tte & TTE_SIDEEFFECT_BIT_UA2005) >> 8;
+    sun4u_tte |= (sun4v_tte & TTE_PRIV_BIT_UA2005) >> 6;
+    sun4u_tte |= (sun4v_tte & TTE_LOCKED_BIT_UA2005) >> 55;
+    return sun4u_tte;
+}
+
 static void replace_tlb_1bit_lru(SparcTLBEntry *tlb,
                                  uint64_t tlb_tag, uint64_t tlb_tte,
-                                 const char *strmmu, CPUSPARCState *env1)
+                                 const char *strmmu, CPUSPARCState *env1,
+                                 uint64_t addr)
 {
     unsigned int i, replace_used;
 
+    tlb_tte = sun4v_tte_to_sun4u(env1, addr, tlb_tte);
     if (cpu_has_hypervisor(env1)) {
         uint64_t new_vaddr = tlb_tag & ~0x1fffULL;
         uint64_t new_size = 1024ULL * (8 << 3 * TTE_PGSIZE(tlb_tte));
@@ -2075,7 +2096,11 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
             return;
         }
     case ASI_ITLB_DATA_IN: /* I-MMU data in */
-        replace_tlb_1bit_lru(env->itlb, env->immu.tag_access, val, "immu", env);
+        /* ignore real translation entries */
+        if (!(addr & TLB_UST1_IS_REAL_BIT)) {
+            replace_tlb_1bit_lru(env->itlb, env->immu.tag_access,
+                                 val, "immu", env, addr);
+        }
         return;
     case ASI_ITLB_DATA_ACCESS: /* I-MMU data access */
         {
@@ -2083,8 +2108,11 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
 
             unsigned int i = (addr >> 3) & 0x3f;
 
-            replace_tlb_entry(&env->itlb[i], env->immu.tag_access, val, env);
-
+            /* ignore real translation entries */
+            if (!(addr & TLB_UST1_IS_REAL_BIT)) {
+                replace_tlb_entry(&env->itlb[i], env->immu.tag_access,
+                                  sun4v_tte_to_sun4u(env, addr, val), env);
+            }
 #ifdef DEBUG_MMU
             DPRINTF_MMU("immu data access replaced entry [%i]\n", i);
             dump_mmu(stdout, fprintf, env);
@@ -2152,14 +2180,21 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
             return;
         }
     case ASI_DTLB_DATA_IN: /* D-MMU data in */
-        replace_tlb_1bit_lru(env->dtlb, env->dmmu.tag_access, val, "dmmu", env);
-        return;
+      /* ignore real translation entries */
+      if (!(addr & TLB_UST1_IS_REAL_BIT)) {
+          replace_tlb_1bit_lru(env->dtlb, env->dmmu.tag_access,
+                               val, "dmmu", env, addr);
+      }
+      return;
     case ASI_DTLB_DATA_ACCESS: /* D-MMU data access */
         {
             unsigned int i = (addr >> 3) & 0x3f;
 
-            replace_tlb_entry(&env->dtlb[i], env->dmmu.tag_access, val, env);
-
+            /* ignore real translation entries */
+            if (!(addr & TLB_UST1_IS_REAL_BIT)) {
+                replace_tlb_entry(&env->dtlb[i], env->dmmu.tag_access,
+                                  sun4v_tte_to_sun4u(env, addr, val), env);
+            }
 #ifdef DEBUG_MMU
             DPRINTF_MMU("dmmu data access replaced entry [%i]\n", i);
             dump_mmu(stdout, fprintf, env);
-- 
2.7.2

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

* [Qemu-devel] [PATCH 27/29] target-sparc: implement sun4v RTC
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (25 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 26/29] target-sparc: store the UA2005 entries in sun4u format Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 28/29] target-sparc: move common cpu initialisation routines to sparc64.c Artyom Tarasenko
                   ` (3 subsequent siblings)
  30 siblings, 0 replies; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 MAINTAINERS                  |   6 +++
 hw/timer/Makefile.objs       |   2 +
 hw/timer/sun4v-rtc.c         | 103 +++++++++++++++++++++++++++++++++++++++++++
 include/hw/timer/sun4v-rtc.h |   1 +
 4 files changed, 112 insertions(+)
 create mode 100644 hw/timer/sun4v-rtc.c
 create mode 100644 include/hw/timer/sun4v-rtc.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 9b7e846..2866d17 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1014,6 +1014,12 @@ M: Dmitry Fleytman <dmitry@daynix.com>
 S: Maintained
 F: hw/net/e1000e*
 
+sun4v RTC
+M: Artyom Tarasenko <atar4qemu@gmail.com>
+S: Maintained
+F: hw/timer/sun4v-rtc.c
+F: include/hw/timer/sun4v-rtc.h
+
 Subsystems
 ----------
 Audio
diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index 7ba8c23..c1e93a3 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -34,3 +34,5 @@ obj-$(CONFIG_ALLWINNER_A10_PIT) += allwinner-a10-pit.o
 
 common-obj-$(CONFIG_STM32F2XX_TIMER) += stm32f2xx_timer.o
 common-obj-$(CONFIG_ASPEED_SOC) += aspeed_timer.o
+
+common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
diff --git a/hw/timer/sun4v-rtc.c b/hw/timer/sun4v-rtc.c
new file mode 100644
index 0000000..bd41e95
--- /dev/null
+++ b/hw/timer/sun4v-rtc.c
@@ -0,0 +1,103 @@
+/*
+ * QEMU sun4v Real Time Clock device
+ *
+ * The sun4v_rtc device (sun4v tod clock)
+ *
+ * Copyright (c) 2016 Artyom Tarasenko
+ *
+ * This code is licensed under the GNU GPL v3 or (at your option) any later
+ * version.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/hw.h"
+#include "hw/sysbus.h"
+#include "qemu/timer.h"
+#include "hw/timer/sun4v-rtc.h"
+
+//#define DEBUG_SUN4V_RTC
+
+#ifdef DEBUG_SUN4V_RTC
+#define DPRINTF(fmt, ...)                                       \
+    do { printf("sun4v_rtc: " fmt , ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) do {} while (0)
+#endif
+
+#define TYPE_SUN4V_RTC "sun4v_rtc"
+#define SUN4V_RTC(obj) OBJECT_CHECK(Sun4vRtc, (obj), TYPE_SUN4V_RTC)
+
+typedef struct Sun4vRtc {
+    SysBusDevice parent_obj;
+
+    MemoryRegion iomem;
+} Sun4vRtc;
+
+static uint64_t sun4v_rtc_read(void *opaque, hwaddr addr,
+                                unsigned size)
+{
+    uint64_t val = qemu_clock_get_ms(QEMU_CLOCK_REALTIME) / 1000;
+    if (!(addr & 4ULL)) {
+        /* accessing the high 32 bits */
+        val >>= 32;
+    }
+    DPRINTF("read from " TARGET_FMT_plx " val %lx\n", addr, val);
+    return val;
+}
+
+static void sun4v_rtc_write(void *opaque, hwaddr addr,
+                             uint64_t val, unsigned size)
+{
+    DPRINTF("write 0x%x to " TARGET_FMT_plx "\n", (unsigned)val, addr);
+}
+
+static const MemoryRegionOps sun4v_rtc_ops = {
+    .read = sun4v_rtc_read,
+    .write = sun4v_rtc_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+void sun4v_rtc_init(hwaddr addr)
+{
+    DeviceState *dev;
+    SysBusDevice *s;
+
+    dev = qdev_create(NULL, TYPE_SUN4V_RTC);
+    s = SYS_BUS_DEVICE(dev);
+    SUN4V_RTC(dev);
+
+    qdev_init_nofail(dev);
+
+    sysbus_mmio_map(s, 0, addr);
+}
+
+static int sun4v_rtc_init1(SysBusDevice *dev)
+{
+    Sun4vRtc *s = SUN4V_RTC(dev);
+
+    memory_region_init_io(&s->iomem, OBJECT(s), &sun4v_rtc_ops, s,
+                          "sun4v-rtc", 0x08ULL);
+    sysbus_init_mmio(dev, &s->iomem);
+    return 0;
+}
+
+static void sun4v_rtc_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = sun4v_rtc_init1;
+}
+
+static const TypeInfo sun4v_rtc_info = {
+    .name          = TYPE_SUN4V_RTC,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(Sun4vRtc),
+    .class_init    = sun4v_rtc_class_init,
+};
+
+static void sun4v_rtc_register_types(void)
+{
+    type_register_static(&sun4v_rtc_info);
+}
+
+type_init(sun4v_rtc_register_types)
diff --git a/include/hw/timer/sun4v-rtc.h b/include/hw/timer/sun4v-rtc.h
new file mode 100644
index 0000000..407278f
--- /dev/null
+++ b/include/hw/timer/sun4v-rtc.h
@@ -0,0 +1 @@
+void sun4v_rtc_init(hwaddr addr);
-- 
2.7.2

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

* [Qemu-devel] [PATCH 28/29] target-sparc: move common cpu initialisation routines to sparc64.c
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (26 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 27/29] target-sparc: implement sun4v RTC Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-11 14:34   ` Richard Henderson
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 29/29] target-sparc: fix up Niagara machine Artyom Tarasenko
                   ` (2 subsequent siblings)
  30 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 hw/sparc64/Makefile.objs   |   1 +
 hw/sparc64/sparc64.c       | 378 +++++++++++++++++++++++++++++++++++++++++++++
 hw/sparc64/sun4u.c         | 351 +----------------------------------------
 hw/timer/sun4v-rtc.c       |   2 +-
 include/hw/sparc/sparc64.h |   5 +
 5 files changed, 389 insertions(+), 348 deletions(-)
 create mode 100644 hw/sparc64/sparc64.c
 create mode 100644 include/hw/sparc/sparc64.h

diff --git a/hw/sparc64/Makefile.objs b/hw/sparc64/Makefile.objs
index a84cfe3..a96b1f8 100644
--- a/hw/sparc64/Makefile.objs
+++ b/hw/sparc64/Makefile.objs
@@ -1 +1,2 @@
+obj-y += sparc64.o
 obj-y += sun4u.o
diff --git a/hw/sparc64/sparc64.c b/hw/sparc64/sparc64.c
new file mode 100644
index 0000000..b3d219c
--- /dev/null
+++ b/hw/sparc64/sparc64.c
@@ -0,0 +1,378 @@
+/*
+ * QEMU Sun4u/Sun4v System Emulator common routines
+ *
+ * Copyright (c) 2005 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "hw/char/serial.h"
+#include "hw/sparc/sparc64.h"
+#include "qemu/timer.h"
+
+
+//#define DEBUG_IRQ
+//#define DEBUG_TIMER
+
+#ifdef DEBUG_IRQ
+#define CPUIRQ_DPRINTF(fmt, ...)                                \
+    do { printf("CPUIRQ: " fmt , ## __VA_ARGS__); } while (0)
+#else
+#define CPUIRQ_DPRINTF(fmt, ...)
+#endif
+
+#ifdef DEBUG_TIMER
+#define TIMER_DPRINTF(fmt, ...)                                  \
+    do { printf("TIMER: " fmt , ## __VA_ARGS__); } while (0)
+#else
+#define TIMER_DPRINTF(fmt, ...)
+#endif
+
+#define TICK_MAX             0x7fffffffffffffffULL
+
+void cpu_check_irqs(CPUSPARCState *env)
+{
+    CPUState *cs;
+    uint32_t pil = env->pil_in |
+                  (env->softint & ~(SOFTINT_TIMER | SOFTINT_STIMER));
+
+    /* TT_IVEC has a higher priority (16) than TT_EXTINT (31..17) */
+    if (env->ivec_status & 0x20) {
+        return;
+    }
+    cs = CPU(sparc_env_get_cpu(env));
+    /* check if TM or SM in SOFTINT are set
+       setting these also causes interrupt 14 */
+    if (env->softint & (SOFTINT_TIMER | SOFTINT_STIMER)) {
+        pil |= 1 << 14;
+    }
+
+    /* The bit corresponding to psrpil is (1<< psrpil), the next bit
+       is (2 << psrpil). */
+    if (pil < (2 << env->psrpil)) {
+        if (cs->interrupt_request & CPU_INTERRUPT_HARD) {
+            CPUIRQ_DPRINTF("Reset CPU IRQ (current interrupt %x)\n",
+                           env->interrupt_index);
+            env->interrupt_index = 0;
+            cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
+        }
+        return;
+    }
+
+    if (cpu_interrupts_enabled(env)) {
+
+        unsigned int i;
+
+        for (i = 15; i > env->psrpil; i--) {
+            if (pil & (1 << i)) {
+                int old_interrupt = env->interrupt_index;
+                int new_interrupt = TT_EXTINT | i;
+
+                if (unlikely(env->tl > 0 && cpu_tsptr(env)->tt > new_interrupt
+                  && ((cpu_tsptr(env)->tt & 0x1f0) == TT_EXTINT))) {
+                    CPUIRQ_DPRINTF("Not setting CPU IRQ: TL=%d "
+                                   "current %x >= pending %x\n",
+                                   env->tl, cpu_tsptr(env)->tt, new_interrupt);
+                } else if (old_interrupt != new_interrupt) {
+                    env->interrupt_index = new_interrupt;
+                    CPUIRQ_DPRINTF("Set CPU IRQ %d old=%x new=%x\n", i,
+                                   old_interrupt, new_interrupt);
+                    cpu_interrupt(cs, CPU_INTERRUPT_HARD);
+                }
+                break;
+            }
+        }
+    } else if (cs->interrupt_request & CPU_INTERRUPT_HARD) {
+        CPUIRQ_DPRINTF("Interrupts disabled, pil=%08x pil_in=%08x softint=%08x "
+                       "current interrupt %x\n",
+                       pil, env->pil_in, env->softint, env->interrupt_index);
+        env->interrupt_index = 0;
+        cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
+    }
+}
+
+static void cpu_kick_irq(SPARCCPU *cpu)
+{
+    CPUState *cs = CPU(cpu);
+    CPUSPARCState *env = &cpu->env;
+
+    cs->halted = 0;
+    cpu_check_irqs(env);
+    qemu_cpu_kick(cs);
+}
+
+void sparc64_cpu_set_ivec_irq(void *opaque, int irq, int level)
+{
+    SPARCCPU *cpu = opaque;
+    CPUSPARCState *env = &cpu->env;
+    CPUState *cs;
+
+    if (level) {
+        if (!(env->ivec_status & 0x20)) {
+            CPUIRQ_DPRINTF("Raise IVEC IRQ %d\n", irq);
+            cs = CPU(cpu);
+            cs->halted = 0;
+            env->interrupt_index = TT_IVEC;
+            env->ivec_status |= 0x20;
+            env->ivec_data[0] = (0x1f << 6) | irq;
+            env->ivec_data[1] = 0;
+            env->ivec_data[2] = 0;
+            cpu_interrupt(cs, CPU_INTERRUPT_HARD);
+        }
+    } else {
+        if (env->ivec_status & 0x20) {
+            CPUIRQ_DPRINTF("Lower IVEC IRQ %d\n", irq);
+            cs = CPU(cpu);
+            env->ivec_status &= ~0x20;
+            cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
+        }
+    }
+}
+
+typedef struct ResetData {
+    SPARCCPU *cpu;
+    uint64_t prom_addr;
+} ResetData;
+
+static CPUTimer *cpu_timer_create(const char *name, SPARCCPU *cpu,
+                                  QEMUBHFunc *cb, uint32_t frequency,
+                                  uint64_t disabled_mask, uint64_t npt_mask)
+{
+    CPUTimer *timer = g_malloc0(sizeof(CPUTimer));
+
+    timer->name = name;
+    timer->frequency = frequency;
+    timer->disabled_mask = disabled_mask;
+    timer->npt_mask = npt_mask;
+
+    timer->disabled = 1;
+    timer->npt = 1;
+    timer->clock_offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+
+    timer->qtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cb, cpu);
+
+    return timer;
+}
+
+static void cpu_timer_reset(CPUTimer *timer)
+{
+    timer->disabled = 1;
+    timer->clock_offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+
+    timer_del(timer->qtimer);
+}
+
+static void main_cpu_reset(void *opaque)
+{
+    ResetData *s = (ResetData *)opaque;
+    CPUSPARCState *env = &s->cpu->env;
+    static unsigned int nr_resets;
+
+    cpu_reset(CPU(s->cpu));
+
+    cpu_timer_reset(env->tick);
+    cpu_timer_reset(env->stick);
+    cpu_timer_reset(env->hstick);
+
+    env->gregs[1] = 0; /* Memory start */
+    env->gregs[2] = ram_size; /* Memory size */
+    env->gregs[3] = 0; /* Machine description XXX */
+    if (nr_resets++ == 0) {
+        /* Power on reset */
+        env->pc = s->prom_addr + 0x20ULL;
+    } else {
+        env->pc = s->prom_addr + 0x40ULL;
+    }
+    env->npc = env->pc + 4;
+}
+
+static void tick_irq(void *opaque)
+{
+    SPARCCPU *cpu = opaque;
+    CPUSPARCState *env = &cpu->env;
+
+    CPUTimer *timer = env->tick;
+
+    if (timer->disabled) {
+        CPUIRQ_DPRINTF("tick_irq: softint disabled\n");
+        return;
+    } else {
+        CPUIRQ_DPRINTF("tick: fire\n");
+    }
+
+    env->softint |= SOFTINT_TIMER;
+    cpu_kick_irq(cpu);
+}
+
+static void stick_irq(void *opaque)
+{
+    SPARCCPU *cpu = opaque;
+    CPUSPARCState *env = &cpu->env;
+
+    CPUTimer *timer = env->stick;
+
+    if (timer->disabled) {
+        CPUIRQ_DPRINTF("stick_irq: softint disabled\n");
+        return;
+    } else {
+        CPUIRQ_DPRINTF("stick: fire\n");
+    }
+
+    env->softint |= SOFTINT_STIMER;
+    cpu_kick_irq(cpu);
+}
+
+static void hstick_irq(void *opaque)
+{
+    SPARCCPU *cpu = opaque;
+    CPUSPARCState *env = &cpu->env;
+
+    CPUTimer *timer = env->hstick;
+
+    if (timer->disabled) {
+        CPUIRQ_DPRINTF("hstick_irq: softint disabled\n");
+        return;
+    } else {
+        CPUIRQ_DPRINTF("hstick: fire\n");
+    }
+
+    env->softint |= SOFTINT_STIMER;
+    cpu_kick_irq(cpu);
+}
+
+static int64_t cpu_to_timer_ticks(int64_t cpu_ticks, uint32_t frequency)
+{
+    return muldiv64(cpu_ticks, NANOSECONDS_PER_SECOND, frequency);
+}
+
+static uint64_t timer_to_cpu_ticks(int64_t timer_ticks, uint32_t frequency)
+{
+    return muldiv64(timer_ticks, frequency, NANOSECONDS_PER_SECOND);
+}
+
+void cpu_tick_set_count(CPUTimer *timer, uint64_t count)
+{
+    uint64_t real_count = count & ~timer->npt_mask;
+    uint64_t npt_bit = count & timer->npt_mask;
+
+    int64_t vm_clock_offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
+                    cpu_to_timer_ticks(real_count, timer->frequency);
+
+    TIMER_DPRINTF("%s set_count count=0x%016lx (npt %s) p=%p\n",
+                  timer->name, real_count,
+                  timer->npt ? "disabled" : "enabled", timer);
+
+    timer->npt = npt_bit ? 1 : 0;
+    timer->clock_offset = vm_clock_offset;
+}
+
+uint64_t cpu_tick_get_count(CPUTimer *timer)
+{
+    uint64_t real_count = timer_to_cpu_ticks(
+                    qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - timer->clock_offset,
+                    timer->frequency);
+
+    TIMER_DPRINTF("%s get_count count=0x%016lx (npt %s) p=%p\n",
+           timer->name, real_count,
+           timer->npt ? "disabled" : "enabled", timer);
+
+    if (timer->npt) {
+        real_count |= timer->npt_mask;
+    }
+
+    return real_count;
+}
+
+void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit)
+{
+    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+
+    uint64_t real_limit = limit & ~timer->disabled_mask;
+    timer->disabled = (limit & timer->disabled_mask) ? 1 : 0;
+
+    int64_t expires = cpu_to_timer_ticks(real_limit, timer->frequency) +
+                    timer->clock_offset;
+
+    if (expires < now) {
+        expires = now + 1;
+    }
+
+    TIMER_DPRINTF("%s set_limit limit=0x%016lx (%s) p=%p "
+                  "called with limit=0x%016lx at 0x%016lx (delta=0x%016lx)\n",
+                  timer->name, real_limit,
+                  timer->disabled ? "disabled" : "enabled",
+                  timer, limit,
+                  timer_to_cpu_ticks(now - timer->clock_offset,
+                                     timer->frequency),
+                  timer_to_cpu_ticks(expires - now, timer->frequency));
+
+    if (!real_limit) {
+        TIMER_DPRINTF("%s set_limit limit=ZERO - not starting timer\n",
+                timer->name);
+        timer_del(timer->qtimer);
+    } else if (timer->disabled) {
+        timer_del(timer->qtimer);
+    } else {
+        timer_mod(timer->qtimer, expires);
+    }
+}
+
+SPARCCPU *sparc64_cpu_devinit(const char *cpu_model,
+                              const char *default_cpu_model, uint64_t prom_addr)
+{
+    SPARCCPU *cpu;
+    CPUSPARCState *env;
+    ResetData *reset_info;
+
+    uint32_t   tick_frequency = 100 * 1000000;
+    uint32_t  stick_frequency = 100 * 1000000;
+    uint32_t hstick_frequency = 100 * 1000000;
+
+    if (cpu_model == NULL) {
+        cpu_model = default_cpu_model;
+    }
+    cpu = cpu_sparc_init(cpu_model);
+    if (cpu == NULL) {
+        fprintf(stderr, "Unable to find Sparc CPU definition\n");
+        exit(1);
+    }
+    env = &cpu->env;
+
+    env->tick = cpu_timer_create("tick", cpu, tick_irq,
+                                  tick_frequency, TICK_INT_DIS,
+                                  TICK_NPT_MASK);
+
+    env->stick = cpu_timer_create("stick", cpu, stick_irq,
+                                   stick_frequency, TICK_INT_DIS,
+                                   TICK_NPT_MASK);
+
+    env->hstick = cpu_timer_create("hstick", cpu, hstick_irq,
+                                    hstick_frequency, TICK_INT_DIS,
+                                    TICK_NPT_MASK);
+
+    reset_info = g_malloc0(sizeof(ResetData));
+    reset_info->cpu = cpu;
+    reset_info->prom_addr = prom_addr;
+    qemu_register_reset(main_cpu_reset, reset_info);
+
+    return cpu;
+}
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 3165e18..9372a56 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -33,29 +33,16 @@
 #include "hw/timer/m48t59.h"
 #include "hw/block/fdc.h"
 #include "net/net.h"
-#include "qemu/timer.h"
-#include "sysemu/sysemu.h"
-#include "hw/boards.h"
+#include "hw/sparc/sparc64.h"
 #include "hw/nvram/openbios_firmware_abi.h"
 #include "hw/nvram/fw_cfg.h"
 #include "hw/sysbus.h"
 #include "hw/ide.h"
 #include "hw/loader.h"
 #include "elf.h"
-#include "sysemu/block-backend.h"
-#include "exec/address-spaces.h"
 #include "qemu/cutils.h"
 
-//#define DEBUG_IRQ
 //#define DEBUG_EBUS
-//#define DEBUG_TIMER
-
-#ifdef DEBUG_IRQ
-#define CPUIRQ_DPRINTF(fmt, ...)                                \
-    do { printf("CPUIRQ: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define CPUIRQ_DPRINTF(fmt, ...)
-#endif
 
 #ifdef DEBUG_EBUS
 #define EBUS_DPRINTF(fmt, ...)                                  \
@@ -64,13 +51,6 @@
 #define EBUS_DPRINTF(fmt, ...)
 #endif
 
-#ifdef DEBUG_TIMER
-#define TIMER_DPRINTF(fmt, ...)                                  \
-    do { printf("TIMER: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define TIMER_DPRINTF(fmt, ...)
-#endif
-
 #define KERNEL_LOAD_ADDR     0x00404000
 #define CMDLINE_ADDR         0x003ff000
 #define PROM_SIZE_MAX        (4 * 1024 * 1024)
@@ -88,8 +68,6 @@
 
 #define IVEC_MAX             0x40
 
-#define TICK_MAX             0x7fffffffffffffffULL
-
 struct hwdef {
     const char * const default_cpu_model;
     uint16_t machine_id;
@@ -237,293 +215,11 @@ static uint64_t sun4u_load_kernel(const char *kernel_filename,
     return kernel_size;
 }
 
-void cpu_check_irqs(CPUSPARCState *env)
-{
-    CPUState *cs;
-    uint32_t pil = env->pil_in |
-                  (env->softint & ~(SOFTINT_TIMER | SOFTINT_STIMER));
-
-    /* TT_IVEC has a higher priority (16) than TT_EXTINT (31..17) */
-    if (env->ivec_status & 0x20) {
-        return;
-    }
-    cs = CPU(sparc_env_get_cpu(env));
-    /* check if TM or SM in SOFTINT are set
-       setting these also causes interrupt 14 */
-    if (env->softint & (SOFTINT_TIMER | SOFTINT_STIMER)) {
-        pil |= 1 << 14;
-    }
-
-    /* The bit corresponding to psrpil is (1<< psrpil), the next bit
-       is (2 << psrpil). */
-    if (pil < (2 << env->psrpil)){
-        if (cs->interrupt_request & CPU_INTERRUPT_HARD) {
-            CPUIRQ_DPRINTF("Reset CPU IRQ (current interrupt %x)\n",
-                           env->interrupt_index);
-            env->interrupt_index = 0;
-            cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
-        }
-        return;
-    }
-
-    if (cpu_interrupts_enabled(env)) {
-
-        unsigned int i;
-
-        for (i = 15; i > env->psrpil; i--) {
-            if (pil & (1 << i)) {
-                int old_interrupt = env->interrupt_index;
-                int new_interrupt = TT_EXTINT | i;
-
-                if (unlikely(env->tl > 0 && cpu_tsptr(env)->tt > new_interrupt
-                  && ((cpu_tsptr(env)->tt & 0x1f0) == TT_EXTINT))) {
-                    CPUIRQ_DPRINTF("Not setting CPU IRQ: TL=%d "
-                                   "current %x >= pending %x\n",
-                                   env->tl, cpu_tsptr(env)->tt, new_interrupt);
-                } else if (old_interrupt != new_interrupt) {
-                    env->interrupt_index = new_interrupt;
-                    CPUIRQ_DPRINTF("Set CPU IRQ %d old=%x new=%x\n", i,
-                                   old_interrupt, new_interrupt);
-                    cpu_interrupt(cs, CPU_INTERRUPT_HARD);
-                }
-                break;
-            }
-        }
-    } else if (cs->interrupt_request & CPU_INTERRUPT_HARD) {
-        CPUIRQ_DPRINTF("Interrupts disabled, pil=%08x pil_in=%08x softint=%08x "
-                       "current interrupt %x\n",
-                       pil, env->pil_in, env->softint, env->interrupt_index);
-        env->interrupt_index = 0;
-        cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
-    }
-}
-
-static void cpu_kick_irq(SPARCCPU *cpu)
-{
-    CPUState *cs = CPU(cpu);
-    CPUSPARCState *env = &cpu->env;
-
-    cs->halted = 0;
-    cpu_check_irqs(env);
-    qemu_cpu_kick(cs);
-}
-
-static void cpu_set_ivec_irq(void *opaque, int irq, int level)
-{
-    SPARCCPU *cpu = opaque;
-    CPUSPARCState *env = &cpu->env;
-    CPUState *cs;
-
-    if (level) {
-        if (!(env->ivec_status & 0x20)) {
-            CPUIRQ_DPRINTF("Raise IVEC IRQ %d\n", irq);
-            cs = CPU(cpu);
-            cs->halted = 0;
-            env->interrupt_index = TT_IVEC;
-            env->ivec_status |= 0x20;
-            env->ivec_data[0] = (0x1f << 6) | irq;
-            env->ivec_data[1] = 0;
-            env->ivec_data[2] = 0;
-            cpu_interrupt(cs, CPU_INTERRUPT_HARD);
-        }
-    } else {
-        if (env->ivec_status & 0x20) {
-            CPUIRQ_DPRINTF("Lower IVEC IRQ %d\n", irq);
-            cs = CPU(cpu);
-            env->ivec_status &= ~0x20;
-            cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
-        }
-    }
-}
-
 typedef struct ResetData {
     SPARCCPU *cpu;
     uint64_t prom_addr;
 } ResetData;
 
-static CPUTimer *cpu_timer_create(const char *name, SPARCCPU *cpu,
-                                  QEMUBHFunc *cb, uint32_t frequency,
-                                  uint64_t disabled_mask, uint64_t npt_mask)
-{
-    CPUTimer *timer = g_malloc0(sizeof (CPUTimer));
-
-    timer->name = name;
-    timer->frequency = frequency;
-    timer->disabled_mask = disabled_mask;
-    timer->npt_mask = npt_mask;
-
-    timer->disabled = 1;
-    timer->npt = 1;
-    timer->clock_offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-
-    timer->qtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cb, cpu);
-
-    return timer;
-}
-
-static void cpu_timer_reset(CPUTimer *timer)
-{
-    timer->disabled = 1;
-    timer->clock_offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-
-    timer_del(timer->qtimer);
-}
-
-static void main_cpu_reset(void *opaque)
-{
-    ResetData *s = (ResetData *)opaque;
-    CPUSPARCState *env = &s->cpu->env;
-    static unsigned int nr_resets;
-
-    cpu_reset(CPU(s->cpu));
-
-    cpu_timer_reset(env->tick);
-    cpu_timer_reset(env->stick);
-    cpu_timer_reset(env->hstick);
-
-    env->gregs[1] = 0; // Memory start
-    env->gregs[2] = ram_size; // Memory size
-    env->gregs[3] = 0; // Machine description XXX
-    if (nr_resets++ == 0) {
-        /* Power on reset */
-        env->pc = s->prom_addr + 0x20ULL;
-    } else {
-        env->pc = s->prom_addr + 0x40ULL;
-    }
-    env->npc = env->pc + 4;
-}
-
-static void tick_irq(void *opaque)
-{
-    SPARCCPU *cpu = opaque;
-    CPUSPARCState *env = &cpu->env;
-
-    CPUTimer* timer = env->tick;
-
-    if (timer->disabled) {
-        CPUIRQ_DPRINTF("tick_irq: softint disabled\n");
-        return;
-    } else {
-        CPUIRQ_DPRINTF("tick: fire\n");
-    }
-
-    env->softint |= SOFTINT_TIMER;
-    cpu_kick_irq(cpu);
-}
-
-static void stick_irq(void *opaque)
-{
-    SPARCCPU *cpu = opaque;
-    CPUSPARCState *env = &cpu->env;
-
-    CPUTimer* timer = env->stick;
-
-    if (timer->disabled) {
-        CPUIRQ_DPRINTF("stick_irq: softint disabled\n");
-        return;
-    } else {
-        CPUIRQ_DPRINTF("stick: fire\n");
-    }
-
-    env->softint |= SOFTINT_STIMER;
-    cpu_kick_irq(cpu);
-}
-
-static void hstick_irq(void *opaque)
-{
-    SPARCCPU *cpu = opaque;
-    CPUSPARCState *env = &cpu->env;
-
-    CPUTimer* timer = env->hstick;
-
-    if (timer->disabled) {
-        CPUIRQ_DPRINTF("hstick_irq: softint disabled\n");
-        return;
-    } else {
-        CPUIRQ_DPRINTF("hstick: fire\n");
-    }
-
-    env->softint |= SOFTINT_STIMER;
-    cpu_kick_irq(cpu);
-}
-
-static int64_t cpu_to_timer_ticks(int64_t cpu_ticks, uint32_t frequency)
-{
-    return muldiv64(cpu_ticks, NANOSECONDS_PER_SECOND, frequency);
-}
-
-static uint64_t timer_to_cpu_ticks(int64_t timer_ticks, uint32_t frequency)
-{
-    return muldiv64(timer_ticks, frequency, NANOSECONDS_PER_SECOND);
-}
-
-void cpu_tick_set_count(CPUTimer *timer, uint64_t count)
-{
-    uint64_t real_count = count & ~timer->npt_mask;
-    uint64_t npt_bit = count & timer->npt_mask;
-
-    int64_t vm_clock_offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
-                    cpu_to_timer_ticks(real_count, timer->frequency);
-
-    TIMER_DPRINTF("%s set_count count=0x%016lx (npt %s) p=%p\n",
-                  timer->name, real_count,
-                  timer->npt ? "disabled" : "enabled", timer);
-
-    timer->npt = npt_bit ? 1 : 0;
-    timer->clock_offset = vm_clock_offset;
-}
-
-uint64_t cpu_tick_get_count(CPUTimer *timer)
-{
-    uint64_t real_count = timer_to_cpu_ticks(
-                    qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - timer->clock_offset,
-                    timer->frequency);
-
-    TIMER_DPRINTF("%s get_count count=0x%016lx (npt %s) p=%p\n",
-           timer->name, real_count,
-           timer->npt ? "disabled" : "enabled", timer);
-
-    if (timer->npt) {
-        real_count |= timer->npt_mask;
-    }
-
-    return real_count;
-}
-
-void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit)
-{
-    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-
-    uint64_t real_limit = limit & ~timer->disabled_mask;
-    timer->disabled = (limit & timer->disabled_mask) ? 1 : 0;
-
-    int64_t expires = cpu_to_timer_ticks(real_limit, timer->frequency) +
-                    timer->clock_offset;
-
-    if (expires < now) {
-        expires = now + 1;
-    }
-
-    TIMER_DPRINTF("%s set_limit limit=0x%016lx (%s) p=%p "
-                  "called with limit=0x%016lx at 0x%016lx (delta=0x%016lx)\n",
-                  timer->name, real_limit,
-                  timer->disabled?"disabled":"enabled",
-                  timer, limit,
-                  timer_to_cpu_ticks(now - timer->clock_offset,
-                                     timer->frequency),
-                  timer_to_cpu_ticks(expires - now, timer->frequency));
-
-    if (!real_limit) {
-        TIMER_DPRINTF("%s set_limit limit=ZERO - not starting timer\n",
-                timer->name);
-        timer_del(timer->qtimer);
-    } else if (timer->disabled) {
-        timer_del(timer->qtimer);
-    } else {
-        timer_mod(timer->qtimer, expires);
-    }
-}
-
 static void isa_irq_handler(void *opaque, int n, int level)
 {
     static const int isa_irq_to_ivec[16] = {
@@ -744,46 +440,6 @@ static const TypeInfo ram_info = {
     .class_init    = ram_class_init,
 };
 
-static SPARCCPU *cpu_devinit(const char *cpu_model, const struct hwdef *hwdef)
-{
-    SPARCCPU *cpu;
-    CPUSPARCState *env;
-    ResetData *reset_info;
-
-    uint32_t   tick_frequency = 100*1000000;
-    uint32_t  stick_frequency = 100*1000000;
-    uint32_t hstick_frequency = 100*1000000;
-
-    if (cpu_model == NULL) {
-        cpu_model = hwdef->default_cpu_model;
-    }
-    cpu = cpu_sparc_init(cpu_model);
-    if (cpu == NULL) {
-        fprintf(stderr, "Unable to find Sparc CPU definition\n");
-        exit(1);
-    }
-    env = &cpu->env;
-
-    env->tick = cpu_timer_create("tick", cpu, tick_irq,
-                                  tick_frequency, TICK_INT_DIS,
-                                  TICK_NPT_MASK);
-
-    env->stick = cpu_timer_create("stick", cpu, stick_irq,
-                                   stick_frequency, TICK_INT_DIS,
-                                   TICK_NPT_MASK);
-
-    env->hstick = cpu_timer_create("hstick", cpu, hstick_irq,
-                                    hstick_frequency, TICK_INT_DIS,
-                                    TICK_NPT_MASK);
-
-    reset_info = g_malloc0(sizeof(ResetData));
-    reset_info->cpu = cpu;
-    reset_info->prom_addr = hwdef->prom_addr;
-    qemu_register_reset(main_cpu_reset, reset_info);
-
-    return cpu;
-}
-
 static void sun4uv_init(MemoryRegion *address_space_mem,
                         MachineState *machine,
                         const struct hwdef *hwdef)
@@ -802,14 +458,15 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
     FWCfgState *fw_cfg;
 
     /* init CPUs */
-    cpu = cpu_devinit(machine->cpu_model, hwdef);
+    cpu = sparc64_cpu_devinit(machine->cpu_model, hwdef->default_cpu_model,
+                              hwdef->prom_addr);
 
     /* set up devices */
     ram_init(0, machine->ram_size);
 
     prom_init(hwdef->prom_addr, bios_name);
 
-    ivec_irqs = qemu_allocate_irqs(cpu_set_ivec_irq, cpu, IVEC_MAX);
+    ivec_irqs = qemu_allocate_irqs(sparc64_cpu_set_ivec_irq, cpu, IVEC_MAX);
     pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, ivec_irqs, &pci_bus2,
                            &pci_bus3, &pbm_irqs);
     pci_vga_init(pci_bus);
diff --git a/hw/timer/sun4v-rtc.c b/hw/timer/sun4v-rtc.c
index bd41e95..57a0bd7 100644
--- a/hw/timer/sun4v-rtc.c
+++ b/hw/timer/sun4v-rtc.c
@@ -36,7 +36,7 @@ typedef struct Sun4vRtc {
 static uint64_t sun4v_rtc_read(void *opaque, hwaddr addr,
                                 unsigned size)
 {
-    uint64_t val = qemu_clock_get_ms(QEMU_CLOCK_REALTIME) / 1000;
+    uint64_t val = get_clock_realtime() / NANOSECONDS_PER_SECOND;
     if (!(addr & 4ULL)) {
         /* accessing the high 32 bits */
         val >>= 32;
diff --git a/include/hw/sparc/sparc64.h b/include/hw/sparc/sparc64.h
new file mode 100644
index 0000000..7748939
--- /dev/null
+++ b/include/hw/sparc/sparc64.h
@@ -0,0 +1,5 @@
+
+SPARCCPU *sparc64_cpu_devinit(const char *cpu_model,
+                              const char *dflt_cpu_model, uint64_t prom_addr);
+
+void sparc64_cpu_set_ivec_irq(void *opaque, int irq, int level);
-- 
2.7.2

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

* [Qemu-devel] [PATCH 29/29] target-sparc: fix up Niagara machine
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (27 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 28/29] target-sparc: move common cpu initialisation routines to sparc64.c Artyom Tarasenko
@ 2016-10-01 10:05 ` Artyom Tarasenko
  2016-10-11 14:43   ` Richard Henderson
  2016-10-01 10:48 ` [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation no-reply
  2016-10-11 21:52 ` Mark Cave-Ayland
  30 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-01 10:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Mark Cave-Ayland, Artyom Tarasenko

Remove the Niagara stub implementation from sun4u.c and add a machine,
compatible with Legion simulator from the OpenSPARC T1 project.

The machine uses the firmware supplied with the OpenSPARC T1 project,
http://download.oracle.com/technetwork/systems/opensparc/OpenSPARCT1_Arch.1.5.tar.bz2
in the directory S10image/, and is able to boot the supplied Solaris 10 image.

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 default-configs/sparc64-softmmu.mak |   2 +
 hw/sparc64/Makefile.objs            |   1 +
 hw/sparc64/niagara.c                | 177 ++++++++++++++++++++++++++++++++++++
 hw/sparc64/sun4u.c                  |  31 -------
 4 files changed, 180 insertions(+), 31 deletions(-)
 create mode 100644 hw/sparc64/niagara.c

diff --git a/default-configs/sparc64-softmmu.mak b/default-configs/sparc64-softmmu.mak
index c0cdd64..c581e61 100644
--- a/default-configs/sparc64-softmmu.mak
+++ b/default-configs/sparc64-softmmu.mak
@@ -13,3 +13,5 @@ CONFIG_IDE_CMD646=y
 CONFIG_PCI_APB=y
 CONFIG_MC146818RTC=y
 CONFIG_ISA_TESTDEV=y
+CONFIG_EMPTY_SLOT=y
+CONFIG_SUN4V_RTC=y
diff --git a/hw/sparc64/Makefile.objs b/hw/sparc64/Makefile.objs
index a96b1f8..cf9de21 100644
--- a/hw/sparc64/Makefile.objs
+++ b/hw/sparc64/Makefile.objs
@@ -1,2 +1,3 @@
 obj-y += sparc64.o
 obj-y += sun4u.o
+obj-y += niagara.o
\ No newline at end of file
diff --git a/hw/sparc64/niagara.c b/hw/sparc64/niagara.c
new file mode 100644
index 0000000..828740c
--- /dev/null
+++ b/hw/sparc64/niagara.c
@@ -0,0 +1,177 @@
+/*
+ * QEMU Sun4v/Niagara System Emulator
+ *
+ * Copyright (c) 2016 Artyom Tarasenko
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "cpu.h"
+#include "hw/hw.h"
+#include "hw/boards.h"
+#include "hw/char/serial.h"
+#include "hw/empty_slot.h"
+#include "hw/loader.h"
+#include "hw/sparc/sparc64.h"
+#include "hw/timer/sun4v-rtc.h"
+#include "exec/address-spaces.h"
+#include "sysemu/block-backend.h"
+
+
+typedef struct NiagaraBoardState {
+    MemoryRegion hv_ram;
+    MemoryRegion partition_ram;
+    MemoryRegion nvram;
+    MemoryRegion md_rom;
+    MemoryRegion hv_rom;
+    MemoryRegion vdisk_ram;
+    MemoryRegion prom;
+} NiagaraBoardState;
+
+#define NIAGARA_HV_RAM_BASE 0x100000ULL
+#define NIAGARA_HV_RAM_SIZE 0x3f00000ULL /* 63 MiB */
+
+#define NIAGARA_PARTITION_RAM_BASE 0x80000000ULL
+
+#define NIAGARA_UART_BASE   0x1f10000000ULL
+
+#define NIAGARA_NVRAM_BASE  0x1f11000000ULL
+#define NIAGARA_NVRAM_SIZE  0x2000
+
+#define NIAGARA_MD_ROM_BASE 0x1f12000000ULL
+#define NIAGARA_MD_ROM_SIZE 0x2000
+
+#define NIAGARA_HV_ROM_BASE 0x1f12080000ULL
+#define NIAGARA_HV_ROM_SIZE 0x2000
+
+#define NIAGARA_IOBBASE     0x9800000000ULL
+#define NIAGARA_IOBSIZE     0x0100000000ULL
+
+#define NIAGARA_VDISK_BASE  0x1f40000000ULL
+#define NIAGARA_RTC_BASE    0xfff0c1fff8ULL
+#define NIAGARA_UART_BASE   0x1f10000000ULL
+
+/* Firmware layout
+ *
+ * |------------------|
+ * |   openboot.bin   |
+ * |------------------| PROM_ADDR + OBP_OFFSET
+ * |      q.bin       |
+ * |------------------| PROM_ADDR + Q_OFFSET
+ * |     reset.bin    |
+ * |------------------| PROM_ADDR
+ */
+#define NIAGARA_PROM_BASE   0xfff0000000ULL
+#define NIAGARA_Q_OFFSET    0x10000ULL
+#define NIAGARA_OBP_OFFSET  0x80000ULL
+#define PROM_SIZE_MAX       (4 * 1024 * 1024)
+
+/* Niagara hardware initialisation */
+static void niagara_init(MachineState *machine)
+{
+    NiagaraBoardState *s = g_new(NiagaraBoardState, 1);
+    DriveInfo *dinfo = drive_get_next(IF_PFLASH);
+    MemoryRegion *sysmem = get_system_memory();
+
+    /* init CPUs */
+    sparc64_cpu_devinit(machine->cpu_model, "Sun UltraSparc T1",
+                        NIAGARA_PROM_BASE);
+    /* set up devices */
+    memory_region_allocate_system_memory(&s->hv_ram, NULL, "sun4v-hv.ram",
+                                         NIAGARA_HV_RAM_SIZE);
+    memory_region_add_subregion(sysmem, NIAGARA_HV_RAM_BASE, &s->hv_ram);
+
+    memory_region_allocate_system_memory(&s->partition_ram, NULL,
+                                         "sun4v-partition.ram",
+                                         machine->ram_size);
+    memory_region_add_subregion(sysmem, NIAGARA_PARTITION_RAM_BASE,
+                                &s->partition_ram);
+
+    memory_region_allocate_system_memory(&s->nvram, NULL,
+                                         "sun4v.nvram", NIAGARA_NVRAM_SIZE);
+    memory_region_add_subregion(sysmem, NIAGARA_NVRAM_BASE, &s->nvram);
+    memory_region_allocate_system_memory(&s->md_rom, NULL,
+                                         "sun4v-md.rom", NIAGARA_MD_ROM_SIZE);
+    memory_region_add_subregion(sysmem, NIAGARA_MD_ROM_BASE, &s->md_rom);
+    memory_region_allocate_system_memory(&s->hv_rom, NULL,
+                                         "sun4v-hv.rom", NIAGARA_HV_ROM_SIZE);
+    memory_region_add_subregion(sysmem, NIAGARA_HV_ROM_BASE, &s->hv_rom);
+    memory_region_allocate_system_memory(&s->prom, NULL,
+                                         "sun4v.prom", PROM_SIZE_MAX);
+    memory_region_add_subregion(sysmem, NIAGARA_PROM_BASE, &s->prom);
+
+    rom_add_file_fixed("nvram1", NIAGARA_NVRAM_BASE, -1);
+    rom_add_file_fixed("1up-md.bin", NIAGARA_MD_ROM_BASE, -1);
+    rom_add_file_fixed("1up-hv.bin", NIAGARA_HV_ROM_BASE, -1);
+
+    rom_add_file_fixed("reset.bin", NIAGARA_PROM_BASE, -1);
+    rom_add_file_fixed("q.bin", NIAGARA_PROM_BASE + NIAGARA_Q_OFFSET, -1);
+    rom_add_file_fixed("openboot.bin", NIAGARA_PROM_BASE + NIAGARA_OBP_OFFSET,
+                       -1);
+
+    /* the virtual ramdisk is kind of initrd, but it resides
+       outside of the partition RAM */
+    if (dinfo) {
+        BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
+        int size = blk_getlength(blk);
+        if (size > 0) {
+            memory_region_allocate_system_memory(&s->vdisk_ram, NULL,
+                                                 "sun4v_vdisk.ram", size);
+            memory_region_add_subregion(get_system_memory(),
+                                        NIAGARA_VDISK_BASE, &s->vdisk_ram);
+            dinfo->is_default = 1;
+            rom_add_file_fixed(blk_bs(blk)->filename, NIAGARA_VDISK_BASE, -1);
+        } else {
+            fprintf(stderr, "qemu: could not load ram disk '%s'\n",
+                    blk_bs(blk)->filename);
+            exit(1);
+        }
+    }
+    serial_mm_init(sysmem, NIAGARA_UART_BASE, 0, NULL, 115200,
+                   serial_hds[0], DEVICE_BIG_ENDIAN);
+
+    empty_slot_init(NIAGARA_IOBBASE, NIAGARA_IOBSIZE);
+    sun4v_rtc_init(NIAGARA_RTC_BASE);
+}
+
+static void niagara_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+
+    mc->desc = "Sun4v platform, Niagara";
+    mc->init = niagara_init;
+    mc->max_cpus = 1; /* XXX for now */
+    mc->default_boot_order = "c";
+}
+
+static const TypeInfo niagara_type = {
+    .name = MACHINE_TYPE_NAME("Niagara"),
+    .parent = TYPE_MACHINE,
+    .class_init = niagara_class_init,
+};
+
+static void niagara_register_types(void)
+{
+    type_register_static(&niagara_type);
+}
+
+type_init(niagara_register_types)
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 9372a56..b4d95cc 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -559,7 +559,6 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
 enum {
     sun4u_id = 0,
     sun4v_id = 64,
-    niagara_id,
 };
 
 static const struct hwdef hwdefs[] = {
@@ -577,13 +576,6 @@ static const struct hwdef hwdefs[] = {
         .prom_addr = 0x1fff0000000ULL,
         .console_serial_base = 0,
     },
-    /* Sun4v generic Niagara machine */
-    {
-        .default_cpu_model = "Sun UltraSparc T1",
-        .machine_id = niagara_id,
-        .prom_addr = 0xfff0000000ULL,
-        .console_serial_base = 0xfff0c2c000ULL,
-    },
 };
 
 /* Sun4u hardware initialisation */
@@ -598,12 +590,6 @@ static void sun4v_init(MachineState *machine)
     sun4uv_init(get_system_memory(), machine, &hwdefs[1]);
 }
 
-/* Niagara hardware initialisation */
-static void niagara_init(MachineState *machine)
-{
-    sun4uv_init(get_system_memory(), machine, &hwdefs[2]);
-}
-
 static void sun4u_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
@@ -637,22 +623,6 @@ static const TypeInfo sun4v_type = {
     .class_init = sun4v_class_init,
 };
 
-static void niagara_class_init(ObjectClass *oc, void *data)
-{
-    MachineClass *mc = MACHINE_CLASS(oc);
-
-    mc->desc = "Sun4v platform, Niagara";
-    mc->init = niagara_init;
-    mc->max_cpus = 1; /* XXX for now */
-    mc->default_boot_order = "c";
-}
-
-static const TypeInfo niagara_type = {
-    .name = MACHINE_TYPE_NAME("Niagara"),
-    .parent = TYPE_MACHINE,
-    .class_init = niagara_class_init,
-};
-
 static void sun4u_register_types(void)
 {
     type_register_static(&ebus_info);
@@ -661,7 +631,6 @@ static void sun4u_register_types(void)
 
     type_register_static(&sun4u_type);
     type_register_static(&sun4v_type);
-    type_register_static(&niagara_type);
 }
 
 type_init(sun4u_register_types)
-- 
2.7.2

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

* Re: [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (28 preceding siblings ...)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 29/29] target-sparc: fix up Niagara machine Artyom Tarasenko
@ 2016-10-01 10:48 ` no-reply
  2016-10-11 21:52 ` Mark Cave-Ayland
  30 siblings, 0 replies; 74+ messages in thread
From: no-reply @ 2016-10-01 10:48 UTC (permalink / raw)
  To: atar4qemu; +Cc: famz, qemu-devel, mark.cave-ayland, rth

Hi,

Your series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 1475316333-9776-1-git-send-email-atar4qemu@gmail.com
Subject: [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

# Useful git options
git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git show --no-patch --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]         patchew/1475316333-9776-1-git-send-email-atar4qemu@gmail.com -> patchew/1475316333-9776-1-git-send-email-atar4qemu@gmail.com
 - [tag update]      patchew/20160930233927.GA5887@nyan -> patchew/20160930233927.GA5887@nyan
Switched to a new branch 'test'
c17b250 target-sparc: fix up Niagara machine
02c9695 target-sparc: move common cpu initialisation routines to sparc64.c
eba1f7f target-sparc: implement sun4v RTC
6dd0663 target-sparc: store the UA2005 entries in sun4u format
211748f target-sparc: implement UA2005 ASI_MMU (0x21)
edb2a07 target-sparc: add more registers to dump_mmu
32c8abd target-sparc: implement ST_BLKINIT_ ASIs
f40c298 target-sparc: implement auto-demapping for UA2005 CPUs
86314ed target-sparc: allow 256M sized pages
ca17811 target-sparc: simplify ultrasparc_tsb_pointer
6837140 target-sparc: implement UA2005 TSB Pointers
53e1f54 target-sparc: use SparcV9MMU type for sparc64 I/D-MMUs
8060eb3 target-sparc: replace the last tlb entry when no free entries left
6256e3c target-sparc: ignore writes to UA2005 CPU mondo queue register
7c80032 target-sparc: allow priveleged ASIs in hyperprivileged mode
daa968e target-sparc: use direct address translation in hyperprivileged mode
d5de2f8 target-sparc: fix immediate UA2005 traps
35ad841 target-sparc: implement UA2005 rdhpstate and wrhpstate instructions
6306606 target-sparc: implement UA2005 GL register
3bc6990 target-sparc: implement UA2005 hypervisor traps
cb87df5 target-sparc: hypervisor mode takes over nucleus mode
ff77431 target-sparc: implement UltraSPARC-T1 Strand status ASR
3d702bc target-sparc: implement UA2005 scratchpad registers
6661917 target-sparc: simplify replace_tlb_entry by using TTE_PGSIZE
f849de9 target-sparc: on UA2005 don't deliver Interrupt_level_n IRQs in hypervisor mode
06ed09a target-sparc: add UltraSPARC T1 TLB #defines
752963e target-sparc: add UA2005 TTE bit #defines
cfbb0e2 target-sparc: use explicit mmu register pointers
3bc8bcd target-sparc: don't trap on MMU-fault if MMU is disabled

=== OUTPUT BEGIN ===
Checking PATCH 1/29: target-sparc: don't trap on MMU-fault if MMU is disabled...
Checking PATCH 2/29: target-sparc: use explicit mmu register pointers...
Checking PATCH 3/29: target-sparc: add UA2005 TTE bit #defines...
Checking PATCH 4/29: target-sparc: add UltraSPARC T1 TLB #defines...
Checking PATCH 5/29: target-sparc: on UA2005 don't deliver Interrupt_level_n IRQs in hypervisor mode...
Checking PATCH 6/29: target-sparc: simplify replace_tlb_entry by using TTE_PGSIZE...
Checking PATCH 7/29: target-sparc: implement UA2005 scratchpad registers...
ERROR: code indent should never use tabs
#17: FILE: target-sparc/asi.h:214:
+#define ASI_HYP_SCRATCHPAD^I0x4f /* (4V) Hypervisor scratchpad^I*/$

total: 1 errors, 0 warnings, 60 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 8/29: target-sparc: implement UltraSPARC-T1 Strand status ASR...
Checking PATCH 9/29: target-sparc: hypervisor mode takes over nucleus mode...
Checking PATCH 10/29: target-sparc: implement UA2005 hypervisor traps...
Checking PATCH 11/29: target-sparc: implement UA2005 GL register...
Checking PATCH 12/29: target-sparc: implement UA2005 rdhpstate and wrhpstate instructions...
Checking PATCH 13/29: target-sparc: fix immediate UA2005 traps...
Checking PATCH 14/29: target-sparc: use direct address translation in hyperprivileged mode...
Checking PATCH 15/29: target-sparc: allow priveleged ASIs in hyperprivileged mode...
Checking PATCH 16/29: target-sparc: ignore writes to UA2005 CPU mondo queue register...
Checking PATCH 17/29: target-sparc: replace the last tlb entry when no free entries left...
Checking PATCH 18/29: target-sparc: use SparcV9MMU type for sparc64 I/D-MMUs...
Checking PATCH 19/29: target-sparc: implement UA2005 TSB Pointers...
Checking PATCH 20/29: target-sparc: simplify ultrasparc_tsb_pointer...
Checking PATCH 21/29: target-sparc: allow 256M sized pages...
Checking PATCH 22/29: target-sparc: implement auto-demapping for UA2005 CPUs...
Checking PATCH 23/29: target-sparc: implement ST_BLKINIT_ ASIs...
Checking PATCH 24/29: target-sparc: add more registers to dump_mmu...
Checking PATCH 25/29: target-sparc: implement UA2005 ASI_MMU (0x21)...
Checking PATCH 26/29: target-sparc: store the UA2005 entries in sun4u format...
ERROR: suspect code indent for conditional statements (6, 10)
#88: FILE: target-sparc/ldst_helper.c:2184:
+      if (!(addr & TLB_UST1_IS_REAL_BIT)) {
+          replace_tlb_1bit_lru(env->dtlb, env->dmmu.tag_access,

total: 1 errors, 0 warnings, 84 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 27/29: target-sparc: implement sun4v RTC...
ERROR: do not use C99 // comments
#59: FILE: hw/timer/sun4v-rtc.c:18:
+//#define DEBUG_SUN4V_RTC

total: 1 errors, 0 warnings, 121 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 28/29: target-sparc: move common cpu initialisation routines to sparc64.c...
ERROR: do not use C99 // comments
#55: FILE: hw/sparc64/sparc64.c:33:
+//#define DEBUG_IRQ

ERROR: do not use C99 // comments
#56: FILE: hw/sparc64/sparc64.c:34:
+//#define DEBUG_TIMER

total: 2 errors, 0 warnings, 800 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 29/29: target-sparc: fix up Niagara machine...
=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

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

* Re: [Qemu-devel] [PATCH 18/29] target-sparc: use SparcV9MMU type for sparc64 I/D-MMUs
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 18/29] target-sparc: use SparcV9MMU type for sparc64 I/D-MMUs Artyom Tarasenko
@ 2016-10-10 20:13   ` Richard Henderson
  2016-10-11 13:56     ` Artyom Tarasenko
  0 siblings, 1 reply; 74+ messages in thread
From: Richard Henderson @ 2016-10-10 20:13 UTC (permalink / raw)
  To: Artyom Tarasenko, qemu-devel; +Cc: Mark Cave-Ayland

On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
> -    //typedef struct SparcMMU
> -    union {
> -        uint64_t immuregs[16];
> -        struct {
> -            uint64_t tsb_tag_target;
> -            uint64_t unused_mmu_primary_context;   // use DMMU
> -            uint64_t unused_mmu_secondary_context; // use DMMU
> -            uint64_t sfsr;
> -            uint64_t sfar;
> -            uint64_t tsb;
> -            uint64_t tag_access;
> -            uint64_t virtual_watchpoint;
> -            uint64_t physical_watchpoint;
> -        } immu;
> -    };
> -    union {
> -        uint64_t dmmuregs[16];
> -        struct {
> -            uint64_t tsb_tag_target;
> -            uint64_t mmu_primary_context;
> -            uint64_t mmu_secondary_context;
> -            uint64_t sfsr;
> -            uint64_t sfar;
> -            uint64_t tsb;
> -            uint64_t tag_access;
> -            uint64_t virtual_watchpoint;
> -            uint64_t physical_watchpoint;
> -        } dmmu;
> -    };
> +    SparcV9MMU immu;
> +    SparcV9MMU dmmu;

You'll find this broke sparc64-linux-user.  You'll need

diff --git a/linux-user/main.c b/linux-user/main.c
index bb48260..b1f1347 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -1163,7 +1163,7 @@ void cpu_loop (CPUSPARCState *env)
                  /* XXX: check env->error_code */
                  info.si_code = TARGET_SEGV_MAPERR;
                  if (trapnr == TT_DFAULT)
-                    info._sifields._sigfault._addr = env->dmmuregs[4];
+                    info._sifields._sigfault._addr = env->dmmu.mmuregs[4];
                  else
                      info._sifields._sigfault._addr = cpu_tsptr(env)->tpc;
                  queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);


r~

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

* Re: [Qemu-devel] [PATCH 01/29] target-sparc: don't trap on MMU-fault if MMU is disabled
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 01/29] target-sparc: don't trap on MMU-fault if MMU is disabled Artyom Tarasenko
@ 2016-10-10 21:14   ` Richard Henderson
  2016-10-11 14:00     ` Artyom Tarasenko
  0 siblings, 1 reply; 74+ messages in thread
From: Richard Henderson @ 2016-10-10 21:14 UTC (permalink / raw)
  To: Artyom Tarasenko, qemu-devel; +Cc: Mark Cave-Ayland

On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
>      if (is_exec) {
> -        helper_raise_exception(env, TT_CODE_ACCESS);
> +        if (env->lsu & (IMMU_E)) {
> +            helper_raise_exception(env, TT_CODE_ACCESS);
> +        }
>      } else {
> -        helper_raise_exception(env, TT_DATA_ACCESS);
> +        if (env->lsu & (DMMU_E)) {
> +                helper_raise_exception(env, TT_DATA_ACCESS);
> +        }

The cpu really does no kind of machine check for a hypervisor write to 
0x1122334455667788?


r~

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

* Re: [Qemu-devel] [PATCH 02/29] target-sparc: use explicit mmu register pointers
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 02/29] target-sparc: use explicit mmu register pointers Artyom Tarasenko
@ 2016-10-10 21:18   ` Richard Henderson
  0 siblings, 0 replies; 74+ messages in thread
From: Richard Henderson @ 2016-10-10 21:18 UTC (permalink / raw)
  To: Artyom Tarasenko, qemu-devel; +Cc: Mark Cave-Ayland

On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
> Use explicit register pointers while accessing D/I-MMU registers.
> Trap on access to missing registers.

... unless the mmu is disabled; see patch 1.  ;-)

> Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
> ---
>  target-sparc/cpu.h         |  4 +++
>  target-sparc/ldst_helper.c | 66 +++++++++++++++++++++++++++++++++++++---------
>  2 files changed, 58 insertions(+), 12 deletions(-)

Otherwise,

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

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

* Re: [Qemu-devel] [PATCH 03/29] target-sparc: add UA2005 TTE bit #defines
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 03/29] target-sparc: add UA2005 TTE bit #defines Artyom Tarasenko
@ 2016-10-10 21:22   ` Richard Henderson
  2016-10-10 21:45     ` Artyom Tarasenko
  0 siblings, 1 reply; 74+ messages in thread
From: Richard Henderson @ 2016-10-10 21:22 UTC (permalink / raw)
  To: Artyom Tarasenko, qemu-devel; +Cc: Mark Cave-Ayland

On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
>  #define TTE_VALID_BIT       (1ULL << 63)
>  #define TTE_NFO_BIT         (1ULL << 60)
> +#define TTE_NFO_BIT_UA2005  (1ULL << 62)
>  #define TTE_USED_BIT        (1ULL << 41)
> +#define TTE_USED_BIT_UA2005 (1ULL << 47)
>  #define TTE_LOCKED_BIT      (1ULL <<  6)
> +#define TTE_LOCKED_BIT_UA2005 (1ULL <<  61)
>  #define TTE_SIDEEFFECT_BIT  (1ULL <<  3)
> +#define TTE_SIDEEFFECT_BIT_UA2005 (1ULL <<  11)
>  #define TTE_PRIV_BIT        (1ULL <<  2)
> +#define TTE_PRIV_BIT_UA2005 (1ULL <<  8)
>  #define TTE_W_OK_BIT        (1ULL <<  1)
> +#define TTE_W_OK_BIT_UA2005 (1ULL <<  6)
>  #define TTE_GLOBAL_BIT      (1ULL <<  0)

Hmm.  Would it make more sense to reorg these as

   TTE_US1_*
   TTE_UA2005_*

with some duplication for the bits that are shared?
As is, it's pretty hard to tell which actually change...


r~

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

* Re: [Qemu-devel] [PATCH 05/29] target-sparc: on UA2005 don't deliver Interrupt_level_n IRQs in hypervisor mode
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 05/29] target-sparc: on UA2005 don't deliver Interrupt_level_n IRQs in hypervisor mode Artyom Tarasenko
@ 2016-10-10 21:23   ` Richard Henderson
  0 siblings, 0 replies; 74+ messages in thread
From: Richard Henderson @ 2016-10-10 21:23 UTC (permalink / raw)
  To: Artyom Tarasenko, qemu-devel; +Cc: Mark Cave-Ayland

On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
> As described in Chapter 5.7.6 of the UltraSPARC Architecture 2005,
> outstanding disrupting exceptions that are destined for privileged mode can only
> cause a trap when the virtual processor is in nonprivileged or privileged mode and
> PSTATE.ie = 1. At all other times, they are held pending.
>
> Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
> ---
>  target-sparc/cpu.h | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

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

* Re: [Qemu-devel] [PATCH 06/29] target-sparc: simplify replace_tlb_entry by using TTE_PGSIZE
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 06/29] target-sparc: simplify replace_tlb_entry by using TTE_PGSIZE Artyom Tarasenko
@ 2016-10-10 21:25   ` Richard Henderson
  0 siblings, 0 replies; 74+ messages in thread
From: Richard Henderson @ 2016-10-10 21:25 UTC (permalink / raw)
  To: Artyom Tarasenko, qemu-devel; +Cc: Mark Cave-Ayland

On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
> Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
> ---
>  target-sparc/ldst_helper.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

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

* Re: [Qemu-devel] [PATCH 07/29] target-sparc: implement UA2005 scratchpad registers
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 07/29] target-sparc: implement UA2005 scratchpad registers Artyom Tarasenko
@ 2016-10-10 21:37   ` Richard Henderson
  0 siblings, 0 replies; 74+ messages in thread
From: Richard Henderson @ 2016-10-10 21:37 UTC (permalink / raw)
  To: Artyom Tarasenko, qemu-devel; +Cc: Mark Cave-Ayland

On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
> +    case ASI_SCRATCHPAD: /* UA2005 privileged scratchpad */
> +        if (unlikely((addr >= 0x20) && (addr < 0x30))) {
> +            /* Hyperprivileged access only */
> +            cpu_unassigned_access(cs, addr, false, false, 1, size);
> +        }
> +        /* fall through */
> +    case ASI_HYP_SCRATCHPAD: /* UA2005 hyperprivileged scratchpad */
> +        {
> +            unsigned int i = (addr >> 3) & 0x7;
> +            ret = env->scratch[i];
> +            break;
> +        }

It *might* speed things up a teeny bit to implement ASI_HYP_SCRATCHPAD inline. 
E.g.

   case GET_ASI_HYP_SCRATCH:
     {
       TCGv_ptr tmp = tcg_temp_new_ptr();
#if UINTPTR_MAX == UINT32_MAX
       tcg_gen_extrl_i64_i32(tmp, addr);
       tcg_gen_andi_i32(tmp, tmp, 7 << 3);
#else
       tcg_gen_andi_i64(tmp, addr, 7 << 3);
#endif
       tcg_gen_add_ptr(tmp, tmp, cpu_env);
       tcg_gen_ld_i64(dst, tmp, offsetof(CPUSPARCState, scratch));
       tcg_temp_free_ptr(tmp);
     }
     break;

Of course, you can't do that for ASI_SCRATCHPAD because of the dynamic check 
against ADDR.

> @@ -2056,6 +2068,9 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
>          return;
>      case ASI_INTR_RECEIVE: /* Interrupt data receive */
>          env->ivec_status = val & 0x20;
> +        if (!env->ivec_status) {
> +            cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
> +        }
>          return;

This belongs in some other patch.


r~

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

* Re: [Qemu-devel] [PATCH 08/29] target-sparc: implement UltraSPARC-T1 Strand status ASR
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 08/29] target-sparc: implement UltraSPARC-T1 Strand status ASR Artyom Tarasenko
@ 2016-10-10 21:38   ` Richard Henderson
  0 siblings, 0 replies; 74+ messages in thread
From: Richard Henderson @ 2016-10-10 21:38 UTC (permalink / raw)
  To: Artyom Tarasenko, qemu-devel; +Cc: Mark Cave-Ayland

On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
> Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
> ---
>  target-sparc/translate.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

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

* Re: [Qemu-devel] [PATCH 09/29] target-sparc: hypervisor mode takes over nucleus mode
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 09/29] target-sparc: hypervisor mode takes over nucleus mode Artyom Tarasenko
@ 2016-10-10 21:41   ` Richard Henderson
  2016-10-12 11:33     ` Artyom Tarasenko
  0 siblings, 1 reply; 74+ messages in thread
From: Richard Henderson @ 2016-10-10 21:41 UTC (permalink / raw)
  To: Artyom Tarasenko, qemu-devel; +Cc: Mark Cave-Ayland

On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
> Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
> ---
>  target-sparc/cpu.h | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
> index 0b5c79f..fbeb8d7 100644
> --- a/target-sparc/cpu.h
> +++ b/target-sparc/cpu.h
> @@ -699,10 +699,10 @@ static inline int cpu_mmu_index(CPUSPARCState *env1, bool ifetch)
>  #elif !defined(TARGET_SPARC64)
>      return env1->psrs;
>  #else
> -    if (env1->tl > 0) {
> -        return MMU_NUCLEUS_IDX;
> -    } else if (cpu_hypervisor_mode(env1)) {
> +    if (cpu_hypervisor_mode(env1)) {
>          return MMU_HYPV_IDX;
> +    } else if (env1->tl > 0) {
> +        return MMU_NUCLEUS_IDX;
>      } else if (cpu_supervisor_mode(env1)) {
>          return MMU_KERNEL_IDX;
>      } else {
>

While playing with your patch set, I discovered that we also need a patch to 
get_asi for ASI_N et al to retain MMU_HYPV_IDX, and not decrease privilege. 
This happens *very* early in the prom boot, with the first casx (when casx is 
implemented inline).


r~

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

* Re: [Qemu-devel] [PATCH 03/29] target-sparc: add UA2005 TTE bit #defines
  2016-10-10 21:22   ` Richard Henderson
@ 2016-10-10 21:45     ` Artyom Tarasenko
  2016-10-11  5:50       ` Richard Henderson
  0 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-10 21:45 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Mark Cave-Ayland, qemu-devel, Artyom Tarasenko

10 окт. 2016 г. 23:22 пользователь "Richard Henderson" <rth@twiddle.net>
написал:
>
> On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
>>
>>  #define TTE_VALID_BIT       (1ULL << 63)
>>  #define TTE_NFO_BIT         (1ULL << 60)
>> +#define TTE_NFO_BIT_UA2005  (1ULL << 62)
>>  #define TTE_USED_BIT        (1ULL << 41)
>> +#define TTE_USED_BIT_UA2005 (1ULL << 47)
>>  #define TTE_LOCKED_BIT      (1ULL <<  6)
>> +#define TTE_LOCKED_BIT_UA2005 (1ULL <<  61)
>>  #define TTE_SIDEEFFECT_BIT  (1ULL <<  3)
>> +#define TTE_SIDEEFFECT_BIT_UA2005 (1ULL <<  11)
>>  #define TTE_PRIV_BIT        (1ULL <<  2)
>> +#define TTE_PRIV_BIT_UA2005 (1ULL <<  8)
>>  #define TTE_W_OK_BIT        (1ULL <<  1)
>> +#define TTE_W_OK_BIT_UA2005 (1ULL <<  6)
>>  #define TTE_GLOBAL_BIT      (1ULL <<  0)
>
>
> Hmm.  Would it make more sense to reorg these as
>
>   TTE_US1_*
>   TTE_UA2005_*
>
> with some duplication for the bits that are shared?
> As is, it's pretty hard to tell which actually change...

All of them :-)
I'm not sure about renaming: the US1 format is still used in T1 on the read
access.

On the other hand, it's not used in T2. And then again we don't have the T2
emulation yet.

Artyom

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

* Re: [Qemu-devel] [PATCH 11/29] target-sparc: implement UA2005 GL register
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 11/29] target-sparc: implement UA2005 GL register Artyom Tarasenko
@ 2016-10-10 21:45   ` Richard Henderson
  2016-10-11 13:54     ` Artyom Tarasenko
  0 siblings, 1 reply; 74+ messages in thread
From: Richard Henderson @ 2016-10-10 21:45 UTC (permalink / raw)
  To: Artyom Tarasenko, qemu-devel; +Cc: Mark Cave-Ayland

On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
>                              case 16: // UA2005 gl
>                                  CHECK_IU_FEATURE(dc, GL);
> -                                tcg_gen_st32_tl(cpu_tmp0, cpu_env,
> -                                                offsetof(CPUSPARCState, gl));
> +                                save_state(dc);
> +                                gen_helper_wrgl(cpu_env, cpu_tmp0);
> +                                dc->npc = DYNAMIC_PC;

Why the state save?  gen_helper_wrgl does not raise an exception...


r~

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

* Re: [Qemu-devel] [PATCH 12/29] target-sparc: implement UA2005 rdhpstate and wrhpstate instructions
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 12/29] target-sparc: implement UA2005 rdhpstate and wrhpstate instructions Artyom Tarasenko
@ 2016-10-10 21:46   ` Richard Henderson
  0 siblings, 0 replies; 74+ messages in thread
From: Richard Henderson @ 2016-10-10 21:46 UTC (permalink / raw)
  To: Artyom Tarasenko, qemu-devel; +Cc: Mark Cave-Ayland

On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
> Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
> ---
>  target-sparc/translate.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

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

* Re: [Qemu-devel] [PATCH 03/29] target-sparc: add UA2005 TTE bit #defines
  2016-10-10 21:45     ` Artyom Tarasenko
@ 2016-10-11  5:50       ` Richard Henderson
  2016-10-11 13:51         ` Artyom Tarasenko
  0 siblings, 1 reply; 74+ messages in thread
From: Richard Henderson @ 2016-10-11  5:50 UTC (permalink / raw)
  To: Artyom Tarasenko; +Cc: Mark Cave-Ayland, qemu-devel, Artyom Tarasenko

On 10/10/2016 04:45 PM, Artyom Tarasenko wrote:
>> Hmm.  Would it make more sense to reorg these as
>>
>>   TTE_US1_*
>>   TTE_UA2005_*
>>
>> with some duplication for the bits that are shared?
>> As is, it's pretty hard to tell which actually change...
>
> All of them :-)
> I'm not sure about renaming: the US1 format is still used in T1 on the read
> access.
>
> On the other hand, it's not used in T2. And then again we don't have the T2
> emulation yet.

Oh my.  Different on T2 as well?

I wonder if it would make sense to have different functions with which to fill 
in the CPUClass hooks (or invent new SPARCCPUClass hooks as necessary) for the 
major entry points.

E.g. sparc_cpu_handle_mmu_fault or get_physical_address could be hooked, so 
that the choice of how to handle the tlb miss is chosen at startup time, and 
not during each fault.  One can arrange subroutines as necessary to share code 
between the alternate routines, such as when T1 needs to use parts of US1.

Similarly for out-of-line ASI handling, which is already beyond messy, with 
handling for all cpus thrown in the same switch statement.


r~

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

* Re: [Qemu-devel] [PATCH 14/29] target-sparc: use direct address translation in hyperprivileged mode
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 14/29] target-sparc: use direct address translation in hyperprivileged mode Artyom Tarasenko
@ 2016-10-11  5:55   ` Richard Henderson
  0 siblings, 0 replies; 74+ messages in thread
From: Richard Henderson @ 2016-10-11  5:55 UTC (permalink / raw)
  To: Artyom Tarasenko, qemu-devel; +Cc: Mark Cave-Ayland

[-- Attachment #1: Type: text/plain, Size: 1642 bytes --]

On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
> Implement translation behavior described in the chapter 13.7 of
> "UltraSPARC T1™ Supplement to the UltraSPARC Architecture 2005".
>
> Please note that QEMU doesn't impelement Real->Physical address
> translation. The "Real Address" is always the "Physical Address".
>
> Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
> ---
>  target-sparc/mmu_helper.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/target-sparc/mmu_helper.c b/target-sparc/mmu_helper.c
> index 32b629f..bef63f8 100644
> --- a/target-sparc/mmu_helper.c
> +++ b/target-sparc/mmu_helper.c
> @@ -498,7 +498,8 @@ static int get_physical_address_data(CPUSPARCState *env,
>      int is_user = (mmu_idx == MMU_USER_IDX ||
>                     mmu_idx == MMU_USER_SECONDARY_IDX);
>
> -    if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */
> +    if ((env->lsu & DMMU_E) == 0 || cpu_hypervisor_mode(env)) {
> +        /* direct translation VA -> PA */
>          *physical = ultrasparc_truncate_physical(address);
>          *prot = PAGE_READ | PAGE_WRITE;
>          return 0;
> @@ -617,8 +618,9 @@ static int get_physical_address_code(CPUSPARCState *env,
>      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 */
> +    if (((env->lsu & IMMU_E) == 0) || (env->pstate & PS_RED) != 0
> +        || cpu_hypervisor_mode(env)) {
> +        /* direct translation VA -> PA */

If we let this depend on my MMU_PHYS_IDX patch, this becomes




[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0014-target-sparc-use-direct-address-translation-in-hyper.patch --]
[-- Type: text/x-patch; name="0014-target-sparc-use-direct-address-translation-in-hyper.patch", Size: 4762 bytes --]

>From b1cb710579877de99fdbc03f30f43622057bb4ca Mon Sep 17 00:00:00 2001
From: Artyom Tarasenko <atar4qemu@gmail.com>
Date: Sat, 1 Oct 2016 12:05:18 +0200
Subject: [PATCH 14/31] target-sparc: use direct address translation in
 hyperprivileged mode
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Implement translation behavior described in the chapter 13.7 of
"UltraSPARC T1™ Supplement to the UltraSPARC Architecture 2005".

Please note that QEMU doesn't impelement Real->Physical address
translation. The "Real Address" is always the "Physical Address".

[rth: Therefore we can merge MMU_HYPV_IDX and MMMU_PHYS_IDX.
This brings NB_MMU_MODES <= 6, which avoids the TLBs being
reduced in size, which will increase performance.]

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
Message-Id: <1475316333-9776-15-git-send-email-atar4qemu@gmail.com>
Signed-off-by: Ricahrd Henderson <rth@twiddle.net>
---
 target-sparc/cpu.h       | 20 ++++++++++++++++----
 target-sparc/translate.c | 18 +++++++++++++-----
 2 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index b0df95f..4309df3 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -223,7 +223,7 @@ enum {
 #if !defined(TARGET_SPARC64)
 #define NB_MMU_MODES 3
 #else
-#define NB_MMU_MODES 7
+#define NB_MMU_MODES 6
 typedef struct trap_state {
     uint64_t tpc;
     uint64_t tnpc;
@@ -665,8 +665,7 @@ int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);
 #define MMU_KERNEL_IDX 2
 #define MMU_KERNEL_SECONDARY_IDX 3
 #define MMU_NUCLEUS_IDX 4
-#define MMU_HYPV_IDX   5
-#define MMU_PHYS_IDX   6
+#define MMU_PHYS_IDX   5
 #else
 #define MMU_USER_IDX   0
 #define MMU_KERNEL_IDX 1
@@ -688,6 +687,11 @@ static inline int cpu_supervisor_mode(CPUSPARCState *env1)
 {
     return env1->pstate & PS_PRIV;
 }
+#else
+static inline int cpu_supervisor_mode(CPUSPARCState *env1)
+{
+    return env1->psrs;
+}
 #endif
 
 static inline int cpu_mmu_index(CPUSPARCState *env, bool ifetch)
@@ -707,7 +711,7 @@ static inline int cpu_mmu_index(CPUSPARCState *env, bool ifetch)
         : (env->lsu & DMMU_E) == 0) {
         return MMU_PHYS_IDX;
     } else if (cpu_hypervisor_mode(env)) {
-        return MMU_HYPV_IDX;
+        return MMU_PHYS_IDX;
     } else if (env->tl > 0) {
         return MMU_NUCLEUS_IDX;
     } else if (cpu_supervisor_mode(env)) {
@@ -755,6 +759,8 @@ trap_state* cpu_tsptr(CPUSPARCState* env);
 #define TB_FLAG_MMU_MASK     7
 #define TB_FLAG_FPU_ENABLED  (1 << 4)
 #define TB_FLAG_AM_ENABLED   (1 << 5)
+#define TB_FLAG_SUPER        (1 << 6)
+#define TB_FLAG_HYPER        (1 << 7)
 #define TB_FLAG_ASI_SHIFT    24
 
 static inline void cpu_get_tb_cpu_state(CPUSPARCState *env, target_ulong *pc,
@@ -764,7 +770,13 @@ static inline void cpu_get_tb_cpu_state(CPUSPARCState *env, target_ulong *pc,
     *pc = env->pc;
     *cs_base = env->npc;
     flags = cpu_mmu_index(env, false);
+    if (cpu_supervisor_mode(env)) {
+        flags |= TB_FLAG_SUPER;
+    }
 #ifdef TARGET_SPARC64
+    if (cpu_hypervisor_mode(env)) {
+        flags |= TB_FLAG_HYPER;
+    }
     if (env->pstate & PS_AM) {
         flags |= TB_FLAG_AM_ENABLED;
     }
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 5d7929b..cdec52b 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -72,9 +72,13 @@ typedef struct DisasContext {
     target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */
     int is_br;
     int mem_idx;
-    int fpu_enabled;
-    int address_mask_32bit;
-    int singlestep;
+    bool fpu_enabled;
+    bool address_mask_32bit;
+    bool singlestep;
+#ifndef CONFIG_USER_ONLY
+    bool supervisor;
+    bool hypervisor;
+#endif
     uint32_t cc_op;  /* current CC operation */
     struct TranslationBlock *tb;
     sparc_def_t *def;
@@ -283,9 +287,9 @@ static void gen_move_Q(DisasContext *dc, unsigned int rd, unsigned int rs)
 #define hypervisor(dc) 0
 #endif
 #else
-#define supervisor(dc) (dc->mem_idx >= MMU_KERNEL_IDX)
+#define supervisor(dc) (dc->supervisor)
 #ifdef TARGET_SPARC64
-#define hypervisor(dc) (dc->mem_idx == MMU_HYPV_IDX)
+#define hypervisor(dc) (dc->hypervisor)
 #else
 #endif
 #endif
@@ -5695,6 +5699,10 @@ void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
     dc->fpu_enabled = tb_fpu_enabled(tb->flags);
     dc->address_mask_32bit = tb_am_enabled(tb->flags);
     dc->singlestep = (cs->singlestep_enabled || singlestep);
+#ifndef CONFIG_USER_ONLY
+    dc->supervisor = (tb->flags & TB_FLAG_SUPER) != 0;
+    dc->hypervisor = (tb->flags & TB_FLAG_HYPER) != 0;
+#endif
 #ifdef TARGET_SPARC64
     dc->fprs_dirty = 0;
     dc->asi = (tb->flags >> TB_FLAG_ASI_SHIFT) & 0xff;
-- 
2.7.4


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

* Re: [Qemu-devel] [PATCH 03/29] target-sparc: add UA2005 TTE bit #defines
  2016-10-11  5:50       ` Richard Henderson
@ 2016-10-11 13:51         ` Artyom Tarasenko
  2016-10-11 15:08           ` Richard Henderson
  0 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-11 13:51 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Mark Cave-Ayland, qemu-devel

On Tue, Oct 11, 2016 at 7:50 AM, Richard Henderson <rth@twiddle.net> wrote:
> On 10/10/2016 04:45 PM, Artyom Tarasenko wrote:
>>>
>>> Hmm.  Would it make more sense to reorg these as
>>>
>>>   TTE_US1_*
>>>   TTE_UA2005_*
>>>
>>> with some duplication for the bits that are shared?
>>> As is, it's pretty hard to tell which actually change...
>>
>>
>> All of them :-)
>> I'm not sure about renaming: the US1 format is still used in T1 on the
>> read
>> access.
>>
>> On the other hand, it's not used in T2. And then again we don't have the
>> T2
>> emulation yet.
>
>
> Oh my.  Different on T2 as well?

T2 has more used bits, and can not use the US1 format, I think.

> I wonder if it would make sense to have different functions with which to
> fill in the CPUClass hooks (or invent new SPARCCPUClass hooks as necessary)
> for the major entry points.
>
> E.g. sparc_cpu_handle_mmu_fault or get_physical_address could be hooked, so
> that the choice of how to handle the tlb miss is chosen at startup time, and
> not during each fault.  One can arrange subroutines as necessary to share
> code between the alternate routines, such as when T1 needs to use parts of
> US1.

Yes, I plan to do it once I get to T2 emulation.

> Similarly for out-of-line ASI handling, which is already beyond messy, with
> handling for all cpus thrown in the same switch statement.

Yes. I think we need to split SPARCv9 standard ASIs from CPU-specific
ones, call cpu-specific handlers first and standard handler
afterwards.
But not in this series.

Artyom

-- 
Regards,
Artyom Tarasenko

SPARC and PPC PReP under qemu blog: http://tyom.blogspot.com/search/label/qemu

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

* Re: [Qemu-devel] [PATCH 11/29] target-sparc: implement UA2005 GL register
  2016-10-10 21:45   ` Richard Henderson
@ 2016-10-11 13:54     ` Artyom Tarasenko
  0 siblings, 0 replies; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-11 13:54 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, Mark Cave-Ayland

On Mon, Oct 10, 2016 at 11:45 PM, Richard Henderson <rth@twiddle.net> wrote:
> On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
>>
>>                              case 16: // UA2005 gl
>>                                  CHECK_IU_FEATURE(dc, GL);
>> -                                tcg_gen_st32_tl(cpu_tmp0, cpu_env,
>> -                                                offsetof(CPUSPARCState,
>> gl));
>> +                                save_state(dc);
>> +                                gen_helper_wrgl(cpu_env, cpu_tmp0);
>> +                                dc->npc = DYNAMIC_PC;
>
>
> Why the state save?  gen_helper_wrgl does not raise an exception...
>

Good point. Will remove.


-- 
Regards,
Artyom Tarasenko

SPARC and PPC PReP under qemu blog: http://tyom.blogspot.com/search/label/qemu

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

* Re: [Qemu-devel] [PATCH 18/29] target-sparc: use SparcV9MMU type for sparc64 I/D-MMUs
  2016-10-10 20:13   ` Richard Henderson
@ 2016-10-11 13:56     ` Artyom Tarasenko
  0 siblings, 0 replies; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-11 13:56 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, Mark Cave-Ayland

On Mon, Oct 10, 2016 at 10:13 PM, Richard Henderson <rth@twiddle.net> wrote:
> On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
>>
>> -    //typedef struct SparcMMU
>> -    union {
>> -        uint64_t immuregs[16];
>> -        struct {
>> -            uint64_t tsb_tag_target;
>> -            uint64_t unused_mmu_primary_context;   // use DMMU
>> -            uint64_t unused_mmu_secondary_context; // use DMMU
>> -            uint64_t sfsr;
>> -            uint64_t sfar;
>> -            uint64_t tsb;
>> -            uint64_t tag_access;
>> -            uint64_t virtual_watchpoint;
>> -            uint64_t physical_watchpoint;
>> -        } immu;
>> -    };
>> -    union {
>> -        uint64_t dmmuregs[16];
>> -        struct {
>> -            uint64_t tsb_tag_target;
>> -            uint64_t mmu_primary_context;
>> -            uint64_t mmu_secondary_context;
>> -            uint64_t sfsr;
>> -            uint64_t sfar;
>> -            uint64_t tsb;
>> -            uint64_t tag_access;
>> -            uint64_t virtual_watchpoint;
>> -            uint64_t physical_watchpoint;
>> -        } dmmu;
>> -    };
>> +    SparcV9MMU immu;
>> +    SparcV9MMU dmmu;
>
>
> You'll find this broke sparc64-linux-user.  You'll need
>
> diff --git a/linux-user/main.c b/linux-user/main.c
> index bb48260..b1f1347 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -1163,7 +1163,7 @@ void cpu_loop (CPUSPARCState *env)
>                  /* XXX: check env->error_code */
>                  info.si_code = TARGET_SEGV_MAPERR;
>                  if (trapnr == TT_DFAULT)
> -                    info._sifields._sigfault._addr = env->dmmuregs[4];
> +                    info._sifields._sigfault._addr = env->dmmu.mmuregs[4];
>                  else
>                      info._sifields._sigfault._addr = cpu_tsptr(env)->tpc;
>                  queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
>

Will add this. Thanks!


-- 
Regards,
Artyom Tarasenko

SPARC and PPC PReP under qemu blog: http://tyom.blogspot.com/search/label/qemu

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

* Re: [Qemu-devel] [PATCH 15/29] target-sparc: allow priveleged ASIs in hyperprivileged mode
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 15/29] target-sparc: allow priveleged ASIs " Artyom Tarasenko
@ 2016-10-11 13:57   ` Richard Henderson
  0 siblings, 0 replies; 74+ messages in thread
From: Richard Henderson @ 2016-10-11 13:57 UTC (permalink / raw)
  To: Artyom Tarasenko, qemu-devel; +Cc: Mark Cave-Ayland

[-- Attachment #1: Type: text/plain, Size: 753 bytes --]

On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
> @@ -1295,10 +1295,9 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
>
>      asi &= 0xff;
>
> -    if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
> -        || (cpu_has_hypervisor(env)
> -            && asi >= 0x30 && asi < 0x80
> -            && !(env->hpstate & HS_PRIV))) {
> +    if (((!cpu_hypervisor_mode(env)) && asi < 0x80)
> +        && (((env->pstate & PS_PRIV) == 0)
> +        || (cpu_has_hypervisor(env) && asi >= 0x30))) {
>          helper_raise_exception(env, TT_PRIV_ACT);
>      }

You need the same change in get_asi.

And perhaps pull out this check as do_check_asi so that we don't need to 
replicate it.  On top of my sparc tree this becomes the following.


r~

[-- Attachment #2: 0015-target-sparc-allow-priveleged-ASIs-in-hyperprivilege.patch --]
[-- Type: text/x-patch, Size: 3484 bytes --]

>From 12425652f5cea3453c6fcf728431c73c449c5311 Mon Sep 17 00:00:00 2001
From: Artyom Tarasenko <atar4qemu@gmail.com>
Date: Sat, 1 Oct 2016 12:05:19 +0200
Subject: [PATCH 15/31] target-sparc: allow priveleged ASIs in hyperprivileged
 mode

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
Message-Id: <1475316333-9776-16-git-send-email-atar4qemu@gmail.com>
---
 target-sparc/ldst_helper.c | 32 ++++++++++++++++----------------
 target-sparc/translate.c   | 15 ++++++++-------
 2 files changed, 24 insertions(+), 23 deletions(-)

diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index 612c82d..fec8139 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -298,6 +298,20 @@ static inline target_ulong asi_address_mask(CPUSPARCState *env,
         return addr;
     }
 }
+
+static inline void do_check_asi(CPUSPARCState *env, int asi, uintptr_t ra)
+{
+    /* ASIs >= 0x80 are user mode.
+     * ASIs >= 0x30 are hyper mode (or super if hyper is not available).
+     * ASIs <= 0x2f are super mode.
+     */
+    if (asi < 0x80
+        && !cpu_hypervisor_mode(env)
+        && (!cpu_supervisor_mode(env)
+            || (asi >= 0x30 && cpu_has_hypervisor(env)))) {
+        cpu_raise_exception_ra(env, TT_PRIV_ACT, ra);
+    }
+}
 #endif
 
 static void do_check_align(CPUSPARCState *env, target_ulong addr,
@@ -1122,14 +1136,7 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
 #endif
 
     asi &= 0xff;
-
-    if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
-        || (cpu_has_hypervisor(env)
-            && asi >= 0x30 && asi < 0x80
-            && !(env->hpstate & HS_PRIV))) {
-        cpu_raise_exception_ra(env, TT_PRIV_ACT, GETPC());
-    }
-
+    do_check_asi(env, asi, GETPC());
     do_check_align(env, addr, size - 1, GETPC());
     addr = asi_address_mask(env, asi, addr);
 
@@ -1427,14 +1434,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
 #endif
 
     asi &= 0xff;
-
-    if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
-        || (cpu_has_hypervisor(env)
-            && asi >= 0x30 && asi < 0x80
-            && !(env->hpstate & HS_PRIV))) {
-        cpu_raise_exception_ra(env, TT_PRIV_ACT, GETPC());
-    }
-
+    do_check_asi(env, asi, GETPC());
     do_check_align(env, addr, size - 1, GETPC());
     addr = asi_address_mask(env, asi, addr);
 
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index cdec52b..29727ac 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -2119,13 +2119,14 @@ static DisasASI get_asi(DisasContext *dc, int insn, TCGMemOp memop)
     if (IS_IMM) {
         asi = dc->asi;
     }
-    /* With v9, all asis below 0x80 are privileged.  */
-    /* ??? We ought to check cpu_has_hypervisor, but we didn't copy
-       down that bit into DisasContext.  For the moment that's ok,
-       since the direct implementations below doesn't have any ASIs
-       in the restricted [0x30, 0x7f] range, and the check will be
-       done properly in the helper.  */
-    if (!supervisor(dc) && asi < 0x80) {
+    /* ASIs >= 0x80 are user mode.
+     * ASIs >= 0x30 are hyper mode (or super if hyper is not available).
+     * ASIs <= 0x2f are super mode.
+     */
+    if (asi < 0x80
+        && !hypervisor(dc)
+        && (!supervisor(dc)
+            || (asi >= 0x30 && (dc->def->features & CPU_FEATURE_HYPV)))) {
         gen_exception(dc, TT_PRIV_ACT);
         type = GET_ASI_EXCP;
     } else {
-- 
2.7.4


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

* Re: [Qemu-devel] [PATCH 16/29] target-sparc: ignore writes to UA2005 CPU mondo queue register
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 16/29] target-sparc: ignore writes to UA2005 CPU mondo queue register Artyom Tarasenko
@ 2016-10-11 13:57   ` Richard Henderson
  0 siblings, 0 replies; 74+ messages in thread
From: Richard Henderson @ 2016-10-11 13:57 UTC (permalink / raw)
  To: Artyom Tarasenko, qemu-devel; +Cc: Mark Cave-Ayland

On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
> Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
> ---
>  target-sparc/ldst_helper.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
> index 70febcb..250c23f 100644
> --- a/target-sparc/ldst_helper.c
> +++ b/target-sparc/ldst_helper.c
> @@ -2100,7 +2100,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
>              env->scratch[i] = val;
>              return;
>          }
> -
> +    case ASI_QUEUE: /* UA2005 CPU mondo queue */
>      case ASI_DCACHE_DATA: /* D-cache data */
>      case ASI_DCACHE_TAG: /* D-cache tag access */
>      case ASI_ESTATE_ERROR_EN: /* E-cache error enable */
>

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

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

* Re: [Qemu-devel] [PATCH 01/29] target-sparc: don't trap on MMU-fault if MMU is disabled
  2016-10-10 21:14   ` Richard Henderson
@ 2016-10-11 14:00     ` Artyom Tarasenko
  2016-10-11 14:50       ` Richard Henderson
  0 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-11 14:00 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, Mark Cave-Ayland

On Mon, Oct 10, 2016 at 11:14 PM, Richard Henderson <rth@twiddle.net> wrote:
> On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
>>
>>      if (is_exec) {
>> -        helper_raise_exception(env, TT_CODE_ACCESS);
>> +        if (env->lsu & (IMMU_E)) {
>> +            helper_raise_exception(env, TT_CODE_ACCESS);
>> +        }
>>      } else {
>> -        helper_raise_exception(env, TT_DATA_ACCESS);
>> +        if (env->lsu & (DMMU_E)) {
>> +                helper_raise_exception(env, TT_DATA_ACCESS);
>> +        }
>
>
> The cpu really does no kind of machine check for a hypervisor write to
> 0x1122334455667788?

A bare metal machine would raise Real Translation Exception. But since
we don't do real addresses...

Artyom

-- 
Regards,
Artyom Tarasenko

SPARC and PPC PReP under qemu blog: http://tyom.blogspot.com/search/label/qemu

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

* Re: [Qemu-devel] [PATCH 20/29] target-sparc: simplify ultrasparc_tsb_pointer
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 20/29] target-sparc: simplify ultrasparc_tsb_pointer Artyom Tarasenko
@ 2016-10-11 14:05   ` Richard Henderson
  2016-10-11 14:08     ` Artyom Tarasenko
  0 siblings, 1 reply; 74+ messages in thread
From: Richard Henderson @ 2016-10-11 14:05 UTC (permalink / raw)
  To: Artyom Tarasenko, qemu-devel; +Cc: Mark Cave-Ayland

On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
> Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
> ---
>  target-sparc/ldst_helper.c | 51 ++++++++++++++--------------------------------
>  1 file changed, 15 insertions(+), 36 deletions(-)

Perhaps this should be folded with patch 19.

> +static uint64_t ultrasparc_tsb_pointer(CPUSPARCState *env, SparcV9MMU mmu,
> +                                       int idx)

Did you really mean to pass the whole mmu structure by value?  That's 16 words 
that need to be copied to perform this call.  I'm sure it would be better to 
pass by (const?) reference.


r~

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

* Re: [Qemu-devel] [PATCH 21/29] target-sparc: allow 256M sized pages
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 21/29] target-sparc: allow 256M sized pages Artyom Tarasenko
@ 2016-10-11 14:07   ` Richard Henderson
  0 siblings, 0 replies; 74+ messages in thread
From: Richard Henderson @ 2016-10-11 14:07 UTC (permalink / raw)
  To: Artyom Tarasenko, qemu-devel; +Cc: Mark Cave-Ayland

On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
> +    uint64_t mask = 1ULL + ~(8192ULL << 3 * TTE_PGSIZE(tlb->tte));

Not the first time it has appeared in this patch series, but I find the "1 + ~" 
idiom to be strange.  Surely plain old "-" is clearer.


r~

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

* Re: [Qemu-devel] [PATCH 20/29] target-sparc: simplify ultrasparc_tsb_pointer
  2016-10-11 14:05   ` Richard Henderson
@ 2016-10-11 14:08     ` Artyom Tarasenko
  0 siblings, 0 replies; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-11 14:08 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, Mark Cave-Ayland

On Tue, Oct 11, 2016 at 4:05 PM, Richard Henderson <rth@twiddle.net> wrote:
> On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
>>
>> Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
>> ---
>>  target-sparc/ldst_helper.c | 51
>> ++++++++++++++--------------------------------
>>  1 file changed, 15 insertions(+), 36 deletions(-)
>
>
> Perhaps this should be folded with patch 19.
>
>> +static uint64_t ultrasparc_tsb_pointer(CPUSPARCState *env, SparcV9MMU
>> mmu,
>> +                                       int idx)
>
>
> Did you really mean to pass the whole mmu structure by value?  That's 16
> words that need to be copied to perform this call.  I'm sure it would be
> better to pass by (const?) reference.

Indeed. Thanks.

-- 
Regards,
Artyom Tarasenko

SPARC and PPC PReP under qemu blog: http://tyom.blogspot.com/search/label/qemu

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

* Re: [Qemu-devel] [PATCH 22/29] target-sparc: implement auto-demapping for UA2005 CPUs
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 22/29] target-sparc: implement auto-demapping for UA2005 CPUs Artyom Tarasenko
@ 2016-10-11 14:17   ` Richard Henderson
  0 siblings, 0 replies; 74+ messages in thread
From: Richard Henderson @ 2016-10-11 14:17 UTC (permalink / raw)
  To: Artyom Tarasenko, qemu-devel; +Cc: Mark Cave-Ayland

On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
> +                uint64_t size = 1024ULL * (8 << 3 * TTE_PGSIZE(tlb[i].tte));

Your previous expression, 8192 << 3 * TTE_PGSIZE is clearer.  Perhaps this 
itself should be extracted as a macro?

> +                if ((new_vaddr == vaddr) || ((new_vaddr < (vaddr + size))
> +                    && (vaddr < (new_vaddr + new_size)))) {

Please drop the unnecessary parenthesis and line up the expressions properly,

   if (new_vaddr == vaddr
       || (new_vaddr < vaddr + size
           && vaddr < new_vaddr + new_size)) {

so that one can tell at a glance how the subexpressions are nested.


r~

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

* Re: [Qemu-devel] [PATCH 23/29] target-sparc: implement ST_BLKINIT_ ASIs
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 23/29] target-sparc: implement ST_BLKINIT_ ASIs Artyom Tarasenko
@ 2016-10-11 14:22   ` Richard Henderson
  0 siblings, 0 replies; 74+ messages in thread
From: Richard Henderson @ 2016-10-11 14:22 UTC (permalink / raw)
  To: Artyom Tarasenko, qemu-devel; +Cc: Mark Cave-Ayland

On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
> @@ -2234,13 +2234,24 @@ static void gen_st_asi(DisasContext *dc, TCGv src, TCGv addr,
>      switch (da.type) {
>      case GET_ASI_EXCP:
>          break;
> -    case GET_ASI_DTWINX: /* Reserved for stda.  */
> -        gen_exception(dc, TT_ILL_INSN);
> -        break;
>      case GET_ASI_DIRECT:
>          gen_address_mask(dc, addr);
>          tcg_gen_qemu_st_tl(src, addr, da.mem_idx, da.memop);
>          break;
> +    case GET_ASI_DTWINX:
> +#ifndef TARGET_SPARC64
> +        gen_exception(dc, TT_ILL_INSN);
> +        break;
> +#else
> +        if (!(dc->def->features & CPU_FEATURE_HYPV)) {
> +            /* Pre OpenSPARC CPUs don't have these */
> +            gen_exception(dc, TT_ILL_INSN);
> +            return;
> +        }
> +        /* in OpenSPARC T1+ CPUs TWINX ASIs in store instructions
> +         * are ST_BLKINIT_ ASIs */
> +        /* fall through */
> +#endif
>      default:

Of course, "DTWINX" is short for "DIRECT TWINX", so you don't need to fall into 
the default case, but into the DIRECT case.

Indeed, built upon my patch set that would reach g_assert_not_reached, since I 
removed all the cases that are handled inline.


r~

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

* Re: [Qemu-devel] [PATCH 24/29] target-sparc: add more registers to dump_mmu
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 24/29] target-sparc: add more registers to dump_mmu Artyom Tarasenko
@ 2016-10-11 14:22   ` Richard Henderson
  0 siblings, 0 replies; 74+ messages in thread
From: Richard Henderson @ 2016-10-11 14:22 UTC (permalink / raw)
  To: Artyom Tarasenko, qemu-devel; +Cc: Mark Cave-Ayland

On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
> Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
> ---
>  target-sparc/mmu_helper.c | 2 ++
>  1 file changed, 2 insertions(+)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

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

* Re: [Qemu-devel] [PATCH 25/29] target-sparc: implement UA2005 ASI_MMU (0x21)
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 25/29] target-sparc: implement UA2005 ASI_MMU (0x21) Artyom Tarasenko
@ 2016-10-11 14:25   ` Richard Henderson
  0 siblings, 0 replies; 74+ messages in thread
From: Richard Henderson @ 2016-10-11 14:25 UTC (permalink / raw)
  To: Artyom Tarasenko, qemu-devel; +Cc: Mark Cave-Ayland

On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
> +          switch ((addr >> 3) & 0x3) {
> +          case 1:
> +              env->dmmu.mmu_primary_context = val;
> +              env->immu.mmu_primary_context = val;
> +              /* can be optimized to only flush MMU_USER_PRIMARY_IDX
> +                 and MMU_KERNEL_PRIMARY_IDX entries */
> +              tlb_flush(CPU(cpu), 1);

This is easy to do with

     tlb_flush_by_mmuidx(CPU(cpu), MMU_USER_IDX, MMU_KERNEL_IDX, -1);

etc.  And it does seem like it would be helpful to avoid flushing MMU_HYPV_IDX 
(or MMU_PHYS_IDX as I would rename it).


r~

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

* Re: [Qemu-devel] [PATCH 26/29] target-sparc: store the UA2005 entries in sun4u format
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 26/29] target-sparc: store the UA2005 entries in sun4u format Artyom Tarasenko
@ 2016-10-11 14:31   ` Richard Henderson
  2016-10-12 11:28     ` Artyom Tarasenko
  0 siblings, 1 reply; 74+ messages in thread
From: Richard Henderson @ 2016-10-11 14:31 UTC (permalink / raw)
  To: Artyom Tarasenko, qemu-devel; +Cc: Mark Cave-Ayland

On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
> +    sun4u_tte = TTE_PA(sun4v_tte) | (sun4v_tte & TTE_VALID_BIT);
> +    sun4u_tte |= (sun4v_tte & 3ULL) << 61;
> +    sun4u_tte |= (sun4v_tte & TTE_NFO_BIT_UA2005) >> 2;
> +    sun4u_tte |= (sun4v_tte & TTE_USED_BIT_UA2005) >> 6;
> +    sun4u_tte |= (sun4v_tte & TTE_W_OK_BIT_UA2005) >> 5;
> +    sun4u_tte |= (sun4v_tte & TTE_SIDEEFFECT_BIT_UA2005) >> 8;
> +    sun4u_tte |= (sun4v_tte & TTE_PRIV_BIT_UA2005) >> 6;
> +    sun4u_tte |= (sun4v_tte & TTE_LOCKED_BIT_UA2005) >> 55;

I think it might be clearer to use

#define CONVERT_BIT(X, SRC, DST) \
     (SRC > DST ? (X) / (SRC / DST) & (DST) : ((X) & SRC) * (DST / SRC))

   sun4u_tte |= CONVERT_BIT(sun4v_tte, TTE_NFO_BIT_UA2005, TTE_NFO_BIT);

The compiler folds all of the constants down to the same code, but you don't 
have to manually compute the shift counts.


r~

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

* Re: [Qemu-devel] [PATCH 28/29] target-sparc: move common cpu initialisation routines to sparc64.c
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 28/29] target-sparc: move common cpu initialisation routines to sparc64.c Artyom Tarasenko
@ 2016-10-11 14:34   ` Richard Henderson
  0 siblings, 0 replies; 74+ messages in thread
From: Richard Henderson @ 2016-10-11 14:34 UTC (permalink / raw)
  To: Artyom Tarasenko, qemu-devel; +Cc: Mark Cave-Ayland

On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
> Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
> ---
>  hw/sparc64/Makefile.objs   |   1 +
>  hw/sparc64/sparc64.c       | 378 +++++++++++++++++++++++++++++++++++++++++++++
>  hw/sparc64/sun4u.c         | 351 +----------------------------------------
>  hw/timer/sun4v-rtc.c       |   2 +-
>  include/hw/sparc/sparc64.h |   5 +
>  5 files changed, 389 insertions(+), 348 deletions(-)
>  create mode 100644 hw/sparc64/sparc64.c
>  create mode 100644 include/hw/sparc/sparc64.h

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

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

* Re: [Qemu-devel] [PATCH 29/29] target-sparc: fix up Niagara machine
  2016-10-01 10:05 ` [Qemu-devel] [PATCH 29/29] target-sparc: fix up Niagara machine Artyom Tarasenko
@ 2016-10-11 14:43   ` Richard Henderson
  2016-10-12 11:27     ` Artyom Tarasenko
  0 siblings, 1 reply; 74+ messages in thread
From: Richard Henderson @ 2016-10-11 14:43 UTC (permalink / raw)
  To: Artyom Tarasenko, qemu-devel; +Cc: Mark Cave-Ayland

On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
> Remove the Niagara stub implementation from sun4u.c and add a machine,
> compatible with Legion simulator from the OpenSPARC T1 project.
>
> The machine uses the firmware supplied with the OpenSPARC T1 project,
> http://download.oracle.com/technetwork/systems/opensparc/OpenSPARCT1_Arch.1.5.tar.bz2
> in the directory S10image/, and is able to boot the supplied Solaris 10 image.
>
> Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>

Reviewed-by: Richard Henderson <rth@twiddle.net>

What do you plan to do about the roms?  Since they're open source, I don't see 
any reason we couldn't commit them into pc-bios/.  Of course if we do that ...

> +    rom_add_file_fixed("nvram1", NIAGARA_NVRAM_BASE, -1);
> +    rom_add_file_fixed("1up-md.bin", NIAGARA_MD_ROM_BASE, -1);
> +    rom_add_file_fixed("1up-hv.bin", NIAGARA_HV_ROM_BASE, -1);
> +
> +    rom_add_file_fixed("reset.bin", NIAGARA_PROM_BASE, -1);
> +    rom_add_file_fixed("q.bin", NIAGARA_PROM_BASE + NIAGARA_Q_OFFSET, -1);
> +    rom_add_file_fixed("openboot.bin", NIAGARA_PROM_BASE + NIAGARA_OBP_OFFSET,
> +                       -1);

... these would surely need better names.


r~

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

* Re: [Qemu-devel] [PATCH 01/29] target-sparc: don't trap on MMU-fault if MMU is disabled
  2016-10-11 14:00     ` Artyom Tarasenko
@ 2016-10-11 14:50       ` Richard Henderson
  2016-10-12 13:24         ` Artyom Tarasenko
  0 siblings, 1 reply; 74+ messages in thread
From: Richard Henderson @ 2016-10-11 14:50 UTC (permalink / raw)
  To: Artyom Tarasenko; +Cc: Mark Cave-Ayland, qemu-devel

On 10/11/2016 09:00 AM, Artyom Tarasenko wrote:
> On Mon, Oct 10, 2016 at 11:14 PM, Richard Henderson <rth@twiddle.net> wrote:
>> On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
>>>
>>>      if (is_exec) {
>>> -        helper_raise_exception(env, TT_CODE_ACCESS);
>>> +        if (env->lsu & (IMMU_E)) {
>>> +            helper_raise_exception(env, TT_CODE_ACCESS);
>>> +        }
>>>      } else {
>>> -        helper_raise_exception(env, TT_DATA_ACCESS);
>>> +        if (env->lsu & (DMMU_E)) {
>>> +                helper_raise_exception(env, TT_DATA_ACCESS);
>>> +        }
>>
>>
>> The cpu really does no kind of machine check for a hypervisor write to
>> 0x1122334455667788?
>
> A bare metal machine would raise Real Translation Exception. But since
> we don't do real addresses...

I was asking about an errant access from the hypervisor itself.  I would have 
thought the guest running without an mmu would be running with real addresses, 
but the hypervisor itself would be running in physical addresses.

But that said, we can't just let the access go completely unreported, surely. 
We can think as if we do real addresses, but with a 1-1 mapping to physical. 
So at least for !cpu_hypervisor_mode(env), a Real Translation Exception would 
seem to be totally justified.


r~

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

* Re: [Qemu-devel] [PATCH 03/29] target-sparc: add UA2005 TTE bit #defines
  2016-10-11 13:51         ` Artyom Tarasenko
@ 2016-10-11 15:08           ` Richard Henderson
  2016-10-12 11:18             ` Artyom Tarasenko
  0 siblings, 1 reply; 74+ messages in thread
From: Richard Henderson @ 2016-10-11 15:08 UTC (permalink / raw)
  To: Artyom Tarasenko; +Cc: Mark Cave-Ayland, qemu-devel

On 10/11/2016 08:51 AM, Artyom Tarasenko wrote:
> On Tue, Oct 11, 2016 at 7:50 AM, Richard Henderson <rth@twiddle.net> wrote:
>> On 10/10/2016 04:45 PM, Artyom Tarasenko wrote:
>>>>
>>>> Hmm.  Would it make more sense to reorg these as
>>>>
>>>>   TTE_US1_*
>>>>   TTE_UA2005_*
>>>>
>>>> with some duplication for the bits that are shared?
>>>> As is, it's pretty hard to tell which actually change...
>>>
>>>
>>> All of them :-)
>>> I'm not sure about renaming: the US1 format is still used in T1 on the
>>> read
>>> access.
>>>
>>> On the other hand, it's not used in T2. And then again we don't have the
>>> T2
>>> emulation yet.
>>
>>
>> Oh my.  Different on T2 as well?
>
> T2 has more used bits, and can not use the US1 format, I think.
>
>> I wonder if it would make sense to have different functions with which to
>> fill in the CPUClass hooks (or invent new SPARCCPUClass hooks as necessary)
>> for the major entry points.
>>
>> E.g. sparc_cpu_handle_mmu_fault or get_physical_address could be hooked, so
>> that the choice of how to handle the tlb miss is chosen at startup time, and
>> not during each fault.  One can arrange subroutines as necessary to share
>> code between the alternate routines, such as when T1 needs to use parts of
>> US1.
>
> Yes, I plan to do it once I get to T2 emulation.

Ok.

>> Similarly for out-of-line ASI handling, which is already beyond messy, with
>> handling for all cpus thrown in the same switch statement.
>
> Yes. I think we need to split SPARCv9 standard ASIs from CPU-specific
> ones, call cpu-specific handlers first and standard handler
> afterwards.
> But not in this series.

Fair enough.

What I would most like to see, for QEMU, is an artificial sun4v compatible 
machine that implements a "hardware" page table walk.  I.e. no use of 
SparcTLBEntry, but walking the page tables directly.

Because QEMU can then satisfy a page lookup internally, without having to 
longjmp out of a memory reference in progress in order to restart the cpu for 
the software TLB miss handler, the emulation runs about 30-50% faster.  At 
least that has been my experience emulating Alpha vs MIPS.

It would require custom roms, but those should be fairly easy to modify from 
the existing source.


r~

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

* Re: [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation
  2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
                   ` (29 preceding siblings ...)
  2016-10-01 10:48 ` [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation no-reply
@ 2016-10-11 21:52 ` Mark Cave-Ayland
  2016-10-12 11:58   ` Artyom Tarasenko
  30 siblings, 1 reply; 74+ messages in thread
From: Mark Cave-Ayland @ 2016-10-11 21:52 UTC (permalink / raw)
  To: Artyom Tarasenko, qemu-devel; +Cc: Richard Henderson

On 01/10/16 11:05, Artyom Tarasenko wrote:

> This patch series adds a Niagara OpenSPARC T1 sun4v machine.
> The most important new feature: it can boot Solaris 10 / sparc64.
> The machine uses a firmware released by Sun as a part of the OpenSPARC project.
> 
> The series are available under:
> https://github.com/artyom-tarasenko/qemu/tree/sun4v-for-upstream
> 
> The command line for booting Solaris 10 / sparc:
> 
> sparc64-softmmu/qemu-system-sparc64 -M Niagara -L /path/to/S10image/ -nographic -m 256 -drive if=pflash,readonly=on,file=/path/to/S10image/disk.s10hw2
> 
> More info under
> http://tyom.blogspot.de/2016/10/qemu-sun4vniagara-target-went-public.html
> 
> Artyom Tarasenko (29):
>   target-sparc: don't trap on MMU-fault if MMU is disabled
>   target-sparc: use explicit mmu register pointers
>   target-sparc: add UA2005 TTE bit #defines
>   target-sparc: add UltraSPARC T1 TLB #defines
>   target-sparc: on UA2005 don't deliver Interrupt_level_n IRQs in
>     hypervisor mode
>   target-sparc: simplify replace_tlb_entry by using TTE_PGSIZE
>   target-sparc: implement UA2005 scratchpad registers
>   target-sparc: implement UltraSPARC-T1 Strand status ASR
>   target-sparc: hypervisor mode takes over nucleus mode
>   target-sparc: implement UA2005 hypervisor traps
>   target-sparc: implement UA2005 GL register
>   target-sparc: implement UA2005 rdhpstate and wrhpstate instructions
>   target-sparc: fix immediate UA2005 traps
>   target-sparc: use direct address translation in hyperprivileged mode
>   target-sparc: allow priveleged ASIs in hyperprivileged mode
>   target-sparc: ignore writes to UA2005 CPU mondo queue register
>   target-sparc: replace the last tlb entry when no free entries left
>   target-sparc: use SparcV9MMU type for sparc64 I/D-MMUs
>   target-sparc: implement UA2005 TSB Pointers
>   target-sparc: simplify ultrasparc_tsb_pointer
>   target-sparc: allow 256M sized pages
>   target-sparc: implement auto-demapping for UA2005 CPUs
>   target-sparc: implement ST_BLKINIT_ ASIs
>   target-sparc: add more registers to dump_mmu
>   target-sparc: implement UA2005 ASI_MMU (0x21)
>   target-sparc: store the UA2005 entries in sun4u format
>   target-sparc: implement sun4v RTC
>   target-sparc: move common cpu initialisation routines to sparc64.c
>   target-sparc: fix up Niagara machine
> 
>  MAINTAINERS                         |   6 +
>  default-configs/sparc64-softmmu.mak |   2 +
>  hw/sparc64/Makefile.objs            |   2 +
>  hw/sparc64/niagara.c                | 177 ++++++++++++++++
>  hw/sparc64/sparc64.c                | 378 +++++++++++++++++++++++++++++++++++
>  hw/sparc64/sun4u.c                  | 382 +----------------------------------
>  hw/timer/Makefile.objs              |   2 +
>  hw/timer/sun4v-rtc.c                | 103 ++++++++++
>  include/hw/sparc/sparc64.h          |   5 +
>  include/hw/timer/sun4v-rtc.h        |   1 +
>  target-sparc/asi.h                  |   1 +
>  target-sparc/cpu.c                  |  13 +-
>  target-sparc/cpu.h                  |  79 +++++---
>  target-sparc/helper.h               |   1 +
>  target-sparc/int64_helper.c         |  42 +++-
>  target-sparc/ldst_helper.c          | 388 ++++++++++++++++++++++++++++--------
>  target-sparc/machine.c              |   4 +-
>  target-sparc/mmu_helper.c           |  28 +--
>  target-sparc/translate.c            |  42 +++-
>  target-sparc/win_helper.c           |  46 ++++-
>  20 files changed, 1171 insertions(+), 531 deletions(-)
>  create mode 100644 hw/sparc64/niagara.c
>  create mode 100644 hw/sparc64/sparc64.c
>  create mode 100644 hw/timer/sun4v-rtc.c
>  create mode 100644 include/hw/sparc/sparc64.h
>  create mode 100644 include/hw/timer/sun4v-rtc.h

In general I think this is a great patchset, although obviously Richard
has further comments on inner workings - excellent job! My only minor
nit is whether -M Niagara should be lower-case to match the rest of the
machine names.

One improvement I'd like to see is a patch to update the documentation
to reflect the new sun4v machine, in particular covering where to get
hold of the PROM/disk images as per the final commit message. And also
does it make sense for us to try and distribute parts of the ROM images
with QEMU, and if so which parts and can we legally do that?

Finally my current understanding is that the atomics/target-sparc
patches will go in first and then this patchset will be rebased upon
those - is that correct? If so, I'll wait for the rebased version before
I give it a thorough test over my sun4u images.


ATB,

Mark.

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

* Re: [Qemu-devel] [PATCH 03/29] target-sparc: add UA2005 TTE bit #defines
  2016-10-11 15:08           ` Richard Henderson
@ 2016-10-12 11:18             ` Artyom Tarasenko
  2016-10-12 13:25               ` Richard Henderson
  0 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-12 11:18 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Mark Cave-Ayland, qemu-devel

On Tue, Oct 11, 2016 at 5:08 PM, Richard Henderson <rth@twiddle.net> wrote:
> On 10/11/2016 08:51 AM, Artyom Tarasenko wrote:
>>
>> On Tue, Oct 11, 2016 at 7:50 AM, Richard Henderson <rth@twiddle.net>
>> wrote:
>>>
>>> On 10/10/2016 04:45 PM, Artyom Tarasenko wrote:
>>>>>
>>>>>
>>>>> Hmm.  Would it make more sense to reorg these as
>>>>>
>>>>>   TTE_US1_*
>>>>>   TTE_UA2005_*
>>>>>
>>>>> with some duplication for the bits that are shared?
>>>>> As is, it's pretty hard to tell which actually change...
>>>>
>>>>
>>>>
>>>> All of them :-)
>>>> I'm not sure about renaming: the US1 format is still used in T1 on the
>>>> read
>>>> access.
>>>>
>>>> On the other hand, it's not used in T2. And then again we don't have the
>>>> T2
>>>> emulation yet.
>>>
>>>
>>>
>>> Oh my.  Different on T2 as well?
>>
>>
>> T2 has more used bits, and can not use the US1 format, I think.
>>
>>> I wonder if it would make sense to have different functions with which to
>>> fill in the CPUClass hooks (or invent new SPARCCPUClass hooks as
>>> necessary)
>>> for the major entry points.
>>>
>>> E.g. sparc_cpu_handle_mmu_fault or get_physical_address could be hooked,
>>> so
>>> that the choice of how to handle the tlb miss is chosen at startup time,
>>> and
>>> not during each fault.  One can arrange subroutines as necessary to share
>>> code between the alternate routines, such as when T1 needs to use parts
>>> of
>>> US1.
>>
>>
>> Yes, I plan to do it once I get to T2 emulation.
>
>
> Ok.
>
>>> Similarly for out-of-line ASI handling, which is already beyond messy,
>>> with
>>> handling for all cpus thrown in the same switch statement.
>>
>>
>> Yes. I think we need to split SPARCv9 standard ASIs from CPU-specific
>> ones, call cpu-specific handlers first and standard handler
>> afterwards.
>> But not in this series.
>
>
> Fair enough.
>
> What I would most like to see, for QEMU, is an artificial sun4v compatible
> machine that implements a "hardware" page table walk.  I.e. no use of
> SparcTLBEntry, but walking the page tables directly.
>
> Because QEMU can then satisfy a page lookup internally, without having to
> longjmp out of a memory reference in progress in order to restart the cpu
> for the software TLB miss handler, the emulation runs about 30-50% faster.
> At least that has been my experience emulating Alpha vs MIPS.
>
> It would require custom roms, but those should be fairly easy to modify from
> the existing source.
>

Maybe it's even possible without the modifications. For instance,
implement the table walk compatible with the current hypervisor, and
then just add possibility to overlay hypervisor call using some CPU
feature flag.


-- 
Regards,
Artyom Tarasenko

SPARC and PPC PReP under qemu blog: http://tyom.blogspot.com/search/label/qemu

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

* Re: [Qemu-devel] [PATCH 29/29] target-sparc: fix up Niagara machine
  2016-10-11 14:43   ` Richard Henderson
@ 2016-10-12 11:27     ` Artyom Tarasenko
  0 siblings, 0 replies; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-12 11:27 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, Mark Cave-Ayland

On Tue, Oct 11, 2016 at 4:43 PM, Richard Henderson <rth@twiddle.net> wrote:
> On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
>>
>> Remove the Niagara stub implementation from sun4u.c and add a machine,
>> compatible with Legion simulator from the OpenSPARC T1 project.
>>
>> The machine uses the firmware supplied with the OpenSPARC T1 project,
>>
>> http://download.oracle.com/technetwork/systems/opensparc/OpenSPARCT1_Arch.1.5.tar.bz2
>> in the directory S10image/, and is able to boot the supplied Solaris 10
>> image.
>>
>> Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
>
>
> Reviewed-by: Richard Henderson <rth@twiddle.net>
>
> What do you plan to do about the roms?  Since they're open source, I don't
> see any reason we couldn't commit them into pc-bios/.

I have no short term plans on that: at least some of the
OBP/Hypervisor code is released under CDDL, which has some
incompatibilities with GPL.

>Of course if we do that ...
>
>> +    rom_add_file_fixed("nvram1", NIAGARA_NVRAM_BASE, -1);
>> +    rom_add_file_fixed("1up-md.bin", NIAGARA_MD_ROM_BASE, -1);
>> +    rom_add_file_fixed("1up-hv.bin", NIAGARA_HV_ROM_BASE, -1);
>> +
>> +    rom_add_file_fixed("reset.bin", NIAGARA_PROM_BASE, -1);
>> +    rom_add_file_fixed("q.bin", NIAGARA_PROM_BASE + NIAGARA_Q_OFFSET,
>> -1);
>> +    rom_add_file_fixed("openboot.bin", NIAGARA_PROM_BASE +
>> NIAGARA_OBP_OFFSET,
>> +                       -1);
>
>
> ... these would surely need better names.

Absolutely.


-- 
Regards,
Artyom Tarasenko

SPARC and PPC PReP under qemu blog: http://tyom.blogspot.com/search/label/qemu

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

* Re: [Qemu-devel] [PATCH 26/29] target-sparc: store the UA2005 entries in sun4u format
  2016-10-11 14:31   ` Richard Henderson
@ 2016-10-12 11:28     ` Artyom Tarasenko
  0 siblings, 0 replies; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-12 11:28 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, Mark Cave-Ayland

On Tue, Oct 11, 2016 at 4:31 PM, Richard Henderson <rth@twiddle.net> wrote:
> On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
>>
>> +    sun4u_tte = TTE_PA(sun4v_tte) | (sun4v_tte & TTE_VALID_BIT);
>> +    sun4u_tte |= (sun4v_tte & 3ULL) << 61;
>> +    sun4u_tte |= (sun4v_tte & TTE_NFO_BIT_UA2005) >> 2;
>> +    sun4u_tte |= (sun4v_tte & TTE_USED_BIT_UA2005) >> 6;
>> +    sun4u_tte |= (sun4v_tte & TTE_W_OK_BIT_UA2005) >> 5;
>> +    sun4u_tte |= (sun4v_tte & TTE_SIDEEFFECT_BIT_UA2005) >> 8;
>> +    sun4u_tte |= (sun4v_tte & TTE_PRIV_BIT_UA2005) >> 6;
>> +    sun4u_tte |= (sun4v_tte & TTE_LOCKED_BIT_UA2005) >> 55;
>
>
> I think it might be clearer to use
>
> #define CONVERT_BIT(X, SRC, DST) \
>     (SRC > DST ? (X) / (SRC / DST) & (DST) : ((X) & SRC) * (DST / SRC))
>
>   sun4u_tte |= CONVERT_BIT(sun4v_tte, TTE_NFO_BIT_UA2005, TTE_NFO_BIT);
>
> The compiler folds all of the constants down to the same code, but you don't
> have to manually compute the shift counts.

Nice! Will do.


-- 
Regards,
Artyom Tarasenko

SPARC and PPC PReP under qemu blog: http://tyom.blogspot.com/search/label/qemu

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

* Re: [Qemu-devel] [PATCH 09/29] target-sparc: hypervisor mode takes over nucleus mode
  2016-10-10 21:41   ` Richard Henderson
@ 2016-10-12 11:33     ` Artyom Tarasenko
  2016-10-12 13:29       ` Richard Henderson
  0 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-12 11:33 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, Mark Cave-Ayland

On Mon, Oct 10, 2016 at 11:41 PM, Richard Henderson <rth@twiddle.net> wrote:
> On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
>>
>> Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
>> ---
>>  target-sparc/cpu.h | 6 +++---
>>  1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
>> index 0b5c79f..fbeb8d7 100644
>> --- a/target-sparc/cpu.h
>> +++ b/target-sparc/cpu.h
>> @@ -699,10 +699,10 @@ static inline int cpu_mmu_index(CPUSPARCState *env1,
>> bool ifetch)
>>  #elif !defined(TARGET_SPARC64)
>>      return env1->psrs;
>>  #else
>> -    if (env1->tl > 0) {
>> -        return MMU_NUCLEUS_IDX;
>> -    } else if (cpu_hypervisor_mode(env1)) {
>> +    if (cpu_hypervisor_mode(env1)) {
>>          return MMU_HYPV_IDX;
>> +    } else if (env1->tl > 0) {
>> +        return MMU_NUCLEUS_IDX;
>>      } else if (cpu_supervisor_mode(env1)) {
>>          return MMU_KERNEL_IDX;
>>      } else {
>>
>
> While playing with your patch set, I discovered that we also need a patch to
> get_asi for ASI_N et al to retain MMU_HYPV_IDX, and not decrease privilege.
> This happens *very* early in the prom boot, with the first casx (when casx
> is implemented inline).

Why is the bug not visible with the current master? I wonder if we
have a symmetrical bug somewhere.


-- 
Regards,
Artyom Tarasenko

SPARC and PPC PReP under qemu blog: http://tyom.blogspot.com/search/label/qemu

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

* Re: [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation
  2016-10-11 21:52 ` Mark Cave-Ayland
@ 2016-10-12 11:58   ` Artyom Tarasenko
  0 siblings, 0 replies; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-12 11:58 UTC (permalink / raw)
  To: Mark Cave-Ayland; +Cc: qemu-devel, Richard Henderson

On Tue, Oct 11, 2016 at 11:52 PM, Mark Cave-Ayland
<mark.cave-ayland@ilande.co.uk> wrote:
> On 01/10/16 11:05, Artyom Tarasenko wrote:
>
>> This patch series adds a Niagara OpenSPARC T1 sun4v machine.
>> The most important new feature: it can boot Solaris 10 / sparc64.
>> The machine uses a firmware released by Sun as a part of the OpenSPARC project.
>>
>> The series are available under:
>> https://github.com/artyom-tarasenko/qemu/tree/sun4v-for-upstream
>>
>> The command line for booting Solaris 10 / sparc:
>>
>> sparc64-softmmu/qemu-system-sparc64 -M Niagara -L /path/to/S10image/ -nographic -m 256 -drive if=pflash,readonly=on,file=/path/to/S10image/disk.s10hw2
>>
>> More info under
>> http://tyom.blogspot.de/2016/10/qemu-sun4vniagara-target-went-public.html
>>
>> Artyom Tarasenko (29):
>>   target-sparc: don't trap on MMU-fault if MMU is disabled
>>   target-sparc: use explicit mmu register pointers
>>   target-sparc: add UA2005 TTE bit #defines
>>   target-sparc: add UltraSPARC T1 TLB #defines
>>   target-sparc: on UA2005 don't deliver Interrupt_level_n IRQs in
>>     hypervisor mode
>>   target-sparc: simplify replace_tlb_entry by using TTE_PGSIZE
>>   target-sparc: implement UA2005 scratchpad registers
>>   target-sparc: implement UltraSPARC-T1 Strand status ASR
>>   target-sparc: hypervisor mode takes over nucleus mode
>>   target-sparc: implement UA2005 hypervisor traps
>>   target-sparc: implement UA2005 GL register
>>   target-sparc: implement UA2005 rdhpstate and wrhpstate instructions
>>   target-sparc: fix immediate UA2005 traps
>>   target-sparc: use direct address translation in hyperprivileged mode
>>   target-sparc: allow priveleged ASIs in hyperprivileged mode
>>   target-sparc: ignore writes to UA2005 CPU mondo queue register
>>   target-sparc: replace the last tlb entry when no free entries left
>>   target-sparc: use SparcV9MMU type for sparc64 I/D-MMUs
>>   target-sparc: implement UA2005 TSB Pointers
>>   target-sparc: simplify ultrasparc_tsb_pointer
>>   target-sparc: allow 256M sized pages
>>   target-sparc: implement auto-demapping for UA2005 CPUs
>>   target-sparc: implement ST_BLKINIT_ ASIs
>>   target-sparc: add more registers to dump_mmu
>>   target-sparc: implement UA2005 ASI_MMU (0x21)
>>   target-sparc: store the UA2005 entries in sun4u format
>>   target-sparc: implement sun4v RTC
>>   target-sparc: move common cpu initialisation routines to sparc64.c
>>   target-sparc: fix up Niagara machine
>>
>>  MAINTAINERS                         |   6 +
>>  default-configs/sparc64-softmmu.mak |   2 +
>>  hw/sparc64/Makefile.objs            |   2 +
>>  hw/sparc64/niagara.c                | 177 ++++++++++++++++
>>  hw/sparc64/sparc64.c                | 378 +++++++++++++++++++++++++++++++++++
>>  hw/sparc64/sun4u.c                  | 382 +----------------------------------
>>  hw/timer/Makefile.objs              |   2 +
>>  hw/timer/sun4v-rtc.c                | 103 ++++++++++
>>  include/hw/sparc/sparc64.h          |   5 +
>>  include/hw/timer/sun4v-rtc.h        |   1 +
>>  target-sparc/asi.h                  |   1 +
>>  target-sparc/cpu.c                  |  13 +-
>>  target-sparc/cpu.h                  |  79 +++++---
>>  target-sparc/helper.h               |   1 +
>>  target-sparc/int64_helper.c         |  42 +++-
>>  target-sparc/ldst_helper.c          | 388 ++++++++++++++++++++++++++++--------
>>  target-sparc/machine.c              |   4 +-
>>  target-sparc/mmu_helper.c           |  28 +--
>>  target-sparc/translate.c            |  42 +++-
>>  target-sparc/win_helper.c           |  46 ++++-
>>  20 files changed, 1171 insertions(+), 531 deletions(-)
>>  create mode 100644 hw/sparc64/niagara.c
>>  create mode 100644 hw/sparc64/sparc64.c
>>  create mode 100644 hw/timer/sun4v-rtc.c
>>  create mode 100644 include/hw/sparc/sparc64.h
>>  create mode 100644 include/hw/timer/sun4v-rtc.h
>
> In general I think this is a great patchset, although obviously Richard
> has further comments on inner workings - excellent job! My only minor
> nit is whether -M Niagara should be lower-case to match the rest of the
> machine names.

I kept it the way it had been originally introduced, but am ok with changing it.

> One improvement I'd like to see is a patch to update the documentation
> to reflect the new sun4v machine, in particular covering where to get
> hold of the PROM/disk images as per the final commit message.

You mean the target-sparc/TODO, or is there more documentation?
I'd rather put it on the http://wiki.qemu.org/SPARC page.

> And also
> does it make sense for us to try and distribute parts of the ROM images
> with QEMU, and if so which parts and can we legally do that?

Good question. I'm not a lawyer, so I had no plans on distributing them.

> Finally my current understanding is that the atomics/target-sparc
> patches will go in first and then this patchset will be rebased upon
> those - is that correct? If so, I'll wait for the rebased version before
> I give it a thorough test over my sun4u images.

Ok. I'm off till the end of October, so let's postpone this series
till November or so.


-- 
Regards,
Artyom Tarasenko

SPARC and PPC PReP under qemu blog: http://tyom.blogspot.com/search/label/qemu

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

* Re: [Qemu-devel] [PATCH 01/29] target-sparc: don't trap on MMU-fault if MMU is disabled
  2016-10-11 14:50       ` Richard Henderson
@ 2016-10-12 13:24         ` Artyom Tarasenko
  0 siblings, 0 replies; 74+ messages in thread
From: Artyom Tarasenko @ 2016-10-12 13:24 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Mark Cave-Ayland, qemu-devel

On Tue, Oct 11, 2016 at 4:50 PM, Richard Henderson <rth@twiddle.net> wrote:
> On 10/11/2016 09:00 AM, Artyom Tarasenko wrote:
>>
>> On Mon, Oct 10, 2016 at 11:14 PM, Richard Henderson <rth@twiddle.net>
>> wrote:
>>>
>>> On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
>>>>
>>>>
>>>>      if (is_exec) {
>>>> -        helper_raise_exception(env, TT_CODE_ACCESS);
>>>> +        if (env->lsu & (IMMU_E)) {
>>>> +            helper_raise_exception(env, TT_CODE_ACCESS);
>>>> +        }
>>>>      } else {
>>>> -        helper_raise_exception(env, TT_DATA_ACCESS);
>>>> +        if (env->lsu & (DMMU_E)) {
>>>> +                helper_raise_exception(env, TT_DATA_ACCESS);
>>>> +        }
>>>
>>>
>>>
>>> The cpu really does no kind of machine check for a hypervisor write to
>>> 0x1122334455667788?
>>
>>
>> A bare metal machine would raise Real Translation Exception. But since
>> we don't do real addresses...
>
>
> I was asking about an errant access from the hypervisor itself.  I would
> have thought the guest running without an mmu would be running with real
> addresses, but the hypervisor itself would be running in physical addresses.
>
> But that said, we can't just let the access go completely unreported,
> surely. We can think as if we do real addresses, but with a 1-1 mapping to
> physical. So at least for !cpu_hypervisor_mode(env), a Real Translation
> Exception would seem to be totally justified.

Good point. data_access_error/instruction_access_error shall happen
in the hypervisor mode, otherwise it shall be data_real_translation_miss /
instruction_real_translation_miss.

Will change it, thanks.

-- 
Regards,
Artyom Tarasenko

SPARC and PPC PReP under qemu blog: http://tyom.blogspot.com/search/label/qemu

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

* Re: [Qemu-devel] [PATCH 03/29] target-sparc: add UA2005 TTE bit #defines
  2016-10-12 11:18             ` Artyom Tarasenko
@ 2016-10-12 13:25               ` Richard Henderson
  0 siblings, 0 replies; 74+ messages in thread
From: Richard Henderson @ 2016-10-12 13:25 UTC (permalink / raw)
  To: Artyom Tarasenko; +Cc: Mark Cave-Ayland, qemu-devel

On 10/12/2016 06:18 AM, Artyom Tarasenko wrote:
>> What I would most like to see, for QEMU, is an artificial sun4v compatible
>> machine that implements a "hardware" page table walk.  I.e. no use of
>> SparcTLBEntry, but walking the page tables directly.
>>
>> Because QEMU can then satisfy a page lookup internally, without having to
>> longjmp out of a memory reference in progress in order to restart the cpu
>> for the software TLB miss handler, the emulation runs about 30-50% faster.
>> At least that has been my experience emulating Alpha vs MIPS.
>>
>> It would require custom roms, but those should be fairly easy to modify from
>> the existing source.
>>
>
> Maybe it's even possible without the modifications. For instance,
> implement the table walk compatible with the current hypervisor, and
> then just add possibility to overlay hypervisor call using some CPU
> feature flag.

Maybe so.  What we lack is being given direct access to the page table base. 
But we know that the CPU structure is in the hypervisor shadow register 0, and 
that offset CPU_ROOT is the page table base.

As long as we're willing to hard-code these two facts concerning any rom we 
care to load, we could in fact implement the tlb miss success path inside QEMU. 
  We would let the rom re-do the work for the tlb miss failure path, on the way 
to raising the exception with the supervisor.


r~

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

* Re: [Qemu-devel] [PATCH 09/29] target-sparc: hypervisor mode takes over nucleus mode
  2016-10-12 11:33     ` Artyom Tarasenko
@ 2016-10-12 13:29       ` Richard Henderson
  2016-11-01 18:12         ` Artyom Tarasenko
  0 siblings, 1 reply; 74+ messages in thread
From: Richard Henderson @ 2016-10-12 13:29 UTC (permalink / raw)
  To: Artyom Tarasenko; +Cc: qemu-devel, Mark Cave-Ayland

On 10/12/2016 06:33 AM, Artyom Tarasenko wrote:
> On Mon, Oct 10, 2016 at 11:41 PM, Richard Henderson <rth@twiddle.net> wrote:
>> On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
>>>
>>> Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
>>> ---
>>>  target-sparc/cpu.h | 6 +++---
>>>  1 file changed, 3 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
>>> index 0b5c79f..fbeb8d7 100644
>>> --- a/target-sparc/cpu.h
>>> +++ b/target-sparc/cpu.h
>>> @@ -699,10 +699,10 @@ static inline int cpu_mmu_index(CPUSPARCState *env1,
>>> bool ifetch)
>>>  #elif !defined(TARGET_SPARC64)
>>>      return env1->psrs;
>>>  #else
>>> -    if (env1->tl > 0) {
>>> -        return MMU_NUCLEUS_IDX;
>>> -    } else if (cpu_hypervisor_mode(env1)) {
>>> +    if (cpu_hypervisor_mode(env1)) {
>>>          return MMU_HYPV_IDX;
>>> +    } else if (env1->tl > 0) {
>>> +        return MMU_NUCLEUS_IDX;
>>>      } else if (cpu_supervisor_mode(env1)) {
>>>          return MMU_KERNEL_IDX;
>>>      } else {
>>>
>>
>> While playing with your patch set, I discovered that we also need a patch to
>> get_asi for ASI_N et al to retain MMU_HYPV_IDX, and not decrease privilege.
>> This happens *very* early in the prom boot, with the first casx (when casx
>> is implemented inline).
>
> Why is the bug not visible with the current master? I wonder if we
> have a symmetrical bug somewhere.

Hmm, I dunno.  I assume it has something to do with casx being implemented out 
of line, and using helper_ld_asi instead of tcg_gen_qemu_ld_tl directly.


r~

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

* Re: [Qemu-devel] [PATCH 09/29] target-sparc: hypervisor mode takes over nucleus mode
  2016-10-12 13:29       ` Richard Henderson
@ 2016-11-01 18:12         ` Artyom Tarasenko
  2016-11-01 19:29           ` Richard Henderson
  0 siblings, 1 reply; 74+ messages in thread
From: Artyom Tarasenko @ 2016-11-01 18:12 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, Mark Cave-Ayland

On Wed, Oct 12, 2016 at 3:29 PM, Richard Henderson <rth@twiddle.net> wrote:
> On 10/12/2016 06:33 AM, Artyom Tarasenko wrote:
>>
>> On Mon, Oct 10, 2016 at 11:41 PM, Richard Henderson <rth@twiddle.net>
>> wrote:
>>>
>>> On 10/01/2016 05:05 AM, Artyom Tarasenko wrote:
>>>>
>>>>
>>>> Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
>>>> ---
>>>>  target-sparc/cpu.h | 6 +++---
>>>>  1 file changed, 3 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
>>>> index 0b5c79f..fbeb8d7 100644
>>>> --- a/target-sparc/cpu.h
>>>> +++ b/target-sparc/cpu.h
>>>> @@ -699,10 +699,10 @@ static inline int cpu_mmu_index(CPUSPARCState
>>>> *env1,
>>>> bool ifetch)
>>>>  #elif !defined(TARGET_SPARC64)
>>>>      return env1->psrs;
>>>>  #else
>>>> -    if (env1->tl > 0) {
>>>> -        return MMU_NUCLEUS_IDX;
>>>> -    } else if (cpu_hypervisor_mode(env1)) {
>>>> +    if (cpu_hypervisor_mode(env1)) {
>>>>          return MMU_HYPV_IDX;
>>>> +    } else if (env1->tl > 0) {
>>>> +        return MMU_NUCLEUS_IDX;
>>>>      } else if (cpu_supervisor_mode(env1)) {
>>>>          return MMU_KERNEL_IDX;
>>>>      } else {
>>>>
>>>
>>> While playing with your patch set, I discovered that we also need a patch
>>> to
>>> get_asi for ASI_N et al to retain MMU_HYPV_IDX, and not decrease
>>> privilege.
>>> This happens *very* early in the prom boot, with the first casx (when
>>> casx
>>> is implemented inline).
>>
>>
>> Why is the bug not visible with the current master? I wonder if we
>> have a symmetrical bug somewhere.
>
>
> Hmm, I dunno.  I assume it has something to do with casx being implemented
> out of line, and using helper_ld_asi instead of tcg_gen_qemu_ld_tl directly.
>

Actually I don't see where the  privilege is decreased: get_asi uses a
local mem_idx variable, the dc->mem_idx is retained.
What patch do you have in mind?


-- 
Regards,
Artyom Tarasenko

SPARC and PPC PReP under qemu blog: http://tyom.blogspot.com/search/label/qemu

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

* Re: [Qemu-devel] [PATCH 09/29] target-sparc: hypervisor mode takes over nucleus mode
  2016-11-01 18:12         ` Artyom Tarasenko
@ 2016-11-01 19:29           ` Richard Henderson
  0 siblings, 0 replies; 74+ messages in thread
From: Richard Henderson @ 2016-11-01 19:29 UTC (permalink / raw)
  To: Artyom Tarasenko; +Cc: qemu-devel, Mark Cave-Ayland

[-- Attachment #1: Type: text/plain, Size: 918 bytes --]

On 11/01/2016 12:12 PM, Artyom Tarasenko wrote:
>>>> While playing with your patch set, I discovered that we also need a
>>>> patch to get_asi for ASI_N et al to retain MMU_HYPV_IDX, and not
>>>> decrease privilege. This happens *very* early in the prom boot, with
>>>> the first casx (when casx is implemented inline).
>>>
>>> Why is the bug not visible with the current master? I wonder if we
>>> have a symmetrical bug somewhere.
>>
>>
>> Hmm, I dunno.  I assume it has something to do with casx being implemented
>> out of line, and using helper_ld_asi instead of tcg_gen_qemu_ld_tl directly.
>
> Actually I don't see where the  privilege is decreased: get_asi uses a
> local mem_idx variable, the dc->mem_idx is retained.
> What patch do you have in mind?

Like this.  Anyway, now that PMM has my atomic and sparc patch sets, you should 
be able to see the problem yourself with your patch set and your rom.


r~

[-- Attachment #2: z1 --]
[-- Type: text/plain, Size: 927 bytes --]

From fa75ae10f26b7611f9f36013a11b066766b9faee Mon Sep 17 00:00:00 2001
From: Richard Henderson <rth@twiddle.net>
Date: Mon, 10 Oct 2016 15:52:49 -0500
Subject: target-sparc: Override ASI_N for hypervisor

Signed-off-by: Richard Henderson <rth@twiddle.net>

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 43f89d4..2b80d79 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -2139,7 +2139,11 @@ static DisasASI get_asi(DisasContext *dc, int insn, TCGMemOp memop)
         case ASI_TWINX_NL:
         case ASI_NUCLEUS_QUAD_LDD:
         case ASI_NUCLEUS_QUAD_LDD_L:
-            mem_idx = MMU_NUCLEUS_IDX;
+            if (hypervisor(dc)) {
+                mem_idx = MMU_PHYS_IDX;
+            } else {
+                mem_idx = MMU_NUCLEUS_IDX;
+            }
             break;
         case ASI_AIUP:  /* As if user primary */
         case ASI_AIUPL: /* As if user primary LE */

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

end of thread, other threads:[~2016-11-01 19:29 UTC | newest]

Thread overview: 74+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-01 10:05 [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation Artyom Tarasenko
2016-10-01 10:05 ` [Qemu-devel] [PATCH 01/29] target-sparc: don't trap on MMU-fault if MMU is disabled Artyom Tarasenko
2016-10-10 21:14   ` Richard Henderson
2016-10-11 14:00     ` Artyom Tarasenko
2016-10-11 14:50       ` Richard Henderson
2016-10-12 13:24         ` Artyom Tarasenko
2016-10-01 10:05 ` [Qemu-devel] [PATCH 02/29] target-sparc: use explicit mmu register pointers Artyom Tarasenko
2016-10-10 21:18   ` Richard Henderson
2016-10-01 10:05 ` [Qemu-devel] [PATCH 03/29] target-sparc: add UA2005 TTE bit #defines Artyom Tarasenko
2016-10-10 21:22   ` Richard Henderson
2016-10-10 21:45     ` Artyom Tarasenko
2016-10-11  5:50       ` Richard Henderson
2016-10-11 13:51         ` Artyom Tarasenko
2016-10-11 15:08           ` Richard Henderson
2016-10-12 11:18             ` Artyom Tarasenko
2016-10-12 13:25               ` Richard Henderson
2016-10-01 10:05 ` [Qemu-devel] [PATCH 04/29] target-sparc: add UltraSPARC T1 TLB #defines Artyom Tarasenko
2016-10-01 10:05 ` [Qemu-devel] [PATCH 05/29] target-sparc: on UA2005 don't deliver Interrupt_level_n IRQs in hypervisor mode Artyom Tarasenko
2016-10-10 21:23   ` Richard Henderson
2016-10-01 10:05 ` [Qemu-devel] [PATCH 06/29] target-sparc: simplify replace_tlb_entry by using TTE_PGSIZE Artyom Tarasenko
2016-10-10 21:25   ` Richard Henderson
2016-10-01 10:05 ` [Qemu-devel] [PATCH 07/29] target-sparc: implement UA2005 scratchpad registers Artyom Tarasenko
2016-10-10 21:37   ` Richard Henderson
2016-10-01 10:05 ` [Qemu-devel] [PATCH 08/29] target-sparc: implement UltraSPARC-T1 Strand status ASR Artyom Tarasenko
2016-10-10 21:38   ` Richard Henderson
2016-10-01 10:05 ` [Qemu-devel] [PATCH 09/29] target-sparc: hypervisor mode takes over nucleus mode Artyom Tarasenko
2016-10-10 21:41   ` Richard Henderson
2016-10-12 11:33     ` Artyom Tarasenko
2016-10-12 13:29       ` Richard Henderson
2016-11-01 18:12         ` Artyom Tarasenko
2016-11-01 19:29           ` Richard Henderson
2016-10-01 10:05 ` [Qemu-devel] [PATCH 10/29] target-sparc: implement UA2005 hypervisor traps Artyom Tarasenko
2016-10-01 10:05 ` [Qemu-devel] [PATCH 11/29] target-sparc: implement UA2005 GL register Artyom Tarasenko
2016-10-10 21:45   ` Richard Henderson
2016-10-11 13:54     ` Artyom Tarasenko
2016-10-01 10:05 ` [Qemu-devel] [PATCH 12/29] target-sparc: implement UA2005 rdhpstate and wrhpstate instructions Artyom Tarasenko
2016-10-10 21:46   ` Richard Henderson
2016-10-01 10:05 ` [Qemu-devel] [PATCH 13/29] target-sparc: fix immediate UA2005 traps Artyom Tarasenko
2016-10-01 10:05 ` [Qemu-devel] [PATCH 14/29] target-sparc: use direct address translation in hyperprivileged mode Artyom Tarasenko
2016-10-11  5:55   ` Richard Henderson
2016-10-01 10:05 ` [Qemu-devel] [PATCH 15/29] target-sparc: allow priveleged ASIs " Artyom Tarasenko
2016-10-11 13:57   ` Richard Henderson
2016-10-01 10:05 ` [Qemu-devel] [PATCH 16/29] target-sparc: ignore writes to UA2005 CPU mondo queue register Artyom Tarasenko
2016-10-11 13:57   ` Richard Henderson
2016-10-01 10:05 ` [Qemu-devel] [PATCH 17/29] target-sparc: replace the last tlb entry when no free entries left Artyom Tarasenko
2016-10-01 10:05 ` [Qemu-devel] [PATCH 18/29] target-sparc: use SparcV9MMU type for sparc64 I/D-MMUs Artyom Tarasenko
2016-10-10 20:13   ` Richard Henderson
2016-10-11 13:56     ` Artyom Tarasenko
2016-10-01 10:05 ` [Qemu-devel] [PATCH 19/29] target-sparc: implement UA2005 TSB Pointers Artyom Tarasenko
2016-10-01 10:05 ` [Qemu-devel] [PATCH 20/29] target-sparc: simplify ultrasparc_tsb_pointer Artyom Tarasenko
2016-10-11 14:05   ` Richard Henderson
2016-10-11 14:08     ` Artyom Tarasenko
2016-10-01 10:05 ` [Qemu-devel] [PATCH 21/29] target-sparc: allow 256M sized pages Artyom Tarasenko
2016-10-11 14:07   ` Richard Henderson
2016-10-01 10:05 ` [Qemu-devel] [PATCH 22/29] target-sparc: implement auto-demapping for UA2005 CPUs Artyom Tarasenko
2016-10-11 14:17   ` Richard Henderson
2016-10-01 10:05 ` [Qemu-devel] [PATCH 23/29] target-sparc: implement ST_BLKINIT_ ASIs Artyom Tarasenko
2016-10-11 14:22   ` Richard Henderson
2016-10-01 10:05 ` [Qemu-devel] [PATCH 24/29] target-sparc: add more registers to dump_mmu Artyom Tarasenko
2016-10-11 14:22   ` Richard Henderson
2016-10-01 10:05 ` [Qemu-devel] [PATCH 25/29] target-sparc: implement UA2005 ASI_MMU (0x21) Artyom Tarasenko
2016-10-11 14:25   ` Richard Henderson
2016-10-01 10:05 ` [Qemu-devel] [PATCH 26/29] target-sparc: store the UA2005 entries in sun4u format Artyom Tarasenko
2016-10-11 14:31   ` Richard Henderson
2016-10-12 11:28     ` Artyom Tarasenko
2016-10-01 10:05 ` [Qemu-devel] [PATCH 27/29] target-sparc: implement sun4v RTC Artyom Tarasenko
2016-10-01 10:05 ` [Qemu-devel] [PATCH 28/29] target-sparc: move common cpu initialisation routines to sparc64.c Artyom Tarasenko
2016-10-11 14:34   ` Richard Henderson
2016-10-01 10:05 ` [Qemu-devel] [PATCH 29/29] target-sparc: fix up Niagara machine Artyom Tarasenko
2016-10-11 14:43   ` Richard Henderson
2016-10-12 11:27     ` Artyom Tarasenko
2016-10-01 10:48 ` [Qemu-devel] [PATCH 00/29] target-sparc: add Niagara OpenSPARC T1 sun4v emulation no-reply
2016-10-11 21:52 ` Mark Cave-Ayland
2016-10-12 11:58   ` Artyom Tarasenko

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.