qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/3] mips: support configurable exception vector base
@ 2016-06-09  9:46 Leon Alrae
  2016-06-09  9:46 ` [Qemu-devel] [PATCH 1/3] target-mips: add exception base to MIPS CPU Leon Alrae
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Leon Alrae @ 2016-06-09  9:46 UTC (permalink / raw)
  To: qemu-devel; +Cc: aurelien

This series implements the last piece of the minimal support required to
boot MIPSr6 SMP Linux on multiple Virtual Processors. Essentially it adds
RESET_BASE register to CM GCR which can be used by the guest to specify the
reset exception base address for each VP.

It applies on top of GIC patches:
https://lists.nongnu.org/archive/html/qemu-devel/2016-03/msg06223.html

Thanks,
Leon

Leon Alrae (3):
  target-mips: add exception base to MIPS CPU
  hw/mips_cpc: make VP correctly start from the reset vector
  hw/mips_cmgcr: implement RESET_BASE register in CM GCR

 hw/misc/mips_cmgcr.c         | 54 +++++++++++++++++++++++++++++++++++++++++++-
 hw/misc/mips_cpc.c           |  5 ++--
 include/hw/misc/mips_cmgcr.h | 18 +++++++++++++++
 target-mips/cpu.h            |  2 ++
 target-mips/helper.c         |  6 ++---
 target-mips/translate.c      |  9 +++++++-
 6 files changed, 86 insertions(+), 8 deletions(-)

-- 
2.7.4

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

* [Qemu-devel] [PATCH 1/3] target-mips: add exception base to MIPS CPU
  2016-06-09  9:46 [Qemu-devel] [PATCH 0/3] mips: support configurable exception vector base Leon Alrae
@ 2016-06-09  9:46 ` Leon Alrae
  2016-06-09  9:46 ` [Qemu-devel] [PATCH 2/3] hw/mips_cpc: make VP correctly start from the reset vector Leon Alrae
  2016-06-09  9:46 ` [Qemu-devel] [PATCH 3/3] hw/mips_cmgcr: implement RESET_BASE register in CM GCR Leon Alrae
  2 siblings, 0 replies; 4+ messages in thread
From: Leon Alrae @ 2016-06-09  9:46 UTC (permalink / raw)
  To: qemu-devel; +Cc: aurelien

Replace hardcoded 0xbfc00000 with exception_base which is initialized with
this default address so there is no functional change here.
However, it is now exposed and consequently it will be possible to modify
it from outside of the CPU.

Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
---
 target-mips/cpu.h       | 2 ++
 target-mips/helper.c    | 6 +++---
 target-mips/translate.c | 9 ++++++++-
 3 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 4ce9d47..2db010f 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -614,6 +614,7 @@ struct CPUMIPSState {
     void *irq[8];
     QEMUTimer *timer; /* Internal timer */
     MemoryRegion *itc_tag; /* ITC Configuration Tags */
+    target_ulong exception_base; /* ExceptionBase input to the core */
 };
 
 /**
@@ -807,6 +808,7 @@ int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc);
 
 #define cpu_init(cpu_model) CPU(cpu_mips_init(cpu_model))
 bool cpu_supports_cps_smp(const char *cpu_model);
+void cpu_set_exception_base(int vp_index, target_ulong address);
 
 /* TODO QOM'ify CPU reset and remove */
 void cpu_state_reset(CPUMIPSState *s);
diff --git a/target-mips/helper.c b/target-mips/helper.c
index 65fbef0..1402ff0 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -640,7 +640,7 @@ void mips_cpu_do_interrupt(CPUState *cs)
         /* EJTAG probe trap enable is not implemented... */
         if (!(env->CP0_Status & (1 << CP0St_EXL)))
             env->CP0_Cause &= ~(1U << CP0Ca_BD);
-        env->active_tc.PC = (int32_t)0xBFC00480;
+        env->active_tc.PC = env->exception_base + 0x480;
         set_hflags_for_handler(env);
         break;
     case EXCP_RESET:
@@ -667,7 +667,7 @@ void mips_cpu_do_interrupt(CPUState *cs)
         env->hflags &= ~(MIPS_HFLAG_KSU);
         if (!(env->CP0_Status & (1 << CP0St_EXL)))
             env->CP0_Cause &= ~(1U << CP0Ca_BD);
-        env->active_tc.PC = (int32_t)0xBFC00000;
+        env->active_tc.PC = env->exception_base;
         set_hflags_for_handler(env);
         break;
     case EXCP_EXT_INTERRUPT:
@@ -849,7 +849,7 @@ void mips_cpu_do_interrupt(CPUState *cs)
         }
         env->hflags &= ~MIPS_HFLAG_BMASK;
         if (env->CP0_Status & (1 << CP0St_BEV)) {
-            env->active_tc.PC = (int32_t)0xBFC00200;
+            env->active_tc.PC = env->exception_base + 0x200;
         } else {
             env->active_tc.PC = (int32_t)(env->CP0_EBase & ~0x3ff);
         }
diff --git a/target-mips/translate.c b/target-mips/translate.c
index f420680..c0aec42 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -20068,6 +20068,7 @@ MIPSCPU *cpu_mips_init(const char *cpu_model)
     cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
     env = &cpu->env;
     env->cpu_model = def;
+    env->exception_base = (int32_t)0xBFC00000;
 
 #ifndef CONFIG_USER_ONLY
     mmu_init(env, def);
@@ -20090,6 +20091,12 @@ bool cpu_supports_cps_smp(const char *cpu_model)
     return (def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
 }
 
+void cpu_set_exception_base(int vp_index, target_ulong address)
+{
+    MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
+    vp->env.exception_base = address;
+}
+
 void cpu_state_reset(CPUMIPSState *env)
 {
     MIPSCPU *cpu = mips_env_get_cpu(env);
@@ -20179,7 +20186,7 @@ void cpu_state_reset(CPUMIPSState *env)
     } else {
         env->CP0_ErrorEPC = env->active_tc.PC;
     }
-    env->active_tc.PC = (int32_t)0xBFC00000;
+    env->active_tc.PC = env->exception_base;
     env->CP0_Random = env->tlb->nb_tlb - 1;
     env->tlb->tlb_in_use = env->tlb->nb_tlb;
     env->CP0_Wired = 0;
-- 
2.7.4

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

* [Qemu-devel] [PATCH 2/3] hw/mips_cpc: make VP correctly start from the reset vector
  2016-06-09  9:46 [Qemu-devel] [PATCH 0/3] mips: support configurable exception vector base Leon Alrae
  2016-06-09  9:46 ` [Qemu-devel] [PATCH 1/3] target-mips: add exception base to MIPS CPU Leon Alrae
@ 2016-06-09  9:46 ` Leon Alrae
  2016-06-09  9:46 ` [Qemu-devel] [PATCH 3/3] hw/mips_cmgcr: implement RESET_BASE register in CM GCR Leon Alrae
  2 siblings, 0 replies; 4+ messages in thread
From: Leon Alrae @ 2016-06-09  9:46 UTC (permalink / raw)
  To: qemu-devel; +Cc: aurelien

When VP enters the Run state it starts execution from the reset vector.
Currently used CPU_INTERRUPT_WAKE does not do that if reset exception
base has been modified. Therefore fix that by simply resetting given VP.

Drop the usage of CPU_INTERRUPT_WAKE also in VP_STOP and instead raise
the CPU_INTERRUPT_HALT to halt a VP.

Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
---
 hw/misc/mips_cpc.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/hw/misc/mips_cpc.c b/hw/misc/mips_cpc.c
index e6a35dd..6d34574 100644
--- a/hw/misc/mips_cpc.c
+++ b/hw/misc/mips_cpc.c
@@ -37,7 +37,7 @@ static void cpc_run_vp(MIPSCPCState *cpc, uint64_t vp_run)
     CPU_FOREACH(cs) {
         uint64_t i = 1ULL << cs->cpu_index;
         if (i & vp_run & ~cpc->vp_running) {
-            cpu_interrupt(cs, CPU_INTERRUPT_WAKE);
+            cpu_reset(cs);
             cpc->vp_running |= i;
         }
     }
@@ -50,8 +50,7 @@ static void cpc_stop_vp(MIPSCPCState *cpc, uint64_t vp_stop)
     CPU_FOREACH(cs) {
         uint64_t i = 1ULL << cs->cpu_index;
         if (i & vp_stop & cpc->vp_running) {
-            cs->halted = 1;
-            cpu_reset_interrupt(cs, CPU_INTERRUPT_WAKE);
+            cpu_interrupt(cs, CPU_INTERRUPT_HALT);
             cpc->vp_running &= ~i;
         }
     }
-- 
2.7.4

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

* [Qemu-devel] [PATCH 3/3] hw/mips_cmgcr: implement RESET_BASE register in CM GCR
  2016-06-09  9:46 [Qemu-devel] [PATCH 0/3] mips: support configurable exception vector base Leon Alrae
  2016-06-09  9:46 ` [Qemu-devel] [PATCH 1/3] target-mips: add exception base to MIPS CPU Leon Alrae
  2016-06-09  9:46 ` [Qemu-devel] [PATCH 2/3] hw/mips_cpc: make VP correctly start from the reset vector Leon Alrae
@ 2016-06-09  9:46 ` Leon Alrae
  2 siblings, 0 replies; 4+ messages in thread
From: Leon Alrae @ 2016-06-09  9:46 UTC (permalink / raw)
  To: qemu-devel; +Cc: aurelien

Implement RESET_BASE register which is local to each VP and a write to
it changes VP's reset exception base. Also, add OTHER register to
allow a software running on one VP to access other VP's local registers.

Guest can use this mechanism to specify custom address from which a VP
will start execution.

Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
---
 hw/misc/mips_cmgcr.c         | 54 +++++++++++++++++++++++++++++++++++++++++++-
 include/hw/misc/mips_cmgcr.h | 18 +++++++++++++++
 2 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/hw/misc/mips_cmgcr.c b/hw/misc/mips_cmgcr.c
index e6cf17d..b3ba166 100644
--- a/hw/misc/mips_cmgcr.c
+++ b/hw/misc/mips_cmgcr.c
@@ -59,6 +59,8 @@ static inline void update_gic_base(MIPSGCRState *gcr, uint64_t val)
 static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size)
 {
     MIPSGCRState *gcr = (MIPSGCRState *) opaque;
+    MIPSGCRVPState *current_vps = &gcr->vps[current_cpu->cpu_index];
+    MIPSGCRVPState *other_vps = &gcr->vps[current_vps->other];
 
     switch (addr) {
     /* Global Control Block Register */
@@ -85,8 +87,14 @@ static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size)
     case MIPS_COCB_OFS + GCR_CL_CONFIG_OFS:
         /* Set PVP to # of VPs - 1 */
         return gcr->num_vps - 1;
+    case MIPS_CLCB_OFS + GCR_CL_RESETBASE_OFS:
+        return current_vps->reset_base;
+    case MIPS_COCB_OFS + GCR_CL_RESETBASE_OFS:
+        return other_vps->reset_base;
     case MIPS_CLCB_OFS + GCR_CL_OTHER_OFS:
-        return 0;
+        return current_vps->other;
+    case MIPS_COCB_OFS + GCR_CL_OTHER_OFS:
+        return other_vps->other;
     default:
         qemu_log_mask(LOG_UNIMP, "Read %d bytes at GCR offset 0x%" HWADDR_PRIx
                       "\n", size, addr);
@@ -95,10 +103,18 @@ static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size)
     return 0;
 }
 
+static inline target_ulong get_exception_base(MIPSGCRVPState *vps)
+{
+    /* TODO: BEV_BASE and SELECT_BEV */
+    return (int32_t)(vps->reset_base & GCR_CL_RESET_BASE_RESETBASE_MSK);
+}
+
 /* Write GCR registers */
 static void gcr_write(void *opaque, hwaddr addr, uint64_t data, unsigned size)
 {
     MIPSGCRState *gcr = (MIPSGCRState *)opaque;
+    MIPSGCRVPState *current_vps = &gcr->vps[current_cpu->cpu_index];
+    MIPSGCRVPState *other_vps = &gcr->vps[current_vps->other];
 
     switch (addr) {
     case GCR_GIC_BASE_OFS:
@@ -107,6 +123,26 @@ static void gcr_write(void *opaque, hwaddr addr, uint64_t data, unsigned size)
     case GCR_CPC_BASE_OFS:
         update_cpc_base(gcr, data);
         break;
+    case MIPS_CLCB_OFS + GCR_CL_RESETBASE_OFS:
+        current_vps->reset_base = data & GCR_CL_RESET_BASE_MSK;
+        cpu_set_exception_base(current_cpu->cpu_index,
+                               get_exception_base(current_vps));
+        break;
+    case MIPS_COCB_OFS + GCR_CL_RESETBASE_OFS:
+        other_vps->reset_base = data & GCR_CL_RESET_BASE_MSK;
+        cpu_set_exception_base(current_vps->other,
+                               get_exception_base(other_vps));
+        break;
+    case MIPS_CLCB_OFS + GCR_CL_OTHER_OFS:
+        if ((data & GCR_CL_OTHER_MSK) < gcr->num_vps) {
+            current_vps->other = data & GCR_CL_OTHER_MSK;
+        }
+        break;
+    case MIPS_COCB_OFS + GCR_CL_OTHER_OFS:
+        if ((data & GCR_CL_OTHER_MSK) < gcr->num_vps) {
+            other_vps->other = data & GCR_CL_OTHER_MSK;
+        }
+        break;
     default:
         qemu_log_mask(LOG_UNIMP, "Write %d bytes at GCR offset 0x%" HWADDR_PRIx
                       " 0x%" PRIx64 "\n", size, addr, data);
@@ -148,9 +184,16 @@ static void mips_gcr_init(Object *obj)
 static void mips_gcr_reset(DeviceState *dev)
 {
     MIPSGCRState *s = MIPS_GCR(dev);
+    int i;
 
     update_gic_base(s, 0);
     update_cpc_base(s, 0);
+
+    for (i = 0; i < s->num_vps; i++) {
+        s->vps[i].other = 0;
+        s->vps[i].reset_base = 0xBFC00000 & GCR_CL_RESET_BASE_MSK;
+        cpu_set_exception_base(i, get_exception_base(&s->vps[i]));
+    }
 }
 
 static const VMStateDescription vmstate_mips_gcr = {
@@ -170,12 +213,21 @@ static Property mips_gcr_properties[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
+static void mips_gcr_realize(DeviceState *dev, Error **errp)
+{
+    MIPSGCRState *s = MIPS_GCR(dev);
+
+    /* Create local set of registers for each VP */
+    s->vps = g_new(MIPSGCRVPState, s->num_vps);
+}
+
 static void mips_gcr_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     dc->props = mips_gcr_properties;
     dc->vmsd = &vmstate_mips_gcr;
     dc->reset = mips_gcr_reset;
+    dc->realize = mips_gcr_realize;
 }
 
 static const TypeInfo mips_gcr_info = {
diff --git a/include/hw/misc/mips_cmgcr.h b/include/hw/misc/mips_cmgcr.h
index 5b90e94..690e1d6 100644
--- a/include/hw/misc/mips_cmgcr.h
+++ b/include/hw/misc/mips_cmgcr.h
@@ -35,6 +35,7 @@
 /* Core Local and Core Other Block Register Map */
 #define GCR_CL_CONFIG_OFS   0x0010
 #define GCR_CL_OTHER_OFS    0x0018
+#define GCR_CL_RESETBASE_OFS 0x0020
 
 /* GCR_L2_CONFIG register fields */
 #define GCR_L2_CONFIG_BYPASS_SHF    20
@@ -50,6 +51,20 @@
 #define GCR_CPC_BASE_CPCBASE_MSK 0xFFFFFFFF8000ULL
 #define GCR_CPC_BASE_MSK (GCR_CPC_BASE_CPCEN_MSK | GCR_CPC_BASE_CPCBASE_MSK)
 
+/* GCR_CL_OTHER_OFS register fields */
+#define GCR_CL_OTHER_VPOTHER_MSK 0x7
+#define GCR_CL_OTHER_MSK GCR_CL_OTHER_VPOTHER_MSK
+
+/* GCR_CL_RESETBASE_OFS register fields */
+#define GCR_CL_RESET_BASE_RESETBASE_MSK 0xFFFFF000U
+#define GCR_CL_RESET_BASE_MSK GCR_CL_RESET_BASE_RESETBASE_MSK
+
+typedef struct MIPSGCRVPState MIPSGCRVPState;
+struct MIPSGCRVPState {
+    uint32_t other;
+    uint64_t reset_base;
+};
+
 typedef struct MIPSGCRState MIPSGCRState;
 struct MIPSGCRState {
     SysBusDevice parent_obj;
@@ -63,6 +78,9 @@ struct MIPSGCRState {
 
     uint64_t cpc_base;
     uint64_t gic_base;
+
+    /* VP Local/Other Registers */
+    MIPSGCRVPState *vps;
 };
 
 #endif /* _MIPS_GCR_H */
-- 
2.7.4

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

end of thread, other threads:[~2016-06-09  9:47 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-06-09  9:46 [Qemu-devel] [PATCH 0/3] mips: support configurable exception vector base Leon Alrae
2016-06-09  9:46 ` [Qemu-devel] [PATCH 1/3] target-mips: add exception base to MIPS CPU Leon Alrae
2016-06-09  9:46 ` [Qemu-devel] [PATCH 2/3] hw/mips_cpc: make VP correctly start from the reset vector Leon Alrae
2016-06-09  9:46 ` [Qemu-devel] [PATCH 3/3] hw/mips_cmgcr: implement RESET_BASE register in CM GCR Leon Alrae

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).