* [Qemu-devel] [PATCH v2] PPC: E500: Implement reboot controller
@ 2011-06-02 18:37 Alexander Graf
2011-06-03 23:42 ` Scott Wood
0 siblings, 1 reply; 3+ messages in thread
From: Alexander Graf @ 2011-06-02 18:37 UTC (permalink / raw)
To: qemu-devel@nongnu.org Developers; +Cc: Scott Wood
When Linux reboots an e500 VM, it writes to a magic register in the
"global-utilities" device indicated by the device tree. We were not
emulating that device so far, renedering the VM reboot-less.
This patch implements that device with only the reboot functionality
implemented and adds it to the device tree. With this patch applied,
I can successfully reboot a -M mpc8544ds VM.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
v1 -> v2:
- change name to mpc8544-guts
- rename file accordingly
- implement PVR and SVR registers
- add stub register defines
- add stderr printf when accessing unknown register
---
Makefile.target | 2 +-
hw/mpc8544_guts.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++++
hw/ppce500_mpc8544ds.c | 4 ++
pc-bios/mpc8544ds.dtb | Bin 12288 -> 2257 bytes
pc-bios/mpc8544ds.dts | 6 ++
5 files changed, 145 insertions(+), 1 deletions(-)
create mode 100644 hw/mpc8544_guts.c
diff --git a/Makefile.target b/Makefile.target
index 602d50d..ee5ef78 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -258,7 +258,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
+obj-ppc-y += ppce500_mpc8544ds.o mpc8544_guts.o
# PowerPC 440 Xilinx ML507 reference board.
obj-ppc-y += virtex_ml507.o
obj-ppc-$(CONFIG_KVM) += kvm_ppc.o
diff --git a/hw/mpc8544_guts.c b/hw/mpc8544_guts.c
new file mode 100644
index 0000000..72b6fb2
--- /dev/null
+++ b/hw/mpc8544_guts.c
@@ -0,0 +1,134 @@
+/*
+ * QEMU PowerPC MPC8544 global util pseudo-device
+ *
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Alexander Graf, <alex@csgraf.de>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * *****************************************************************
+ *
+ * The documentation for this device is noted in the MPC8544 documentation,
+ * file name "MPC8544ERM.pdf". You can easily find it on the web.
+ *
+ */
+
+#include "hw.h"
+#include "sysemu.h"
+#include "sysbus.h"
+
+#define MPC8544_GUTS_MMIO_SIZE 0x1000
+#define MPC8544_GUTS_RSTCR_RESET 0x02
+
+#define MPC8544_GUTS_ADDR_PORPLLSR 0x00
+#define MPC8544_GUTS_ADDR_PORBMSR 0x04
+#define MPC8544_GUTS_ADDR_PORIMPSCR 0x08
+#define MPC8544_GUTS_ADDR_PORDEVSR 0x0C
+#define MPC8544_GUTS_ADDR_PORDBGMSR 0x10
+#define MPC8544_GUTS_ADDR_PORDEVSR2 0x14
+#define MPC8544_GUTS_ADDR_GPPORCR 0x20
+#define MPC8544_GUTS_ADDR_GPIOCR 0x30
+#define MPC8544_GUTS_ADDR_GPOUTDR 0x40
+#define MPC8544_GUTS_ADDR_GPINDR 0x50
+#define MPC8544_GUTS_ADDR_PMUXCR 0x60
+#define MPC8544_GUTS_ADDR_DEVDISR 0x70
+#define MPC8544_GUTS_ADDR_POWMGTCSR 0x80
+#define MPC8544_GUTS_ADDR_MCPSUMR 0x90
+#define MPC8544_GUTS_ADDR_RSTRSCR 0x94
+#define MPC8544_GUTS_ADDR_PVR 0xA0
+#define MPC8544_GUTS_ADDR_SVR 0xA4
+#define MPC8544_GUTS_ADDR_RSTCR 0xB0
+#define MPC8544_GUTS_ADDR_IOVSELSR 0xC0
+#define MPC8544_GUTS_ADDR_DDRCSR 0xB20
+#define MPC8544_GUTS_ADDR_DDRCDR 0xB24
+#define MPC8544_GUTS_ADDR_DDRCLKDR 0xB28
+#define MPC8544_GUTS_ADDR_CLKOCR 0xE00
+#define MPC8544_GUTS_ADDR_SRDS1CR1 0xF04
+#define MPC8544_GUTS_ADDR_SRDS2CR1 0xF10
+#define MPC8544_GUTS_ADDR_SRDS2CR3 0xF18
+
+struct GutsState {
+ SysBusDevice busdev;
+};
+
+typedef struct GutsState GutsState;
+
+static uint32_t mpc8544_guts_read32(void *opaque, target_phys_addr_t addr)
+{
+ uint32_t value = 0;
+ CPUState *env = cpu_single_env;
+
+ addr &= MPC8544_GUTS_MMIO_SIZE - 1;
+ switch (addr) {
+ case MPC8544_GUTS_ADDR_PVR:
+ value = env->spr[SPR_PVR];
+ break;
+ case MPC8544_GUTS_ADDR_SVR:
+ value = env->spr[SPR_E500_SVR];
+ break;
+ default:
+ fprintf(stderr, "Unknown register read: %x = %x\n", (int)addr, value);
+ break;
+ }
+
+ return value;
+}
+
+static CPUReadMemoryFunc * const mpc8544_guts_read[] = {
+ NULL,
+ NULL,
+ &mpc8544_guts_read32,
+};
+
+static void mpc8544_guts_write32(void *opaque, target_phys_addr_t addr,
+ uint32_t value)
+{
+ addr &= MPC8544_GUTS_MMIO_SIZE - 1;
+
+ switch (addr) {
+ case MPC8544_GUTS_ADDR_RSTCR:
+ if (value & MPC8544_GUTS_RSTCR_RESET) {
+ qemu_system_reset_request();
+ }
+ break;
+ default:
+ fprintf(stderr, "Unknown register write: %x = %x\n", (int)addr, value);
+ break;
+ }
+}
+
+static CPUWriteMemoryFunc * const mpc8544_guts_write[] = {
+ NULL,
+ NULL,
+ &mpc8544_guts_write32,
+};
+
+static int mpc8544_guts_initfn(SysBusDevice *dev)
+{
+ GutsState *s;
+ int iomem;
+
+ s = FROM_SYSBUS(GutsState, sysbus_from_qdev(dev));
+
+ iomem = cpu_register_io_memory(mpc8544_guts_read, mpc8544_guts_write, s,
+ DEVICE_BIG_ENDIAN);
+ sysbus_init_mmio(dev, MPC8544_GUTS_MMIO_SIZE, iomem);
+
+ return 0;
+}
+
+static SysBusDeviceInfo mpc8544_guts_info = {
+ .init = mpc8544_guts_initfn,
+ .qdev.name = "mpc8544-guts",
+ .qdev.size = sizeof(GutsState),
+};
+
+static void mpc8544_pci_register(void)
+{
+ sysbus_register_withprop(&mpc8544_guts_info);
+}
+device_init(mpc8544_pci_register);
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index 6b57fbf..3ba8e75 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -50,6 +50,7 @@
#define MPC8544_PCI_REGS_SIZE 0x1000
#define MPC8544_PCI_IO 0xE1000000
#define MPC8544_PCI_IOLEN 0x10000
+#define MPC8544_UTIL_BASE (MPC8544_CCSRBAR_BASE + 0xe0000)
struct boot_info
{
@@ -270,6 +271,9 @@ static void mpc8544ds_init(ram_addr_t ram_size,
serial_hds[0], 1, 1);
}
+ /* General Utility device */
+ sysbus_create_simple("mpc8544-guts", MPC8544_UTIL_BASE, NULL);
+
/* PCI */
dev = sysbus_create_varargs("e500-pcihost", MPC8544_PCI_REGS_BASE,
mpic[pci_irq_nrs[0]], mpic[pci_irq_nrs[1]],
diff --git a/pc-bios/mpc8544ds.dtb b/pc-bios/mpc8544ds.dtb
index 3299546696bf21f53f8ce2c9eba7fcb740c547da..189224e5875e9dd0d9195c22624b85bfb29dd820 100644
GIT binary patch
delta 254
zcmZojxG1P`f%o5A1_q9c3=9kw3=HfkKw1Nc1%X%qh=G7H7bvbX(NK8fZXcF<W}pZQ
zP*4ga1H?=qIz1;pDKSU4v?Mbpvm`UM*df&b2!JvS3?TI&!`RY_b98bGk}XV4Omx#r
zONv2~Kmd~G0AgPTJ`fjdCrAtk7?pqo$b7IJ1<9E}V<(HT2Fe0W{sB?|1MENsNY4YH
t9_P(1to)3Ofs?1OZDx#~Y{00zIh$RZkr!lrMq;sUQE^Ff(d4Ndb^tN<Dt7<?
literal 12288
zcmeHIJ8u&~5Z)um5MBxr1r@SLgOE>gBs)q$VJkovDTp5sUCx{MlzVY^28Sx5qJ!T+
zNtKd<A{{NFM>0PEYG{D@_IA$pB`MM&G$W079^cH)ez$l2eEs)#rP_+*gHo3YTJMqG
zBwZpUakiCed@SvM>esQ;EYNxd_U6{cdbiVg__RzQev7m*jT>t`E)mFIB*j_Li~Xkc
z9WM;LT<7GP+#On5D|zB$lb&vuvXbj8@WNiF+cqptv7NKAYqQuJ)c3(k>IbIhI<>`)
zN?jmz{B&dnAe-kqZC>D=t>lHywl-R3zOo6|^r;Up>~F#$VgCu)%^BaX`BZ#Jp$h-1
z=D$Ibg!{cK-O4|*KF(y$73nC+4onm^mq`1y*ky|GoB*1-I{iqH@V=*UGy81&RL}UU
zWHj<1N<;1LSeDV}8tE~qn&4*%Kc>H#XJT9v<URSUPVFXe{*x&wdzf>UI1>d1eH(GU
zy4LNQhsH5F`y)!3YtFrxN5*_1z<pA1!<etOsN~DuPJ81RgPE9@bI$bGmR9?nd!{t-
zdmX$z)QJQ$L4J_(e0Yu!>pNKajOD$+n+q*5c!wJPFiTrWs$-XSFey{NNM?UNT=m8G
z0X(3$;p^mU$XGS|9G3{+*v-RMl;U&HcBzg+6}CU)6V|z_)KBDDz&Xw|p<Gv~*Br-+
zd3YvT=W=F7%A>ZPvoXU;JqM=H)9PC?E8)1UpUd%nwtg<h`&rCfuC`yr3*SxD;yL2}
z-X=v48*?_uhWsH#tWA0h0OZ&z>?SFOXZglP8AL7SI9mACdrzzN&0PY5^G&jOf8cTV
zkb|1LHc^LUE|D6X;}4Tu$8ZgX{ui9hv%mG#{{r@aE=I{fhssZ))GLCWP^)EcFvxVC
zyS@&?TrKCpOKt7)ThUhKx~k}2wbejB4}85{9Hd%hdQS~p-}8ss4TD&_C|1FV2xI2b
z#wmhG@6aEeyPN4}BOUt(iav)ko*yRu{*0e_@gDsxVpunb2YRf6xX@WPN{f7Ix~Z4x
zxR?p}NnB(}80t(dR~7c0H2P@VN{3!NAVQ|u$V=VG%lGF)W<WEBDhu;skc<l2vKZpA
zhzJA1fG{8o2m``^Fdz&F1HynXAPfit!hkR!3<v|lfG{8o2m``^Fdz&F1HynXAPfit
W!hkR!3<v|lfG{8o2m}8&1AhU`J`#BV
diff --git a/pc-bios/mpc8544ds.dts b/pc-bios/mpc8544ds.dts
index 872152d..fd792d5 100644
--- a/pc-bios/mpc8544ds.dts
+++ b/pc-bios/mpc8544ds.dts
@@ -82,6 +82,12 @@
compatible = "chrp,open-pic";
device_type = "open-pic";
};
+
+ global-utilities@e0000 { //global utilities block
+ compatible = "fsl,mpc8544-guts";
+ reg = <0xe0000 0x1000>;
+ fsl,has-rstcr;
+ };
};
pci0: pci@e0008000 {
--
1.6.0.2
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [Qemu-devel] [PATCH v2] PPC: E500: Implement reboot controller
2011-06-02 18:37 [Qemu-devel] [PATCH v2] PPC: E500: Implement reboot controller Alexander Graf
@ 2011-06-03 23:42 ` Scott Wood
2011-06-03 23:52 ` Alexander Graf
0 siblings, 1 reply; 3+ messages in thread
From: Scott Wood @ 2011-06-03 23:42 UTC (permalink / raw)
To: Alexander Graf; +Cc: qemu-devel@nongnu.org Developers
On Thu, 2 Jun 2011 20:37:30 +0200
Alexander Graf <agraf@suse.de> wrote:
> + case MPC8544_GUTS_ADDR_PVR:
> + value = env->spr[SPR_PVR];
> + break;
> + case MPC8544_GUTS_ADDR_SVR:
> + value = env->spr[SPR_E500_SVR];
> + break;
Heh, I didn't even realize these were in there -- I was just thinking of
the guest using the SPR version of SVR to decide how to program devices
like guts or tsec, and the conflicting demands that might place on that
value if you have both directly-assigned devices and emulated devices that
target a specific chip.
I can see where that produced confusion. :-)
> + default:
> + fprintf(stderr, "Unknown register read: %x = %x\n", (int)addr, value);
> + break;
> + }
Should say something like "guts" or __func__ in there somewhere.
Especially if we're going to throw away the upper 4 bits of the address. :-)
-Scott
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Qemu-devel] [PATCH v2] PPC: E500: Implement reboot controller
2011-06-03 23:42 ` Scott Wood
@ 2011-06-03 23:52 ` Alexander Graf
0 siblings, 0 replies; 3+ messages in thread
From: Alexander Graf @ 2011-06-03 23:52 UTC (permalink / raw)
To: Scott Wood; +Cc: qemu-devel@nongnu.org Developers
On 04.06.2011, at 01:42, Scott Wood wrote:
> On Thu, 2 Jun 2011 20:37:30 +0200
> Alexander Graf <agraf@suse.de> wrote:
>
>> + case MPC8544_GUTS_ADDR_PVR:
>> + value = env->spr[SPR_PVR];
>> + break;
>> + case MPC8544_GUTS_ADDR_SVR:
>> + value = env->spr[SPR_E500_SVR];
>> + break;
>
> Heh, I didn't even realize these were in there -- I was just thinking of
> the guest using the SPR version of SVR to decide how to program devices
> like guts or tsec, and the conflicting demands that might place on that
> value if you have both directly-assigned devices and emulated devices that
> target a specific chip.
>
> I can see where that produced confusion. :-)
Yeah, pretty confusing :). Well, they were easy enough to add and at least cover the very unusual use-case that a guest OS reads from mmio instead of its SPRs *shrug* :).
>
>> + default:
>> + fprintf(stderr, "Unknown register read: %x = %x\n", (int)addr, value);
>> + break;
>> + }
>
> Should say something like "guts" or __func__ in there somewhere.
> Especially if we're going to throw away the upper 4 bits of the address. :-)
Good point :). v3 is out.
Alex
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2011-06-03 23:52 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-06-02 18:37 [Qemu-devel] [PATCH v2] PPC: E500: Implement reboot controller Alexander Graf
2011-06-03 23:42 ` Scott Wood
2011-06-03 23:52 ` 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).