All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/5] OpenRISC SMP Support
@ 2017-08-23  5:57 ` Stafford Horne
  0 siblings, 0 replies; 24+ messages in thread
From: Stafford Horne @ 2017-08-23  5:57 UTC (permalink / raw)
  To: QEMU Development; +Cc: Richard Henderson, Openrisc, Stafford Horne

Hello,

This series adds SMP support for OpenRISC.  The platform is based on the
work that Stefan Kristiansson did around 2012 implemented in Verilog and
run on FPGAs.  I have been working to upstream this work, these are my QEMU
patches I have been used to help with testing.

I have documented the platform in the OpenRISC 1.2 specification proposal
available here:
  https://github.com/stffrdhrn/doc/raw/arch-1.2-proposal/openrisc-arch-1.2-rev0.pdf

My latest kernel patches are available here:
  https://github.com/stffrdhrn/linux.git openrisc-4.13-smp-qspinlock

Stafford Horne (5):
  openrisc/ompic: Add OpenRISC Multicore PIC (OMPIC)
  target/openrisc: Make coreid and numcores configurable in state
  openrisc/cputimer: Perparation for Multicore
  openrisc: Initial SMP support
  openrisc: Only kick cpu on timeout, not on update

 default-configs/or1k-softmmu.mak |   1 +
 hw/intc/Makefile.objs            |   1 +
 hw/intc/ompic.c                  | 179 +++++++++++++++++++++++++++++++++++++++
 hw/openrisc/cputimer.c           |  64 ++++++++++----
 hw/openrisc/openrisc_sim.c       |  87 ++++++++++++++-----
 target/openrisc/cpu.c            |   1 -
 target/openrisc/cpu.h            |   7 +-
 target/openrisc/machine.c        |   8 +-
 target/openrisc/sys_helper.c     |   8 +-
 9 files changed, 308 insertions(+), 48 deletions(-)
 create mode 100644 hw/intc/ompic.c

-- 
2.13.5

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

* [OpenRISC] [PATCH 0/5] OpenRISC SMP Support
@ 2017-08-23  5:57 ` Stafford Horne
  0 siblings, 0 replies; 24+ messages in thread
From: Stafford Horne @ 2017-08-23  5:57 UTC (permalink / raw)
  To: openrisc

Hello,

This series adds SMP support for OpenRISC.  The platform is based on the
work that Stefan Kristiansson did around 2012 implemented in Verilog and
run on FPGAs.  I have been working to upstream this work, these are my QEMU
patches I have been used to help with testing.

I have documented the platform in the OpenRISC 1.2 specification proposal
available here:
  https://github.com/stffrdhrn/doc/raw/arch-1.2-proposal/openrisc-arch-1.2-rev0.pdf

My latest kernel patches are available here:
  https://github.com/stffrdhrn/linux.git openrisc-4.13-smp-qspinlock

Stafford Horne (5):
  openrisc/ompic: Add OpenRISC Multicore PIC (OMPIC)
  target/openrisc: Make coreid and numcores configurable in state
  openrisc/cputimer: Perparation for Multicore
  openrisc: Initial SMP support
  openrisc: Only kick cpu on timeout, not on update

 default-configs/or1k-softmmu.mak |   1 +
 hw/intc/Makefile.objs            |   1 +
 hw/intc/ompic.c                  | 179 +++++++++++++++++++++++++++++++++++++++
 hw/openrisc/cputimer.c           |  64 ++++++++++----
 hw/openrisc/openrisc_sim.c       |  87 ++++++++++++++-----
 target/openrisc/cpu.c            |   1 -
 target/openrisc/cpu.h            |   7 +-
 target/openrisc/machine.c        |   8 +-
 target/openrisc/sys_helper.c     |   8 +-
 9 files changed, 308 insertions(+), 48 deletions(-)
 create mode 100644 hw/intc/ompic.c

-- 
2.13.5


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

* [Qemu-devel] [PATCH 1/5] openrisc/ompic: Add OpenRISC Multicore PIC (OMPIC)
  2017-08-23  5:57 ` [OpenRISC] " Stafford Horne
@ 2017-08-23  5:57   ` Stafford Horne
  -1 siblings, 0 replies; 24+ messages in thread
From: Stafford Horne @ 2017-08-23  5:57 UTC (permalink / raw)
  To: QEMU Development; +Cc: Richard Henderson, Openrisc, Stafford Horne

Add OpenRISC Multicore PIC which handles inter processor interrupts
(IPI) between cores.  In OpenRISC all device interrupts are routed to
each core enabling this device to be simple.

Signed-off-by: Stafford Horne <shorne@gmail.com>
---
 default-configs/or1k-softmmu.mak |   1 +
 hw/intc/Makefile.objs            |   1 +
 hw/intc/ompic.c                  | 179 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 181 insertions(+)
 create mode 100644 hw/intc/ompic.c

diff --git a/default-configs/or1k-softmmu.mak b/default-configs/or1k-softmmu.mak
index 10bfa7abb8..6f5824fd48 100644
--- a/default-configs/or1k-softmmu.mak
+++ b/default-configs/or1k-softmmu.mak
@@ -2,3 +2,4 @@
 
 CONFIG_SERIAL=y
 CONFIG_OPENCORES_ETH=y
+CONFIG_OMPIC=y
diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index 78426a7daf..ae358569a1 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -43,3 +43,4 @@ obj-$(CONFIG_ASPEED_SOC) += aspeed_vic.o
 obj-$(CONFIG_ARM_GIC) += arm_gicv3_cpuif.o
 obj-$(CONFIG_MIPS_CPS) += mips_gic.o
 obj-$(CONFIG_NIOS2) += nios2_iic.o
+obj-$(CONFIG_OMPIC) += ompic.o
diff --git a/hw/intc/ompic.c b/hw/intc/ompic.c
new file mode 100644
index 0000000000..c0e34d1268
--- /dev/null
+++ b/hw/intc/ompic.c
@@ -0,0 +1,179 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Authors: Stafford Horne <shorne@gmail.com>
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "hw/hw.h"
+#include "hw/sysbus.h"
+#include "exec/memory.h"
+
+#define TYPE_OR1K_OMPIC "or1k-ompic"
+#define OR1K_OMPIC(obj) OBJECT_CHECK(OR1KOMPICState, (obj), TYPE_OR1K_OMPIC)
+
+#define OMPIC_CTRL_IRQ_ACK  (1 << 31)
+#define OMPIC_CTRL_IRQ_GEN  (1 << 30)
+#define OMPIC_CTRL_DST(cpu) (((cpu) >> 16) & 0x3fff)
+
+#define OMPIC_REG(addr)     (((addr) >> 2) & 0x1)
+#define OMPIC_SRC_CPU(addr) (((addr) >> 3) & 0x4f)
+#define OMPIC_DST_CPU(addr) (((addr) >> 3) & 0x4f)
+
+#define OMPIC_STATUS_IRQ_PENDING (1 << 30)
+#define OMPIC_STATUS_SRC(cpu)    (((cpu) & 0x3fff) << 16)
+#define OMPIC_STATUS_DATA(data)  ((data) & 0xffff)
+
+#define OMPIC_CONTROL 0
+#define OMPIC_STATUS  1
+
+#define OMPIC_MAX_CPUS 4 /* Real max is much higher, but dont waste memory */
+#define OMPIC_ADDRSPACE_SZ (OMPIC_MAX_CPUS * 2 * 4) /* 2 32-bit regs per cpu */
+
+typedef struct OR1KOMPICState OR1KOMPICState;
+typedef struct OR1KOMPICCPUState OR1KOMPICCPUState;
+
+struct OR1KOMPICCPUState {
+    qemu_irq irq;
+    uint32_t status;
+    uint32_t control;
+};
+
+struct OR1KOMPICState {
+    SysBusDevice parent_obj;
+    MemoryRegion mr;
+
+    OR1KOMPICCPUState cpus[OMPIC_MAX_CPUS];
+
+    uint32_t num_cpus;
+};
+
+static uint64_t ompic_read(void *opaque, hwaddr addr, unsigned size)
+{
+    OR1KOMPICState *s = opaque;
+    int src_cpu = OMPIC_SRC_CPU(addr);
+
+    /* We can only write to control control, write control + update status */
+    if (OMPIC_REG(addr) == OMPIC_CONTROL) {
+        return s->cpus[src_cpu].control;
+    } else {
+        return s->cpus[src_cpu].status;
+   }
+
+}
+
+static void ompic_write(void *opaque, hwaddr addr, uint64_t data, unsigned size)
+{
+    OR1KOMPICState *s = opaque;
+    /* We can only write to control control, write control + update status */
+    if (OMPIC_REG(addr) == OMPIC_CONTROL) {
+        int src_cpu = OMPIC_SRC_CPU(addr);
+
+        s->cpus[src_cpu].control = data;
+
+        if (data & OMPIC_CTRL_IRQ_GEN) {
+            int dst_cpu = OMPIC_CTRL_DST(data);
+
+            s->cpus[dst_cpu].status = OMPIC_STATUS_IRQ_PENDING |
+                OMPIC_STATUS_SRC(src_cpu) |
+                OMPIC_STATUS_DATA(data);
+
+            qemu_irq_raise(s->cpus[dst_cpu].irq);
+        }
+        if (data & OMPIC_CTRL_IRQ_ACK) {
+            s->cpus[src_cpu].status &= ~OMPIC_STATUS_IRQ_PENDING;
+            qemu_irq_lower(s->cpus[src_cpu].irq);
+        }
+    }
+}
+
+static const MemoryRegionOps ompic_ops = {
+    .read = ompic_read,
+    .write = ompic_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .impl = {
+        .max_access_size = 8,
+    },
+};
+
+static void or1k_ompic_init(Object *obj)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    OR1KOMPICState *s = OR1K_OMPIC(obj);
+
+    memory_region_init_io(&s->mr, OBJECT(s), &ompic_ops, s,
+                          "or1k-ompic", OMPIC_ADDRSPACE_SZ);
+    sysbus_init_mmio(sbd, &s->mr);
+}
+
+static void or1k_ompic_realize(DeviceState *dev, Error **errp)
+{
+    OR1KOMPICState *s = OR1K_OMPIC(dev);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+    int i;
+
+    if (s->num_cpus > OMPIC_MAX_CPUS) {
+        error_setg(errp, "Exceeded maximum CPUs %d", s->num_cpus);
+        return;
+    }
+    /* Init IRQ sources for all CPUs */
+    for (i = 0; i < s->num_cpus; i++) {
+        sysbus_init_irq(sbd, &s->cpus[i].irq);
+    }
+}
+
+static Property or1k_ompic_properties[] = {
+    DEFINE_PROP_UINT32("num-cpus", OR1KOMPICState, num_cpus, 1),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static const VMStateDescription vmstate_or1k_ompic_cpu = {
+    .name = "or1k_ompic_cpu",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+         VMSTATE_UINT32(status, OR1KOMPICCPUState),
+         VMSTATE_UINT32(control, OR1KOMPICCPUState),
+         VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription vmstate_or1k_ompic = {
+    .name = TYPE_OR1K_OMPIC,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+         VMSTATE_STRUCT_ARRAY(cpus, OR1KOMPICState, OMPIC_MAX_CPUS, 1,
+             vmstate_or1k_ompic_cpu, OR1KOMPICCPUState),
+         VMSTATE_UINT32(num_cpus, OR1KOMPICState),
+         VMSTATE_END_OF_LIST()
+    }
+};
+
+static void or1k_ompic_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->props = or1k_ompic_properties;
+    dc->realize = or1k_ompic_realize;
+    dc->vmsd = &vmstate_or1k_ompic;
+}
+
+static const TypeInfo or1k_ompic_info = {
+    .name          = TYPE_OR1K_OMPIC,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(OR1KOMPICState),
+    .instance_init = or1k_ompic_init,
+    .class_init    = or1k_ompic_class_init,
+};
+
+static void or1k_ompic_register_types(void)
+{
+    type_register_static(&or1k_ompic_info);
+}
+
+type_init(or1k_ompic_register_types)
-- 
2.13.5

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

* [OpenRISC] [PATCH 1/5] openrisc/ompic: Add OpenRISC Multicore PIC (OMPIC)
@ 2017-08-23  5:57   ` Stafford Horne
  0 siblings, 0 replies; 24+ messages in thread
From: Stafford Horne @ 2017-08-23  5:57 UTC (permalink / raw)
  To: openrisc

Add OpenRISC Multicore PIC which handles inter processor interrupts
(IPI) between cores.  In OpenRISC all device interrupts are routed to
each core enabling this device to be simple.

Signed-off-by: Stafford Horne <shorne@gmail.com>
---
 default-configs/or1k-softmmu.mak |   1 +
 hw/intc/Makefile.objs            |   1 +
 hw/intc/ompic.c                  | 179 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 181 insertions(+)
 create mode 100644 hw/intc/ompic.c

diff --git a/default-configs/or1k-softmmu.mak b/default-configs/or1k-softmmu.mak
index 10bfa7abb8..6f5824fd48 100644
--- a/default-configs/or1k-softmmu.mak
+++ b/default-configs/or1k-softmmu.mak
@@ -2,3 +2,4 @@
 
 CONFIG_SERIAL=y
 CONFIG_OPENCORES_ETH=y
+CONFIG_OMPIC=y
diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index 78426a7daf..ae358569a1 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -43,3 +43,4 @@ obj-$(CONFIG_ASPEED_SOC) += aspeed_vic.o
 obj-$(CONFIG_ARM_GIC) += arm_gicv3_cpuif.o
 obj-$(CONFIG_MIPS_CPS) += mips_gic.o
 obj-$(CONFIG_NIOS2) += nios2_iic.o
+obj-$(CONFIG_OMPIC) += ompic.o
diff --git a/hw/intc/ompic.c b/hw/intc/ompic.c
new file mode 100644
index 0000000000..c0e34d1268
--- /dev/null
+++ b/hw/intc/ompic.c
@@ -0,0 +1,179 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Authors: Stafford Horne <shorne@gmail.com>
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "hw/hw.h"
+#include "hw/sysbus.h"
+#include "exec/memory.h"
+
+#define TYPE_OR1K_OMPIC "or1k-ompic"
+#define OR1K_OMPIC(obj) OBJECT_CHECK(OR1KOMPICState, (obj), TYPE_OR1K_OMPIC)
+
+#define OMPIC_CTRL_IRQ_ACK  (1 << 31)
+#define OMPIC_CTRL_IRQ_GEN  (1 << 30)
+#define OMPIC_CTRL_DST(cpu) (((cpu) >> 16) & 0x3fff)
+
+#define OMPIC_REG(addr)     (((addr) >> 2) & 0x1)
+#define OMPIC_SRC_CPU(addr) (((addr) >> 3) & 0x4f)
+#define OMPIC_DST_CPU(addr) (((addr) >> 3) & 0x4f)
+
+#define OMPIC_STATUS_IRQ_PENDING (1 << 30)
+#define OMPIC_STATUS_SRC(cpu)    (((cpu) & 0x3fff) << 16)
+#define OMPIC_STATUS_DATA(data)  ((data) & 0xffff)
+
+#define OMPIC_CONTROL 0
+#define OMPIC_STATUS  1
+
+#define OMPIC_MAX_CPUS 4 /* Real max is much higher, but dont waste memory */
+#define OMPIC_ADDRSPACE_SZ (OMPIC_MAX_CPUS * 2 * 4) /* 2 32-bit regs per cpu */
+
+typedef struct OR1KOMPICState OR1KOMPICState;
+typedef struct OR1KOMPICCPUState OR1KOMPICCPUState;
+
+struct OR1KOMPICCPUState {
+    qemu_irq irq;
+    uint32_t status;
+    uint32_t control;
+};
+
+struct OR1KOMPICState {
+    SysBusDevice parent_obj;
+    MemoryRegion mr;
+
+    OR1KOMPICCPUState cpus[OMPIC_MAX_CPUS];
+
+    uint32_t num_cpus;
+};
+
+static uint64_t ompic_read(void *opaque, hwaddr addr, unsigned size)
+{
+    OR1KOMPICState *s = opaque;
+    int src_cpu = OMPIC_SRC_CPU(addr);
+
+    /* We can only write to control control, write control + update status */
+    if (OMPIC_REG(addr) == OMPIC_CONTROL) {
+        return s->cpus[src_cpu].control;
+    } else {
+        return s->cpus[src_cpu].status;
+   }
+
+}
+
+static void ompic_write(void *opaque, hwaddr addr, uint64_t data, unsigned size)
+{
+    OR1KOMPICState *s = opaque;
+    /* We can only write to control control, write control + update status */
+    if (OMPIC_REG(addr) == OMPIC_CONTROL) {
+        int src_cpu = OMPIC_SRC_CPU(addr);
+
+        s->cpus[src_cpu].control = data;
+
+        if (data & OMPIC_CTRL_IRQ_GEN) {
+            int dst_cpu = OMPIC_CTRL_DST(data);
+
+            s->cpus[dst_cpu].status = OMPIC_STATUS_IRQ_PENDING |
+                OMPIC_STATUS_SRC(src_cpu) |
+                OMPIC_STATUS_DATA(data);
+
+            qemu_irq_raise(s->cpus[dst_cpu].irq);
+        }
+        if (data & OMPIC_CTRL_IRQ_ACK) {
+            s->cpus[src_cpu].status &= ~OMPIC_STATUS_IRQ_PENDING;
+            qemu_irq_lower(s->cpus[src_cpu].irq);
+        }
+    }
+}
+
+static const MemoryRegionOps ompic_ops = {
+    .read = ompic_read,
+    .write = ompic_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .impl = {
+        .max_access_size = 8,
+    },
+};
+
+static void or1k_ompic_init(Object *obj)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    OR1KOMPICState *s = OR1K_OMPIC(obj);
+
+    memory_region_init_io(&s->mr, OBJECT(s), &ompic_ops, s,
+                          "or1k-ompic", OMPIC_ADDRSPACE_SZ);
+    sysbus_init_mmio(sbd, &s->mr);
+}
+
+static void or1k_ompic_realize(DeviceState *dev, Error **errp)
+{
+    OR1KOMPICState *s = OR1K_OMPIC(dev);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+    int i;
+
+    if (s->num_cpus > OMPIC_MAX_CPUS) {
+        error_setg(errp, "Exceeded maximum CPUs %d", s->num_cpus);
+        return;
+    }
+    /* Init IRQ sources for all CPUs */
+    for (i = 0; i < s->num_cpus; i++) {
+        sysbus_init_irq(sbd, &s->cpus[i].irq);
+    }
+}
+
+static Property or1k_ompic_properties[] = {
+    DEFINE_PROP_UINT32("num-cpus", OR1KOMPICState, num_cpus, 1),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static const VMStateDescription vmstate_or1k_ompic_cpu = {
+    .name = "or1k_ompic_cpu",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+         VMSTATE_UINT32(status, OR1KOMPICCPUState),
+         VMSTATE_UINT32(control, OR1KOMPICCPUState),
+         VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription vmstate_or1k_ompic = {
+    .name = TYPE_OR1K_OMPIC,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+         VMSTATE_STRUCT_ARRAY(cpus, OR1KOMPICState, OMPIC_MAX_CPUS, 1,
+             vmstate_or1k_ompic_cpu, OR1KOMPICCPUState),
+         VMSTATE_UINT32(num_cpus, OR1KOMPICState),
+         VMSTATE_END_OF_LIST()
+    }
+};
+
+static void or1k_ompic_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->props = or1k_ompic_properties;
+    dc->realize = or1k_ompic_realize;
+    dc->vmsd = &vmstate_or1k_ompic;
+}
+
+static const TypeInfo or1k_ompic_info = {
+    .name          = TYPE_OR1K_OMPIC,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(OR1KOMPICState),
+    .instance_init = or1k_ompic_init,
+    .class_init    = or1k_ompic_class_init,
+};
+
+static void or1k_ompic_register_types(void)
+{
+    type_register_static(&or1k_ompic_info);
+}
+
+type_init(or1k_ompic_register_types)
-- 
2.13.5


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

* [Qemu-devel] [PATCH 2/5] target/openrisc: Make coreid and numcores configurable in state
  2017-08-23  5:57 ` [OpenRISC] " Stafford Horne
@ 2017-08-23  5:57   ` Stafford Horne
  -1 siblings, 0 replies; 24+ messages in thread
From: Stafford Horne @ 2017-08-23  5:57 UTC (permalink / raw)
  To: QEMU Development; +Cc: Richard Henderson, Openrisc, Stafford Horne

Previously coreid and numcores were hard coded as 0 and 1 respectively
as OpenRISC QEMU did not have multicore support.

Multicore support is now being added so these registers need to have
configured values.

Signed-off-by: Stafford Horne <shorne@gmail.com>
---
 hw/openrisc/openrisc_sim.c   | 3 +++
 target/openrisc/cpu.h        | 3 +++
 target/openrisc/machine.c    | 7 +++++--
 target/openrisc/sys_helper.c | 4 ++--
 4 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index e1eeffc490..44a657753d 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -110,6 +110,9 @@ static void openrisc_sim_init(MachineState *machine)
 
     for (n = 0; n < smp_cpus; n++) {
         cpu = cpu_openrisc_init(cpu_model);
+        cpu->env.coreid = n;
+        cpu->env.numcores = smp_cpus;
+
         if (cpu == NULL) {
             fprintf(stderr, "Unable to find CPU definition!\n");
             exit(1);
diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 2721432c4f..4a61e5abfc 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -319,7 +319,10 @@ typedef struct CPUOpenRISCState {
 
     uint32_t picmr;         /* Interrupt mask register */
     uint32_t picsr;         /* Interrupt contrl register*/
+    uint32_t coreid;
+    uint32_t numcores;
 #endif
+
     void *irq[32];          /* Interrupt irq input */
 } CPUOpenRISCState;
 
diff --git a/target/openrisc/machine.c b/target/openrisc/machine.c
index a20cce705d..a879b2b539 100644
--- a/target/openrisc/machine.c
+++ b/target/openrisc/machine.c
@@ -104,8 +104,8 @@ static const VMStateInfo vmstate_sr = {
 
 static const VMStateDescription vmstate_env = {
     .name = "env",
-    .version_id = 6,
-    .minimum_version_id = 6,
+    .version_id = 7,
+    .minimum_version_id = 7,
     .post_load = env_post_load,
     .fields = (VMStateField[]) {
         VMSTATE_UINTTL_2DARRAY(shadow_gpr, CPUOpenRISCState, 16, 32),
@@ -152,6 +152,9 @@ static const VMStateDescription vmstate_env = {
         VMSTATE_UINT32(picmr, CPUOpenRISCState),
         VMSTATE_UINT32(picsr, CPUOpenRISCState),
 
+        VMSTATE_UINT32(coreid, CPUOpenRISCState),
+        VMSTATE_UINT32(numcores, CPUOpenRISCState),
+
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index abdef5d6a5..e138bcf9db 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -249,10 +249,10 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
         return env->esr;
 
     case TO_SPR(0, 128): /* COREID */
-        return 0;
+        return env->coreid;
 
     case TO_SPR(0, 129): /* NUMCORES */
-        return 1;
+        return env->numcores;
 
     case TO_SPR(0, 1024) ... TO_SPR(0, 1024 + (16 * 32)): /* Shadow GPRs */
         idx = (spr - 1024);
-- 
2.13.5

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

* [OpenRISC] [PATCH 2/5] target/openrisc: Make coreid and numcores configurable in state
@ 2017-08-23  5:57   ` Stafford Horne
  0 siblings, 0 replies; 24+ messages in thread
From: Stafford Horne @ 2017-08-23  5:57 UTC (permalink / raw)
  To: openrisc

Previously coreid and numcores were hard coded as 0 and 1 respectively
as OpenRISC QEMU did not have multicore support.

Multicore support is now being added so these registers need to have
configured values.

Signed-off-by: Stafford Horne <shorne@gmail.com>
---
 hw/openrisc/openrisc_sim.c   | 3 +++
 target/openrisc/cpu.h        | 3 +++
 target/openrisc/machine.c    | 7 +++++--
 target/openrisc/sys_helper.c | 4 ++--
 4 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index e1eeffc490..44a657753d 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -110,6 +110,9 @@ static void openrisc_sim_init(MachineState *machine)
 
     for (n = 0; n < smp_cpus; n++) {
         cpu = cpu_openrisc_init(cpu_model);
+        cpu->env.coreid = n;
+        cpu->env.numcores = smp_cpus;
+
         if (cpu == NULL) {
             fprintf(stderr, "Unable to find CPU definition!\n");
             exit(1);
diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 2721432c4f..4a61e5abfc 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -319,7 +319,10 @@ typedef struct CPUOpenRISCState {
 
     uint32_t picmr;         /* Interrupt mask register */
     uint32_t picsr;         /* Interrupt contrl register*/
+    uint32_t coreid;
+    uint32_t numcores;
 #endif
+
     void *irq[32];          /* Interrupt irq input */
 } CPUOpenRISCState;
 
diff --git a/target/openrisc/machine.c b/target/openrisc/machine.c
index a20cce705d..a879b2b539 100644
--- a/target/openrisc/machine.c
+++ b/target/openrisc/machine.c
@@ -104,8 +104,8 @@ static const VMStateInfo vmstate_sr = {
 
 static const VMStateDescription vmstate_env = {
     .name = "env",
-    .version_id = 6,
-    .minimum_version_id = 6,
+    .version_id = 7,
+    .minimum_version_id = 7,
     .post_load = env_post_load,
     .fields = (VMStateField[]) {
         VMSTATE_UINTTL_2DARRAY(shadow_gpr, CPUOpenRISCState, 16, 32),
@@ -152,6 +152,9 @@ static const VMStateDescription vmstate_env = {
         VMSTATE_UINT32(picmr, CPUOpenRISCState),
         VMSTATE_UINT32(picsr, CPUOpenRISCState),
 
+        VMSTATE_UINT32(coreid, CPUOpenRISCState),
+        VMSTATE_UINT32(numcores, CPUOpenRISCState),
+
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index abdef5d6a5..e138bcf9db 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -249,10 +249,10 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
         return env->esr;
 
     case TO_SPR(0, 128): /* COREID */
-        return 0;
+        return env->coreid;
 
     case TO_SPR(0, 129): /* NUMCORES */
-        return 1;
+        return env->numcores;
 
     case TO_SPR(0, 1024) ... TO_SPR(0, 1024 + (16 * 32)): /* Shadow GPRs */
         idx = (spr - 1024);
-- 
2.13.5


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

* [Qemu-devel] [PATCH 3/5] openrisc/cputimer: Perparation for Multicore
  2017-08-23  5:57 ` [OpenRISC] " Stafford Horne
@ 2017-08-23  5:57   ` Stafford Horne
  -1 siblings, 0 replies; 24+ messages in thread
From: Stafford Horne @ 2017-08-23  5:57 UTC (permalink / raw)
  To: QEMU Development; +Cc: Richard Henderson, Openrisc, Stafford Horne

In order to support multicore system we move some of the previously
static state variables into the state of each core.

On the other hand in order to allow timers to be synced between each
code the ttcr (tick timer count register) is moved out of the core.
This is not as per real hardware spec which has a separate timer counter
per core, but it seems the most simple way to keep each clock in sync.

Signed-off-by: Stafford Horne <shorne@gmail.com>
---
 hw/openrisc/cputimer.c       | 62 +++++++++++++++++++++++++++++++++-----------
 target/openrisc/cpu.c        |  1 -
 target/openrisc/cpu.h        |  4 ++-
 target/openrisc/machine.c    |  1 -
 target/openrisc/sys_helper.c |  4 +--
 5 files changed, 52 insertions(+), 20 deletions(-)

diff --git a/hw/openrisc/cputimer.c b/hw/openrisc/cputimer.c
index febc469170..4c5415ff75 100644
--- a/hw/openrisc/cputimer.c
+++ b/hw/openrisc/cputimer.c
@@ -25,39 +25,56 @@
 
 #define TIMER_PERIOD 50 /* 50 ns period for 20 MHz timer */
 
-/* The time when TTCR changes */
-static uint64_t last_clk;
-static int is_counting;
+/* Tick Timer global state to allow all cores to be in sync */
+typedef struct OR1KTimerState {
+    uint32_t ttcr;
+    uint64_t last_clk;
+} OR1KTimerState;
 
+static OR1KTimerState *or1k_timer;
+
+void cpu_openrisc_count_set(OpenRISCCPU *cpu, uint32_t val)
+{
+    or1k_timer->ttcr = val;
+}
+
+uint32_t cpu_openrisc_count_get(OpenRISCCPU *cpu)
+{
+    return or1k_timer->ttcr;
+}
+
+/* Add elapsed ticks to ttcr */
 void cpu_openrisc_count_update(OpenRISCCPU *cpu)
 {
     uint64_t now;
 
-    if (!is_counting) {
+    if (!cpu->env.is_counting) {
         return;
     }
     now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-    cpu->env.ttcr += (uint32_t)((now - last_clk) / TIMER_PERIOD);
-    last_clk = now;
+    or1k_timer->ttcr += (uint32_t)((now - or1k_timer->last_clk)
+                                    / TIMER_PERIOD);
+    or1k_timer->last_clk = now;
 }
 
+/* Update the next timeout time as difference between ttmr and ttcr */
 void cpu_openrisc_timer_update(OpenRISCCPU *cpu)
 {
     uint32_t wait;
     uint64_t now, next;
 
-    if (!is_counting) {
+    if (!cpu->env.is_counting) {
         return;
     }
 
     cpu_openrisc_count_update(cpu);
-    now = last_clk;
+    now = or1k_timer->last_clk;
 
-    if ((cpu->env.ttmr & TTMR_TP) <= (cpu->env.ttcr & TTMR_TP)) {
-        wait = TTMR_TP - (cpu->env.ttcr & TTMR_TP) + 1;
+    if ((cpu->env.ttmr & TTMR_TP) <= (or1k_timer->ttcr & TTMR_TP)) {
+        wait = TTMR_TP - (or1k_timer->ttcr & TTMR_TP) + 1;
         wait += cpu->env.ttmr & TTMR_TP;
     } else {
-        wait = (cpu->env.ttmr & TTMR_TP) - (cpu->env.ttcr & TTMR_TP);
+        wait = (cpu->env.ttmr & TTMR_TP) - (or1k_timer->ttcr & TTMR_TP);
     }
     next = now + (uint64_t)wait * TIMER_PERIOD;
     timer_mod(cpu->env.timer, next);
@@ -66,7 +83,7 @@ void cpu_openrisc_timer_update(OpenRISCCPU *cpu)
 
 void cpu_openrisc_count_start(OpenRISCCPU *cpu)
 {
-    is_counting = 1;
+    cpu->env.is_counting = 1;
     cpu_openrisc_count_update(cpu);
 }
 
@@ -74,7 +91,7 @@ void cpu_openrisc_count_stop(OpenRISCCPU *cpu)
 {
     timer_del(cpu->env.timer);
     cpu_openrisc_count_update(cpu);
-    is_counting = 0;
+    cpu->env.is_counting = 0;
 }
 
 static void openrisc_timer_cb(void *opaque)
@@ -93,7 +110,7 @@ static void openrisc_timer_cb(void *opaque)
     case TIMER_NONE:
         break;
     case TIMER_INTR:
-        cpu->env.ttcr = 0;
+        or1k_timer->ttcr = 0;
         break;
     case TIMER_SHOT:
         cpu_openrisc_count_stop(cpu);
@@ -105,9 +122,24 @@ static void openrisc_timer_cb(void *opaque)
     cpu_openrisc_timer_update(cpu);
 }
 
+static const VMStateDescription vmstate_or1k_timer = {
+    .name = "or1k_timer",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(ttcr, OR1KTimerState),
+        VMSTATE_UINT64(last_clk, OR1KTimerState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 void cpu_openrisc_clock_init(OpenRISCCPU *cpu)
 {
     cpu->env.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &openrisc_timer_cb, cpu);
     cpu->env.ttmr = 0x00000000;
-    cpu->env.ttcr = 0x00000000;
+
+    if (or1k_timer == NULL) {
+        or1k_timer = g_new0(OR1KTimerState, 1);
+        vmstate_register(NULL, 0, &vmstate_or1k_timer, or1k_timer);
+    }
 }
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index 1d6330cbcc..0a46684987 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -61,7 +61,6 @@ static void openrisc_cpu_reset(CPUState *s)
     cpu->env.picsr = 0x00000000;
 
     cpu->env.ttmr = 0x00000000;
-    cpu->env.ttcr = 0x00000000;
 #endif
 }
 
diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 4a61e5abfc..265f48ca43 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -315,7 +315,7 @@ typedef struct CPUOpenRISCState {
 
     QEMUTimer *timer;
     uint32_t ttmr;          /* Timer tick mode register */
-    uint32_t ttcr;          /* Timer tick count register */
+    int is_counting;
 
     uint32_t picmr;         /* Interrupt mask register */
     uint32_t picsr;         /* Interrupt contrl register*/
@@ -376,6 +376,8 @@ void cpu_openrisc_pic_init(OpenRISCCPU *cpu);
 
 /* hw/openrisc_timer.c */
 void cpu_openrisc_clock_init(OpenRISCCPU *cpu);
+uint32_t cpu_openrisc_count_get(OpenRISCCPU *cpu);
+void cpu_openrisc_count_set(OpenRISCCPU *cpu, uint32_t val);
 void cpu_openrisc_count_update(OpenRISCCPU *cpu);
 void cpu_openrisc_timer_update(OpenRISCCPU *cpu);
 void cpu_openrisc_count_start(OpenRISCCPU *cpu);
diff --git a/target/openrisc/machine.c b/target/openrisc/machine.c
index a879b2b539..c6a945f0df 100644
--- a/target/openrisc/machine.c
+++ b/target/openrisc/machine.c
@@ -147,7 +147,6 @@ static const VMStateDescription vmstate_env = {
 
         VMSTATE_TIMER_PTR(timer, CPUOpenRISCState),
         VMSTATE_UINT32(ttmr, CPUOpenRISCState),
-        VMSTATE_UINT32(ttcr, CPUOpenRISCState),
 
         VMSTATE_UINT32(picmr, CPUOpenRISCState),
         VMSTATE_UINT32(picsr, CPUOpenRISCState),
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index e138bcf9db..35be44beff 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -188,7 +188,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
         break;
 
     case TO_SPR(10, 1): /* TTCR */
-        env->ttcr = rb;
+        cpu_openrisc_count_set(cpu, rb);
         if (env->ttmr & TIMER_NONE) {
             return;
         }
@@ -311,7 +311,7 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
 
     case TO_SPR(10, 1): /* TTCR */
         cpu_openrisc_count_update(cpu);
-        return env->ttcr;
+        return cpu_openrisc_count_get(cpu);
 
     default:
         break;
-- 
2.13.5

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

* [OpenRISC] [PATCH 3/5] openrisc/cputimer: Perparation for Multicore
@ 2017-08-23  5:57   ` Stafford Horne
  0 siblings, 0 replies; 24+ messages in thread
From: Stafford Horne @ 2017-08-23  5:57 UTC (permalink / raw)
  To: openrisc

In order to support multicore system we move some of the previously
static state variables into the state of each core.

On the other hand in order to allow timers to be synced between each
code the ttcr (tick timer count register) is moved out of the core.
This is not as per real hardware spec which has a separate timer counter
per core, but it seems the most simple way to keep each clock in sync.

Signed-off-by: Stafford Horne <shorne@gmail.com>
---
 hw/openrisc/cputimer.c       | 62 +++++++++++++++++++++++++++++++++-----------
 target/openrisc/cpu.c        |  1 -
 target/openrisc/cpu.h        |  4 ++-
 target/openrisc/machine.c    |  1 -
 target/openrisc/sys_helper.c |  4 +--
 5 files changed, 52 insertions(+), 20 deletions(-)

diff --git a/hw/openrisc/cputimer.c b/hw/openrisc/cputimer.c
index febc469170..4c5415ff75 100644
--- a/hw/openrisc/cputimer.c
+++ b/hw/openrisc/cputimer.c
@@ -25,39 +25,56 @@
 
 #define TIMER_PERIOD 50 /* 50 ns period for 20 MHz timer */
 
-/* The time when TTCR changes */
-static uint64_t last_clk;
-static int is_counting;
+/* Tick Timer global state to allow all cores to be in sync */
+typedef struct OR1KTimerState {
+    uint32_t ttcr;
+    uint64_t last_clk;
+} OR1KTimerState;
 
+static OR1KTimerState *or1k_timer;
+
+void cpu_openrisc_count_set(OpenRISCCPU *cpu, uint32_t val)
+{
+    or1k_timer->ttcr = val;
+}
+
+uint32_t cpu_openrisc_count_get(OpenRISCCPU *cpu)
+{
+    return or1k_timer->ttcr;
+}
+
+/* Add elapsed ticks to ttcr */
 void cpu_openrisc_count_update(OpenRISCCPU *cpu)
 {
     uint64_t now;
 
-    if (!is_counting) {
+    if (!cpu->env.is_counting) {
         return;
     }
     now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-    cpu->env.ttcr += (uint32_t)((now - last_clk) / TIMER_PERIOD);
-    last_clk = now;
+    or1k_timer->ttcr += (uint32_t)((now - or1k_timer->last_clk)
+                                    / TIMER_PERIOD);
+    or1k_timer->last_clk = now;
 }
 
+/* Update the next timeout time as difference between ttmr and ttcr */
 void cpu_openrisc_timer_update(OpenRISCCPU *cpu)
 {
     uint32_t wait;
     uint64_t now, next;
 
-    if (!is_counting) {
+    if (!cpu->env.is_counting) {
         return;
     }
 
     cpu_openrisc_count_update(cpu);
-    now = last_clk;
+    now = or1k_timer->last_clk;
 
-    if ((cpu->env.ttmr & TTMR_TP) <= (cpu->env.ttcr & TTMR_TP)) {
-        wait = TTMR_TP - (cpu->env.ttcr & TTMR_TP) + 1;
+    if ((cpu->env.ttmr & TTMR_TP) <= (or1k_timer->ttcr & TTMR_TP)) {
+        wait = TTMR_TP - (or1k_timer->ttcr & TTMR_TP) + 1;
         wait += cpu->env.ttmr & TTMR_TP;
     } else {
-        wait = (cpu->env.ttmr & TTMR_TP) - (cpu->env.ttcr & TTMR_TP);
+        wait = (cpu->env.ttmr & TTMR_TP) - (or1k_timer->ttcr & TTMR_TP);
     }
     next = now + (uint64_t)wait * TIMER_PERIOD;
     timer_mod(cpu->env.timer, next);
@@ -66,7 +83,7 @@ void cpu_openrisc_timer_update(OpenRISCCPU *cpu)
 
 void cpu_openrisc_count_start(OpenRISCCPU *cpu)
 {
-    is_counting = 1;
+    cpu->env.is_counting = 1;
     cpu_openrisc_count_update(cpu);
 }
 
@@ -74,7 +91,7 @@ void cpu_openrisc_count_stop(OpenRISCCPU *cpu)
 {
     timer_del(cpu->env.timer);
     cpu_openrisc_count_update(cpu);
-    is_counting = 0;
+    cpu->env.is_counting = 0;
 }
 
 static void openrisc_timer_cb(void *opaque)
@@ -93,7 +110,7 @@ static void openrisc_timer_cb(void *opaque)
     case TIMER_NONE:
         break;
     case TIMER_INTR:
-        cpu->env.ttcr = 0;
+        or1k_timer->ttcr = 0;
         break;
     case TIMER_SHOT:
         cpu_openrisc_count_stop(cpu);
@@ -105,9 +122,24 @@ static void openrisc_timer_cb(void *opaque)
     cpu_openrisc_timer_update(cpu);
 }
 
+static const VMStateDescription vmstate_or1k_timer = {
+    .name = "or1k_timer",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(ttcr, OR1KTimerState),
+        VMSTATE_UINT64(last_clk, OR1KTimerState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 void cpu_openrisc_clock_init(OpenRISCCPU *cpu)
 {
     cpu->env.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &openrisc_timer_cb, cpu);
     cpu->env.ttmr = 0x00000000;
-    cpu->env.ttcr = 0x00000000;
+
+    if (or1k_timer == NULL) {
+        or1k_timer = g_new0(OR1KTimerState, 1);
+        vmstate_register(NULL, 0, &vmstate_or1k_timer, or1k_timer);
+    }
 }
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index 1d6330cbcc..0a46684987 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -61,7 +61,6 @@ static void openrisc_cpu_reset(CPUState *s)
     cpu->env.picsr = 0x00000000;
 
     cpu->env.ttmr = 0x00000000;
-    cpu->env.ttcr = 0x00000000;
 #endif
 }
 
diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 4a61e5abfc..265f48ca43 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -315,7 +315,7 @@ typedef struct CPUOpenRISCState {
 
     QEMUTimer *timer;
     uint32_t ttmr;          /* Timer tick mode register */
-    uint32_t ttcr;          /* Timer tick count register */
+    int is_counting;
 
     uint32_t picmr;         /* Interrupt mask register */
     uint32_t picsr;         /* Interrupt contrl register*/
@@ -376,6 +376,8 @@ void cpu_openrisc_pic_init(OpenRISCCPU *cpu);
 
 /* hw/openrisc_timer.c */
 void cpu_openrisc_clock_init(OpenRISCCPU *cpu);
+uint32_t cpu_openrisc_count_get(OpenRISCCPU *cpu);
+void cpu_openrisc_count_set(OpenRISCCPU *cpu, uint32_t val);
 void cpu_openrisc_count_update(OpenRISCCPU *cpu);
 void cpu_openrisc_timer_update(OpenRISCCPU *cpu);
 void cpu_openrisc_count_start(OpenRISCCPU *cpu);
diff --git a/target/openrisc/machine.c b/target/openrisc/machine.c
index a879b2b539..c6a945f0df 100644
--- a/target/openrisc/machine.c
+++ b/target/openrisc/machine.c
@@ -147,7 +147,6 @@ static const VMStateDescription vmstate_env = {
 
         VMSTATE_TIMER_PTR(timer, CPUOpenRISCState),
         VMSTATE_UINT32(ttmr, CPUOpenRISCState),
-        VMSTATE_UINT32(ttcr, CPUOpenRISCState),
 
         VMSTATE_UINT32(picmr, CPUOpenRISCState),
         VMSTATE_UINT32(picsr, CPUOpenRISCState),
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index e138bcf9db..35be44beff 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -188,7 +188,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
         break;
 
     case TO_SPR(10, 1): /* TTCR */
-        env->ttcr = rb;
+        cpu_openrisc_count_set(cpu, rb);
         if (env->ttmr & TIMER_NONE) {
             return;
         }
@@ -311,7 +311,7 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
 
     case TO_SPR(10, 1): /* TTCR */
         cpu_openrisc_count_update(cpu);
-        return env->ttcr;
+        return cpu_openrisc_count_get(cpu);
 
     default:
         break;
-- 
2.13.5


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

* [Qemu-devel] [PATCH 4/5] openrisc: Initial SMP support
  2017-08-23  5:57 ` [OpenRISC] " Stafford Horne
@ 2017-08-23  5:57   ` Stafford Horne
  -1 siblings, 0 replies; 24+ messages in thread
From: Stafford Horne @ 2017-08-23  5:57 UTC (permalink / raw)
  To: QEMU Development; +Cc: Richard Henderson, Openrisc, Stafford Horne

Wire in ompic and add basic support for SMP.  The OpenRISC is special in
that interrupts for devices are routed to each core's PIC.  This is
achieved using the qemu_irq_split utility, but this currently limits
OpenRISC to 2 cores.

This models the reference architecture described in the OpenRISC spec
1.2 proposal.

  https://github.com/stffrdhrn/doc/raw/arch-1.2-proposal/openrisc-arch-1.2-rev0.pdf

The changes to the intialization of the sim include:

CPU Reset
 o Reset each cpu to the bootstrap PC rather than only a single cpu as
   done before.
 o During Kernel loading the bootstrap PC is saved in a static global.

Network Initialization
 o Connect the interrupt to each CPU
 o Use more simple sysbus_mmio_map() rather than memory_region_add_subregion()

Sim Initialization
 o Initialize the pic and tick timer per cpu
 o Wire in the OMPIC if SMP is enabled
 o Wire the serial irq to each CPU using qemu_irq_split()

Signed-off-by: Stafford Horne <shorne@gmail.com>
---
 hw/openrisc/openrisc_sim.c | 84 +++++++++++++++++++++++++++++++++-------------
 1 file changed, 61 insertions(+), 23 deletions(-)

diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index 44a657753d..f06a3e111b 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -35,36 +35,60 @@
 
 #define KERNEL_LOAD_ADDR 0x100
 
+static struct openrisc_boot_info {
+    uint32_t bootstrap_pc;
+} boot_info;
+
 static void main_cpu_reset(void *opaque)
 {
     OpenRISCCPU *cpu = opaque;
+    CPUState *cs = CPU(cpu);
 
     cpu_reset(CPU(cpu));
+
+    cpu_set_pc(cs, boot_info.bootstrap_pc);
 }
 
-static void openrisc_sim_net_init(MemoryRegion *address_space,
-                                  hwaddr base,
-                                  hwaddr descriptors,
-                                  qemu_irq irq, NICInfo *nd)
+static void openrisc_sim_net_init(hwaddr base, hwaddr descriptors,
+                                  int num_cpus, qemu_irq **cpu_irqs,
+                                  int irq_pin, NICInfo *nd)
 {
     DeviceState *dev;
     SysBusDevice *s;
+    int i;
 
     dev = qdev_create(NULL, "open_eth");
     qdev_set_nic_properties(dev, nd);
     qdev_init_nofail(dev);
 
     s = SYS_BUS_DEVICE(dev);
-    sysbus_connect_irq(s, 0, irq);
-    memory_region_add_subregion(address_space, base,
-                                sysbus_mmio_get_region(s, 0));
-    memory_region_add_subregion(address_space, descriptors,
-                                sysbus_mmio_get_region(s, 1));
+    for (i = 0; i < num_cpus; i++) {
+        sysbus_connect_irq(s, 0, cpu_irqs[i][irq_pin]);
+    }
+    sysbus_mmio_map(s, 0, base);
+    sysbus_mmio_map(s, 1, descriptors);
 }
 
-static void cpu_openrisc_load_kernel(ram_addr_t ram_size,
-                                     const char *kernel_filename,
-                                     OpenRISCCPU *cpu)
+static void openrisc_sim_ompic_init(hwaddr base, int num_cpus,
+                                    qemu_irq **cpu_irqs, int irq_pin)
+{
+    DeviceState *dev;
+    SysBusDevice *s;
+    int i;
+
+    dev = qdev_create(NULL, "or1k-ompic");
+    qdev_prop_set_uint32(dev, "num-cpus", num_cpus);
+    qdev_init_nofail(dev);
+
+    s = SYS_BUS_DEVICE(dev);
+    for (i = 0; i < num_cpus; i++) {
+        sysbus_connect_irq(s, i, cpu_irqs[i][irq_pin]);
+    }
+    sysbus_mmio_map(s, 0, base);
+}
+
+static void openrisc_load_kernel(ram_addr_t ram_size,
+                                 const char *kernel_filename)
 {
     long kernel_size;
     uint64_t elf_entry;
@@ -83,6 +107,9 @@ static void cpu_openrisc_load_kernel(ram_addr_t ram_size,
             kernel_size = load_image_targphys(kernel_filename,
                                               KERNEL_LOAD_ADDR,
                                               ram_size - KERNEL_LOAD_ADDR);
+        }
+
+        if (entry <= 0) {
             entry = KERNEL_LOAD_ADDR;
         }
 
@@ -91,7 +118,7 @@ static void cpu_openrisc_load_kernel(ram_addr_t ram_size,
                     kernel_filename);
             exit(1);
         }
-        cpu->env.pc = entry;
+        boot_info.bootstrap_pc = entry;
     }
 }
 
@@ -102,6 +129,8 @@ static void openrisc_sim_init(MachineState *machine)
     const char *kernel_filename = machine->kernel_filename;
     OpenRISCCPU *cpu = NULL;
     MemoryRegion *ram;
+    qemu_irq *cpu_irqs[2];
+    qemu_irq serial_irq;
     int n;
 
     if (!cpu_model) {
@@ -117,33 +146,42 @@ static void openrisc_sim_init(MachineState *machine)
             fprintf(stderr, "Unable to find CPU definition!\n");
             exit(1);
         }
+        cpu_openrisc_pic_init(cpu);
+        cpu_irqs[n] = (qemu_irq *) cpu->env.irq;
+
+        cpu_openrisc_clock_init(cpu);
+
         qemu_register_reset(main_cpu_reset, cpu);
-        main_cpu_reset(cpu);
     }
 
     ram = g_malloc(sizeof(*ram));
     memory_region_init_ram(ram, NULL, "openrisc.ram", ram_size, &error_fatal);
     memory_region_add_subregion(get_system_memory(), 0, ram);
 
-    cpu_openrisc_pic_init(cpu);
-    cpu_openrisc_clock_init(cpu);
+    if (nd_table[0].used) {
+        openrisc_sim_net_init(0x92000000, 0x92000400, smp_cpus,
+                              cpu_irqs, 4, nd_table);
+    }
 
-    serial_mm_init(get_system_memory(), 0x90000000, 0, cpu->env.irq[2],
-                   115200, serial_hds[0], DEVICE_NATIVE_ENDIAN);
+    if (smp_cpus > 1) {
+        openrisc_sim_ompic_init(0x98000000, smp_cpus, cpu_irqs, 1);
 
-    if (nd_table[0].used) {
-        openrisc_sim_net_init(get_system_memory(), 0x92000000,
-                              0x92000400, cpu->env.irq[4], nd_table);
+        serial_irq = qemu_irq_split(cpu_irqs[0][2], cpu_irqs[1][2]);
+    } else {
+        serial_irq = cpu_irqs[0][2];
     }
 
-    cpu_openrisc_load_kernel(ram_size, kernel_filename, cpu);
+    serial_mm_init(get_system_memory(), 0x90000000, 0, serial_irq,
+                   115200, serial_hds[0], DEVICE_NATIVE_ENDIAN);
+
+    openrisc_load_kernel(ram_size, kernel_filename);
 }
 
 static void openrisc_sim_machine_init(MachineClass *mc)
 {
     mc->desc = "or1k simulation";
     mc->init = openrisc_sim_init;
-    mc->max_cpus = 1;
+    mc->max_cpus = 2;
     mc->is_default = 1;
 }
 
-- 
2.13.5

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

* [OpenRISC] [PATCH 4/5] openrisc: Initial SMP support
@ 2017-08-23  5:57   ` Stafford Horne
  0 siblings, 0 replies; 24+ messages in thread
From: Stafford Horne @ 2017-08-23  5:57 UTC (permalink / raw)
  To: openrisc

Wire in ompic and add basic support for SMP.  The OpenRISC is special in
that interrupts for devices are routed to each core's PIC.  This is
achieved using the qemu_irq_split utility, but this currently limits
OpenRISC to 2 cores.

This models the reference architecture described in the OpenRISC spec
1.2 proposal.

  https://github.com/stffrdhrn/doc/raw/arch-1.2-proposal/openrisc-arch-1.2-rev0.pdf

The changes to the intialization of the sim include:

CPU Reset
 o Reset each cpu to the bootstrap PC rather than only a single cpu as
   done before.
 o During Kernel loading the bootstrap PC is saved in a static global.

Network Initialization
 o Connect the interrupt to each CPU
 o Use more simple sysbus_mmio_map() rather than memory_region_add_subregion()

Sim Initialization
 o Initialize the pic and tick timer per cpu
 o Wire in the OMPIC if SMP is enabled
 o Wire the serial irq to each CPU using qemu_irq_split()

Signed-off-by: Stafford Horne <shorne@gmail.com>
---
 hw/openrisc/openrisc_sim.c | 84 +++++++++++++++++++++++++++++++++-------------
 1 file changed, 61 insertions(+), 23 deletions(-)

diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index 44a657753d..f06a3e111b 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -35,36 +35,60 @@
 
 #define KERNEL_LOAD_ADDR 0x100
 
+static struct openrisc_boot_info {
+    uint32_t bootstrap_pc;
+} boot_info;
+
 static void main_cpu_reset(void *opaque)
 {
     OpenRISCCPU *cpu = opaque;
+    CPUState *cs = CPU(cpu);
 
     cpu_reset(CPU(cpu));
+
+    cpu_set_pc(cs, boot_info.bootstrap_pc);
 }
 
-static void openrisc_sim_net_init(MemoryRegion *address_space,
-                                  hwaddr base,
-                                  hwaddr descriptors,
-                                  qemu_irq irq, NICInfo *nd)
+static void openrisc_sim_net_init(hwaddr base, hwaddr descriptors,
+                                  int num_cpus, qemu_irq **cpu_irqs,
+                                  int irq_pin, NICInfo *nd)
 {
     DeviceState *dev;
     SysBusDevice *s;
+    int i;
 
     dev = qdev_create(NULL, "open_eth");
     qdev_set_nic_properties(dev, nd);
     qdev_init_nofail(dev);
 
     s = SYS_BUS_DEVICE(dev);
-    sysbus_connect_irq(s, 0, irq);
-    memory_region_add_subregion(address_space, base,
-                                sysbus_mmio_get_region(s, 0));
-    memory_region_add_subregion(address_space, descriptors,
-                                sysbus_mmio_get_region(s, 1));
+    for (i = 0; i < num_cpus; i++) {
+        sysbus_connect_irq(s, 0, cpu_irqs[i][irq_pin]);
+    }
+    sysbus_mmio_map(s, 0, base);
+    sysbus_mmio_map(s, 1, descriptors);
 }
 
-static void cpu_openrisc_load_kernel(ram_addr_t ram_size,
-                                     const char *kernel_filename,
-                                     OpenRISCCPU *cpu)
+static void openrisc_sim_ompic_init(hwaddr base, int num_cpus,
+                                    qemu_irq **cpu_irqs, int irq_pin)
+{
+    DeviceState *dev;
+    SysBusDevice *s;
+    int i;
+
+    dev = qdev_create(NULL, "or1k-ompic");
+    qdev_prop_set_uint32(dev, "num-cpus", num_cpus);
+    qdev_init_nofail(dev);
+
+    s = SYS_BUS_DEVICE(dev);
+    for (i = 0; i < num_cpus; i++) {
+        sysbus_connect_irq(s, i, cpu_irqs[i][irq_pin]);
+    }
+    sysbus_mmio_map(s, 0, base);
+}
+
+static void openrisc_load_kernel(ram_addr_t ram_size,
+                                 const char *kernel_filename)
 {
     long kernel_size;
     uint64_t elf_entry;
@@ -83,6 +107,9 @@ static void cpu_openrisc_load_kernel(ram_addr_t ram_size,
             kernel_size = load_image_targphys(kernel_filename,
                                               KERNEL_LOAD_ADDR,
                                               ram_size - KERNEL_LOAD_ADDR);
+        }
+
+        if (entry <= 0) {
             entry = KERNEL_LOAD_ADDR;
         }
 
@@ -91,7 +118,7 @@ static void cpu_openrisc_load_kernel(ram_addr_t ram_size,
                     kernel_filename);
             exit(1);
         }
-        cpu->env.pc = entry;
+        boot_info.bootstrap_pc = entry;
     }
 }
 
@@ -102,6 +129,8 @@ static void openrisc_sim_init(MachineState *machine)
     const char *kernel_filename = machine->kernel_filename;
     OpenRISCCPU *cpu = NULL;
     MemoryRegion *ram;
+    qemu_irq *cpu_irqs[2];
+    qemu_irq serial_irq;
     int n;
 
     if (!cpu_model) {
@@ -117,33 +146,42 @@ static void openrisc_sim_init(MachineState *machine)
             fprintf(stderr, "Unable to find CPU definition!\n");
             exit(1);
         }
+        cpu_openrisc_pic_init(cpu);
+        cpu_irqs[n] = (qemu_irq *) cpu->env.irq;
+
+        cpu_openrisc_clock_init(cpu);
+
         qemu_register_reset(main_cpu_reset, cpu);
-        main_cpu_reset(cpu);
     }
 
     ram = g_malloc(sizeof(*ram));
     memory_region_init_ram(ram, NULL, "openrisc.ram", ram_size, &error_fatal);
     memory_region_add_subregion(get_system_memory(), 0, ram);
 
-    cpu_openrisc_pic_init(cpu);
-    cpu_openrisc_clock_init(cpu);
+    if (nd_table[0].used) {
+        openrisc_sim_net_init(0x92000000, 0x92000400, smp_cpus,
+                              cpu_irqs, 4, nd_table);
+    }
 
-    serial_mm_init(get_system_memory(), 0x90000000, 0, cpu->env.irq[2],
-                   115200, serial_hds[0], DEVICE_NATIVE_ENDIAN);
+    if (smp_cpus > 1) {
+        openrisc_sim_ompic_init(0x98000000, smp_cpus, cpu_irqs, 1);
 
-    if (nd_table[0].used) {
-        openrisc_sim_net_init(get_system_memory(), 0x92000000,
-                              0x92000400, cpu->env.irq[4], nd_table);
+        serial_irq = qemu_irq_split(cpu_irqs[0][2], cpu_irqs[1][2]);
+    } else {
+        serial_irq = cpu_irqs[0][2];
     }
 
-    cpu_openrisc_load_kernel(ram_size, kernel_filename, cpu);
+    serial_mm_init(get_system_memory(), 0x90000000, 0, serial_irq,
+                   115200, serial_hds[0], DEVICE_NATIVE_ENDIAN);
+
+    openrisc_load_kernel(ram_size, kernel_filename);
 }
 
 static void openrisc_sim_machine_init(MachineClass *mc)
 {
     mc->desc = "or1k simulation";
     mc->init = openrisc_sim_init;
-    mc->max_cpus = 1;
+    mc->max_cpus = 2;
     mc->is_default = 1;
 }
 
-- 
2.13.5


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

* [Qemu-devel] [PATCH 5/5] openrisc: Only kick cpu on timeout, not on update
  2017-08-23  5:57 ` [OpenRISC] " Stafford Horne
@ 2017-08-23  5:57   ` Stafford Horne
  -1 siblings, 0 replies; 24+ messages in thread
From: Stafford Horne @ 2017-08-23  5:57 UTC (permalink / raw)
  To: QEMU Development; +Cc: Richard Henderson, Openrisc, Stafford Horne

Previously we were kicking the cpu on every update.  This caused
problems noticeable in SMP configurations where one CPU got pinned
continuously servicing timer exceptions.

Signed-off-by: Stafford Horne <shorne@gmail.com>
---
 hw/openrisc/cputimer.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/openrisc/cputimer.c b/hw/openrisc/cputimer.c
index 4c5415ff75..850f88761c 100644
--- a/hw/openrisc/cputimer.c
+++ b/hw/openrisc/cputimer.c
@@ -78,7 +78,6 @@ void cpu_openrisc_timer_update(OpenRISCCPU *cpu)
     }
     next = now + (uint64_t)wait * TIMER_PERIOD;
     timer_mod(cpu->env.timer, next);
-    qemu_cpu_kick(CPU(cpu));
 }
 
 void cpu_openrisc_count_start(OpenRISCCPU *cpu)
@@ -120,6 +119,7 @@ static void openrisc_timer_cb(void *opaque)
     }
 
     cpu_openrisc_timer_update(cpu);
+    qemu_cpu_kick(CPU(cpu));
 }
 
 static const VMStateDescription vmstate_or1k_timer = {
-- 
2.13.5

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

* [OpenRISC] [PATCH 5/5] openrisc: Only kick cpu on timeout, not on update
@ 2017-08-23  5:57   ` Stafford Horne
  0 siblings, 0 replies; 24+ messages in thread
From: Stafford Horne @ 2017-08-23  5:57 UTC (permalink / raw)
  To: openrisc

Previously we were kicking the cpu on every update.  This caused
problems noticeable in SMP configurations where one CPU got pinned
continuously servicing timer exceptions.

Signed-off-by: Stafford Horne <shorne@gmail.com>
---
 hw/openrisc/cputimer.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/openrisc/cputimer.c b/hw/openrisc/cputimer.c
index 4c5415ff75..850f88761c 100644
--- a/hw/openrisc/cputimer.c
+++ b/hw/openrisc/cputimer.c
@@ -78,7 +78,6 @@ void cpu_openrisc_timer_update(OpenRISCCPU *cpu)
     }
     next = now + (uint64_t)wait * TIMER_PERIOD;
     timer_mod(cpu->env.timer, next);
-    qemu_cpu_kick(CPU(cpu));
 }
 
 void cpu_openrisc_count_start(OpenRISCCPU *cpu)
@@ -120,6 +119,7 @@ static void openrisc_timer_cb(void *opaque)
     }
 
     cpu_openrisc_timer_update(cpu);
+    qemu_cpu_kick(CPU(cpu));
 }
 
 static const VMStateDescription vmstate_or1k_timer = {
-- 
2.13.5


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

* Re: [Qemu-devel] [PATCH 0/5] OpenRISC SMP Support
  2017-08-23  5:57 ` [OpenRISC] " Stafford Horne
@ 2017-10-07  0:21   ` Stafford Horne
  -1 siblings, 0 replies; 24+ messages in thread
From: Stafford Horne @ 2017-10-07  0:21 UTC (permalink / raw)
  To: QEMU Development
  Cc: Richard Henderson, Openrisc, Stafford Horne, Peter Maydell

Hello,

Any takers on this?  If not Ill consider sending a pull request
if/when the merge window is open.

-Stafford

On Wed, Aug 23, 2017 at 2:57 PM, Stafford Horne <shorne@gmail.com> wrote:
> Hello,
>
> This series adds SMP support for OpenRISC.  The platform is based on the
> work that Stefan Kristiansson did around 2012 implemented in Verilog and
> run on FPGAs.  I have been working to upstream this work, these are my QEMU
> patches I have been used to help with testing.
>
> I have documented the platform in the OpenRISC 1.2 specification proposal
> available here:
>   https://github.com/stffrdhrn/doc/raw/arch-1.2-proposal/openrisc-arch-1.2-rev0.pdf
>
> My latest kernel patches are available here:
>   https://github.com/stffrdhrn/linux.git openrisc-4.13-smp-qspinlock
>
> Stafford Horne (5):
>   openrisc/ompic: Add OpenRISC Multicore PIC (OMPIC)
>   target/openrisc: Make coreid and numcores configurable in state
>   openrisc/cputimer: Perparation for Multicore
>   openrisc: Initial SMP support
>   openrisc: Only kick cpu on timeout, not on update
>
>  default-configs/or1k-softmmu.mak |   1 +
>  hw/intc/Makefile.objs            |   1 +
>  hw/intc/ompic.c                  | 179 +++++++++++++++++++++++++++++++++++++++
>  hw/openrisc/cputimer.c           |  64 ++++++++++----
>  hw/openrisc/openrisc_sim.c       |  87 ++++++++++++++-----
>  target/openrisc/cpu.c            |   1 -
>  target/openrisc/cpu.h            |   7 +-
>  target/openrisc/machine.c        |   8 +-
>  target/openrisc/sys_helper.c     |   8 +-
>  9 files changed, 308 insertions(+), 48 deletions(-)
>  create mode 100644 hw/intc/ompic.c
>
> --
> 2.13.5
>

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

* [OpenRISC] [PATCH 0/5] OpenRISC SMP Support
@ 2017-10-07  0:21   ` Stafford Horne
  0 siblings, 0 replies; 24+ messages in thread
From: Stafford Horne @ 2017-10-07  0:21 UTC (permalink / raw)
  To: openrisc

Hello,

Any takers on this?  If not Ill consider sending a pull request
if/when the merge window is open.

-Stafford

On Wed, Aug 23, 2017 at 2:57 PM, Stafford Horne <shorne@gmail.com> wrote:
> Hello,
>
> This series adds SMP support for OpenRISC.  The platform is based on the
> work that Stefan Kristiansson did around 2012 implemented in Verilog and
> run on FPGAs.  I have been working to upstream this work, these are my QEMU
> patches I have been used to help with testing.
>
> I have documented the platform in the OpenRISC 1.2 specification proposal
> available here:
>   https://github.com/stffrdhrn/doc/raw/arch-1.2-proposal/openrisc-arch-1.2-rev0.pdf
>
> My latest kernel patches are available here:
>   https://github.com/stffrdhrn/linux.git openrisc-4.13-smp-qspinlock
>
> Stafford Horne (5):
>   openrisc/ompic: Add OpenRISC Multicore PIC (OMPIC)
>   target/openrisc: Make coreid and numcores configurable in state
>   openrisc/cputimer: Perparation for Multicore
>   openrisc: Initial SMP support
>   openrisc: Only kick cpu on timeout, not on update
>
>  default-configs/or1k-softmmu.mak |   1 +
>  hw/intc/Makefile.objs            |   1 +
>  hw/intc/ompic.c                  | 179 +++++++++++++++++++++++++++++++++++++++
>  hw/openrisc/cputimer.c           |  64 ++++++++++----
>  hw/openrisc/openrisc_sim.c       |  87 ++++++++++++++-----
>  target/openrisc/cpu.c            |   1 -
>  target/openrisc/cpu.h            |   7 +-
>  target/openrisc/machine.c        |   8 +-
>  target/openrisc/sys_helper.c     |   8 +-
>  9 files changed, 308 insertions(+), 48 deletions(-)
>  create mode 100644 hw/intc/ompic.c
>
> --
> 2.13.5
>

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

* Re: [Qemu-devel] [PATCH 2/5] target/openrisc: Make coreid and numcores configurable in state
  2017-08-23  5:57   ` [OpenRISC] " Stafford Horne
@ 2017-10-12 20:48     ` Richard Henderson
  -1 siblings, 0 replies; 24+ messages in thread
From: Richard Henderson @ 2017-10-12 20:48 UTC (permalink / raw)
  To: Stafford Horne, QEMU Development; +Cc: Openrisc, Richard Henderson

On 08/22/2017 10:57 PM, Stafford Horne wrote:
> Previously coreid and numcores were hard coded as 0 and 1 respectively
> as OpenRISC QEMU did not have multicore support.
> 
> Multicore support is now being added so these registers need to have
> configured values.
> 
> Signed-off-by: Stafford Horne <shorne@gmail.com>
> ---
>  hw/openrisc/openrisc_sim.c   | 3 +++
>  target/openrisc/cpu.h        | 3 +++
>  target/openrisc/machine.c    | 7 +++++--
>  target/openrisc/sys_helper.c | 4 ++--
>  4 files changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
> index e1eeffc490..44a657753d 100644
> --- a/hw/openrisc/openrisc_sim.c
> +++ b/hw/openrisc/openrisc_sim.c
> @@ -110,6 +110,9 @@ static void openrisc_sim_init(MachineState *machine)
>  
>      for (n = 0; n < smp_cpus; n++) {
>          cpu = cpu_openrisc_init(cpu_model);
> +        cpu->env.coreid = n;
> +        cpu->env.numcores = smp_cpus;

This duplicates cpu->parent_obj.cpu_index.  Also c.f. max_cpus vs smp_cpus; the
latter can change via hot-plug.

> @@ -104,8 +104,8 @@ static const VMStateInfo vmstate_sr = {
>  
>  static const VMStateDescription vmstate_env = {
>      .name = "env",
> -    .version_id = 6,
> -    .minimum_version_id = 6,
> +    .version_id = 7,
> +    .minimum_version_id = 7,
>      .post_load = env_post_load,
>      .fields = (VMStateField[]) {
>          VMSTATE_UINTTL_2DARRAY(shadow_gpr, CPUOpenRISCState, 16, 32),
> @@ -152,6 +152,9 @@ static const VMStateDescription vmstate_env = {
>          VMSTATE_UINT32(picmr, CPUOpenRISCState),
>          VMSTATE_UINT32(picsr, CPUOpenRISCState),
>  
> +        VMSTATE_UINT32(coreid, CPUOpenRISCState),
> +        VMSTATE_UINT32(numcores, CPUOpenRISCState),

If you use the above directly you don't need to save/restore these yourself.

>      case TO_SPR(0, 128): /* COREID */
> -        return 0;
> +        return env->coreid;

>      case TO_SPR(0, 129): /* NUMCORES */
> -        return 1;
> +        return env->numcores;

Just use the global variable directly here, IMO.


r~

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

* [OpenRISC] [Qemu-devel] [PATCH 2/5] target/openrisc: Make coreid and numcores configurable in state
@ 2017-10-12 20:48     ` Richard Henderson
  0 siblings, 0 replies; 24+ messages in thread
From: Richard Henderson @ 2017-10-12 20:48 UTC (permalink / raw)
  To: openrisc

On 08/22/2017 10:57 PM, Stafford Horne wrote:
> Previously coreid and numcores were hard coded as 0 and 1 respectively
> as OpenRISC QEMU did not have multicore support.
> 
> Multicore support is now being added so these registers need to have
> configured values.
> 
> Signed-off-by: Stafford Horne <shorne@gmail.com>
> ---
>  hw/openrisc/openrisc_sim.c   | 3 +++
>  target/openrisc/cpu.h        | 3 +++
>  target/openrisc/machine.c    | 7 +++++--
>  target/openrisc/sys_helper.c | 4 ++--
>  4 files changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
> index e1eeffc490..44a657753d 100644
> --- a/hw/openrisc/openrisc_sim.c
> +++ b/hw/openrisc/openrisc_sim.c
> @@ -110,6 +110,9 @@ static void openrisc_sim_init(MachineState *machine)
>  
>      for (n = 0; n < smp_cpus; n++) {
>          cpu = cpu_openrisc_init(cpu_model);
> +        cpu->env.coreid = n;
> +        cpu->env.numcores = smp_cpus;

This duplicates cpu->parent_obj.cpu_index.  Also c.f. max_cpus vs smp_cpus; the
latter can change via hot-plug.

> @@ -104,8 +104,8 @@ static const VMStateInfo vmstate_sr = {
>  
>  static const VMStateDescription vmstate_env = {
>      .name = "env",
> -    .version_id = 6,
> -    .minimum_version_id = 6,
> +    .version_id = 7,
> +    .minimum_version_id = 7,
>      .post_load = env_post_load,
>      .fields = (VMStateField[]) {
>          VMSTATE_UINTTL_2DARRAY(shadow_gpr, CPUOpenRISCState, 16, 32),
> @@ -152,6 +152,9 @@ static const VMStateDescription vmstate_env = {
>          VMSTATE_UINT32(picmr, CPUOpenRISCState),
>          VMSTATE_UINT32(picsr, CPUOpenRISCState),
>  
> +        VMSTATE_UINT32(coreid, CPUOpenRISCState),
> +        VMSTATE_UINT32(numcores, CPUOpenRISCState),

If you use the above directly you don't need to save/restore these yourself.

>      case TO_SPR(0, 128): /* COREID */
> -        return 0;
> +        return env->coreid;

>      case TO_SPR(0, 129): /* NUMCORES */
> -        return 1;
> +        return env->numcores;

Just use the global variable directly here, IMO.


r~


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

* Re: [Qemu-devel] [PATCH 1/5] openrisc/ompic: Add OpenRISC Multicore PIC (OMPIC)
  2017-08-23  5:57   ` [OpenRISC] " Stafford Horne
@ 2017-10-12 20:48     ` Richard Henderson
  -1 siblings, 0 replies; 24+ messages in thread
From: Richard Henderson @ 2017-10-12 20:48 UTC (permalink / raw)
  To: Stafford Horne, QEMU Development; +Cc: Openrisc, Richard Henderson

On 08/22/2017 10:57 PM, Stafford Horne wrote:
> Add OpenRISC Multicore PIC which handles inter processor interrupts
> (IPI) between cores.  In OpenRISC all device interrupts are routed to
> each core enabling this device to be simple.
> 
> Signed-off-by: Stafford Horne <shorne@gmail.com>
> ---
>  default-configs/or1k-softmmu.mak |   1 +
>  hw/intc/Makefile.objs            |   1 +
>  hw/intc/ompic.c                  | 179 +++++++++++++++++++++++++++++++++++++++
>  3 files changed, 181 insertions(+)
>  create mode 100644 hw/intc/ompic.c

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

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

* [OpenRISC] [Qemu-devel] [PATCH 1/5] openrisc/ompic: Add OpenRISC Multicore PIC (OMPIC)
@ 2017-10-12 20:48     ` Richard Henderson
  0 siblings, 0 replies; 24+ messages in thread
From: Richard Henderson @ 2017-10-12 20:48 UTC (permalink / raw)
  To: openrisc

On 08/22/2017 10:57 PM, Stafford Horne wrote:
> Add OpenRISC Multicore PIC which handles inter processor interrupts
> (IPI) between cores.  In OpenRISC all device interrupts are routed to
> each core enabling this device to be simple.
> 
> Signed-off-by: Stafford Horne <shorne@gmail.com>
> ---
>  default-configs/or1k-softmmu.mak |   1 +
>  hw/intc/Makefile.objs            |   1 +
>  hw/intc/ompic.c                  | 179 +++++++++++++++++++++++++++++++++++++++
>  3 files changed, 181 insertions(+)
>  create mode 100644 hw/intc/ompic.c

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

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

* Re: [Qemu-devel] [PATCH 3/5] openrisc/cputimer: Perparation for Multicore
  2017-08-23  5:57   ` [OpenRISC] " Stafford Horne
@ 2017-10-12 20:50     ` Richard Henderson
  -1 siblings, 0 replies; 24+ messages in thread
From: Richard Henderson @ 2017-10-12 20:50 UTC (permalink / raw)
  To: Stafford Horne, QEMU Development; +Cc: Openrisc, Richard Henderson

On 08/22/2017 10:57 PM, Stafford Horne wrote:
> In order to support multicore system we move some of the previously
> static state variables into the state of each core.
> 
> On the other hand in order to allow timers to be synced between each
> code the ttcr (tick timer count register) is moved out of the core.
> This is not as per real hardware spec which has a separate timer counter
> per core, but it seems the most simple way to keep each clock in sync.
> 
> Signed-off-by: Stafford Horne <shorne@gmail.com>
> ---
>  hw/openrisc/cputimer.c       | 62 +++++++++++++++++++++++++++++++++-----------
>  target/openrisc/cpu.c        |  1 -
>  target/openrisc/cpu.h        |  4 ++-
>  target/openrisc/machine.c    |  1 -
>  target/openrisc/sys_helper.c |  4 +--
>  5 files changed, 52 insertions(+), 20 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

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

* [OpenRISC] [Qemu-devel] [PATCH 3/5] openrisc/cputimer: Perparation for Multicore
@ 2017-10-12 20:50     ` Richard Henderson
  0 siblings, 0 replies; 24+ messages in thread
From: Richard Henderson @ 2017-10-12 20:50 UTC (permalink / raw)
  To: openrisc

On 08/22/2017 10:57 PM, Stafford Horne wrote:
> In order to support multicore system we move some of the previously
> static state variables into the state of each core.
> 
> On the other hand in order to allow timers to be synced between each
> code the ttcr (tick timer count register) is moved out of the core.
> This is not as per real hardware spec which has a separate timer counter
> per core, but it seems the most simple way to keep each clock in sync.
> 
> Signed-off-by: Stafford Horne <shorne@gmail.com>
> ---
>  hw/openrisc/cputimer.c       | 62 +++++++++++++++++++++++++++++++++-----------
>  target/openrisc/cpu.c        |  1 -
>  target/openrisc/cpu.h        |  4 ++-
>  target/openrisc/machine.c    |  1 -
>  target/openrisc/sys_helper.c |  4 +--
>  5 files changed, 52 insertions(+), 20 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

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

* Re: [Qemu-devel] [PATCH 4/5] openrisc: Initial SMP support
  2017-08-23  5:57   ` [OpenRISC] " Stafford Horne
@ 2017-10-12 21:28     ` Richard Henderson
  -1 siblings, 0 replies; 24+ messages in thread
From: Richard Henderson @ 2017-10-12 21:28 UTC (permalink / raw)
  To: Stafford Horne, QEMU Development; +Cc: Openrisc, Richard Henderson

On 08/22/2017 10:57 PM, Stafford Horne wrote:
> Wire in ompic and add basic support for SMP.  The OpenRISC is special in
> that interrupts for devices are routed to each core's PIC.  This is
> achieved using the qemu_irq_split utility, but this currently limits
> OpenRISC to 2 cores.
> 
> This models the reference architecture described in the OpenRISC spec
> 1.2 proposal.
> 
>   https://github.com/stffrdhrn/doc/raw/arch-1.2-proposal/openrisc-arch-1.2-rev0.pdf
> 
> The changes to the intialization of the sim include:
> 
> CPU Reset
>  o Reset each cpu to the bootstrap PC rather than only a single cpu as
>    done before.
>  o During Kernel loading the bootstrap PC is saved in a static global.
> 
> Network Initialization
>  o Connect the interrupt to each CPU
>  o Use more simple sysbus_mmio_map() rather than memory_region_add_subregion()
> 
> Sim Initialization
>  o Initialize the pic and tick timer per cpu
>  o Wire in the OMPIC if SMP is enabled
>  o Wire the serial irq to each CPU using qemu_irq_split()
> 
> Signed-off-by: Stafford Horne <shorne@gmail.com>
> ---
>  hw/openrisc/openrisc_sim.c | 84 +++++++++++++++++++++++++++++++++-------------
>  1 file changed, 61 insertions(+), 23 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

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

* [OpenRISC] [Qemu-devel] [PATCH 4/5] openrisc: Initial SMP support
@ 2017-10-12 21:28     ` Richard Henderson
  0 siblings, 0 replies; 24+ messages in thread
From: Richard Henderson @ 2017-10-12 21:28 UTC (permalink / raw)
  To: openrisc

On 08/22/2017 10:57 PM, Stafford Horne wrote:
> Wire in ompic and add basic support for SMP.  The OpenRISC is special in
> that interrupts for devices are routed to each core's PIC.  This is
> achieved using the qemu_irq_split utility, but this currently limits
> OpenRISC to 2 cores.
> 
> This models the reference architecture described in the OpenRISC spec
> 1.2 proposal.
> 
>   https://github.com/stffrdhrn/doc/raw/arch-1.2-proposal/openrisc-arch-1.2-rev0.pdf
> 
> The changes to the intialization of the sim include:
> 
> CPU Reset
>  o Reset each cpu to the bootstrap PC rather than only a single cpu as
>    done before.
>  o During Kernel loading the bootstrap PC is saved in a static global.
> 
> Network Initialization
>  o Connect the interrupt to each CPU
>  o Use more simple sysbus_mmio_map() rather than memory_region_add_subregion()
> 
> Sim Initialization
>  o Initialize the pic and tick timer per cpu
>  o Wire in the OMPIC if SMP is enabled
>  o Wire the serial irq to each CPU using qemu_irq_split()
> 
> Signed-off-by: Stafford Horne <shorne@gmail.com>
> ---
>  hw/openrisc/openrisc_sim.c | 84 +++++++++++++++++++++++++++++++++-------------
>  1 file changed, 61 insertions(+), 23 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~


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

* Re: [Qemu-devel] [PATCH 5/5] openrisc: Only kick cpu on timeout, not on update
  2017-08-23  5:57   ` [OpenRISC] " Stafford Horne
@ 2017-10-12 21:28     ` Richard Henderson
  -1 siblings, 0 replies; 24+ messages in thread
From: Richard Henderson @ 2017-10-12 21:28 UTC (permalink / raw)
  To: Stafford Horne, QEMU Development; +Cc: Openrisc, Richard Henderson

On 08/22/2017 10:57 PM, Stafford Horne wrote:
> Previously we were kicking the cpu on every update.  This caused
> problems noticeable in SMP configurations where one CPU got pinned
> continuously servicing timer exceptions.
> 
> Signed-off-by: Stafford Horne <shorne@gmail.com>
> ---
>  hw/openrisc/cputimer.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

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

* [OpenRISC] [Qemu-devel] [PATCH 5/5] openrisc: Only kick cpu on timeout, not on update
@ 2017-10-12 21:28     ` Richard Henderson
  0 siblings, 0 replies; 24+ messages in thread
From: Richard Henderson @ 2017-10-12 21:28 UTC (permalink / raw)
  To: openrisc

On 08/22/2017 10:57 PM, Stafford Horne wrote:
> Previously we were kicking the cpu on every update.  This caused
> problems noticeable in SMP configurations where one CPU got pinned
> continuously servicing timer exceptions.
> 
> Signed-off-by: Stafford Horne <shorne@gmail.com>
> ---
>  hw/openrisc/cputimer.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~


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

end of thread, other threads:[~2017-10-12 21:28 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-23  5:57 [Qemu-devel] [PATCH 0/5] OpenRISC SMP Support Stafford Horne
2017-08-23  5:57 ` [OpenRISC] " Stafford Horne
2017-08-23  5:57 ` [Qemu-devel] [PATCH 1/5] openrisc/ompic: Add OpenRISC Multicore PIC (OMPIC) Stafford Horne
2017-08-23  5:57   ` [OpenRISC] " Stafford Horne
2017-10-12 20:48   ` [Qemu-devel] " Richard Henderson
2017-10-12 20:48     ` [OpenRISC] " Richard Henderson
2017-08-23  5:57 ` [Qemu-devel] [PATCH 2/5] target/openrisc: Make coreid and numcores configurable in state Stafford Horne
2017-08-23  5:57   ` [OpenRISC] " Stafford Horne
2017-10-12 20:48   ` [Qemu-devel] " Richard Henderson
2017-10-12 20:48     ` [OpenRISC] " Richard Henderson
2017-08-23  5:57 ` [Qemu-devel] [PATCH 3/5] openrisc/cputimer: Perparation for Multicore Stafford Horne
2017-08-23  5:57   ` [OpenRISC] " Stafford Horne
2017-10-12 20:50   ` [Qemu-devel] " Richard Henderson
2017-10-12 20:50     ` [OpenRISC] " Richard Henderson
2017-08-23  5:57 ` [Qemu-devel] [PATCH 4/5] openrisc: Initial SMP support Stafford Horne
2017-08-23  5:57   ` [OpenRISC] " Stafford Horne
2017-10-12 21:28   ` [Qemu-devel] " Richard Henderson
2017-10-12 21:28     ` [OpenRISC] " Richard Henderson
2017-08-23  5:57 ` [Qemu-devel] [PATCH 5/5] openrisc: Only kick cpu on timeout, not on update Stafford Horne
2017-08-23  5:57   ` [OpenRISC] " Stafford Horne
2017-10-12 21:28   ` [Qemu-devel] " Richard Henderson
2017-10-12 21:28     ` [OpenRISC] " Richard Henderson
2017-10-07  0:21 ` [Qemu-devel] [PATCH 0/5] OpenRISC SMP Support Stafford Horne
2017-10-07  0:21   ` [OpenRISC] " Stafford Horne

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.