All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/30] target-sparc sun4v support
@ 2017-01-18 22:38 Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 01/30] target-sparc: ignore MMU-faults if MMU is disabled in hypervisor mode Artyom Tarasenko
                   ` (29 more replies)
  0 siblings, 30 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, Artyom Tarasenko

This series adds sun4v support. Its v2 was previously submitted via Richard's tree, but produced 
a clang warning due to a missing #ifdef.

v2 -> v3:
added an #ifdef to avoid unused function warning in user mode

The following changes since commit 23eb9e6b6d5315171cc15969bbc755f258004df0:

  Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2017-01-16' into staging (2017-01-17 13:53:50 +0000)

are available in the git repository at:

  https://github.com/artyom-tarasenko/qemu/ tags/pull-sun4v-20170118

for you to fetch changes up to a2664ca0eced57dfc9f261fa1b210f24ddac649d:

  target-sparc: fix up niagara machine (2017-01-18 22:03:44 +0100)

----------------------------------------------------------------
Artyom Tarasenko (30):
      target-sparc: ignore MMU-faults if MMU is disabled in hypervisor mode
      target-sparc: store cpu super- and hypervisor flags in TB
      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: add more registers to dump_mmu
      target-sparc: implement UA2005 ASI_MMU (0x21)
      target-sparc: store the UA2005 entries in sun4u format
      target-sparc: add ST_BLKINIT_ ASIs for UA2005+ CPUs
      target-sparc: implement sun4v RTC
      target-sparc: move common cpu initialisation routines to sparc64.c
      target-sparc: fix up niagara machine

 MAINTAINERS                         |   7 +
 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                  | 379 +----------------------------------
 hw/timer/Makefile.objs              |   2 +
 hw/timer/sun4v-rtc.c                | 102 ++++++++++
 include/hw/sparc/sparc64.h          |   5 +
 include/hw/timer/sun4v-rtc.h        |   1 +
 linux-user/main.c                   |   2 +-
 qemu-doc.texi                       |  14 +-
 target/sparc/asi.h                  |   1 +
 target/sparc/cpu.c                  |  13 +-
 target/sparc/cpu.h                  | 105 +++++++---
 target/sparc/helper.h               |   1 +
 target/sparc/int64_helper.c         |  43 +++-
 target/sparc/ldst_helper.c          | 387 ++++++++++++++++++++++++++++--------
 target/sparc/machine.c              |   4 +-
 target/sparc/mmu_helper.c           |  20 +-
 target/sparc/translate.c            |  64 +++++-
 target/sparc/win_helper.c           |  46 ++++-
 22 files changed, 1227 insertions(+), 528 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

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

* [Qemu-devel] [PULL 01/30] target-sparc: ignore MMU-faults if MMU is disabled in hypervisor mode
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 02/30] target-sparc: store cpu super- and hypervisor flags in TB Artyom Tarasenko
                   ` (28 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, Artyom Tarasenko

while IMMU/DMMU is disabled
- ignore MMU-faults in hypervisorv mode or if CPU doesn't have hypervisor
- signal TT_INSN_REAL_TRANSLATION_MISS/TT_DATA_REAL_TRANSLATION_MISS otherwise

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

diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 601c018..e815a19 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -68,6 +68,8 @@
 #define TT_DATA_ACCESS 0x32
 #define TT_UNALIGNED 0x34
 #define TT_PRIV_ACT 0x37
+#define TT_INSN_REAL_TRANSLATION_MISS 0x3e
+#define TT_DATA_REAL_TRANSLATION_MISS 0x3f
 #define TT_EXTINT   0x40
 #define TT_IVEC     0x60
 #define TT_TMISS    0x64
diff --git a/target/sparc/ldst_helper.c b/target/sparc/ldst_helper.c
index a0171f7..e479efd 100644
--- a/target/sparc/ldst_helper.c
+++ b/target/sparc/ldst_helper.c
@@ -1664,14 +1664,25 @@ void sparc_cpu_unassigned_access(CPUState *cs, hwaddr addr,
 {
     SPARCCPU *cpu = SPARC_CPU(cs);
     CPUSPARCState *env = &cpu->env;
-    int tt = is_exec ? TT_CODE_ACCESS : TT_DATA_ACCESS;
 
 #ifdef DEBUG_UNASSIGNED
     printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx
            "\n", addr, env->pc);
 #endif
 
-    cpu_raise_exception_ra(env, tt, GETPC());
+    if (is_exec) { /* XXX has_hypervisor */
+        if (env->lsu & (IMMU_E)) {
+            cpu_raise_exception_ra(env, TT_CODE_ACCESS, GETPC());
+        } else if (cpu_has_hypervisor(env) && !(env->hpstate & HS_PRIV)) {
+            cpu_raise_exception_ra(env, TT_INSN_REAL_TRANSLATION_MISS, GETPC());
+        }
+    } else {
+        if (env->lsu & (DMMU_E)) {
+            cpu_raise_exception_ra(env, TT_DATA_ACCESS, GETPC());
+        } else if (cpu_has_hypervisor(env) && !(env->hpstate & HS_PRIV)) {
+            cpu_raise_exception_ra(env, TT_DATA_REAL_TRANSLATION_MISS, GETPC());
+        }
+    }
 }
 #endif
 #endif
-- 
2.7.2

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

* [Qemu-devel] [PULL 02/30] target-sparc: store cpu super- and hypervisor flags in TB
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 01/30] target-sparc: ignore MMU-faults if MMU is disabled in hypervisor mode Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 03/30] target-sparc: use explicit mmu register pointers Artyom Tarasenko
                   ` (27 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, Artyom Tarasenko

Suggested-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target/sparc/cpu.h       | 17 +++++++++++++++++
 target/sparc/translate.c | 24 +++++++++++++++++++-----
 2 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index e815a19..1e65c94 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -670,6 +670,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)
@@ -736,6 +741,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,
@@ -745,7 +752,17 @@ 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);
+#ifndef CONFIG_USER_ONLY
+    if (cpu_supervisor_mode(env)) {
+        flags |= TB_FLAG_SUPER;
+    }
+#endif
 #ifdef TARGET_SPARC64
+#ifndef CONFIG_USER_ONLY
+    if (cpu_hypervisor_mode(env)) {
+        flags |= TB_FLAG_HYPER;
+    }
+#endif
     if (env->pstate & PS_AM) {
         flags |= TB_FLAG_AM_ENABLED;
     }
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index ead585e..729f4e2 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -72,9 +72,16 @@ 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;
+#ifdef TARGET_SPARC64
+    bool hypervisor;
+#endif
+#endif
+
     uint32_t cc_op;  /* current CC operation */
     struct TranslationBlock *tb;
     sparc_def_t *def;
@@ -283,10 +290,11 @@ 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)
 #ifdef TARGET_SPARC64
-#define hypervisor(dc) (dc->mem_idx == MMU_HYPV_IDX)
+#define hypervisor(dc) (dc->hypervisor)
+#define supervisor(dc) (dc->supervisor | dc->hypervisor)
 #else
+#define supervisor(dc) (dc->supervisor)
 #endif
 #endif
 
@@ -5710,9 +5718,15 @@ 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;
+#endif
 #ifdef TARGET_SPARC64
     dc->fprs_dirty = 0;
     dc->asi = (tb->flags >> TB_FLAG_ASI_SHIFT) & 0xff;
+#ifndef CONFIG_USER_ONLY
+    dc->hypervisor = (tb->flags & TB_FLAG_HYPER) != 0;
+#endif
 #endif
 
     num_insns = 0;
-- 
2.7.2

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

* [Qemu-devel] [PULL 03/30] target-sparc: use explicit mmu register pointers
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 01/30] target-sparc: ignore MMU-faults if MMU is disabled in hypervisor mode Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 02/30] target-sparc: store cpu super- and hypervisor flags in TB Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 04/30] target-sparc: add UA2005 TTE bit #defines Artyom Tarasenko
                   ` (26 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, Artyom Tarasenko

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

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
 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 1e65c94..10c9ac6 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -446,6 +446,8 @@ struct CPUSPARCState {
             uint64_t sfar;
             uint64_t tsb;
             uint64_t tag_access;
+            uint64_t virtual_watchpoint;
+            uint64_t physical_watchpoint;
         } immu;
     };
     union {
@@ -458,6 +460,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 e479efd..20e202b 100644
--- a/target/sparc/ldst_helper.c
+++ b/target/sparc/ldst_helper.c
@@ -1220,14 +1220,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 */
@@ -1263,12 +1274,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;
         }
@@ -1456,6 +1493,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;
             }
 
@@ -1526,9 +1564,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] 40+ messages in thread

* [Qemu-devel] [PULL 04/30] target-sparc: add UA2005 TTE bit #defines
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (2 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 03/30] target-sparc: use explicit mmu register pointers Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 05/30] target-sparc: add UltraSPARC T1 TLB #defines Artyom Tarasenko
                   ` (25 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, Artyom Tarasenko

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

diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 10c9ac6..4c4c159 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -304,19 +304,36 @@ enum {
 #define TTE_W_OK_BIT        (1ULL <<  1)
 #define TTE_GLOBAL_BIT      (1ULL <<  0)
 
+#define TTE_NFO_BIT_UA2005  (1ULL << 62)
+#define TTE_USED_BIT_UA2005 (1ULL << 47)
+#define TTE_LOCKED_BIT_UA2005 (1ULL <<  61)
+#define TTE_SIDEEFFECT_BIT_UA2005 (1ULL <<  11)
+#define TTE_PRIV_BIT_UA2005 (1ULL <<  8)
+#define TTE_W_OK_BIT_UA2005 (1ULL <<  6)
+
 #define TTE_IS_VALID(tte)   ((tte) & TTE_VALID_BIT)
 #define TTE_IS_NFO(tte)     ((tte) & TTE_NFO_BIT)
 #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] 40+ messages in thread

* [Qemu-devel] [PULL 05/30] target-sparc: add UltraSPARC T1 TLB #defines
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (3 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 04/30] target-sparc: add UA2005 TTE bit #defines Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 06/30] target-sparc: on UA2005 don't deliver Interrupt_level_n IRQs in hypervisor mode Artyom Tarasenko
                   ` (24 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, 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 4c4c159..f65d8b5 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -336,6 +336,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] 40+ messages in thread

* [Qemu-devel] [PULL 06/30] target-sparc: on UA2005 don't deliver Interrupt_level_n IRQs in hypervisor mode
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (4 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 05/30] target-sparc: add UltraSPARC T1 TLB #defines Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 07/30] target-sparc: simplify replace_tlb_entry by using TTE_PGSIZE Artyom Tarasenko
                   ` (23 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, 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>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
 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 f65d8b5..21fe0d1 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -736,8 +736,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] 40+ messages in thread

* [Qemu-devel] [PULL 07/30] target-sparc: simplify replace_tlb_entry by using TTE_PGSIZE
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (5 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 06/30] target-sparc: on UA2005 don't deliver Interrupt_level_n IRQs in hypervisor mode Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 08/30] target-sparc: implement UA2005 scratchpad registers Artyom Tarasenko
                   ` (22 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
 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 20e202b..7a134b3 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] 40+ messages in thread

* [Qemu-devel] [PULL 08/30] target-sparc: implement UA2005 scratchpad registers
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (6 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 07/30] target-sparc: simplify replace_tlb_entry by using TTE_PGSIZE Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 09/30] target-sparc: implement UltraSPARC-T1 Strand status ASR Artyom Tarasenko
                   ` (21 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, 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 | 24 ++++++++++++++++++++++++
 3 files changed, 26 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 21fe0d1..9307b91 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -523,6 +523,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 7a134b3..2e6439a 100644
--- a/target/sparc/ldst_helper.c
+++ b/target/sparc/ldst_helper.c
@@ -1351,6 +1351,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 */
@@ -1603,6 +1615,18 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
     case ASI_INTR_RECEIVE: /* Interrupt data receive */
         env->ivec_status = val & 0x20;
         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] 40+ messages in thread

* [Qemu-devel] [PULL 09/30] target-sparc: implement UltraSPARC-T1 Strand status ASR
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (7 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 08/30] target-sparc: implement UA2005 scratchpad registers Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 10/30] target-sparc: hypervisor mode takes over nucleus mode Artyom Tarasenko
                   ` (20 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, Artyom Tarasenko

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

diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 729f4e2..8902e44 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -3429,6 +3429,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] 40+ messages in thread

* [Qemu-devel] [PULL 10/30] target-sparc: hypervisor mode takes over nucleus mode
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (8 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 09/30] target-sparc: implement UltraSPARC-T1 Strand status ASR Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 11/30] target-sparc: implement UA2005 hypervisor traps Artyom Tarasenko
                   ` (19 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, Artyom Tarasenko

Accordinf to UA2005, 9.3.3 "Address Space Identifiers",

"In hyperprivileged mode, all instruction fetches and loads and stores with implicit
ASIs use a physical address, regardless of the value of TL".

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target/sparc/cpu.h       | 4 ++--
 target/sparc/translate.c | 6 +++++-
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 9307b91..00fbb4e 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -719,10 +719,10 @@ static inline int cpu_mmu_index(CPUSPARCState *env, bool ifetch)
         ? (env->lsu & IMMU_E) == 0 || (env->pstate & PS_RED) != 0
         : (env->lsu & DMMU_E) == 0) {
         return MMU_PHYS_IDX;
-    } else if (env->tl > 0) {
-        return MMU_NUCLEUS_IDX;
     } else if (cpu_hypervisor_mode(env)) {
         return MMU_HYPV_IDX;
+    } else if (env->tl > 0) {
+        return MMU_NUCLEUS_IDX;
     } else if (cpu_supervisor_mode(env)) {
         return MMU_KERNEL_IDX;
     } else {
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 8902e44..009ea3a 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -2142,7 +2142,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_HYPV_IDX;
+            } else {
+                mem_idx = MMU_NUCLEUS_IDX;
+            }
             break;
         case ASI_AIUP:  /* As if user primary */
         case ASI_AIUPL: /* As if user primary LE */
-- 
2.7.2

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

* [Qemu-devel] [PULL 11/30] target-sparc: implement UA2005 hypervisor traps
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (9 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 10/30] target-sparc: hypervisor mode takes over nucleus mode Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 12/30] target-sparc: implement UA2005 GL register Artyom Tarasenko
                   ` (18 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, Artyom Tarasenko

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

diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 00fbb4e..f173dd6 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -79,6 +79,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..8300eb4 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,36 @@ 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_INSN_REAL_TRANSLATION_MISS ... TT_DATA_REAL_TRANSLATION_MISS:
+    case TT_HTRAP ... TT_HTRAP + 127:
+        env->hpstate |= HS_PRIV;
         break;
     default:
         cpu_change_pstate(env, PS_PEF | PS_PRIV | PS_AG);
@@ -158,8 +180,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 2d5b546..45ee4e6 100644
--- a/target/sparc/win_helper.c
+++ b/target/sparc/win_helper.c
@@ -366,6 +366,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);
@@ -387,6 +390,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] 40+ messages in thread

* [Qemu-devel] [PULL 12/30] target-sparc: implement UA2005 GL register
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (10 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 11/30] target-sparc: implement UA2005 hypervisor traps Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 13/30] target-sparc: implement UA2005 rdhpstate and wrhpstate instructions Artyom Tarasenko
                   ` (17 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, 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    |  3 +--
 target/sparc/win_helper.c   | 40 ++++++++++++++++++++++++++++++++++++++--
 6 files changed, 58 insertions(+), 7 deletions(-)

diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index d6583f1..d606eb5 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -57,9 +57,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
@@ -744,14 +748,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 f173dd6..857e93b 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -515,6 +515,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;
@@ -615,6 +616,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 3ef38b9..b8f1e78 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 8300eb4..605747c 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 & 7ULL) << 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 009ea3a..a40c974 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -4558,8 +4558,7 @@ 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));
+                                gen_helper_wrgl(cpu_env, cpu_tmp0);
                                 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 45ee4e6..71b3dd3 100644
--- a/target/sparc/win_helper.c
+++ b/target/sparc/win_helper.c
@@ -290,6 +290,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);
@@ -305,14 +309,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;
@@ -367,7 +397,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--;
 
@@ -391,7 +424,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] 40+ messages in thread

* [Qemu-devel] [PULL 13/30] target-sparc: implement UA2005 rdhpstate and wrhpstate instructions
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (11 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 12/30] target-sparc: implement UA2005 GL register Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 14/30] target-sparc: fix immediate UA2005 traps Artyom Tarasenko
                   ` (16 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
 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 a40c974..399a8ac 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -3468,7 +3468,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();
@@ -4592,7 +4593,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] 40+ messages in thread

* [Qemu-devel] [PULL 14/30] target-sparc: fix immediate UA2005 traps
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (12 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 13/30] target-sparc: implement UA2005 rdhpstate and wrhpstate instructions Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 15/30] target-sparc: use direct address translation in hyperprivileged mode Artyom Tarasenko
                   ` (15 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, 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 399a8ac..1099976 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -3298,7 +3298,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] 40+ messages in thread

* [Qemu-devel] [PULL 15/30] target-sparc: use direct address translation in hyperprivileged mode
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (13 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 14/30] target-sparc: fix immediate UA2005 traps Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 16/30] target-sparc: allow priveleged ASIs " Artyom Tarasenko
                   ` (14 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, Artyom Tarasenko

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

Suggested-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 target/sparc/cpu.h       | 7 +++----
 target/sparc/translate.c | 2 +-
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 857e93b..53afa18 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -230,7 +230,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;
@@ -676,8 +676,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
@@ -723,7 +722,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)) {
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 1099976..0f20ed0 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -2143,7 +2143,7 @@ static DisasASI get_asi(DisasContext *dc, int insn, TCGMemOp memop)
         case ASI_NUCLEUS_QUAD_LDD:
         case ASI_NUCLEUS_QUAD_LDD_L:
             if (hypervisor(dc)) {
-                mem_idx = MMU_HYPV_IDX;
+                mem_idx = MMU_PHYS_IDX;
             } else {
                 mem_idx = MMU_NUCLEUS_IDX;
             }
-- 
2.7.2

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

* [Qemu-devel] [PULL 16/30] target-sparc: allow priveleged ASIs in hyperprivileged mode
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (14 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 15/30] target-sparc: use direct address translation in hyperprivileged mode Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 17/30] target-sparc: ignore writes to UA2005 CPU mondo queue register Artyom Tarasenko
                   ` (13 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, Artyom Tarasenko

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

diff --git a/target/sparc/ldst_helper.c b/target/sparc/ldst_helper.c
index 2e6439a..ade4fb0 100644
--- a/target/sparc/ldst_helper.c
+++ b/target/sparc/ldst_helper.c
@@ -293,6 +293,22 @@ static inline target_ulong asi_address_mask(CPUSPARCState *env,
     }
     return addr;
 }
+
+#ifndef CONFIG_USER_ONLY
+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 /* !CONFIG_USER_ONLY */
 #endif
 
 static void do_check_align(CPUSPARCState *env, target_ulong addr,
@@ -1118,13 +1134,7 @@ 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))) {
-        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);
 
@@ -1423,13 +1433,7 @@ 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))) {
-        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);
 
-- 
2.7.2

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

* [Qemu-devel] [PULL 17/30] target-sparc: ignore writes to UA2005 CPU mondo queue register
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (15 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 16/30] target-sparc: allow priveleged ASIs " Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 18/30] target-sparc: replace the last tlb entry when no free entries left Artyom Tarasenko
                   ` (12 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
 target/sparc/ldst_helper.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/sparc/ldst_helper.c b/target/sparc/ldst_helper.c
index ade4fb0..d3747cf 100644
--- a/target/sparc/ldst_helper.c
+++ b/target/sparc/ldst_helper.c
@@ -1631,6 +1631,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] 40+ messages in thread

* [Qemu-devel] [PULL 18/30] target-sparc: replace the last tlb entry when no free entries left
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (16 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 17/30] target-sparc: ignore writes to UA2005 CPU mondo queue register Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 19/30] target-sparc: use SparcV9MMU type for sparc64 I/D-MMUs Artyom Tarasenko
                   ` (11 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, 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 d3747cf..029120d 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] 40+ messages in thread

* [Qemu-devel] [PULL 19/30] target-sparc: use SparcV9MMU type for sparc64 I/D-MMUs
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (17 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 18/30] target-sparc: replace the last tlb entry when no free entries left Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 20/30] target-sparc: implement UA2005 TSB Pointers Artyom Tarasenko
                   ` (10 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 linux-user/main.c          |  2 +-
 target/sparc/cpu.h         | 48 +++++++++++++++++-----------------------------
 target/sparc/ldst_helper.c |  8 ++++----
 target/sparc/machine.c     |  4 ++--
 4 files changed, 25 insertions(+), 37 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index c1d5eb4..94a636f 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -1166,7 +1166,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);
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 53afa18..c92bd25 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -404,7 +404,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 */
@@ -457,35 +472,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 029120d..a96b031 100644
--- a/target/sparc/ldst_helper.c
+++ b/target/sparc/ldst_helper.c
@@ -1483,7 +1483,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;
@@ -1514,7 +1514,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]);
             }
@@ -1548,7 +1548,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:
@@ -1591,7 +1591,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 aea6397..39e262c 100644
--- a/target/sparc/machine.c
+++ b/target/sparc/machine.c
@@ -148,8 +148,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] 40+ messages in thread

* [Qemu-devel] [PULL 20/30] target-sparc: implement UA2005 TSB Pointers
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (18 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 19/30] target-sparc: use SparcV9MMU type for sparc64 I/D-MMUs Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 21/30] target-sparc: simplify ultrasparc_tsb_pointer Artyom Tarasenko
                   ` (9 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, 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 c92bd25..9e9b22a 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -417,6 +417,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 a96b031..aa6f77d 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;
@@ -1256,16 +1268,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 */
@@ -1324,16 +1340,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 */
@@ -1471,7 +1491,67 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
     case ASI_TWINX_SL: /* Secondary, twinx, LE */
         /* These are always handled inline.  */
         g_assert_not_reached();
-
+    /* 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] 40+ messages in thread

* [Qemu-devel] [PULL 21/30] target-sparc: simplify ultrasparc_tsb_pointer
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (19 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 20/30] target-sparc: implement UA2005 TSB Pointers Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 22/30] target-sparc: allow 256M sized pages Artyom Tarasenko
                   ` (8 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, 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 aa6f77d..d4eee33 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,
+                                       const SparcV9MMU *mmu, const 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
@@ -1268,20 +1259,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 */
@@ -1340,20 +1325,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] 40+ messages in thread

* [Qemu-devel] [PULL 22/30] target-sparc: allow 256M sized pages
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (20 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 21/30] target-sparc: simplify ultrasparc_tsb_pointer Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 23/30] target-sparc: implement auto-demapping for UA2005 CPUs Artyom Tarasenko
                   ` (7 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, 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 044e88c..fa70dc0 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 = -(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] 40+ messages in thread

* [Qemu-devel] [PULL 23/30] target-sparc: implement auto-demapping for UA2005 CPUs
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (21 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 22/30] target-sparc: allow 256M sized pages Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 24/30] target-sparc: add more registers to dump_mmu Artyom Tarasenko
                   ` (6 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, Artyom Tarasenko

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

diff --git a/target/sparc/ldst_helper.c b/target/sparc/ldst_helper.c
index d4eee33..4f55388 100644
--- a/target/sparc/ldst_helper.c
+++ b/target/sparc/ldst_helper.c
@@ -210,6 +210,28 @@ 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 = 8192ULL << 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 = 8192ULL << 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] 40+ messages in thread

* [Qemu-devel] [PULL 24/30] target-sparc: add more registers to dump_mmu
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (22 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 23/30] target-sparc: implement auto-demapping for UA2005 CPUs Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 25/30] target-sparc: implement UA2005 ASI_MMU (0x21) Artyom Tarasenko
                   ` (5 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
 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 fa70dc0..8b4664d 100644
--- a/target/sparc/mmu_helper.c
+++ b/target/sparc/mmu_helper.c
@@ -741,6 +741,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] 40+ messages in thread

* [Qemu-devel] [PULL 25/30] target-sparc: implement UA2005 ASI_MMU (0x21)
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (23 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 24/30] target-sparc: add more registers to dump_mmu Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 27/30] target-sparc: add ST_BLKINIT_ ASIs for UA2005+ CPUs Artyom Tarasenko
                   ` (4 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, Artyom Tarasenko

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

diff --git a/target/sparc/ldst_helper.c b/target/sparc/ldst_helper.c
index 4f55388..c69167e 100644
--- a/target/sparc/ldst_helper.c
+++ b/target/sparc/ldst_helper.c
@@ -1396,6 +1396,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 */
@@ -1714,6 +1726,25 @@ 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;
+              tlb_flush_by_mmuidx(CPU(cpu), MMU_USER_IDX, MMU_KERNEL_IDX, -1);
+              break;
+          case 2:
+              env->dmmu.mmu_secondary_context = val;
+              env->immu.mmu_secondary_context = val;
+              tlb_flush_by_mmuidx(CPU(cpu), MMU_USER_SECONDARY_IDX,
+                                  MMU_KERNEL_SECONDARY_IDX, -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] 40+ messages in thread

* [Qemu-devel] [PULL 27/30] target-sparc: add ST_BLKINIT_ ASIs for UA2005+ CPUs
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (24 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 25/30] target-sparc: implement UA2005 ASI_MMU (0x21) Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 28/30] target-sparc: implement sun4v RTC Artyom Tarasenko
                   ` (3 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, 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/translate.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 0f20ed0..655060c 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -2321,8 +2321,19 @@ static void gen_st_asi(DisasContext *dc, TCGv src, TCGv addr,
     case GET_ASI_EXCP:
         break;
     case GET_ASI_DTWINX: /* Reserved for stda.  */
+#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
     case GET_ASI_DIRECT:
         gen_address_mask(dc, addr);
         tcg_gen_qemu_st_tl(src, addr, da.mem_idx, da.memop);
-- 
2.7.2

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

* [Qemu-devel] [PULL 28/30] target-sparc: implement sun4v RTC
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (25 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 27/30] target-sparc: add ST_BLKINIT_ ASIs for UA2005+ CPUs Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 29/30] target-sparc: move common cpu initialisation routines to sparc64.c Artyom Tarasenko
                   ` (2 subsequent siblings)
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
---
 MAINTAINERS                  |   6 +++
 hw/timer/Makefile.objs       |   2 +
 hw/timer/sun4v-rtc.c         | 102 +++++++++++++++++++++++++++++++++++++++++++
 include/hw/timer/sun4v-rtc.h |   1 +
 4 files changed, 111 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 1444b26..54588e5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1098,6 +1098,12 @@ F: hw/nvram/chrp_nvram.c
 F: include/hw/nvram/chrp_nvram.h
 F: tests/prom-env-test.c
 
+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..82e9e14
--- /dev/null
+++ b/hw/timer/sun4v-rtc.c
@@ -0,0 +1,102 @@
+/*
+ * 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);
+
+    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] 40+ messages in thread

* [Qemu-devel] [PULL 29/30] target-sparc: move common cpu initialisation routines to sparc64.c
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (26 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 28/30] target-sparc: implement sun4v RTC Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-18 22:38 ` [Qemu-devel] [PULL 30/30] target-sparc: fix up niagara machine Artyom Tarasenko
  2017-01-19 19:21 ` [Qemu-devel] [PULL 00/30] target-sparc sun4v support Peter Maydell
  29 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, Artyom Tarasenko

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
 hw/sparc64/Makefile.objs   |   1 +
 hw/sparc64/sparc64.c       | 378 +++++++++++++++++++++++++++++++++++++++++++++
 hw/sparc64/sun4u.c         | 348 +----------------------------------------
 hw/timer/sun4v-rtc.c       |   2 +-
 include/hw/sparc/sparc64.h |   5 +
 5 files changed, 389 insertions(+), 345 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 4663315..232d4a6 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -38,25 +38,15 @@
 #include "hw/boards.h"
 #include "hw/nvram/sun_nvram.h"
 #include "hw/nvram/chrp_nvram.h"
+#include "hw/sparc/sparc64.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, ...)                                  \
@@ -65,13 +55,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)
@@ -89,8 +72,6 @@
 
 #define IVEC_MAX             0x40
 
-#define TICK_MAX             0x7fffffffffffffffULL
-
 struct hwdef {
     const char * const default_cpu_model;
     uint16_t machine_id;
@@ -216,293 +197,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] = {
@@ -723,46 +422,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)
@@ -781,14 +440,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 82e9e14..31052322 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] 40+ messages in thread

* [Qemu-devel] [PULL 30/30] target-sparc: fix up niagara machine
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (27 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 29/30] target-sparc: move common cpu initialisation routines to sparc64.c Artyom Tarasenko
@ 2017-01-18 22:38 ` Artyom Tarasenko
  2017-01-23 12:40   ` Peter Maydell
  2017-01-19 19:21 ` [Qemu-devel] [PULL 00/30] target-sparc sun4v support Peter Maydell
  29 siblings, 1 reply; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-18 22:38 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, mark.cave-ayland, rth, 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.

Note that for compatibility with the naming conventions for SPARC machines
the new machine name is lowercase niagara.

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
 MAINTAINERS                         |  13 +--
 default-configs/sparc64-softmmu.mak |   2 +
 hw/sparc64/Makefile.objs            |   1 +
 hw/sparc64/niagara.c                | 177 ++++++++++++++++++++++++++++++++++++
 hw/sparc64/sun4u.c                  |  31 -------
 qemu-doc.texi                       |  14 ++-
 6 files changed, 199 insertions(+), 39 deletions(-)
 create mode 100644 hw/sparc64/niagara.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 54588e5..b5ebfab 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -725,6 +725,13 @@ S: Maintained
 F: hw/sparc64/sun4u.c
 F: pc-bios/openbios-sparc64
 
+Sun4v
+M: Artyom Tarasenko <atar4qemu@gmail.com>
+S: Maintained
+F: hw/sparc64/sun4v.c
+F: hw/timer/sun4v-rtc.c
+F: include/hw/timer/sun4v-rtc.h
+
 Leon3
 M: Fabien Chouteau <chouteau@adacore.com>
 S: Maintained
@@ -1098,12 +1105,6 @@ F: hw/nvram/chrp_nvram.c
 F: include/hw/nvram/chrp_nvram.h
 F: tests/prom-env-test.c
 
-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/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..b55d4bb
--- /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 232d4a6..d1a6bca 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -542,7 +542,6 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
 enum {
     sun4u_id = 0,
     sun4v_id = 64,
-    niagara_id,
 };
 
 static const struct hwdef hwdefs[] = {
@@ -560,13 +559,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 */
@@ -581,12 +573,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);
@@ -620,22 +606,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);
@@ -644,7 +614,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)
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 02cb39d..0b2746f 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -2138,7 +2138,17 @@ Use the executable @file{qemu-system-sparc64} to simulate a Sun4u
 (UltraSPARC PC-like machine), Sun4v (T1 PC-like machine), or generic
 Niagara (T1) machine. The Sun4u emulator is mostly complete, being
 able to run Linux, NetBSD and OpenBSD in headless (-nographic) mode. The
-Sun4v and Niagara emulators are still a work in progress.
+Sun4v emulator is still a work in progress.
+
+The Niagara T1 emulator makes use of firmware and OS binaries supplied in the S10image/ directory
+of the OpenSPARC T1 project @url{http://download.oracle.com/technetwork/systems/opensparc/OpenSPARCT1_Arch.1.5.tar.bz2}
+and is able to boot the disk.s10hw2 Solaris image.
+@example
+qemu-system-sparc64 -M niagara -L /path-to/S10image/ \
+                    -nographic -m 256 \
+                    -drive if=pflash,readonly=on,file=/S10image/disk.s10hw2
+@end example
+
 
 QEMU emulates the following peripherals:
 
@@ -2173,7 +2183,7 @@ Set OpenBIOS variables in NVRAM, for example:
 qemu-system-sparc64 -prom-env 'auto-boot?=false'
 @end example
 
-@item -M [sun4u|sun4v|Niagara]
+@item -M [sun4u|sun4v|niagara]
 
 Set the emulated machine type. The default is sun4u.
 
-- 
2.7.2

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

* Re: [Qemu-devel] [PULL 00/30] target-sparc sun4v support
  2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
                   ` (28 preceding siblings ...)
  2017-01-18 22:38 ` [Qemu-devel] [PULL 30/30] target-sparc: fix up niagara machine Artyom Tarasenko
@ 2017-01-19 19:21 ` Peter Maydell
  29 siblings, 0 replies; 40+ messages in thread
From: Peter Maydell @ 2017-01-19 19:21 UTC (permalink / raw)
  To: Artyom Tarasenko; +Cc: QEMU Developers, Mark Cave-Ayland, Richard Henderson

On 18 January 2017 at 22:38, Artyom Tarasenko <atar4qemu@gmail.com> wrote:
> This series adds sun4v support. Its v2 was previously submitted via Richard's tree, but produced
> a clang warning due to a missing #ifdef.
>
> v2 -> v3:
> added an #ifdef to avoid unused function warning in user mode
>
> The following changes since commit 23eb9e6b6d5315171cc15969bbc755f258004df0:
>
>   Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2017-01-16' into staging (2017-01-17 13:53:50 +0000)
>
> are available in the git repository at:
>
>   https://github.com/artyom-tarasenko/qemu/ tags/pull-sun4v-20170118
>
> for you to fetch changes up to a2664ca0eced57dfc9f261fa1b210f24ddac649d:
>
>   target-sparc: fix up niagara machine (2017-01-18 22:03:44 +0100)
>

Applied, thanks.

-- PMM

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

* Re: [Qemu-devel] [PULL 30/30] target-sparc: fix up niagara machine
  2017-01-18 22:38 ` [Qemu-devel] [PULL 30/30] target-sparc: fix up niagara machine Artyom Tarasenko
@ 2017-01-23 12:40   ` Peter Maydell
  2017-01-23 14:10     ` Artyom Tarasenko
  0 siblings, 1 reply; 40+ messages in thread
From: Peter Maydell @ 2017-01-23 12:40 UTC (permalink / raw)
  To: Artyom Tarasenko; +Cc: QEMU Developers, Mark Cave-Ayland, Richard Henderson

On 18 January 2017 at 22:38, Artyom Tarasenko <atar4qemu@gmail.com> 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.
>
> Note that for compatibility with the naming conventions for SPARC machines
> the new machine name is lowercase niagara.
>
> Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
> Reviewed-by: Richard Henderson <rth@twiddle.net>

I see that 'make check' now warns:
  GTESTER check-qtest-sparc64
Could not open option rom 'nvram1': No such file or directory
Could not open option rom '1up-md.bin': No such file or directory
Could not open option rom '1up-hv.bin': No such file or directory
Could not open option rom 'reset.bin': No such file or directory
Could not open option rom 'q.bin': No such file or directory
Could not open option rom 'openboot.bin': No such file or directory

(though the tests still pass).

Could we either ship these images in pc-bios if they're
necessary, or not complain that they don't exist if they're
not necessary, please?

thanks
-- PMM

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

* Re: [Qemu-devel] [PULL 30/30] target-sparc: fix up niagara machine
  2017-01-23 12:40   ` Peter Maydell
@ 2017-01-23 14:10     ` Artyom Tarasenko
  2017-01-23 14:24       ` Peter Maydell
  2017-01-27 15:07       ` Jakub Jermář
  0 siblings, 2 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-23 14:10 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers, Mark Cave-Ayland, Richard Henderson

On Mon, Jan 23, 2017 at 1:40 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 18 January 2017 at 22:38, Artyom Tarasenko <atar4qemu@gmail.com> 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.
>>
>> Note that for compatibility with the naming conventions for SPARC machines
>> the new machine name is lowercase niagara.
>>
>> Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
>> Reviewed-by: Richard Henderson <rth@twiddle.net>
>
> I see that 'make check' now warns:
>   GTESTER check-qtest-sparc64
> Could not open option rom 'nvram1': No such file or directory
> Could not open option rom '1up-md.bin': No such file or directory
> Could not open option rom '1up-hv.bin': No such file or directory
> Could not open option rom 'reset.bin': No such file or directory
> Could not open option rom 'q.bin': No such file or directory
> Could not open option rom 'openboot.bin': No such file or directory
>
> (though the tests still pass).
>
> Could we either ship these images in pc-bios if they're
> necessary, or not complain that they don't exist if they're
> not necessary, please?

I wonder what would be the best option  here. The images are
necessary, so the last option - not complaining - can be misleading
for a user.

Concerning shipping them.
Pros:
- the images are obviously freely distributable (the link above).
- the corresponding source code was open-sourced by Sun under various
licenses (GPL for hypervisor, BSD for openboot).
Cons:
- there is no exact tag the the OpenSPARC source tree which would
correspond to the binaries.
- building them is tricky, because it requires Solaris 9 / SPARC.

What do you think would be a better option?

-- 
Regards,
Artyom Tarasenko

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

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

* Re: [Qemu-devel] [PULL 30/30] target-sparc: fix up niagara machine
  2017-01-23 14:10     ` Artyom Tarasenko
@ 2017-01-23 14:24       ` Peter Maydell
  2017-01-23 14:59         ` Artyom Tarasenko
  2017-02-24 11:50         ` Peter Maydell
  2017-01-27 15:07       ` Jakub Jermář
  1 sibling, 2 replies; 40+ messages in thread
From: Peter Maydell @ 2017-01-23 14:24 UTC (permalink / raw)
  To: Artyom Tarasenko; +Cc: QEMU Developers, Mark Cave-Ayland, Richard Henderson

On 23 January 2017 at 14:10, Artyom Tarasenko <atar4qemu@gmail.com> wrote:
> On Mon, Jan 23, 2017 at 1:40 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
>> I see that 'make check' now warns:
>>   GTESTER check-qtest-sparc64
>> Could not open option rom 'nvram1': No such file or directory
>> Could not open option rom '1up-md.bin': No such file or directory
>> Could not open option rom '1up-hv.bin': No such file or directory
>> Could not open option rom 'reset.bin': No such file or directory
>> Could not open option rom 'q.bin': No such file or directory
>> Could not open option rom 'openboot.bin': No such file or directory
>>
>> (though the tests still pass).
>>
>> Could we either ship these images in pc-bios if they're
>> necessary, or not complain that they don't exist if they're
>> not necessary, please?
>
> I wonder what would be the best option  here. The images are
> necessary, so the last option - not complaining - can be misleading
> for a user.

If they're actually necessary then perhaps we should refuse
to start entirely?

> Concerning shipping them.
> Pros:
> - the images are obviously freely distributable (the link above).
> - the corresponding source code was open-sourced by Sun under various
> licenses (GPL for hypervisor, BSD for openboot).
> Cons:
> - there is no exact tag the the OpenSPARC source tree which would
> correspond to the binaries.
> - building them is tricky, because it requires Solaris 9 / SPARC.
>
> What do you think would be a better option?

One thing we could do is only warn if !qtest_enabled().
We do this for some other boards that otherwise fail entirely
when their BIOS image is not present. This is sufficient for
the qtest checks which don't actually try to run code on the
guest, but merely interact with it via the qtest protocol.

We do ship some other ROMs that are only buildable on the
right host hardware, so it's not impossible, but I don't know
the details of our rules about what we put in pc-bios/.

thanks
-- PMM

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

* Re: [Qemu-devel] [PULL 30/30] target-sparc: fix up niagara machine
  2017-01-23 14:24       ` Peter Maydell
@ 2017-01-23 14:59         ` Artyom Tarasenko
  2017-01-23 15:05           ` Peter Maydell
  2017-02-24 11:50         ` Peter Maydell
  1 sibling, 1 reply; 40+ messages in thread
From: Artyom Tarasenko @ 2017-01-23 14:59 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers, Mark Cave-Ayland, Richard Henderson

On Mon, Jan 23, 2017 at 3:24 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 23 January 2017 at 14:10, Artyom Tarasenko <atar4qemu@gmail.com> wrote:
>> On Mon, Jan 23, 2017 at 1:40 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
>>> I see that 'make check' now warns:
>>>   GTESTER check-qtest-sparc64
>>> Could not open option rom 'nvram1': No such file or directory
>>> Could not open option rom '1up-md.bin': No such file or directory
>>> Could not open option rom '1up-hv.bin': No such file or directory
>>> Could not open option rom 'reset.bin': No such file or directory
>>> Could not open option rom 'q.bin': No such file or directory
>>> Could not open option rom 'openboot.bin': No such file or directory
>>>
>>> (though the tests still pass).
>>>
>>> Could we either ship these images in pc-bios if they're
>>> necessary, or not complain that they don't exist if they're
>>> not necessary, please?
>>
>> I wonder what would be the best option  here. The images are
>> necessary, so the last option - not complaining - can be misleading
>> for a user.
>
> If they're actually necessary then perhaps we should refuse
> to start entirely?

Yes, I think it's a best option. Don't load any images with the
-nodefaults option and fail on missing ones wintout -nodefaults.

Is there a failing variant of rom_add_file_fixed (I guess it's not
uncommon, but I don't find it in include/hw/loader.h) or do I just
check the return status?

>> Concerning shipping them.
>> Pros:
>> - the images are obviously freely distributable (the link above).
>> - the corresponding source code was open-sourced by Sun under various
>> licenses (GPL for hypervisor, BSD for openboot).
>> Cons:
>> - there is no exact tag the the OpenSPARC source tree which would
>> correspond to the binaries.
>> - building them is tricky, because it requires Solaris 9 / SPARC.
>>
>> What do you think would be a better option?
>
> One thing we could do is only warn if !qtest_enabled().
> We do this for some other boards that otherwise fail entirely
> when their BIOS image is not present. This is sufficient for
> the qtest checks which don't actually try to run code on the
> guest, but merely interact with it via the qtest protocol.
>
> We do ship some other ROMs that are only buildable on the
> right host hardware, so it's not impossible, but I don't know
> the details of our rules about what we put in pc-bios/.

Who may know them? I see no general maintainer for the pc-bios
directory as such in our MAINTAINERS file.

-- 
Regards,
Artyom Tarasenko

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

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

* Re: [Qemu-devel] [PULL 30/30] target-sparc: fix up niagara machine
  2017-01-23 14:59         ` Artyom Tarasenko
@ 2017-01-23 15:05           ` Peter Maydell
  0 siblings, 0 replies; 40+ messages in thread
From: Peter Maydell @ 2017-01-23 15:05 UTC (permalink / raw)
  To: Artyom Tarasenko; +Cc: QEMU Developers, Mark Cave-Ayland, Richard Henderson

On 23 January 2017 at 14:59, Artyom Tarasenko <atar4qemu@gmail.com> wrote:
> On Mon, Jan 23, 2017 at 3:24 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
>> If they're actually necessary then perhaps we should refuse
>> to start entirely?
>
> Yes, I think it's a best option. Don't load any images with the
> -nodefaults option and fail on missing ones wintout -nodefaults.
>
> Is there a failing variant of rom_add_file_fixed (I guess it's not
> uncommon, but I don't find it in include/hw/loader.h) or do I just
> check the return status?

I think you just have to check the return status.

thanks
-- PMM

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

* Re: [Qemu-devel] [PULL 30/30] target-sparc: fix up niagara machine
  2017-01-23 14:10     ` Artyom Tarasenko
  2017-01-23 14:24       ` Peter Maydell
@ 2017-01-27 15:07       ` Jakub Jermář
  1 sibling, 0 replies; 40+ messages in thread
From: Jakub Jermář @ 2017-01-27 15:07 UTC (permalink / raw)
  To: qemu-devel

Hi Artyom,

On 01/23/2017 03:10 PM, Artyom Tarasenko wrote:
> On Mon, Jan 23, 2017 at 1:40 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
>> On 18 January 2017 at 22:38, Artyom Tarasenko <atar4qemu@gmail.com> 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.
>>>
>>> Note that for compatibility with the naming conventions for SPARC machines
>>> the new machine name is lowercase niagara.
>>>
>>> Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
>>> Reviewed-by: Richard Henderson <rth@twiddle.net>
>>
>> I see that 'make check' now warns:
>>   GTESTER check-qtest-sparc64
>> Could not open option rom 'nvram1': No such file or directory
>> Could not open option rom '1up-md.bin': No such file or directory
>> Could not open option rom '1up-hv.bin': No such file or directory
>> Could not open option rom 'reset.bin': No such file or directory
>> Could not open option rom 'q.bin': No such file or directory
>> Could not open option rom 'openboot.bin': No such file or directory
>>
>> (though the tests still pass).
>>
>> Could we either ship these images in pc-bios if they're
>> necessary, or not complain that they don't exist if they're
>> not necessary, please?
> 
> I wonder what would be the best option  here. The images are
> necessary, so the last option - not complaining - can be misleading
> for a user.
> 
> Concerning shipping them.
> Pros:
> - the images are obviously freely distributable (the link above).
> - the corresponding source code was open-sourced by Sun under various
> licenses (GPL for hypervisor, BSD for openboot).
> Cons:
> - there is no exact tag the the OpenSPARC source tree which would
> correspond to the binaries.
> - building them is tricky, because it requires Solaris 9 / SPARC.
> 
> What do you think would be a better option?

I'd strongly prefer the option to build QEMU's own binaries and
distribute them in pc-bios/. Downloading this 190M tarball is a nuisance
and depending on their continued existence on the Oracle server is a risk.

Where does the dependency on Solaris 9 come from? You should be able to
run unmodified Solaris 9 binaries on eg. Solaris 10...

Best,
Jakub

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

* Re: [Qemu-devel] [PULL 30/30] target-sparc: fix up niagara machine
  2017-01-23 14:24       ` Peter Maydell
  2017-01-23 14:59         ` Artyom Tarasenko
@ 2017-02-24 11:50         ` Peter Maydell
  2017-02-24 12:35           ` Artyom Tarasenko
  1 sibling, 1 reply; 40+ messages in thread
From: Peter Maydell @ 2017-02-24 11:50 UTC (permalink / raw)
  To: Artyom Tarasenko; +Cc: QEMU Developers, Mark Cave-Ayland, Richard Henderson

On 23 January 2017 at 14:24, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 23 January 2017 at 14:10, Artyom Tarasenko <atar4qemu@gmail.com> wrote:
>> On Mon, Jan 23, 2017 at 1:40 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
>>> I see that 'make check' now warns:
>>>   GTESTER check-qtest-sparc64
>>> Could not open option rom 'nvram1': No such file or directory
>>> Could not open option rom '1up-md.bin': No such file or directory
>>> Could not open option rom '1up-hv.bin': No such file or directory
>>> Could not open option rom 'reset.bin': No such file or directory
>>> Could not open option rom 'q.bin': No such file or directory
>>> Could not open option rom 'openboot.bin': No such file or directory
>>>
>>> (though the tests still pass).

> One thing we could do is only warn if !qtest_enabled().

I notice that 'make check' still warns about these missing option
rom files...could somebody write a patch to silence it, please?

thanks
-- PMM

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

* Re: [Qemu-devel] [PULL 30/30] target-sparc: fix up niagara machine
  2017-02-24 11:50         ` Peter Maydell
@ 2017-02-24 12:35           ` Artyom Tarasenko
  0 siblings, 0 replies; 40+ messages in thread
From: Artyom Tarasenko @ 2017-02-24 12:35 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers, Mark Cave-Ayland, Richard Henderson

On Fri, Feb 24, 2017 at 12:50 PM, Peter Maydell
<peter.maydell@linaro.org> wrote:
> On 23 January 2017 at 14:24, Peter Maydell <peter.maydell@linaro.org> wrote:
>> On 23 January 2017 at 14:10, Artyom Tarasenko <atar4qemu@gmail.com> wrote:
>>> On Mon, Jan 23, 2017 at 1:40 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
>>>> I see that 'make check' now warns:
>>>>   GTESTER check-qtest-sparc64
>>>> Could not open option rom 'nvram1': No such file or directory
>>>> Could not open option rom '1up-md.bin': No such file or directory
>>>> Could not open option rom '1up-hv.bin': No such file or directory
>>>> Could not open option rom 'reset.bin': No such file or directory
>>>> Could not open option rom 'q.bin': No such file or directory
>>>> Could not open option rom 'openboot.bin': No such file or directory
>>>>
>>>> (though the tests still pass).
>
>> One thing we could do is only warn if !qtest_enabled().
>
> I notice that 'make check' still warns about these missing option
> rom files...could somebody write a patch to silence it, please?

Actually I sent a patch one month ago:
http://lists.gnu.org/archive/html/qemu-devel/2017-01/msg05272.html

I think I've waited long enough  for nacks.
Will send a pull request with it.

-- 
Regards,
Artyom Tarasenko

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

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

* [Qemu-devel] [PULL 30/30] target-sparc: fix up niagara machine
  2017-01-12  2:55 Richard Henderson
@ 2017-01-12  2:56 ` Richard Henderson
  0 siblings, 0 replies; 40+ messages in thread
From: Richard Henderson @ 2017-01-12  2:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: atar4qemu, mark.cave-ayland, peter.maydell

From: Artyom Tarasenko <atar4qemu@gmail.com>

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.

Note that for compatibility with the naming conventions for SPARC machines
the new machine name is lowercase niagara.

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Message-Id: <662c7a5b81926a9daba26c943b0c11e99068c867.1484165352.git.atar4qemu@gmail.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 MAINTAINERS                         |  13 +--
 default-configs/sparc64-softmmu.mak |   2 +
 hw/sparc64/Makefile.objs            |   1 +
 hw/sparc64/niagara.c                | 177 ++++++++++++++++++++++++++++++++++++
 hw/sparc64/sun4u.c                  |  31 -------
 qemu-doc.texi                       |  14 ++-
 6 files changed, 199 insertions(+), 39 deletions(-)
 create mode 100644 hw/sparc64/niagara.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 54588e5..b5ebfab 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -725,6 +725,13 @@ S: Maintained
 F: hw/sparc64/sun4u.c
 F: pc-bios/openbios-sparc64
 
+Sun4v
+M: Artyom Tarasenko <atar4qemu@gmail.com>
+S: Maintained
+F: hw/sparc64/sun4v.c
+F: hw/timer/sun4v-rtc.c
+F: include/hw/timer/sun4v-rtc.h
+
 Leon3
 M: Fabien Chouteau <chouteau@adacore.com>
 S: Maintained
@@ -1098,12 +1105,6 @@ F: hw/nvram/chrp_nvram.c
 F: include/hw/nvram/chrp_nvram.h
 F: tests/prom-env-test.c
 
-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/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..b55d4bb
--- /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 232d4a6..d1a6bca 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -542,7 +542,6 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
 enum {
     sun4u_id = 0,
     sun4v_id = 64,
-    niagara_id,
 };
 
 static const struct hwdef hwdefs[] = {
@@ -560,13 +559,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 */
@@ -581,12 +573,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);
@@ -620,22 +606,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);
@@ -644,7 +614,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)
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 02cb39d..0b2746f 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -2138,7 +2138,17 @@ Use the executable @file{qemu-system-sparc64} to simulate a Sun4u
 (UltraSPARC PC-like machine), Sun4v (T1 PC-like machine), or generic
 Niagara (T1) machine. The Sun4u emulator is mostly complete, being
 able to run Linux, NetBSD and OpenBSD in headless (-nographic) mode. The
-Sun4v and Niagara emulators are still a work in progress.
+Sun4v emulator is still a work in progress.
+
+The Niagara T1 emulator makes use of firmware and OS binaries supplied in the S10image/ directory
+of the OpenSPARC T1 project @url{http://download.oracle.com/technetwork/systems/opensparc/OpenSPARCT1_Arch.1.5.tar.bz2}
+and is able to boot the disk.s10hw2 Solaris image.
+@example
+qemu-system-sparc64 -M niagara -L /path-to/S10image/ \
+                    -nographic -m 256 \
+                    -drive if=pflash,readonly=on,file=/S10image/disk.s10hw2
+@end example
+
 
 QEMU emulates the following peripherals:
 
@@ -2173,7 +2183,7 @@ Set OpenBIOS variables in NVRAM, for example:
 qemu-system-sparc64 -prom-env 'auto-boot?=false'
 @end example
 
-@item -M [sun4u|sun4v|Niagara]
+@item -M [sun4u|sun4v|niagara]
 
 Set the emulated machine type. The default is sun4u.
 
-- 
2.9.3

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

end of thread, other threads:[~2017-02-24 12:35 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-18 22:38 [Qemu-devel] [PULL 00/30] target-sparc sun4v support Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 01/30] target-sparc: ignore MMU-faults if MMU is disabled in hypervisor mode Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 02/30] target-sparc: store cpu super- and hypervisor flags in TB Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 03/30] target-sparc: use explicit mmu register pointers Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 04/30] target-sparc: add UA2005 TTE bit #defines Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 05/30] target-sparc: add UltraSPARC T1 TLB #defines Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 06/30] target-sparc: on UA2005 don't deliver Interrupt_level_n IRQs in hypervisor mode Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 07/30] target-sparc: simplify replace_tlb_entry by using TTE_PGSIZE Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 08/30] target-sparc: implement UA2005 scratchpad registers Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 09/30] target-sparc: implement UltraSPARC-T1 Strand status ASR Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 10/30] target-sparc: hypervisor mode takes over nucleus mode Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 11/30] target-sparc: implement UA2005 hypervisor traps Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 12/30] target-sparc: implement UA2005 GL register Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 13/30] target-sparc: implement UA2005 rdhpstate and wrhpstate instructions Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 14/30] target-sparc: fix immediate UA2005 traps Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 15/30] target-sparc: use direct address translation in hyperprivileged mode Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 16/30] target-sparc: allow priveleged ASIs " Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 17/30] target-sparc: ignore writes to UA2005 CPU mondo queue register Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 18/30] target-sparc: replace the last tlb entry when no free entries left Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 19/30] target-sparc: use SparcV9MMU type for sparc64 I/D-MMUs Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 20/30] target-sparc: implement UA2005 TSB Pointers Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 21/30] target-sparc: simplify ultrasparc_tsb_pointer Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 22/30] target-sparc: allow 256M sized pages Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 23/30] target-sparc: implement auto-demapping for UA2005 CPUs Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 24/30] target-sparc: add more registers to dump_mmu Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 25/30] target-sparc: implement UA2005 ASI_MMU (0x21) Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 27/30] target-sparc: add ST_BLKINIT_ ASIs for UA2005+ CPUs Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 28/30] target-sparc: implement sun4v RTC Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 29/30] target-sparc: move common cpu initialisation routines to sparc64.c Artyom Tarasenko
2017-01-18 22:38 ` [Qemu-devel] [PULL 30/30] target-sparc: fix up niagara machine Artyom Tarasenko
2017-01-23 12:40   ` Peter Maydell
2017-01-23 14:10     ` Artyom Tarasenko
2017-01-23 14:24       ` Peter Maydell
2017-01-23 14:59         ` Artyom Tarasenko
2017-01-23 15:05           ` Peter Maydell
2017-02-24 11:50         ` Peter Maydell
2017-02-24 12:35           ` Artyom Tarasenko
2017-01-27 15:07       ` Jakub Jermář
2017-01-19 19:21 ` [Qemu-devel] [PULL 00/30] target-sparc sun4v support Peter Maydell
  -- strict thread matches above, loose matches on Subject: below --
2017-01-12  2:55 Richard Henderson
2017-01-12  2:56 ` [Qemu-devel] [PULL 30/30] target-sparc: fix up niagara machine Richard Henderson

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.