* [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS
@ 2011-07-23 10:49 Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 01/28] PPC: Move openpic to target specific code compilation Alexander Graf
` (27 more replies)
0 siblings, 28 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:49 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
Due to popular demand, I got involved in the dirty arts of SMP
programming :). This patch set adds support for the MPC8544DS board
(e500v2) to run with up to 32 virtual CPUs.
This works fine with emulation and Linux guests. It also works with
KVM.
For non-Linux guests, TLB invalidation broadcasting is still missing,
but for now this is enough to get Linux up and running.
I've used the chance while touching the code to also clean up ugly
code that just diverged over time between the 3 KVM capable PPC
targets (frequency device-tree entries). They're intertwined with
this series, but I hope not too hard to understand, so they don't
hurt being there.
v1 -> v2:
- MPIC: Use MAX_IPI instead of hardcoded 4
- MPIC: Max cpus is 15 due to cINT routing
- MPIC: Drop cINT patch
- MPIC: Report nb_cpus not MAX_CPUS in MPIC capabilities
- MPIC: Add cINT patch to fix CINT dispatch
- Clockfreq: enable 64bit clockfreq values
- Spin: New MMIO based device
- Spin: map the secondary NIP instead of 0 1:1
- Spin: only map 64MB for TLB, same as u-boot
- Spin: prepare code for 64-bit spinnings
- MPC8544: Generate CPU nodes on demand, not ahead of time
Alexander Graf (28):
PPC: Move openpic to target specific code compilation
PPC: Add CPU local MMIO regions to MPIC
PPC: Extend MPIC MMIO range
PPC: Fix IPI support in MPIC
PPC: Set MPIC IDE for IPI to 0
PPC: MPIC: Remove read functionality for WO registers
PPC: MPIC: Fix CI bit definitions
PPC: Bump MPIC up to 32 supported CPUs
PPC: E500: create multiple envs
PPC: E500: Generate IRQ lines for many CPUs
device tree: add nop_node
PPC: bamboo: Move host fdt copy to target
PPC: KVM: Add generic function to read host clockfreq
PPC: E500: Use generic kvm function for freq
PPC: E500: Remove mpc8544_copy_soc_cell
PPC: bamboo: Use kvm api for freq and clock frequencies
PPC: KVM: Remove kvmppc_read_host_property
PPC: KVM: Add stubs for kvm helper functions
PPC: E500: Update freqs for all CPUs
PPC: E500: Remove unneeded CPU nodes
PPC: E500: Add PV spinning code
PPC: E500: Update cpu-release-addr property in cpu nodes
device tree: add add_subnode command
device tree: dont fail operations
device tree: give dt more size
MPC8544DS: Remove CPU nodes
MPC8544DS: Generate CPU nodes on init
PPC: E500: Bump CPU count to 15
Makefile.objs | 1 -
Makefile.target | 4 +-
device_tree.c | 92 +++++++++++++++++++----
device_tree.h | 2 +
hw/openpic.c | 160 +++++++++++++++++++++++++---------------
hw/ppc440_bamboo.c | 16 ++++-
hw/ppce500_mpc8544ds.c | 191 ++++++++++++++++++++++++++++--------------------
hw/ppce500_spin.c | 182 +++++++++++++++++++++++++++++++++++++++++++++
pc-bios/mpc8544ds.dtb | Bin 2277 -> 2028 bytes
pc-bios/mpc8544ds.dts | 12 ---
target-ppc/kvm.c | 67 +++++++++++++++++
target-ppc/kvm_ppc.c | 65 ----------------
target-ppc/kvm_ppc.h | 39 +++++++---
13 files changed, 584 insertions(+), 247 deletions(-)
create mode 100644 hw/ppce500_spin.c
^ permalink raw reply [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 01/28] PPC: Move openpic to target specific code compilation
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
@ 2011-07-23 10:49 ` Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 02/28] PPC: Add CPU local MMIO regions to MPIC Alexander Graf
` (26 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:49 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
The MPIC has some funny feature where it maps different registers to an MMIO
region depending which CPU accesses them.
To be able to reflect that, we need to make OpenPIC be compiled in the target
code, so it can access cpu_single_env.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
Makefile.objs | 1 -
Makefile.target | 2 ++
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/Makefile.objs b/Makefile.objs
index 6991a9f..36919f8 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -208,7 +208,6 @@ hw-obj-$(CONFIG_SMARTCARD_NSS) += ccid-card-emulated.o
hw-obj-$(CONFIG_USB_REDIR) += usb-redir.o
# PPC devices
-hw-obj-$(CONFIG_OPENPIC) += openpic.o
hw-obj-$(CONFIG_PREP_PCI) += prep_pci.o
# Mac shared devices
hw-obj-$(CONFIG_MACIO) += macio.o
diff --git a/Makefile.target b/Makefile.target
index cde509b..19f6101 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -256,6 +256,8 @@ obj-ppc-y += ppce500_mpc8544ds.o mpc8544_guts.o
obj-ppc-y += virtex_ml507.o
obj-ppc-$(CONFIG_KVM) += kvm_ppc.o
obj-ppc-$(CONFIG_FDT) += device_tree.o
+# PowerPC OpenPIC
+obj-ppc-y += openpic.o
# Xilinx PPC peripherals
obj-ppc-y += xilinx_intc.o
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 02/28] PPC: Add CPU local MMIO regions to MPIC
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 01/28] PPC: Move openpic to target specific code compilation Alexander Graf
@ 2011-07-23 10:49 ` Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 03/28] PPC: Extend MPIC MMIO range Alexander Graf
` (25 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:49 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
The MPIC exports a register set for each CPU connected to it. They can all
be accessed through specific registers or using a shadow page that is mapped
differently depending on which CPU accesses it.
This patch implements the shadow map, making it possible for guests to access
the CPU local registers using the same address on each CPU.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
hw/openpic.c | 110 ++++++++++++++++++++++++++++++++++++++--------------------
1 files changed, 72 insertions(+), 38 deletions(-)
diff --git a/hw/openpic.c b/hw/openpic.c
index 6d2cf99..491bfee 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -2,6 +2,7 @@
* OpenPIC emulation
*
* Copyright (c) 2004 Jocelyn Mayer
+ * 2011 Alexander Graf
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -161,6 +162,16 @@ static inline int test_bit (uint32_t *field, int bit)
return (field[bit >> 5] & 1 << (bit & 0x1F)) != 0;
}
+static int get_current_cpu(void)
+{
+ return cpu_single_env->cpu_index;
+}
+
+static uint32_t openpic_cpu_read_internal(void *opaque, target_phys_addr_t addr,
+ int idx);
+static void openpic_cpu_write_internal(void *opaque, target_phys_addr_t addr,
+ uint32_t val, int idx);
+
enum {
IRQ_EXTERNAL = 0x01,
IRQ_INTERNAL = 0x02,
@@ -590,18 +601,27 @@ static void openpic_gbl_write (void *opaque, target_phys_addr_t addr, uint32_t v
DPRINTF("%s: addr " TARGET_FMT_plx " <= %08x\n", __func__, addr, val);
if (addr & 0xF)
return;
- addr &= 0xFF;
switch (addr) {
- case 0x00: /* FREP */
+ case 0x40:
+ case 0x50:
+ case 0x60:
+ case 0x70:
+ case 0x80:
+ case 0x90:
+ case 0xA0:
+ case 0xB0:
+ openpic_cpu_write_internal(opp, addr, val, get_current_cpu());
+ break;
+ case 0x1000: /* FREP */
break;
- case 0x20: /* GLBC */
+ case 0x1020: /* GLBC */
if (val & 0x80000000 && opp->reset)
opp->reset(opp);
opp->glbc = val & ~0x80000000;
break;
- case 0x80: /* VENI */
+ case 0x1080: /* VENI */
break;
- case 0x90: /* PINT */
+ case 0x1090: /* PINT */
for (idx = 0; idx < opp->nb_cpus; idx++) {
if ((val & (1 << idx)) && !(opp->pint & (1 << idx))) {
DPRINTF("Raise OpenPIC RESET output for CPU %d\n", idx);
@@ -615,22 +635,20 @@ static void openpic_gbl_write (void *opaque, target_phys_addr_t addr, uint32_t v
}
opp->pint = val;
break;
-#if MAX_IPI > 0
- case 0xA0: /* IPI_IPVP */
- case 0xB0:
- case 0xC0:
- case 0xD0:
+ case 0x10A0: /* IPI_IPVP */
+ case 0x10B0:
+ case 0x10C0:
+ case 0x10D0:
{
int idx;
- idx = (addr - 0xA0) >> 4;
+ idx = (addr - 0x10A0) >> 4;
write_IRQreg(opp, opp->irq_ipi0 + idx, IRQ_IPVP, val);
}
break;
-#endif
- case 0xE0: /* SPVE */
+ case 0x10E0: /* SPVE */
opp->spve = val & 0x000000FF;
break;
- case 0xF0: /* TIFR */
+ case 0x10F0: /* TIFR */
opp->tifr = val;
break;
default:
@@ -647,36 +665,43 @@ static uint32_t openpic_gbl_read (void *opaque, target_phys_addr_t addr)
retval = 0xFFFFFFFF;
if (addr & 0xF)
return retval;
- addr &= 0xFF;
switch (addr) {
- case 0x00: /* FREP */
+ case 0x1000: /* FREP */
retval = opp->frep;
break;
- case 0x20: /* GLBC */
+ case 0x1020: /* GLBC */
retval = opp->glbc;
break;
- case 0x80: /* VENI */
+ case 0x1080: /* VENI */
retval = opp->veni;
break;
- case 0x90: /* PINT */
+ case 0x1090: /* PINT */
retval = 0x00000000;
break;
-#if MAX_IPI > 0
- case 0xA0: /* IPI_IPVP */
+ case 0x40:
+ case 0x50:
+ case 0x60:
+ case 0x70:
+ case 0x80:
+ case 0x90:
+ case 0xA0:
case 0xB0:
- case 0xC0:
- case 0xD0:
+ retval = openpic_cpu_read_internal(opp, addr, get_current_cpu());
+ break;
+ case 0x10A0: /* IPI_IPVP */
+ case 0x10B0:
+ case 0x10C0:
+ case 0x10D0:
{
int idx;
- idx = (addr - 0xA0) >> 4;
+ idx = (addr - 0x10A0) >> 4;
retval = read_IRQreg(opp, opp->irq_ipi0 + idx, IRQ_IPVP);
}
break;
-#endif
- case 0xE0: /* SPVE */
+ case 0x10E0: /* SPVE */
retval = opp->spve;
break;
- case 0xF0: /* TIFR */
+ case 0x10F0: /* TIFR */
retval = opp->tifr;
break;
default:
@@ -794,23 +819,23 @@ static uint32_t openpic_src_read (void *opaque, uint32_t addr)
return retval;
}
-static void openpic_cpu_write (void *opaque, target_phys_addr_t addr, uint32_t val)
+static void openpic_cpu_write_internal(void *opaque, target_phys_addr_t addr,
+ uint32_t val, int idx)
{
openpic_t *opp = opaque;
IRQ_src_t *src;
IRQ_dst_t *dst;
- int idx, s_IRQ, n_IRQ;
+ int s_IRQ, n_IRQ;
- DPRINTF("%s: addr " TARGET_FMT_plx " <= %08x\n", __func__, addr, val);
+ DPRINTF("%s: cpu %d addr " TARGET_FMT_plx " <= %08x\n", __func__, idx,
+ addr, val);
if (addr & 0xF)
return;
- addr &= 0x1FFF0;
- idx = addr / 0x1000;
dst = &opp->dst[idx];
addr &= 0xFF0;
switch (addr) {
#if MAX_IPI > 0
- case 0x40: /* PIPD */
+ case 0x40: /* IPIDR */
case 0x50:
case 0x60:
case 0x70:
@@ -852,20 +877,24 @@ static void openpic_cpu_write (void *opaque, target_phys_addr_t addr, uint32_t v
}
}
-static uint32_t openpic_cpu_read (void *opaque, target_phys_addr_t addr)
+static void openpic_cpu_write(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+ openpic_cpu_write_internal(opaque, addr, val, (addr & 0x1f000) >> 12);
+}
+
+static uint32_t openpic_cpu_read_internal(void *opaque, target_phys_addr_t addr,
+ int idx)
{
openpic_t *opp = opaque;
IRQ_src_t *src;
IRQ_dst_t *dst;
uint32_t retval;
- int idx, n_IRQ;
+ int n_IRQ;
- DPRINTF("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
+ DPRINTF("%s: cpu %d addr " TARGET_FMT_plx "\n", __func__, idx, addr);
retval = 0xFFFFFFFF;
if (addr & 0xF)
return retval;
- addr &= 0x1FFF0;
- idx = addr / 0x1000;
dst = &opp->dst[idx];
addr &= 0xFF0;
switch (addr) {
@@ -925,6 +954,11 @@ static uint32_t openpic_cpu_read (void *opaque, target_phys_addr_t addr)
return retval;
}
+static uint32_t openpic_cpu_read(void *opaque, target_phys_addr_t addr)
+{
+ return openpic_cpu_read_internal(opaque, addr, (addr & 0x1f000) >> 12);
+}
+
static void openpic_buggy_write (void *opaque,
target_phys_addr_t addr, uint32_t val)
{
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 03/28] PPC: Extend MPIC MMIO range
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 01/28] PPC: Move openpic to target specific code compilation Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 02/28] PPC: Add CPU local MMIO regions to MPIC Alexander Graf
@ 2011-07-23 10:49 ` Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 04/28] PPC: Fix IPI support in MPIC Alexander Graf
` (24 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:49 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
The MPIC exports a page for each CPU that it controls. To support more than
one CPU, we need to also reserve the MMIO space according to the amount of
CPUs we want to support.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
hw/openpic.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/hw/openpic.c b/hw/openpic.c
index 491bfee..ad45331 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -128,7 +128,7 @@ enum {
#define MPIC_MSI_REG_START 0x11C00
#define MPIC_MSI_REG_SIZE 0x100
#define MPIC_CPU_REG_START 0x20000
-#define MPIC_CPU_REG_SIZE 0x100
+#define MPIC_CPU_REG_SIZE 0x100 + ((MAX_CPU - 1) * 0x1000)
enum mpic_ide_bits {
IDR_EP = 0,
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 04/28] PPC: Fix IPI support in MPIC
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
` (2 preceding siblings ...)
2011-07-23 10:49 ` [Qemu-devel] [PATCH 03/28] PPC: Extend MPIC MMIO range Alexander Graf
@ 2011-07-23 10:49 ` Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 05/28] PPC: Set MPIC IDE for IPI to 0 Alexander Graf
` (23 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:49 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
The current IPI support in the MPIC code is incomplete and doesn't work. This
code adds proper support for IPIs in MPIC by using the IDE register to remember
which CPUs IPIs are still outstanding to. New triggers through the IPI trigger
register only add to the list of CPUs we want to IPI.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
v1 -> v2:
- Use MAX_IPI instead of hardcoded 4
Signed-off-by: Alexander Graf <agraf@suse.de>
---
hw/openpic.c | 17 +++++++++++++++--
1 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/hw/openpic.c b/hw/openpic.c
index ad45331..9ac3b3d 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -57,7 +57,7 @@
#define MAX_MBX 4
#define MAX_TMR 4
#define VECTOR_BITS 8
-#define MAX_IPI 0
+#define MAX_IPI 4
#define VID (0x00000000)
@@ -840,7 +840,9 @@ static void openpic_cpu_write_internal(void *opaque, target_phys_addr_t addr,
case 0x60:
case 0x70:
idx = (addr - 0x40) >> 4;
- write_IRQreg(opp, opp->irq_ipi0 + idx, IRQ_IDE, val);
+ /* we use IDE as mask which CPUs to deliver the IPI to still. */
+ write_IRQreg(opp, opp->irq_ipi0 + idx, IRQ_IDE,
+ opp->src[opp->irq_ipi0 + idx].ide | val);
openpic_set_irq(opp, opp->irq_ipi0 + idx, 1);
openpic_set_irq(opp, opp->irq_ipi0 + idx, 0);
break;
@@ -934,6 +936,17 @@ static uint32_t openpic_cpu_read_internal(void *opaque, target_phys_addr_t addr,
reset_bit(&src->ipvp, IPVP_ACTIVITY);
src->pending = 0;
}
+
+ if ((n_IRQ >= opp->irq_ipi0) && (n_IRQ < (opp->irq_ipi0 + MAX_IPI))) {
+ src->ide &= ~(1 << idx);
+ if (src->ide && !test_bit(&src->ipvp, IPVP_SENSE)) {
+ /* trigger on CPUs that didn't know about it yet */
+ openpic_set_irq(opp, n_IRQ, 1);
+ openpic_set_irq(opp, n_IRQ, 0);
+ /* if all CPUs knew about it, set active bit again */
+ set_bit(&src->ipvp, IPVP_ACTIVITY);
+ }
+ }
}
break;
case 0xB0: /* PEOI */
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 05/28] PPC: Set MPIC IDE for IPI to 0
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
` (3 preceding siblings ...)
2011-07-23 10:49 ` [Qemu-devel] [PATCH 04/28] PPC: Fix IPI support in MPIC Alexander Graf
@ 2011-07-23 10:49 ` Alexander Graf
2011-07-25 8:46 ` Elie Richa
2011-07-23 10:49 ` [Qemu-devel] [PATCH 06/28] PPC: MPIC: Remove read functionality for WO registers Alexander Graf
` (22 subsequent siblings)
27 siblings, 1 reply; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:49 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
We use the IDE register with IPIs as a mask to keep track which processors
have already acknowledged the respective interrupt. So we need to initialize
it to 0 to make sure that it doesn't accidently fire an IPI on CPU0 when the
first IPI is triggered.
Reported-by: Elie Richa <richa@adacore.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
hw/openpic.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/hw/openpic.c b/hw/openpic.c
index 9ac3b3d..1f7753d 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -1304,6 +1304,10 @@ static void mpic_reset (void *opaque)
mpp->src[i].ipvp = 0x80800000;
mpp->src[i].ide = 0x00000001;
}
+ /* Set IDE for IPIs to 0 so we don't get spurious interrupts */
+ for (i = mpp->irq_ipi0; i < MAX_IPI; i++) {
+ mpp->src[i].ide = 0;
+ }
/* Initialise IRQ destinations */
for (i = 0; i < MAX_CPU; i++) {
mpp->dst[i].pctp = 0x0000000F;
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 06/28] PPC: MPIC: Remove read functionality for WO registers
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
` (4 preceding siblings ...)
2011-07-23 10:49 ` [Qemu-devel] [PATCH 05/28] PPC: Set MPIC IDE for IPI to 0 Alexander Graf
@ 2011-07-23 10:49 ` Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 07/28] PPC: MPIC: Fix CI bit definitions Alexander Graf
` (21 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:49 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
The IPI dispatch registers are write only according to every MPIC
spec I have found. So instead of pretending you could read back something
from them, better not handle them at all.
Reported-by: Elie Richa <richa@adacore.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
hw/openpic.c | 7 -------
1 files changed, 0 insertions(+), 7 deletions(-)
diff --git a/hw/openpic.c b/hw/openpic.c
index 1f7753d..3f50421 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -952,13 +952,6 @@ static uint32_t openpic_cpu_read_internal(void *opaque, target_phys_addr_t addr,
case 0xB0: /* PEOI */
retval = 0;
break;
-#if MAX_IPI > 0
- case 0x40: /* IDE */
- case 0x50:
- idx = (addr - 0x40) >> 4;
- retval = read_IRQreg(opp, opp->irq_ipi0 + idx, IRQ_IDE);
- break;
-#endif
default:
break;
}
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 07/28] PPC: MPIC: Fix CI bit definitions
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
` (5 preceding siblings ...)
2011-07-23 10:49 ` [Qemu-devel] [PATCH 06/28] PPC: MPIC: Remove read functionality for WO registers Alexander Graf
@ 2011-07-23 10:49 ` Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 08/28] PPC: Bump MPIC up to 32 supported CPUs Alexander Graf
` (20 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:49 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
The bit definitions for critical interrupt routing are in PowerPC order
(most significant bit is 0), while we end up shifting it with normal bit
order. Turn the numbers around so we actually end up fetching the
right ones.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
hw/openpic.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/hw/openpic.c b/hw/openpic.c
index 3f50421..af07e13 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -131,11 +131,11 @@ enum {
#define MPIC_CPU_REG_SIZE 0x100 + ((MAX_CPU - 1) * 0x1000)
enum mpic_ide_bits {
- IDR_EP = 0,
- IDR_CI0 = 1,
- IDR_CI1 = 2,
- IDR_P1 = 30,
- IDR_P0 = 31,
+ IDR_EP = 31,
+ IDR_CI0 = 30,
+ IDR_CI1 = 29,
+ IDR_P1 = 1,
+ IDR_P0 = 0,
};
#else
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 08/28] PPC: Bump MPIC up to 32 supported CPUs
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
` (6 preceding siblings ...)
2011-07-23 10:49 ` [Qemu-devel] [PATCH 07/28] PPC: MPIC: Fix CI bit definitions Alexander Graf
@ 2011-07-23 10:49 ` Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 09/28] PPC: E500: create multiple envs Alexander Graf
` (19 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:49 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
The MPIC emulation is now capable of handling up to 32 CPUs. Reflect that in
the code exporting the numbers out and fix an integer overflow while at it.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
v1 -> v2:
- Max cpus is 15 due to cINT routing
- Report nb_cpus not MAX_CPUS in MPIC capabilities
---
hw/openpic.c | 10 +++-------
1 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/hw/openpic.c b/hw/openpic.c
index af07e13..aa8446c 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -63,7 +63,7 @@
#elif defined(USE_MPCxxx)
-#define MAX_CPU 2
+#define MAX_CPU 15
#define MAX_IRQ 128
#define MAX_DBL 0
#define MAX_MBX 0
@@ -507,7 +507,7 @@ static inline void write_IRQreg (openpic_t *opp, int n_IRQ,
break;
case IRQ_IDE:
tmp = val & 0xC0000000;
- tmp |= val & ((1 << MAX_CPU) - 1);
+ tmp |= val & ((1ULL << MAX_CPU) - 1);
opp->src[n_IRQ].ide = tmp;
DPRINTF("Set IDE %d to 0x%08x\n", n_IRQ, opp->src[n_IRQ].ide);
break;
@@ -1288,7 +1288,7 @@ static void mpic_reset (void *opaque)
mpp->glbc = 0x80000000;
/* Initialise controller registers */
- mpp->frep = 0x004f0002;
+ mpp->frep = 0x004f0002 | ((mpp->nb_cpus - 1) << 8);
mpp->veni = VENI;
mpp->pint = 0x00000000;
mpp->spve = 0x0000FFFF;
@@ -1689,10 +1689,6 @@ qemu_irq *mpic_init (target_phys_addr_t base, int nb_cpus,
{mpic_cpu_read, mpic_cpu_write, MPIC_CPU_REG_START, MPIC_CPU_REG_SIZE},
};
- /* XXX: for now, only one CPU is supported */
- if (nb_cpus != 1)
- return NULL;
-
mpp = qemu_mallocz(sizeof(openpic_t));
for (i = 0; i < sizeof(list)/sizeof(list[0]); i++) {
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 09/28] PPC: E500: create multiple envs
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
` (7 preceding siblings ...)
2011-07-23 10:49 ` [Qemu-devel] [PATCH 08/28] PPC: Bump MPIC up to 32 supported CPUs Alexander Graf
@ 2011-07-23 10:49 ` Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 10/28] PPC: E500: Generate IRQ lines for many CPUs Alexander Graf
` (18 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:49 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
When creating a VM, we should go through smp_cpus and create a virtual CPU for
every CPU the user requested. This patch adds support for that and moves some
code around to make that more convenient.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
hw/ppce500_mpc8544ds.c | 44 +++++++++++++++++++++++++++++---------------
1 files changed, 29 insertions(+), 15 deletions(-)
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index b739ce2..cefb415 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -226,7 +226,7 @@ static void mpc8544ds_init(ram_addr_t ram_size,
const char *cpu_model)
{
PCIBus *pci_bus;
- CPUState *env;
+ CPUState *env = NULL;
uint64_t elf_entry;
uint64_t elf_lowaddr;
target_phys_addr_t entry=0;
@@ -240,24 +240,40 @@ static void mpc8544ds_init(ram_addr_t ram_size,
qemu_irq *irqs, *mpic;
DeviceState *dev;
struct boot_info *boot_info;
+ CPUState *firstenv = NULL;
- /* Setup CPU */
+ /* Setup CPUs */
if (cpu_model == NULL) {
cpu_model = "e500v2_v30";
}
- env = cpu_ppc_init(cpu_model);
- if (!env) {
- fprintf(stderr, "Unable to initialize CPU!\n");
- exit(1);
- }
+ for (i = 0; i < smp_cpus; i++) {
+ qemu_irq *input;
+ env = cpu_ppc_init(cpu_model);
+ if (!env) {
+ fprintf(stderr, "Unable to initialize CPU!\n");
+ exit(1);
+ }
+
+ if (!firstenv) {
+ firstenv = env;
+ }
- /* XXX register timer? */
- ppc_emb_timers_init(env, 400000000, PPC_INTERRUPT_DECR);
- ppc_dcr_init(env, NULL, NULL);
+ env->spr[SPR_BOOKE_PIR] = env->cpu_index = i;
- /* Register reset handler */
- qemu_register_reset(mpc8544ds_cpu_reset, env);
+ /* XXX register timer? */
+ ppc_emb_timers_init(env, 400000000, PPC_INTERRUPT_DECR);
+ ppc_dcr_init(env, NULL, NULL);
+ /* XXX Enable DEC interrupts - probably wrong in the backend */
+ env->spr[SPR_40x_TCR] = 1 << 26;
+
+ /* Register reset handler */
+ boot_info = qemu_mallocz(sizeof(struct boot_info));
+ qemu_register_reset(mpc8544ds_cpu_reset, env);
+ env->load_info = boot_info;
+ }
+
+ env = firstenv;
/* Fixup Memory size on a alignment boundary */
ram_size &= ~(RAM_SIZES_ALIGN - 1);
@@ -336,8 +352,6 @@ static void mpc8544ds_init(ram_addr_t ram_size,
}
}
- boot_info = qemu_mallocz(sizeof(struct boot_info));
-
/* If we're loading a kernel directly, we must load the device tree too. */
if (kernel_filename) {
#ifndef CONFIG_FDT
@@ -350,10 +364,10 @@ static void mpc8544ds_init(ram_addr_t ram_size,
exit(1);
}
+ boot_info = env->load_info;
boot_info->entry = entry;
boot_info->dt_base = dt_base;
}
- env->load_info = boot_info;
if (kvm_enabled()) {
kvmppc_init();
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 10/28] PPC: E500: Generate IRQ lines for many CPUs
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
` (8 preceding siblings ...)
2011-07-23 10:49 ` [Qemu-devel] [PATCH 09/28] PPC: E500: create multiple envs Alexander Graf
@ 2011-07-23 10:49 ` Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 11/28] device tree: add nop_node Alexander Graf
` (17 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:49 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
Now that we can generate multiple envs for all our virtual CPUs, we
also need to tell the MPIC that we have multiple CPUs connected and
connect them all to the respective virtual interrupt lines.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
hw/ppce500_mpc8544ds.c | 17 ++++++++++++-----
1 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index cefb415..7ce9bc7 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -237,7 +237,7 @@ static void mpc8544ds_init(ram_addr_t ram_size,
target_long initrd_size=0;
int i=0;
unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};
- qemu_irq *irqs, *mpic;
+ qemu_irq **irqs, *mpic;
DeviceState *dev;
struct boot_info *boot_info;
CPUState *firstenv = NULL;
@@ -247,6 +247,8 @@ static void mpc8544ds_init(ram_addr_t ram_size,
cpu_model = "e500v2_v30";
}
+ irqs = qemu_mallocz(smp_cpus * sizeof(qemu_irq *));
+ irqs[0] = qemu_mallocz(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);
for (i = 0; i < smp_cpus; i++) {
qemu_irq *input;
env = cpu_ppc_init(cpu_model);
@@ -259,6 +261,10 @@ static void mpc8544ds_init(ram_addr_t ram_size,
firstenv = env;
}
+ irqs[i] = irqs[0] + (i * OPENPIC_OUTPUT_NB);
+ input = (qemu_irq *)env->irq_inputs;
+ irqs[i][OPENPIC_OUTPUT_INT] = input[PPCE500_INPUT_INT];
+ irqs[i][OPENPIC_OUTPUT_CINT] = input[PPCE500_INPUT_CINT];
env->spr[SPR_BOOKE_PIR] = env->cpu_index = i;
/* XXX register timer? */
@@ -283,10 +289,11 @@ static void mpc8544ds_init(ram_addr_t ram_size,
"mpc8544ds.ram", ram_size));
/* MPIC */
- irqs = qemu_mallocz(sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);
- irqs[OPENPIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPCE500_INPUT_INT];
- irqs[OPENPIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPCE500_INPUT_CINT];
- mpic = mpic_init(MPC8544_MPIC_REGS_BASE, 1, &irqs, NULL);
+ mpic = mpic_init(MPC8544_MPIC_REGS_BASE, smp_cpus, irqs, NULL);
+
+ if (!mpic) {
+ cpu_abort(env, "MPIC failed to initialize\n");
+ }
/* Serial */
if (serial_hds[0]) {
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 11/28] device tree: add nop_node
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
` (9 preceding siblings ...)
2011-07-23 10:49 ` [Qemu-devel] [PATCH 10/28] PPC: E500: Generate IRQ lines for many CPUs Alexander Graf
@ 2011-07-23 10:49 ` Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 12/28] PPC: bamboo: Move host fdt copy to target Alexander Graf
` (16 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:49 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
We have a qemu internal abstraction layer on FDT. While I'm not fully convinced
we need it at all, it's missing the nop_node functionality that we now need
on e500. So let's add it and think about the general future of that API later.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
device_tree.c | 11 +++++++++++
device_tree.h | 1 +
2 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/device_tree.c b/device_tree.c
index f5d5eb1..ec79dba 100644
--- a/device_tree.c
+++ b/device_tree.c
@@ -107,3 +107,14 @@ int qemu_devtree_setprop_string(void *fdt, const char *node_path,
return fdt_setprop_string(fdt, offset, property, string);
}
+
+int qemu_devtree_nop_node(void *fdt, const char *node_path)
+{
+ int offset;
+
+ offset = fdt_path_offset(fdt, node_path);
+ if (offset < 0)
+ return offset;
+
+ return fdt_nop_node(fdt, offset);
+}
diff --git a/device_tree.h b/device_tree.h
index cecd98f..76fce5f 100644
--- a/device_tree.h
+++ b/device_tree.h
@@ -22,5 +22,6 @@ int qemu_devtree_setprop_cell(void *fdt, const char *node_path,
const char *property, uint32_t val);
int qemu_devtree_setprop_string(void *fdt, const char *node_path,
const char *property, const char *string);
+int qemu_devtree_nop_node(void *fdt, const char *node_path);
#endif /* __DEVICE_TREE_H__ */
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 12/28] PPC: bamboo: Move host fdt copy to target
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
` (10 preceding siblings ...)
2011-07-23 10:49 ` [Qemu-devel] [PATCH 11/28] device tree: add nop_node Alexander Graf
@ 2011-07-23 10:49 ` Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 13/28] PPC: KVM: Add generic function to read host clockfreq Alexander Graf
` (15 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:49 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
We have some code in generic kvm_ppc.c that is only used by 440. Move to
the 440 specific device code.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
hw/ppc440_bamboo.c | 37 +++++++++++++++++++++++++++++++++++--
target-ppc/kvm_ppc.c | 30 ------------------------------
target-ppc/kvm_ppc.h | 1 -
3 files changed, 35 insertions(+), 33 deletions(-)
diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
index 20b8629..a059f6b 100644
--- a/hw/ppc440_bamboo.c
+++ b/hw/ppc440_bamboo.c
@@ -31,6 +31,38 @@
#define FDT_ADDR 0x1800000
#define RAMDISK_ADDR 0x1900000
+#ifdef CONFIG_FDT
+static int bamboo_copy_host_cell(void *fdt, const char *node, const char *prop)
+{
+ uint32_t cell;
+ int ret;
+
+ ret = kvmppc_read_host_property(node, prop, &cell, sizeof(cell));
+ if (ret < 0) {
+ fprintf(stderr, "couldn't read host %s/%s\n", node, prop);
+ goto out;
+ }
+
+ ret = qemu_devtree_setprop_cell(fdt, node, prop, cell);
+ if (ret < 0) {
+ fprintf(stderr, "couldn't set guest %s/%s\n", node, prop);
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+static void bamboo_fdt_update(void *fdt)
+{
+ /* Copy data from the host device tree into the guest. Since the guest can
+ * directly access the timebase without host involvement, we must expose
+ * the correct frequencies. */
+ bamboo_copy_host_cell(fdt, "/cpus/cpu@0", "clock-frequency");
+ bamboo_copy_host_cell(fdt, "/cpus/cpu@0", "timebase-frequency");
+}
+#endif
+
static int bamboo_load_device_tree(target_phys_addr_t addr,
uint32_t ramsize,
target_phys_addr_t initrd_base,
@@ -76,8 +108,9 @@ static int bamboo_load_device_tree(target_phys_addr_t addr,
if (ret < 0)
fprintf(stderr, "couldn't set /chosen/bootargs\n");
- if (kvm_enabled())
- kvmppc_fdt_update(fdt);
+ if (kvm_enabled()) {
+ bamboo_fdt_update(fdt);
+ }
ret = rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr);
qemu_free(fdt);
diff --git a/target-ppc/kvm_ppc.c b/target-ppc/kvm_ppc.c
index 536fcab..7cc522a 100644
--- a/target-ppc/kvm_ppc.c
+++ b/target-ppc/kvm_ppc.c
@@ -54,36 +54,6 @@ free:
free(path);
return ret;
}
-
-static int kvmppc_copy_host_cell(void *fdt, const char *node, const char *prop)
-{
- uint32_t cell;
- int ret;
-
- ret = kvmppc_read_host_property(node, prop, &cell, sizeof(cell));
- if (ret < 0) {
- fprintf(stderr, "couldn't read host %s/%s\n", node, prop);
- goto out;
- }
-
- ret = qemu_devtree_setprop_cell(fdt, node, prop, cell);
- if (ret < 0) {
- fprintf(stderr, "couldn't set guest %s/%s\n", node, prop);
- goto out;
- }
-
-out:
- return ret;
-}
-
-void kvmppc_fdt_update(void *fdt)
-{
- /* Copy data from the host device tree into the guest. Since the guest can
- * directly access the timebase without host involvement, we must expose
- * the correct frequencies. */
- kvmppc_copy_host_cell(fdt, "/cpus/cpu@0", "clock-frequency");
- kvmppc_copy_host_cell(fdt, "/cpus/cpu@0", "timebase-frequency");
-}
#endif
static void kvmppc_timer_hack(void *opaque)
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index 45a1373..2f32249 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -10,7 +10,6 @@
#define __KVM_PPC_H__
void kvmppc_init(void);
-void kvmppc_fdt_update(void *fdt);
#ifndef CONFIG_KVM
static inline int kvmppc_read_host_property(const char *node_path, const char *prop,
void *val, size_t len)
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 13/28] PPC: KVM: Add generic function to read host clockfreq
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
` (11 preceding siblings ...)
2011-07-23 10:49 ` [Qemu-devel] [PATCH 12/28] PPC: bamboo: Move host fdt copy to target Alexander Graf
@ 2011-07-23 10:49 ` Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 14/28] PPC: E500: Use generic kvm function for freq Alexander Graf
` (14 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:49 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
We need to find out the host's clock-frequency when running on KVM, so
let's export a respective function.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
v1 -> v2:
- enable 64bit values
---
target-ppc/kvm.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++
target-ppc/kvm_ppc.h | 1 +
2 files changed, 68 insertions(+), 0 deletions(-)
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 21f35af..219e7a7 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -14,6 +14,7 @@
*
*/
+#include <dirent.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
@@ -38,6 +39,8 @@
do { } while (0)
#endif
+#define PROC_DEVTREE_CPU "/proc/device-tree/cpus/"
+
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
KVM_CAP_LAST_INFO
};
@@ -509,6 +512,70 @@ uint32_t kvmppc_get_tbfreq(void)
return retval;
}
+/* Try to find a device tree node for a CPU with clock-frequency property */
+static int kvmppc_find_cpu_dt(char *buf, int buf_len)
+{
+ struct dirent *dirp;
+ DIR *dp;
+
+ if ((dp = opendir(PROC_DEVTREE_CPU)) == NULL) {
+ printf("Can't open directory " PROC_DEVTREE_CPU "\n");
+ return -1;
+ }
+
+ buf[0] = '\0';
+ while ((dirp = readdir(dp)) != NULL) {
+ FILE *f;
+ snprintf(buf, buf_len, "%s%s/clock-frequency", PROC_DEVTREE_CPU,
+ dirp->d_name);
+ f = fopen(buf, "r");
+ if (f) {
+ snprintf(buf, buf_len, "%scpus/%s", PROC_DEVTREE_CPU, dirp->d_name);
+ fclose(f);
+ break;
+ }
+ buf[0] = '\0';
+ }
+ closedir(dp);
+ if (buf[0] == '\0') {
+ printf("Unknown host!\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+uint64_t kvmppc_get_clockfreq(void)
+{
+ char buf[512];
+ uint32_t tb[2];
+ FILE *f;
+ int len;
+
+ if (kvmppc_find_cpu_dt(buf, sizeof(buf))) {
+ return 0;
+ }
+
+ snprintf(buf, sizeof(buf), "%s/clock-frequency", buf);
+
+ f = fopen(buf, "rb");
+ if (!f) {
+ return -1;
+ }
+
+ len = fread(tb, sizeof(tb[0]), 2, f);
+ fclose(f);
+ switch (len) {
+ case 1:
+ /* freq is only a single cell */
+ return tb[0];
+ case 2:
+ return *(uint64_t*)tb;
+ }
+
+ return 0;
+}
+
int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len)
{
uint32_t *hc = (uint32_t*)buf;
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index 2f32249..7c08c0f 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -23,6 +23,7 @@ int kvmppc_read_host_property(const char *node_path, const char *prop,
#endif
uint32_t kvmppc_get_tbfreq(void);
+uint64_t kvmppc_get_clockfreq(void);
int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len);
int kvmppc_set_interrupt(CPUState *env, int irq, int level);
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 14/28] PPC: E500: Use generic kvm function for freq
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
` (12 preceding siblings ...)
2011-07-23 10:49 ` [Qemu-devel] [PATCH 13/28] PPC: KVM: Add generic function to read host clockfreq Alexander Graf
@ 2011-07-23 10:49 ` Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 15/28] PPC: E500: Remove mpc8544_copy_soc_cell Alexander Graf
` (13 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:49 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
Now that we have generic KVM functions to read out the host tb and clock
frequencies, let's use them in the e500 code!
Signed-off-by: Alexander Graf <agraf@suse.de>
---
hw/ppce500_mpc8544ds.c | 44 +++++++++-----------------------------------
1 files changed, 9 insertions(+), 35 deletions(-)
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index 7ce9bc7..eedd149 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -14,8 +14,6 @@
* (at your option) any later version.
*/
-#include <dirent.h>
-
#include "config.h"
#include "qemu-common.h"
#include "net.h"
@@ -96,6 +94,9 @@ static int mpc8544_load_device_tree(CPUState *env,
int fdt_size;
void *fdt;
uint8_t hypercall[16];
+ char cpu_name[128] = "/cpus/PowerPC,8544@0";
+ uint32_t clock_freq = 400000000;
+ uint32_t tb_freq = 400000000;
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE);
if (!filename) {
@@ -133,32 +134,9 @@ static int mpc8544_load_device_tree(CPUState *env,
fprintf(stderr, "couldn't set /chosen/bootargs\n");
if (kvm_enabled()) {
- struct dirent *dirp;
- DIR *dp;
- char buf[128];
-
- if ((dp = opendir("/proc/device-tree/cpus/")) == NULL) {
- printf("Can't open directory /proc/device-tree/cpus/\n");
- ret = -1;
- goto out;
- }
-
- buf[0] = '\0';
- while ((dirp = readdir(dp)) != NULL) {
- if (strncmp(dirp->d_name, "PowerPC", 7) == 0) {
- snprintf(buf, 128, "/cpus/%s", dirp->d_name);
- break;
- }
- }
- closedir(dp);
- if (buf[0] == '\0') {
- printf("Unknow host!\n");
- ret = -1;
- goto out;
- }
-
- mpc8544_copy_soc_cell(fdt, buf, "clock-frequency");
- mpc8544_copy_soc_cell(fdt, buf, "timebase-frequency");
+ /* Read out host's frequencies */
+ clock_freq = kvmppc_get_clockfreq();
+ tb_freq = kvmppc_get_tbfreq();
/* indicate KVM hypercall interface */
qemu_devtree_setprop_string(fdt, "/hypervisor", "compatible",
@@ -166,15 +144,11 @@ static int mpc8544_load_device_tree(CPUState *env,
kvmppc_get_hypercall(env, hypercall, sizeof(hypercall));
qemu_devtree_setprop(fdt, "/hypervisor", "hcall-instructions",
hypercall, sizeof(hypercall));
- } else {
- const uint32_t freq = 400000000;
-
- qemu_devtree_setprop_cell(fdt, "/cpus/PowerPC,8544@0",
- "clock-frequency", freq);
- qemu_devtree_setprop_cell(fdt, "/cpus/PowerPC,8544@0",
- "timebase-frequency", freq);
}
+ qemu_devtree_setprop_cell(fdt, cpu_name, "clock-frequency", clock_freq);
+ qemu_devtree_setprop_cell(fdt, cpu_name, "timebase-frequency", tb_freq);
+
ret = rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr);
qemu_free(fdt);
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 15/28] PPC: E500: Remove mpc8544_copy_soc_cell
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
` (13 preceding siblings ...)
2011-07-23 10:49 ` [Qemu-devel] [PATCH 14/28] PPC: E500: Use generic kvm function for freq Alexander Graf
@ 2011-07-23 10:49 ` Alexander Graf
2011-07-23 10:50 ` [Qemu-devel] [PATCH 16/28] PPC: bamboo: Use kvm api for freq and clock frequencies Alexander Graf
` (12 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:49 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
We don't need mpc8544_copy_soc_cell anymore, since we're explicitly reading
host values and writing guest values respectively.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
hw/ppce500_mpc8544ds.c | 24 ------------------------
1 files changed, 0 insertions(+), 24 deletions(-)
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index eedd149..8a51ac7 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -56,30 +56,6 @@ struct boot_info
uint32_t entry;
};
-#ifdef CONFIG_FDT
-static int mpc8544_copy_soc_cell(void *fdt, const char *node, const char *prop)
-{
- uint32_t cell;
- int ret;
-
- ret = kvmppc_read_host_property(node, prop, &cell, sizeof(cell));
- if (ret < 0) {
- fprintf(stderr, "couldn't read host %s/%s\n", node, prop);
- goto out;
- }
-
- ret = qemu_devtree_setprop_cell(fdt, "/cpus/PowerPC,8544@0",
- prop, cell);
- if (ret < 0) {
- fprintf(stderr, "couldn't set guest /cpus/PowerPC,8544@0/%s\n", prop);
- goto out;
- }
-
-out:
- return ret;
-}
-#endif
-
static int mpc8544_load_device_tree(CPUState *env,
target_phys_addr_t addr,
uint32_t ramsize,
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 16/28] PPC: bamboo: Use kvm api for freq and clock frequencies
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
` (14 preceding siblings ...)
2011-07-23 10:49 ` [Qemu-devel] [PATCH 15/28] PPC: E500: Remove mpc8544_copy_soc_cell Alexander Graf
@ 2011-07-23 10:50 ` Alexander Graf
2011-07-23 10:50 ` [Qemu-devel] [PATCH 17/28] PPC: KVM: Remove kvmppc_read_host_property Alexander Graf
` (11 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:50 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
Now that we have nice and shiny APIs to read out the host's clock and timebase
frequencies, let's use them in the bamboo code as well!
Signed-off-by: Alexander Graf <agraf@suse.de>
---
hw/ppc440_bamboo.c | 45 ++++++++++++---------------------------------
1 files changed, 12 insertions(+), 33 deletions(-)
diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
index a059f6b..afcf97b 100644
--- a/hw/ppc440_bamboo.c
+++ b/hw/ppc440_bamboo.c
@@ -31,38 +31,6 @@
#define FDT_ADDR 0x1800000
#define RAMDISK_ADDR 0x1900000
-#ifdef CONFIG_FDT
-static int bamboo_copy_host_cell(void *fdt, const char *node, const char *prop)
-{
- uint32_t cell;
- int ret;
-
- ret = kvmppc_read_host_property(node, prop, &cell, sizeof(cell));
- if (ret < 0) {
- fprintf(stderr, "couldn't read host %s/%s\n", node, prop);
- goto out;
- }
-
- ret = qemu_devtree_setprop_cell(fdt, node, prop, cell);
- if (ret < 0) {
- fprintf(stderr, "couldn't set guest %s/%s\n", node, prop);
- goto out;
- }
-
-out:
- return ret;
-}
-
-static void bamboo_fdt_update(void *fdt)
-{
- /* Copy data from the host device tree into the guest. Since the guest can
- * directly access the timebase without host involvement, we must expose
- * the correct frequencies. */
- bamboo_copy_host_cell(fdt, "/cpus/cpu@0", "clock-frequency");
- bamboo_copy_host_cell(fdt, "/cpus/cpu@0", "timebase-frequency");
-}
-#endif
-
static int bamboo_load_device_tree(target_phys_addr_t addr,
uint32_t ramsize,
target_phys_addr_t initrd_base,
@@ -75,6 +43,8 @@ static int bamboo_load_device_tree(target_phys_addr_t addr,
char *filename;
int fdt_size;
void *fdt;
+ uint32_t tb_freq = 400000000;
+ uint32_t clock_freq = 400000000;
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE);
if (!filename) {
@@ -108,10 +78,19 @@ static int bamboo_load_device_tree(target_phys_addr_t addr,
if (ret < 0)
fprintf(stderr, "couldn't set /chosen/bootargs\n");
+ /* Copy data from the host device tree into the guest. Since the guest can
+ * directly access the timebase without host involvement, we must expose
+ * the correct frequencies. */
if (kvm_enabled()) {
- bamboo_fdt_update(fdt);
+ tb_freq = kvmppc_get_tbfreq();
+ clock_freq = kvmppc_get_clockfreq();
}
+ qemu_devtree_setprop_cell(fdt, "/cpus/cpu@0", "clock-frequency",
+ clock_freq);
+ qemu_devtree_setprop_cell(fdt, "/cpus/cpu@0", "timebase-frequency",
+ tb_freq);
+
ret = rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr);
qemu_free(fdt);
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 17/28] PPC: KVM: Remove kvmppc_read_host_property
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
` (15 preceding siblings ...)
2011-07-23 10:50 ` [Qemu-devel] [PATCH 16/28] PPC: bamboo: Use kvm api for freq and clock frequencies Alexander Graf
@ 2011-07-23 10:50 ` Alexander Graf
2011-07-23 10:50 ` [Qemu-devel] [PATCH 18/28] PPC: KVM: Add stubs for kvm helper functions Alexander Graf
` (10 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:50 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
We just got rid of the last user of kvmppc_read_host_property, so we
can now safely remove it.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-ppc/kvm_ppc.c | 35 -----------------------------------
target-ppc/kvm_ppc.h | 11 -----------
2 files changed, 0 insertions(+), 46 deletions(-)
diff --git a/target-ppc/kvm_ppc.c b/target-ppc/kvm_ppc.c
index 7cc522a..0c9b530 100644
--- a/target-ppc/kvm_ppc.c
+++ b/target-ppc/kvm_ppc.c
@@ -21,41 +21,6 @@
static QEMUTimer *kvmppc_timer;
static unsigned int kvmppc_timer_rate;
-#ifdef CONFIG_FDT
-int kvmppc_read_host_property(const char *node_path, const char *prop,
- void *val, size_t len)
-{
- char *path;
- FILE *f;
- int ret = 0;
- int pathlen;
-
- pathlen = snprintf(NULL, 0, "%s/%s/%s", PROC_DEVTREE_PATH, node_path, prop)
- + 1;
- path = qemu_malloc(pathlen);
-
- snprintf(path, pathlen, "%s/%s/%s", PROC_DEVTREE_PATH, node_path, prop);
-
- f = fopen(path, "rb");
- if (f == NULL) {
- ret = errno;
- goto free;
- }
-
- len = fread(val, len, 1, f);
- if (len != 1) {
- ret = ferror(f);
- goto close;
- }
-
-close:
- fclose(f);
-free:
- free(path);
- return ret;
-}
-#endif
-
static void kvmppc_timer_hack(void *opaque)
{
qemu_service_io();
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index 7c08c0f..0c659c8 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -10,17 +10,6 @@
#define __KVM_PPC_H__
void kvmppc_init(void);
-#ifndef CONFIG_KVM
-static inline int kvmppc_read_host_property(const char *node_path, const char *prop,
- void *val, size_t len)
-{
- assert(0);
- return -ENOSYS;
-}
-#else
-int kvmppc_read_host_property(const char *node_path, const char *prop,
- void *val, size_t len);
-#endif
uint32_t kvmppc_get_tbfreq(void);
uint64_t kvmppc_get_clockfreq(void);
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 18/28] PPC: KVM: Add stubs for kvm helper functions
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
` (16 preceding siblings ...)
2011-07-23 10:50 ` [Qemu-devel] [PATCH 17/28] PPC: KVM: Remove kvmppc_read_host_property Alexander Graf
@ 2011-07-23 10:50 ` Alexander Graf
2011-07-23 10:50 ` [Qemu-devel] [PATCH 19/28] PPC: E500: Update freqs for all CPUs Alexander Graf
` (9 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:50 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
We have a bunch of helper functions that don't have any stubs for them in case
we don't have CONFIG_KVM enabled. That didn't bite us so far, because gcc can
optimize them out pretty well, but we should really provide them.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
v1 -> v2:
- use uint64_t for clockfreq
---
target-ppc/kvm_ppc.h | 26 ++++++++++++++++++++++++++
1 files changed, 26 insertions(+), 0 deletions(-)
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index 0c659c8..76f98d9 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -11,11 +11,37 @@
void kvmppc_init(void);
+#ifdef CONFIG_KVM
+
uint32_t kvmppc_get_tbfreq(void);
uint64_t kvmppc_get_clockfreq(void);
int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len);
int kvmppc_set_interrupt(CPUState *env, int irq, int level);
+#else
+
+static inline uint32_t kvmppc_get_tbfreq(void)
+{
+ return 0;
+}
+
+static inline uint64_t kvmppc_get_clockfreq(void)
+{
+ return 0;
+}
+
+static inline int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len)
+{
+ return -1;
+}
+
+static inline int kvmppc_set_interrupt(CPUState *env, int irq, int level)
+{
+ return -1;
+}
+
+#endif
+
#ifndef CONFIG_KVM
#define kvmppc_eieio() do { } while (0)
#else
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 19/28] PPC: E500: Update freqs for all CPUs
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
` (17 preceding siblings ...)
2011-07-23 10:50 ` [Qemu-devel] [PATCH 18/28] PPC: KVM: Add stubs for kvm helper functions Alexander Graf
@ 2011-07-23 10:50 ` Alexander Graf
2011-07-23 10:50 ` [Qemu-devel] [PATCH 20/28] PPC: E500: Remove unneeded CPU nodes Alexander Graf
` (8 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:50 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
Now that we can so nicely find out the host's frequencies, we should also
make sure that we get them into all virtual CPUs' device tree nodes.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
hw/ppce500_mpc8544ds.c | 10 +++++++---
1 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index 8a51ac7..e99065c 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -70,9 +70,9 @@ static int mpc8544_load_device_tree(CPUState *env,
int fdt_size;
void *fdt;
uint8_t hypercall[16];
- char cpu_name[128] = "/cpus/PowerPC,8544@0";
uint32_t clock_freq = 400000000;
uint32_t tb_freq = 400000000;
+ int i;
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE);
if (!filename) {
@@ -122,8 +122,12 @@ static int mpc8544_load_device_tree(CPUState *env,
hypercall, sizeof(hypercall));
}
- qemu_devtree_setprop_cell(fdt, cpu_name, "clock-frequency", clock_freq);
- qemu_devtree_setprop_cell(fdt, cpu_name, "timebase-frequency", tb_freq);
+ for (i = 0; i < smp_cpus; i++) {
+ char cpu_name[128];
+ snprintf(cpu_name, sizeof(cpu_name), "/cpus/PowerPC,8544@%x", i);
+ qemu_devtree_setprop_cell(fdt, cpu_name, "clock-frequency", clock_freq);
+ qemu_devtree_setprop_cell(fdt, cpu_name, "timebase-frequency", tb_freq);
+ }
ret = rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr);
qemu_free(fdt);
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 20/28] PPC: E500: Remove unneeded CPU nodes
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
` (18 preceding siblings ...)
2011-07-23 10:50 ` [Qemu-devel] [PATCH 19/28] PPC: E500: Update freqs for all CPUs Alexander Graf
@ 2011-07-23 10:50 ` Alexander Graf
2011-07-23 10:50 ` [Qemu-devel] [PATCH 21/28] PPC: E500: Add PV spinning code Alexander Graf
` (7 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:50 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
We should only keep CPU nodes in the device tree around that we really have
virtual CPUs for. So remove all superfluous entries that we just keep there
in case someone wants to create a lot of vCPUs.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
hw/ppce500_mpc8544ds.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index e99065c..c74119a 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -129,6 +129,12 @@ static int mpc8544_load_device_tree(CPUState *env,
qemu_devtree_setprop_cell(fdt, cpu_name, "timebase-frequency", tb_freq);
}
+ for (i = smp_cpus; i < 32; i++) {
+ char cpu_name[128];
+ snprintf(cpu_name, sizeof(cpu_name), "/cpus/PowerPC,8544@%x", i);
+ qemu_devtree_nop_node(fdt, cpu_name);
+ }
+
ret = rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr);
qemu_free(fdt);
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 21/28] PPC: E500: Add PV spinning code
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
` (19 preceding siblings ...)
2011-07-23 10:50 ` [Qemu-devel] [PATCH 20/28] PPC: E500: Remove unneeded CPU nodes Alexander Graf
@ 2011-07-23 10:50 ` Alexander Graf
2011-07-25 20:40 ` Scott Wood
2011-07-23 10:50 ` [Qemu-devel] [PATCH 22/28] PPC: E500: Update cpu-release-addr property in cpu nodes Alexander Graf
` (6 subsequent siblings)
27 siblings, 1 reply; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:50 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
CPUs that are not the boot CPU need to run in spinning code to check if they
should run off to execute and if so where to jump to. This usually happens
by leaving secondary CPUs looping and checking if some variable in memory
changed.
In an environment like Qemu however we can be more clever. We can just export
the spin table the primary CPU modifies as MMIO region that would event based
wake up the respective secondary CPUs. That saves us quite some cycles while
the secondary CPUs are not up yet.
So this patch adds a PV device that simply exports the spinning table into the
guest and thus allows the primary CPU to wake up secondary ones.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
v1 -> v2:
- change into MMIO scheme
- map the secondary NIP instead of 0 1:1
- only map 64MB for TLB, same as u-boot
- prepare code for 64-bit spinnings
---
Makefile.target | 2 +-
hw/ppce500_mpc8544ds.c | 33 ++++++++-
hw/ppce500_spin.c | 182 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 212 insertions(+), 5 deletions(-)
create mode 100644 hw/ppce500_spin.c
diff --git a/Makefile.target b/Makefile.target
index 19f6101..925abd3 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -251,7 +251,7 @@ endif
obj-ppc-y += ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
obj-ppc-y += ppc440.o ppc440_bamboo.o
# PowerPC E500 boards
-obj-ppc-y += ppce500_mpc8544ds.o mpc8544_guts.o
+obj-ppc-y += ppce500_mpc8544ds.o mpc8544_guts.o ppce500_spin.o
# PowerPC 440 Xilinx ML507 reference board.
obj-ppc-y += virtex_ml507.o
obj-ppc-$(CONFIG_KVM) += kvm_ppc.o
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index c74119a..96a5362 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -49,6 +49,7 @@
#define MPC8544_PCI_IO 0xE1000000
#define MPC8544_PCI_IOLEN 0x10000
#define MPC8544_UTIL_BASE (MPC8544_CCSRBAR_BASE + 0xe0000)
+#define MPC8544_SPIN_BASE 0xEF000000
struct boot_info
{
@@ -164,6 +165,18 @@ static void mmubooke_create_initial_mapping(CPUState *env,
tlb->mas7_3 |= MAS3_UR | MAS3_UW | MAS3_UX | MAS3_SR | MAS3_SW | MAS3_SX;
}
+static void mpc8544ds_cpu_reset_sec(void *opaque)
+{
+ CPUState *env = opaque;
+
+ cpu_reset(env);
+
+ /* Secondary CPU starts in halted state for now. Needs to change when
+ implementing non-kernel boot. */
+ env->halted = 1;
+ env->exception_index = EXCP_HLT;
+}
+
static void mpc8544ds_cpu_reset(void *opaque)
{
CPUState *env = opaque;
@@ -172,6 +185,7 @@ static void mpc8544ds_cpu_reset(void *opaque)
cpu_reset(env);
/* Set initial guest state. */
+ env->halted = 0;
env->gpr[1] = (16<<20) - 8;
env->gpr[3] = bi->dt_base;
env->nip = bi->entry;
@@ -199,7 +213,6 @@ static void mpc8544ds_init(ram_addr_t ram_size,
unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};
qemu_irq **irqs, *mpic;
DeviceState *dev;
- struct boot_info *boot_info;
CPUState *firstenv = NULL;
/* Setup CPUs */
@@ -234,9 +247,16 @@ static void mpc8544ds_init(ram_addr_t ram_size,
env->spr[SPR_40x_TCR] = 1 << 26;
/* Register reset handler */
- boot_info = qemu_mallocz(sizeof(struct boot_info));
- qemu_register_reset(mpc8544ds_cpu_reset, env);
- env->load_info = boot_info;
+ if (!i) {
+ /* Primary CPU */
+ struct boot_info *boot_info;
+ boot_info = qemu_mallocz(sizeof(struct boot_info));
+ qemu_register_reset(mpc8544ds_cpu_reset, env);
+ env->load_info = boot_info;
+ } else {
+ /* Secondary CPUs */
+ qemu_register_reset(mpc8544ds_cpu_reset_sec, env);
+ }
}
env = firstenv;
@@ -289,6 +309,9 @@ static void mpc8544ds_init(ram_addr_t ram_size,
}
}
+ /* Register spinning region */
+ sysbus_create_simple("e500-spin", MPC8544_SPIN_BASE, NULL);
+
/* Load kernel. */
if (kernel_filename) {
kernel_size = load_uimage(kernel_filename, &entry, &loadaddr, NULL);
@@ -321,6 +344,8 @@ static void mpc8544ds_init(ram_addr_t ram_size,
/* If we're loading a kernel directly, we must load the device tree too. */
if (kernel_filename) {
+ struct boot_info *boot_info;
+
#ifndef CONFIG_FDT
cpu_abort(env, "Compiled without FDT support - can't load kernel\n");
#endif
diff --git a/hw/ppce500_spin.c b/hw/ppce500_spin.c
new file mode 100644
index 0000000..299aab6
--- /dev/null
+++ b/hw/ppce500_spin.c
@@ -0,0 +1,182 @@
+#include "hw.h"
+#include "sysemu.h"
+#include "sysbus.h"
+#include "rwhandler.h"
+#include "kvm.h"
+
+#define MAX_CPUS 32
+
+typedef struct spin_info {
+ uint64_t addr;
+ uint64_t r3;
+ uint32_t resv;
+ uint32_t pir;
+ uint64_t r6;
+} __attribute__ ((packed)) SpinInfo;
+
+typedef struct spin_state {
+ SysBusDevice busdev;
+ ReadWriteHandler rw;
+ SpinInfo spin[MAX_CPUS];
+} SpinState;
+
+typedef struct spin_kick {
+ CPUState *env;
+ SpinInfo *spin;
+} SpinKick;
+
+static void spin_reset(void *opaque)
+{
+ SpinState *s = opaque;
+ int i;
+
+ for (i = 0; i < MAX_CPUS; i++) {
+ SpinInfo *info = &s->spin[i];
+
+ info->pir = i;
+ info->r3 = i;
+ info->addr = 1;
+ info->r6 = 0;
+ }
+}
+
+/* Create -kernel TLB entries for BookE, linearly spanning 256MB. */
+static inline target_phys_addr_t booke206_page_size_to_tlb(uint64_t size)
+{
+ return (ffs(size >> 10) - 1) >> 1;
+}
+
+static void mmubooke_create_initial_mapping(CPUState *env,
+ target_ulong va,
+ target_phys_addr_t pa,
+ target_phys_addr_t len)
+{
+ ppcmas_tlb_t *tlb = booke206_get_tlbm(env, 1, 0, 0);
+ target_phys_addr_t size;
+
+ size = (booke206_page_size_to_tlb(len) << MAS1_TSIZE_SHIFT);
+ tlb->mas1 = MAS1_VALID | size;
+ tlb->mas2 = va & TARGET_PAGE_MASK;
+ tlb->mas7_3 = pa & TARGET_PAGE_MASK;
+ tlb->mas7_3 |= MAS3_UR | MAS3_UW | MAS3_UX | MAS3_SR | MAS3_SW | MAS3_SX;
+}
+
+static void spin_kick(void *data)
+{
+ SpinKick *kick = data;
+ CPUState *env = kick->env;
+ SpinInfo *curspin = kick->spin;
+ target_phys_addr_t map_size = 64 * 1024 * 1024;
+
+ cpu_synchronize_state(env);
+ curspin->pir = env->spr[SPR_PIR];
+ env->nip = curspin->addr;
+ env->gpr[3] = curspin->r3;
+ env->gpr[4] = 0;
+ env->gpr[5] = 0;
+ env->gpr[6] = curspin->r6;
+ env->gpr[7] = map_size;
+ env->gpr[8] = 0;
+ env->gpr[9] = 0;
+
+ mmubooke_create_initial_mapping(env, env->nip, env->nip, map_size);
+
+ env->halted = 0;
+ env->exception_index = -1;
+ qemu_cpu_kick(env);
+}
+
+static void spin_write(ReadWriteHandler *h, pcibus_t addr, uint32_t value,
+ int len)
+{
+ SpinState *s = container_of(h, SpinState, rw);
+ int env_idx = addr / sizeof(SpinInfo);
+ CPUState *env;
+ SpinInfo *curspin = &s->spin[env_idx];
+ uint8_t *curspin_p = (uint8_t*)curspin;
+
+ for (env = first_cpu; env != NULL; env = env->next_cpu) {
+ if (env->cpu_index == env_idx) {
+ break;
+ }
+ }
+
+ if (!env) {
+ /* Unknown CPU */
+ return;
+ }
+
+ if (!env->cpu_index) {
+ /* primary CPU doesn't spin */
+ return;
+ }
+
+ curspin_p = &curspin_p[addr % sizeof(SpinInfo)];
+ switch (len) {
+ case 1:
+ stb_p(curspin_p, value);
+ break;
+ case 2:
+ stw_p(curspin_p, value);
+ break;
+ case 4:
+ stl_p(curspin_p, value);
+ break;
+ }
+
+ if (!(curspin->addr & 1)) {
+ /* run CPU */
+ SpinKick kick = {
+ .env = env,
+ .spin = curspin,
+ };
+
+ run_on_cpu(env, spin_kick, &kick);
+ }
+}
+
+static uint32_t spin_read(ReadWriteHandler *h, pcibus_t addr, int len)
+{
+ SpinState *s = container_of(h, SpinState, rw);
+ uint8_t *spin_p = &((uint8_t*)s->spin)[addr];
+
+ switch (len) {
+ case 1:
+ return ldub_p(spin_p);
+ case 2:
+ return lduw_p(spin_p);
+ case 4:
+ return ldl_p(spin_p);
+ default:
+ assert(0);
+ }
+}
+
+static int ppce500_spin_initfn(SysBusDevice *dev)
+{
+ SpinState *s;
+ int iomem;
+
+ s = FROM_SYSBUS(SpinState, sysbus_from_qdev(dev));
+
+ s->rw.read = spin_read;
+ s->rw.write = spin_write;
+ iomem = cpu_register_io_memory_simple(&s->rw, DEVICE_BIG_ENDIAN);
+ sysbus_init_mmio(dev, sizeof(SpinInfo) * MAX_CPUS, iomem);
+
+ qemu_register_reset(spin_reset, s);
+
+ return 0;
+}
+
+static SysBusDeviceInfo ppce500_spin_info = {
+ .init = ppce500_spin_initfn,
+ .qdev.name = "e500-spin",
+ .qdev.size = sizeof(SpinState),
+};
+
+static void ppce500_spin_register(void)
+{
+ sysbus_register_withprop(&ppce500_spin_info);
+}
+device_init(ppce500_spin_register);
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 22/28] PPC: E500: Update cpu-release-addr property in cpu nodes
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
` (20 preceding siblings ...)
2011-07-23 10:50 ` [Qemu-devel] [PATCH 21/28] PPC: E500: Add PV spinning code Alexander Graf
@ 2011-07-23 10:50 ` Alexander Graf
2011-07-23 10:50 ` [Qemu-devel] [PATCH 23/28] device tree: add add_subnode command Alexander Graf
` (5 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:50 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
The guest OS wants to know where the guest spins, so let's tell him while
updating the CPU nodes with the frequencies anyways.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
v1 -> v2:
- use new spin table address
---
hw/ppce500_mpc8544ds.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index 96a5362..b48e95b 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -125,9 +125,15 @@ static int mpc8544_load_device_tree(CPUState *env,
for (i = 0; i < smp_cpus; i++) {
char cpu_name[128];
+ uint64_t cpu_release_addr[] = {
+ cpu_to_be64(MPC8544_SPIN_BASE + (i * 0x20))
+ };
+
snprintf(cpu_name, sizeof(cpu_name), "/cpus/PowerPC,8544@%x", i);
qemu_devtree_setprop_cell(fdt, cpu_name, "clock-frequency", clock_freq);
qemu_devtree_setprop_cell(fdt, cpu_name, "timebase-frequency", tb_freq);
+ qemu_devtree_setprop(fdt, cpu_name, "cpu-release-addr",
+ cpu_release_addr, sizeof(cpu_release_addr));
}
for (i = smp_cpus; i < 32; i++) {
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 23/28] device tree: add add_subnode command
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
` (21 preceding siblings ...)
2011-07-23 10:50 ` [Qemu-devel] [PATCH 22/28] PPC: E500: Update cpu-release-addr property in cpu nodes Alexander Graf
@ 2011-07-23 10:50 ` Alexander Graf
2011-07-23 10:50 ` [Qemu-devel] [PATCH 24/28] device tree: dont fail operations Alexander Graf
` (4 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:50 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
We want to be able to create subnodes in our device tree, so export it through
the qemu device tree abstraction framework.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
device_tree.c | 24 ++++++++++++++++++++++++
device_tree.h | 1 +
2 files changed, 25 insertions(+), 0 deletions(-)
diff --git a/device_tree.c b/device_tree.c
index ec79dba..e58d522 100644
--- a/device_tree.c
+++ b/device_tree.c
@@ -118,3 +118,27 @@ int qemu_devtree_nop_node(void *fdt, const char *node_path)
return fdt_nop_node(fdt, offset);
}
+
+int qemu_devtree_add_subnode(void *fdt, const char *name)
+{
+ int offset;
+ char *dupname = qemu_strdup(name);
+ char *basename = strrchr(dupname, '/');
+ int retval;
+
+ if (!basename) {
+ return -1;
+ }
+
+ basename[0] = '\0';
+ basename++;
+
+ offset = fdt_path_offset(fdt, dupname);
+ if (offset < 0) {
+ return offset;
+ }
+
+ retval = fdt_add_subnode(fdt, offset, basename);
+ qemu_free(dupname);
+ return retval;
+}
diff --git a/device_tree.h b/device_tree.h
index 76fce5f..4378685 100644
--- a/device_tree.h
+++ b/device_tree.h
@@ -23,5 +23,6 @@ int qemu_devtree_setprop_cell(void *fdt, const char *node_path,
int qemu_devtree_setprop_string(void *fdt, const char *node_path,
const char *property, const char *string);
int qemu_devtree_nop_node(void *fdt, const char *node_path);
+int qemu_devtree_add_subnode(void *fdt, const char *name);
#endif /* __DEVICE_TREE_H__ */
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 24/28] device tree: dont fail operations
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
` (22 preceding siblings ...)
2011-07-23 10:50 ` [Qemu-devel] [PATCH 23/28] device tree: add add_subnode command Alexander Graf
@ 2011-07-23 10:50 ` Alexander Graf
2011-07-23 10:50 ` [Qemu-devel] [PATCH 25/28] device tree: give dt more size Alexander Graf
` (3 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:50 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
When we screw up and issue an FDT command that doesn't work, we really need to
know immediately and usually can't continue to create the machine. To make sure
we don't need to add error checking in all device tree modification code users,
we can just add the fail checks to the qemu abstract functions.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
device_tree.c | 76 ++++++++++++++++++++++++++++++++++++++------------------
1 files changed, 51 insertions(+), 25 deletions(-)
diff --git a/device_tree.c b/device_tree.c
index e58d522..2af345b 100644
--- a/device_tree.c
+++ b/device_tree.c
@@ -72,56 +72,81 @@ fail:
return NULL;
}
-int qemu_devtree_setprop(void *fdt, const char *node_path,
- const char *property, void *val_array, int size)
+static int findnode_nofail(void *fdt, const char *node_path)
{
int offset;
offset = fdt_path_offset(fdt, node_path);
- if (offset < 0)
- return offset;
+ if (offset < 0) {
+ fprintf(stderr, "%s Couldn't find node %s: %s\n", __func__, node_path,
+ fdt_strerror(offset));
+ exit(1);
+ }
+
+ return offset;
+}
+
+int qemu_devtree_setprop(void *fdt, const char *node_path,
+ const char *property, void *val_array, int size)
+{
+ int r;
+
+ r = fdt_setprop(fdt, findnode_nofail(fdt, node_path), property, val_array, size);
+ if (r < 0) {
+ fprintf(stderr, "%s: Couldn't set %s/%s: %s\n", __func__, node_path,
+ property, fdt_strerror(r));
+ exit(1);
+ }
- return fdt_setprop(fdt, offset, property, val_array, size);
+ return r;
}
int qemu_devtree_setprop_cell(void *fdt, const char *node_path,
const char *property, uint32_t val)
{
- int offset;
+ int r;
- offset = fdt_path_offset(fdt, node_path);
- if (offset < 0)
- return offset;
+ r = fdt_setprop_cell(fdt, findnode_nofail(fdt, node_path), property, val);
+ if (r < 0) {
+ fprintf(stderr, "%s: Couldn't set %s/%s = %#08x: %s\n", __func__,
+ node_path, property, val, fdt_strerror(r));
+ exit(1);
+ }
- return fdt_setprop_cell(fdt, offset, property, val);
+ return r;
}
int qemu_devtree_setprop_string(void *fdt, const char *node_path,
const char *property, const char *string)
{
- int offset;
+ int r;
- offset = fdt_path_offset(fdt, node_path);
- if (offset < 0)
- return offset;
+ r = fdt_setprop_string(fdt, findnode_nofail(fdt, node_path), property, string);
+ if (r < 0) {
+ fprintf(stderr, "%s: Couldn't set %s/%s = %s: %s\n", __func__,
+ node_path, property, string, fdt_strerror(r));
+ exit(1);
+ }
- return fdt_setprop_string(fdt, offset, property, string);
+ return r;
}
int qemu_devtree_nop_node(void *fdt, const char *node_path)
{
- int offset;
+ int r;
- offset = fdt_path_offset(fdt, node_path);
- if (offset < 0)
- return offset;
+ r = fdt_nop_node(fdt, findnode_nofail(fdt, node_path));
+ if (r < 0) {
+ fprintf(stderr, "%s: Couldn't nop node %s: %s\n", __func__, node_path,
+ fdt_strerror(r));
+ exit(1);
+ }
- return fdt_nop_node(fdt, offset);
+ return r;
}
int qemu_devtree_add_subnode(void *fdt, const char *name)
{
- int offset;
char *dupname = qemu_strdup(name);
char *basename = strrchr(dupname, '/');
int retval;
@@ -133,12 +158,13 @@ int qemu_devtree_add_subnode(void *fdt, const char *name)
basename[0] = '\0';
basename++;
- offset = fdt_path_offset(fdt, dupname);
- if (offset < 0) {
- return offset;
+ retval = fdt_add_subnode(fdt, findnode_nofail(fdt, dupname), basename);
+ if (retval < 0) {
+ fprintf(stderr, "FDT: Failed to create subnode %s: %s\n", name,
+ fdt_strerror(retval));
+ exit(1);
}
- retval = fdt_add_subnode(fdt, offset, basename);
qemu_free(dupname);
return retval;
}
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 25/28] device tree: give dt more size
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
` (23 preceding siblings ...)
2011-07-23 10:50 ` [Qemu-devel] [PATCH 24/28] device tree: dont fail operations Alexander Graf
@ 2011-07-23 10:50 ` Alexander Graf
2011-07-23 10:50 ` [Qemu-devel] [PATCH 26/28] MPC8544DS: Remove CPU nodes Alexander Graf
` (2 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:50 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
We currently load a device tree blob and then just take its size x2 to
account for modifications we do inside. While this is nice and great,
it fails when we have a small device tree as blob and lots of nodes added
in machine init code.
So for now, just make it 20k bigger than it was before. We maybe want to
be more clever about this later.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
device_tree.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/device_tree.c b/device_tree.c
index 2af345b..0c0550b 100644
--- a/device_tree.c
+++ b/device_tree.c
@@ -41,6 +41,7 @@ void *load_device_tree(const char *filename_path, int *sizep)
}
/* Expand to 2x size to give enough room for manipulation. */
+ dt_size += 10000;
dt_size *= 2;
/* First allocate space in qemu for device tree */
fdt = qemu_mallocz(dt_size);
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 26/28] MPC8544DS: Remove CPU nodes
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
` (24 preceding siblings ...)
2011-07-23 10:50 ` [Qemu-devel] [PATCH 25/28] device tree: give dt more size Alexander Graf
@ 2011-07-23 10:50 ` Alexander Graf
2011-07-23 10:50 ` [Qemu-devel] [PATCH 27/28] MPC8544DS: Generate CPU nodes on init Alexander Graf
2011-07-23 10:50 ` [Qemu-devel] [PATCH 28/28] PPC: E500: Bump CPU count to 15 Alexander Graf
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:50 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
We want to generate the CPU nodes in machine init code, so remove them from
the device tree definition that we precompile.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
pc-bios/mpc8544ds.dtb | Bin 2277 -> 2028 bytes
pc-bios/mpc8544ds.dts | 12 ------------
2 files changed, 0 insertions(+), 12 deletions(-)
diff --git a/pc-bios/mpc8544ds.dtb b/pc-bios/mpc8544ds.dtb
index ae318b1fe83846cc2e133951a3666fcfcdf87f79..c6d302153c7407d5d0127be29b0c35f80e47f8fb 100644
GIT binary patch
delta 424
zcmaDV_=aEO0`I@K3=HgV7#J8V7#P?t0BH>%76f7eAO-?P8KC%#jT*{~lRq;qVGNu+
zgGpO80wTx2Se#mvnV92XVrpOj5@H5o79dUoaVFO=n@yHu7E~<+@qhp%%K^lVK&%DC
zOh63N(K9)OS(!0yas{(Dk?LOn)z6*G!y?7RuxYXeOPCPDVW4@8NM@d#Jb@*NiQ(ep
zFD&Xnqh(mF<QVQVF#G^2fdh6R3*?3eK>TTP3F~Xi9v};53e2?<KrxtWfnp$OF!&E7
zLApVn2ZjurwO}FhPlr`dQBX*1n*4+<n2~GZ2Ia}o?0Nb{iFxU%#SBTM#ky%lsfDGf
edC8Rw$*DOxx|w+?sTB;#Ir+)i2&u`Q9CHADZ%Xk1
delta 636
zcmaFE|5Q-p0`I@K3=AAk85kHW7#P?qfV2h>3j(nK5CZ{YE>PTIqlPkLJ!3$Ad1_IB
zvyO$SiHU;&Seh9~vH-DTazQCb0LJ$Paex5E4+OFmkod`He4yqApb%Vr6B@stfk6!<
z4_B}V%tP=uK>19QJs6iW9+>=rQJZnmWEm!T#^aN1n7mbC@*oFs0P!Ut)&gQCAci^e
z?&LL0%0TrOh*s~wtStKu$plcqfdJG*M&`*4%wa-|B0wQVBw?w^FPM{<7?mdbu&4v=
zD`Bx>Vl<e%fkldm(RuP2me-bdku<<uD*+UPxfUqK2ntdV_z%P&`#=!_^f#-u;0ETO
z4y&M|z{ml*!iFuFF?#X@wu$vAy2**j8L7HCnR%(Y#hF#944D`rFf}OBU`|P9Zfa6u
zajI@wQEFjnYF=_BLsDrm5-&L?KRFwTUzC`ao?6V1oSKuPo0*rA%2+WufPD@C{)cX6
diff --git a/pc-bios/mpc8544ds.dts b/pc-bios/mpc8544ds.dts
index a88b47c..7eb3160 100644
--- a/pc-bios/mpc8544ds.dts
+++ b/pc-bios/mpc8544ds.dts
@@ -25,18 +25,6 @@
cpus {
#address-cells = <1>;
#size-cells = <0>;
-
- PowerPC,8544@0 {
- device_type = "cpu";
- reg = <0x0>;
- d-cache-line-size = <32>; // 32 bytes
- i-cache-line-size = <32>; // 32 bytes
- d-cache-size = <0x8000>; // L1, 32K
- i-cache-size = <0x8000>; // L1, 32K
- timebase-frequency = <0>;
- bus-frequency = <0>;
- clock-frequency = <0>;
- };
};
memory {
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 27/28] MPC8544DS: Generate CPU nodes on init
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
` (25 preceding siblings ...)
2011-07-23 10:50 ` [Qemu-devel] [PATCH 26/28] MPC8544DS: Remove CPU nodes Alexander Graf
@ 2011-07-23 10:50 ` Alexander Graf
2011-07-23 10:50 ` [Qemu-devel] [PATCH 28/28] PPC: E500: Bump CPU count to 15 Alexander Graf
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:50 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
With this patch, we generate CPU nodes in the machine initialization, giving
us the freedom to generate as many nodes as we want and as the machine supports,
but only those.
This is a first step towards a much cleaner device tree generation
infrastructure, where we would not require precompiled dtb blobs anymore.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
hw/ppce500_mpc8544ds.c | 46 +++++++++++++++++++++++++++++++++-------------
1 files changed, 33 insertions(+), 13 deletions(-)
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index b48e95b..9c82044 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -123,23 +123,43 @@ static int mpc8544_load_device_tree(CPUState *env,
hypercall, sizeof(hypercall));
}
- for (i = 0; i < smp_cpus; i++) {
+ /* We need to generate the cpu nodes in reverse order, so Linux can pick
+ the first node as boot node and be happy */
+ for (i = smp_cpus - 1; i >= 0; i--) {
char cpu_name[128];
- uint64_t cpu_release_addr[] = {
- cpu_to_be64(MPC8544_SPIN_BASE + (i * 0x20))
- };
+ uint64_t cpu_release_addr = cpu_to_be64(MPC8544_SPIN_BASE + (i * 0x20));
+
+ for (env = first_cpu; env != NULL; env = env->next_cpu) {
+ if (env->cpu_index == i) {
+ break;
+ }
+ }
+
+ if (!env) {
+ continue;
+ }
- snprintf(cpu_name, sizeof(cpu_name), "/cpus/PowerPC,8544@%x", i);
+ snprintf(cpu_name, sizeof(cpu_name), "/cpus/PowerPC,8544@%x", env->cpu_index);
+ qemu_devtree_add_subnode(fdt, cpu_name);
qemu_devtree_setprop_cell(fdt, cpu_name, "clock-frequency", clock_freq);
qemu_devtree_setprop_cell(fdt, cpu_name, "timebase-frequency", tb_freq);
- qemu_devtree_setprop(fdt, cpu_name, "cpu-release-addr",
- cpu_release_addr, sizeof(cpu_release_addr));
- }
-
- for (i = smp_cpus; i < 32; i++) {
- char cpu_name[128];
- snprintf(cpu_name, sizeof(cpu_name), "/cpus/PowerPC,8544@%x", i);
- qemu_devtree_nop_node(fdt, cpu_name);
+ qemu_devtree_setprop_string(fdt, cpu_name, "device_type", "cpu");
+ qemu_devtree_setprop_cell(fdt, cpu_name, "reg", env->cpu_index);
+ qemu_devtree_setprop_cell(fdt, cpu_name, "d-cache-line-size",
+ env->dcache_line_size);
+ qemu_devtree_setprop_cell(fdt, cpu_name, "i-cache-line-size",
+ env->icache_line_size);
+ qemu_devtree_setprop_cell(fdt, cpu_name, "d-cache-size", 0x8000);
+ qemu_devtree_setprop_cell(fdt, cpu_name, "i-cache-size", 0x8000);
+ qemu_devtree_setprop_cell(fdt, cpu_name, "bus-frequency", 0);
+ if (env->cpu_index) {
+ qemu_devtree_setprop_string(fdt, cpu_name, "status", "disabled");
+ qemu_devtree_setprop_string(fdt, cpu_name, "enable-method", "spin-table");
+ qemu_devtree_setprop(fdt, cpu_name, "cpu-release-addr",
+ &cpu_release_addr, sizeof(cpu_release_addr));
+ } else {
+ qemu_devtree_setprop_string(fdt, cpu_name, "status", "okay");
+ }
}
ret = rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr);
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [Qemu-devel] [PATCH 28/28] PPC: E500: Bump CPU count to 15
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
` (26 preceding siblings ...)
2011-07-23 10:50 ` [Qemu-devel] [PATCH 27/28] MPC8544DS: Generate CPU nodes on init Alexander Graf
@ 2011-07-23 10:50 ` Alexander Graf
27 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-23 10:50 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Scott Wood, Elie Richa
Now that we have everything in place, make the machine description
aware of the fact that we can now handle 15 virtual CPUs!
Signed-off-by: Alexander Graf <agraf@suse.de>
---
v1 -> v2:
- Max cpus is 15 because of MPIC
---
hw/ppce500_mpc8544ds.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index 9c82044..f903e53 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -396,6 +396,7 @@ static QEMUMachine mpc8544ds_machine = {
.name = "mpc8544ds",
.desc = "mpc8544ds",
.init = mpc8544ds_init,
+ .max_cpus = 15,
};
static void mpc8544ds_machine_init(void)
--
1.6.0.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [Qemu-devel] [PATCH 05/28] PPC: Set MPIC IDE for IPI to 0
2011-07-23 10:49 ` [Qemu-devel] [PATCH 05/28] PPC: Set MPIC IDE for IPI to 0 Alexander Graf
@ 2011-07-25 8:46 ` Elie Richa
2011-07-25 8:50 ` Alexander Graf
0 siblings, 1 reply; 34+ messages in thread
From: Elie Richa @ 2011-07-25 8:46 UTC (permalink / raw)
To: Alexander Graf; +Cc: Scott Wood, QEMU-devel Developers
On 07/23/2011 12:49 PM, Alexander Graf wrote:
> @@ -1304,6 +1304,10 @@ static void mpic_reset (void *opaque)
> mpp->src[i].ipvp = 0x80800000;
> mpp->src[i].ide = 0x00000001;
> }
> + /* Set IDE for IPIs to 0 so we don't get spurious interrupts */
> + for (i = mpp->irq_ipi0; i< MAX_IPI; i++) {
I suppose you meant i < mpp->irq_ipi0 + MAX_IPI in that loop condition right? ;)
> + mpp->src[i].ide = 0;
> + }
> /* Initialise IRQ destinations */
> for (i = 0; i< MAX_CPU; i++) {
> mpp->dst[i].pctp = 0x0000000F;
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [Qemu-devel] [PATCH 05/28] PPC: Set MPIC IDE for IPI to 0
2011-07-25 8:46 ` Elie Richa
@ 2011-07-25 8:50 ` Alexander Graf
0 siblings, 0 replies; 34+ messages in thread
From: Alexander Graf @ 2011-07-25 8:50 UTC (permalink / raw)
To: Elie Richa; +Cc: Scott Wood, QEMU-devel Developers
On 25.07.2011, at 10:46, Elie Richa wrote:
>
>
> On 07/23/2011 12:49 PM, Alexander Graf wrote:
>> @@ -1304,6 +1304,10 @@ static void mpic_reset (void *opaque)
>> mpp->src[i].ipvp = 0x80800000;
>> mpp->src[i].ide = 0x00000001;
>> }
>> + /* Set IDE for IPIs to 0 so we don't get spurious interrupts */
>> + for (i = mpp->irq_ipi0; i< MAX_IPI; i++) {
>
> I suppose you meant i < mpp->irq_ipi0 + MAX_IPI in that loop condition right? ;)
Ouch. How did that happen? :)
Alex
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [Qemu-devel] [PATCH 21/28] PPC: E500: Add PV spinning code
2011-07-23 10:50 ` [Qemu-devel] [PATCH 21/28] PPC: E500: Add PV spinning code Alexander Graf
@ 2011-07-25 20:40 ` Scott Wood
2011-07-27 13:34 ` Alexander Graf
0 siblings, 1 reply; 34+ messages in thread
From: Scott Wood @ 2011-07-25 20:40 UTC (permalink / raw)
To: Alexander Graf; +Cc: Elie Richa, QEMU-devel Developers
On Sat, 23 Jul 2011 12:50:05 +0200
Alexander Graf <agraf@suse.de> wrote:
> +typedef struct spin_info {
> + uint64_t addr;
> + uint64_t r3;
> + uint32_t resv;
> + uint32_t pir;
> + uint64_t r6;
> +} __attribute__ ((packed)) SpinInfo;
Note that r6 isn't part of the ePAPR spin table -- I think it may have been
in an early draft and gotten into U-Boot that way. A future ePAPR could
assign another use to that position in the spin table.
Do we support any host ABIs strange enough that __attribute__((packed))
would be needed here?
> +static void mmubooke_create_initial_mapping(CPUState *env,
> + target_ulong va,
> + target_phys_addr_t pa,
> + target_phys_addr_t len)
> +{
> + ppcmas_tlb_t *tlb = booke206_get_tlbm(env, 1, 0, 0);
> + target_phys_addr_t size;
> +
> + size = (booke206_page_size_to_tlb(len) << MAS1_TSIZE_SHIFT);
> + tlb->mas1 = MAS1_VALID | size;
> + tlb->mas2 = va & TARGET_PAGE_MASK;
> + tlb->mas7_3 = pa & TARGET_PAGE_MASK;
> + tlb->mas7_3 |= MAS3_UR | MAS3_UW | MAS3_UX | MAS3_SR | MAS3_SW | MAS3_SX;
> +}
[snip]
> + mmubooke_create_initial_mapping(env, env->nip, env->nip, map_size);
ePAPR says:
The Secondary IMA (SIMA) mapping in the MMU shall map effective address 0
to the entry_addr field in the spin table, aligned down to the SIMA size.
Note that it's possible for the physical entry point to be > 4GiB on a
32-bit target.
Also, MAS2[M] should be set, even if it doesn't affect anything real under
qemu/kvm.
I know that U-Boot has the same behavior on both counts. U-Boot is wrong.
-Scott
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [Qemu-devel] [PATCH 21/28] PPC: E500: Add PV spinning code
2011-07-25 20:40 ` Scott Wood
@ 2011-07-27 13:34 ` Alexander Graf
2011-07-27 16:18 ` Scott Wood
0 siblings, 1 reply; 34+ messages in thread
From: Alexander Graf @ 2011-07-27 13:34 UTC (permalink / raw)
To: Scott Wood; +Cc: Elie Richa, QEMU-devel Developers
On 07/25/2011 10:40 PM, Scott Wood wrote:
> On Sat, 23 Jul 2011 12:50:05 +0200
> Alexander Graf<agraf@suse.de> wrote:
>
>> +typedef struct spin_info {
>> + uint64_t addr;
>> + uint64_t r3;
>> + uint32_t resv;
>> + uint32_t pir;
>> + uint64_t r6;
>> +} __attribute__ ((packed)) SpinInfo;
> Note that r6 isn't part of the ePAPR spin table -- I think it may have been
> in an early draft and gotten into U-Boot that way. A future ePAPR could
> assign another use to that position in the spin table.
How is the size defined then?
> Do we support any host ABIs strange enough that __attribute__((packed))
> would be needed here?
I don't think we do, but in general I prefer to be safe rather than
sorry. It doesn't hurt, right?
>> +static void mmubooke_create_initial_mapping(CPUState *env,
>> + target_ulong va,
>> + target_phys_addr_t pa,
>> + target_phys_addr_t len)
>> +{
>> + ppcmas_tlb_t *tlb = booke206_get_tlbm(env, 1, 0, 0);
>> + target_phys_addr_t size;
>> +
>> + size = (booke206_page_size_to_tlb(len)<< MAS1_TSIZE_SHIFT);
>> + tlb->mas1 = MAS1_VALID | size;
>> + tlb->mas2 = va& TARGET_PAGE_MASK;
>> + tlb->mas7_3 = pa& TARGET_PAGE_MASK;
>> + tlb->mas7_3 |= MAS3_UR | MAS3_UW | MAS3_UX | MAS3_SR | MAS3_SW | MAS3_SX;
>> +}
> [snip]
>> + mmubooke_create_initial_mapping(env, env->nip, env->nip, map_size);
> ePAPR says:
>
> The Secondary IMA (SIMA) mapping in the MMU shall map effective address 0
> to the entry_addr field in the spin table, aligned down to the SIMA size.
So it jumps to nip & ~64MB?
> Note that it's possible for the physical entry point to be> 4GiB on a
> 32-bit target.
>
> Also, MAS2[M] should be set, even if it doesn't affect anything real under
> qemu/kvm.
Ok :)
> I know that U-Boot has the same behavior on both counts. U-Boot is wrong.
If you say so, I'll align it with ePAPR then.
Alex
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [Qemu-devel] [PATCH 21/28] PPC: E500: Add PV spinning code
2011-07-27 13:34 ` Alexander Graf
@ 2011-07-27 16:18 ` Scott Wood
0 siblings, 0 replies; 34+ messages in thread
From: Scott Wood @ 2011-07-27 16:18 UTC (permalink / raw)
To: Alexander Graf; +Cc: Elie Richa, QEMU-devel Developers
On Wed, 27 Jul 2011 15:34:31 +0200
Alexander Graf <agraf@suse.de> wrote:
> On 07/25/2011 10:40 PM, Scott Wood wrote:
> > On Sat, 23 Jul 2011 12:50:05 +0200
> > Alexander Graf<agraf@suse.de> wrote:
> >
> >> +typedef struct spin_info {
> >> + uint64_t addr;
> >> + uint64_t r3;
> >> + uint32_t resv;
> >> + uint32_t pir;
> >> + uint64_t r6;
> >> +} __attribute__ ((packed)) SpinInfo;
> > Note that r6 isn't part of the ePAPR spin table -- I think it may have been
> > in an early draft and gotten into U-Boot that way. A future ePAPR could
> > assign another use to that position in the spin table.
>
> How is the size defined then?
The size of what?
The size of the IMA is up to the boot program (ePAPR 1.1 will impose a
minimum of 1 MiB), and is conveyed to the OS in r7.
The size of the spin table entry is determined by the release method name.
If fields are added in the future, we'd call it something like
"spin-table-v2". Any OS that writes to the r6 field with a "spin-table"
release-method is invoking undefined behavior.
> > Do we support any host ABIs strange enough that __attribute__((packed))
> > would be needed here?
>
> I don't think we do, but in general I prefer to be safe rather than
> sorry. It doesn't hurt, right?
GCC takes it as meaning the start of the structure could be misaligned, and
thus generates poor code for some architectures.
I think specifying both packed and an explicit struct alignment will avoid
that problem and still be sufficiently paranoid, if desired. Not that this
is particularly performance critical, of course. :-)
> >> +static void mmubooke_create_initial_mapping(CPUState *env,
> >> + target_ulong va,
> >> + target_phys_addr_t pa,
> >> + target_phys_addr_t len)
> >> +{
> >> + ppcmas_tlb_t *tlb = booke206_get_tlbm(env, 1, 0, 0);
> >> + target_phys_addr_t size;
> >> +
> >> + size = (booke206_page_size_to_tlb(len)<< MAS1_TSIZE_SHIFT);
> >> + tlb->mas1 = MAS1_VALID | size;
> >> + tlb->mas2 = va& TARGET_PAGE_MASK;
> >> + tlb->mas7_3 = pa& TARGET_PAGE_MASK;
> >> + tlb->mas7_3 |= MAS3_UR | MAS3_UW | MAS3_UX | MAS3_SR | MAS3_SW | MAS3_SX;
> >> +}
> > [snip]
> >> + mmubooke_create_initial_mapping(env, env->nip, env->nip, map_size);
> > ePAPR says:
> >
> > The Secondary IMA (SIMA) mapping in the MMU shall map effective address 0
> > to the entry_addr field in the spin table, aligned down to the SIMA size.
>
> So it jumps to nip & ~64MB?
Yes.
-Scott
^ permalink raw reply [flat|nested] 34+ messages in thread
end of thread, other threads:[~2011-07-27 16:18 UTC | newest]
Thread overview: 34+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-07-23 10:49 [Qemu-devel] [PATCH 00/28] SMP support for MPC8544DS Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 01/28] PPC: Move openpic to target specific code compilation Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 02/28] PPC: Add CPU local MMIO regions to MPIC Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 03/28] PPC: Extend MPIC MMIO range Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 04/28] PPC: Fix IPI support in MPIC Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 05/28] PPC: Set MPIC IDE for IPI to 0 Alexander Graf
2011-07-25 8:46 ` Elie Richa
2011-07-25 8:50 ` Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 06/28] PPC: MPIC: Remove read functionality for WO registers Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 07/28] PPC: MPIC: Fix CI bit definitions Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 08/28] PPC: Bump MPIC up to 32 supported CPUs Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 09/28] PPC: E500: create multiple envs Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 10/28] PPC: E500: Generate IRQ lines for many CPUs Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 11/28] device tree: add nop_node Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 12/28] PPC: bamboo: Move host fdt copy to target Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 13/28] PPC: KVM: Add generic function to read host clockfreq Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 14/28] PPC: E500: Use generic kvm function for freq Alexander Graf
2011-07-23 10:49 ` [Qemu-devel] [PATCH 15/28] PPC: E500: Remove mpc8544_copy_soc_cell Alexander Graf
2011-07-23 10:50 ` [Qemu-devel] [PATCH 16/28] PPC: bamboo: Use kvm api for freq and clock frequencies Alexander Graf
2011-07-23 10:50 ` [Qemu-devel] [PATCH 17/28] PPC: KVM: Remove kvmppc_read_host_property Alexander Graf
2011-07-23 10:50 ` [Qemu-devel] [PATCH 18/28] PPC: KVM: Add stubs for kvm helper functions Alexander Graf
2011-07-23 10:50 ` [Qemu-devel] [PATCH 19/28] PPC: E500: Update freqs for all CPUs Alexander Graf
2011-07-23 10:50 ` [Qemu-devel] [PATCH 20/28] PPC: E500: Remove unneeded CPU nodes Alexander Graf
2011-07-23 10:50 ` [Qemu-devel] [PATCH 21/28] PPC: E500: Add PV spinning code Alexander Graf
2011-07-25 20:40 ` Scott Wood
2011-07-27 13:34 ` Alexander Graf
2011-07-27 16:18 ` Scott Wood
2011-07-23 10:50 ` [Qemu-devel] [PATCH 22/28] PPC: E500: Update cpu-release-addr property in cpu nodes Alexander Graf
2011-07-23 10:50 ` [Qemu-devel] [PATCH 23/28] device tree: add add_subnode command Alexander Graf
2011-07-23 10:50 ` [Qemu-devel] [PATCH 24/28] device tree: dont fail operations Alexander Graf
2011-07-23 10:50 ` [Qemu-devel] [PATCH 25/28] device tree: give dt more size Alexander Graf
2011-07-23 10:50 ` [Qemu-devel] [PATCH 26/28] MPC8544DS: Remove CPU nodes Alexander Graf
2011-07-23 10:50 ` [Qemu-devel] [PATCH 27/28] MPC8544DS: Generate CPU nodes on init Alexander Graf
2011-07-23 10:50 ` [Qemu-devel] [PATCH 28/28] PPC: E500: Bump CPU count to 15 Alexander Graf
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).