* [Qemu-devel] [RFC 0/6] ppc/prep: add IBM RS/6000 43p machine
@ 2013-03-14 22:12 Hervé Poussineau
2013-03-14 22:12 ` [Qemu-devel] [RFC 1/6] pci: add MPC105 PCI host bridge emulation Hervé Poussineau
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Hervé Poussineau @ 2013-03-14 22:12 UTC (permalink / raw)
To: qemu-devel; +Cc: Andreas Färber, Hervé Poussineau
Hi,
This patchset (sent as RFC) adds an emulation of the IBM RS/6000 43p, also known as 7248.
It contains the strict minimum to be able to boot a PReP boot partition on a IDE hard disk.
It has been tested with the official firmware, named P93H1904.IMG.
However, Andreas has already some preliminary patches for OpenBIOS to support PReP machines.
Command line may look like
qemu-system-ppc -M 43p -bios P93H1904.IMG -readconfig ibm_43p.cfg
-device ide-hd,drive=hd0 -drive if=none,id=hd0,cache=writeback,file="hda.qcow2"
Known bugs/missing parts:
- incomplete MPC105 (PCI host bridge) emulation (IRQs, memory controller)
- no video card (should be a S3)
- can't boot from IDE cdroms (overlapping commands not supported by QEMU IDE emulation)
- can't boot from floppies (READ commands are issued, but it seems completion is ignored)
- can't boot from network
- hack added in the m48t59 device (anyone knowing the m48t59 emulation to comment?)
- QEMU can't change endianness at runtime
Patchet also doesn't pass checkpatch.pl yet.
Please comment.
Regards,
Hervé
Hervé Poussineau (6):
pci: add MPC105 PCI host bridge emulation
prep: add IBM RS/6000 7248 (43p) machine emulation
prep: add RS/6000 debug device
m48t59: move ISA ports registration to QOM constructor
m48t59: hack(?) to make it work on IBM 43p
prep: QOM'ify System I/O
default-configs/ppc-softmmu.mak | 1 +
docs/ibm_43p.cfg | 48 +++++
hw/Makefile.objs | 1 +
hw/m48t59.c | 11 +-
hw/mpc105.c | 419 +++++++++++++++++++++++++++++++++++++++
hw/pci/pci_ids.h | 1 +
hw/ppc/Makefile.objs | 2 +
hw/ppc/prep.c | 94 +++++++++
hw/ppc/prep_systemio.c | 290 +++++++++++++++++++++++++++
hw/ppc/rs6000_debug.c | 260 ++++++++++++++++++++++++
trace-events | 11 +
11 files changed, 1133 insertions(+), 5 deletions(-)
create mode 100644 docs/ibm_43p.cfg
create mode 100644 hw/mpc105.c
create mode 100644 hw/ppc/prep_systemio.c
create mode 100644 hw/ppc/rs6000_debug.c
--
1.7.10.4
^ permalink raw reply [flat|nested] 7+ messages in thread
* [Qemu-devel] [RFC 1/6] pci: add MPC105 PCI host bridge emulation
2013-03-14 22:12 [Qemu-devel] [RFC 0/6] ppc/prep: add IBM RS/6000 43p machine Hervé Poussineau
@ 2013-03-14 22:12 ` Hervé Poussineau
2013-03-14 22:12 ` [Qemu-devel] [RFC 2/6] prep: add IBM RS/6000 7248 (43p) machine emulation Hervé Poussineau
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Hervé Poussineau @ 2013-03-14 22:12 UTC (permalink / raw)
To: qemu-devel; +Cc: Andreas Färber, Hervé Poussineau
Missing parts are:
- set_irq() and map_irq() functions
- missing handling of non-contiguous I/O
- migration
There is also somewhere a bug in the memory controller, which means
that some real firmwares may not detect the correct amount of memory.
This can be bypassed by adding '-m 1G' on the command line.
---
default-configs/ppc-softmmu.mak | 1 +
hw/Makefile.objs | 1 +
hw/mpc105.c | 419 +++++++++++++++++++++++++++++++++++++++
hw/pci/pci_ids.h | 1 +
trace-events | 7 +
5 files changed, 429 insertions(+)
create mode 100644 hw/mpc105.c
diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak
index c209a8d..45ab549 100644
--- a/default-configs/ppc-softmmu.mak
+++ b/default-configs/ppc-softmmu.mak
@@ -27,6 +27,7 @@ CONFIG_MAC_NVRAM=y
CONFIG_MAC_DBDMA=y
CONFIG_HEATHROW_PIC=y
CONFIG_GRACKLE_PCI=y
+CONFIG_MPC105_PCI=y
CONFIG_UNIN_PCI=y
CONFIG_DEC_PCI=y
CONFIG_PPCE500_PCI=y
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index eb7eb31..098d5d3 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -50,6 +50,7 @@ common-obj-y += pam.o
common-obj-$(CONFIG_PREP_PCI) += prep_pci.o
common-obj-$(CONFIG_I82378) += i82378.o
common-obj-$(CONFIG_PC87312) += pc87312.o
+common-obj-$(CONFIG_MPC105_PCI) += mpc105.o
# Mac shared devices
common-obj-$(CONFIG_MACIO) += macio.o
common-obj-$(CONFIG_CUDA) += cuda.o
diff --git a/hw/mpc105.c b/hw/mpc105.c
new file mode 100644
index 0000000..63be5b5
--- /dev/null
+++ b/hw/mpc105.c
@@ -0,0 +1,419 @@
+/*
+ * QEMU MPC-105 Eagle PCI host
+ *
+ * Copyright (c) 2013 Hervé Poussineau
+ *
+ * This program 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) version 3 or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "pci/pci.h"
+#include "pci/pci_bus.h"
+#include "pci/pci_host.h"
+#include "exec/address-spaces.h"
+#include "pc.h"
+#include "loader.h"
+#include "trace.h"
+
+#define TYPE_MPC105_PCI_HOST_BRIDGE "mpc105-pcihost"
+#define MPC105_PCI_HOST_BRIDGE(obj) \
+ OBJECT_CHECK(Mpc105HostState, (obj), TYPE_MPC105_PCI_HOST_BRIDGE)
+
+#define TYPE_MPC105 "mpc105"
+#define MPC105(obj) \
+ OBJECT_CHECK(Mpc105State, (obj), TYPE_MPC105)
+
+#define MEM_STA_03 0x0080
+#define MEM_STA_47 0x0084
+#define EXT_MEM_STA_03 0x0088
+#define EXT_MEM_STA_47 0x008c
+#define MEM_END_03 0x0090
+#define MEM_END_47 0x0094
+#define EXT_MEM_END_03 0x0098
+#define EXT_MEM_END_47 0x009c
+#define MEM_BANK_EN 0x00a0
+#define PROC_CFG_A8 0x00a8
+#define PROC_CFG_AC 0x00ac
+#define ALT_OSV_1 0x00ba
+#define ERR_EN_REG1 0x00c0
+#define ERR_DR1 0x00c1
+#define ERR_EN_REG2 0x00c4
+#define MEM_CFG_1 0x00f0
+#define MEM_CFG_2 0x00f4
+#define MEM_CFG_4 0x00fc
+
+#define BIOS_SIZE (1024 * 1024)
+
+typedef struct Mpc105State {
+ PCIDevice dev;
+ uint32_t ram_size;
+ char *bios_name;
+ MemoryRegion bios;
+ MemoryRegion simm[8];
+ bool use_sizer[8];
+ MemoryRegion simm_sizer[8];
+} Mpc105State;
+
+static uint64_t mpc105_unassigned_read(void *opaque, hwaddr addr,
+ unsigned int size)
+{
+ trace_mpc105_unassigned_mem_read(addr);
+ return 0;
+}
+
+static void mpc105_unassigned_write(void *opaque, hwaddr addr, uint64_t data,
+ unsigned int size)
+{
+ trace_mpc105_unassigned_mem_write(addr, data);
+}
+
+static const MemoryRegionOps mpc105_unassigned_ops = {
+ .read = mpc105_unassigned_read,
+ .write = mpc105_unassigned_write,
+};
+
+static void mpc105_write_config(PCIDevice *dev, uint32_t addr, uint32_t val, int l)
+{
+ Mpc105State *s = MPC105(dev);
+ uint8_t *pci_conf;
+ int i;
+
+ pci_conf = s->dev.config;
+
+ pci_default_write_config(dev, addr, val, l);
+ if ((addr >= MEM_STA_03 && addr <= MEM_BANK_EN) || addr == MEM_CFG_1) {
+ uint32_t start_address, end_address;
+ uint32_t start, ext_start, end, ext_end;
+ uint32_t cfg1 = pci_get_long(pci_conf + MEM_CFG_1);
+ uint8_t en;
+ bool enabled;
+
+ memory_region_transaction_begin();
+ if (cfg1 & (1 << 19)) {
+ /* MEMGO enabled */
+ en = pci_get_byte(pci_conf + MEM_BANK_EN);
+ } else {
+ en = 0;
+ }
+
+ for (i = 0; i < 8; i++) {
+ enabled = (en & (1 << i));
+
+ start = pci_get_byte(pci_conf + MEM_STA_03 + i);
+ ext_start = pci_get_byte(pci_conf + EXT_MEM_STA_03 + i) & 0x3;
+ end = pci_get_byte(pci_conf + MEM_END_03 + i);
+ ext_end = pci_get_byte(pci_conf + EXT_MEM_STA_03 + i) & 0x3;
+ start_address = (ext_start << 28) | (start << 20);
+ end_address = (ext_end << 28) | (end << 20) | 0xfffff;
+
+ enabled &= start_address < end_address;
+
+ if (enabled) {
+ trace_mpc105_simm_enable(i, start_address, end_address + 1);
+ } else {
+ trace_mpc105_simm_disable(i);
+ }
+
+ if (memory_region_size(&s->simm[i]) == 0) {
+ continue;
+ }
+
+ /* Clean links between system memory, simm_sizer and simm */
+ if (s->use_sizer[i]) {
+ memory_region_del_subregion(get_system_memory(), &s->simm_sizer[i]);
+ memory_region_del_subregion(&s->simm_sizer[i], &s->simm[i]);
+ s->use_sizer[i] = false;
+ } else {
+ memory_region_del_subregion(get_system_memory(), &s->simm[i]);
+ }
+
+ /* Recreate links compatible with new memory layout */
+ if (enabled && end_address - start_address + 1 < memory_region_size(&s->simm[i])) {
+ memory_region_init_io(&s->simm_sizer[i], &mpc105_unassigned_ops,
+ s, memory_region_name(&s->simm_sizer[i]),
+ end_address - start_address + 1);
+ memory_region_add_subregion(&s->simm_sizer[i], 0, &s->simm[i]);
+ memory_region_add_subregion(get_system_memory(), start_address, &s->simm_sizer[i]);
+ s->use_sizer[i] = true;
+ } else {
+ memory_region_add_subregion(get_system_memory(), start_address, &s->simm[i]);
+ }
+ memory_region_set_enabled(&s->simm[i], enabled);
+ }
+ memory_region_transaction_commit();
+ }
+}
+
+static void mpc105_reset(Mpc105State *s)
+{
+ uint8_t *pci_conf;
+ int id;
+
+ pci_conf = s->dev.config;
+
+ memset(pci_conf + PCI_CONFIG_HEADER_SIZE, 0, PCI_CONFIG_SPACE_SIZE - PCI_CONFIG_HEADER_SIZE);
+ pci_conf[PCI_COMMAND] = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_conf[PCI_STATUS] = PCI_STATUS_FAST_BACK;
+ pci_set_long(pci_conf + PROC_CFG_A8, 0xff000010);
+ pci_set_long(pci_conf + PROC_CFG_AC, 0x000c060c);
+ pci_set_byte(pci_conf + ALT_OSV_1, 0x04);
+ pci_set_byte(pci_conf + ERR_EN_REG1, 0x01);
+ pci_set_long(pci_conf + MEM_CFG_1, 0xff020000);
+ pci_set_long(pci_conf + MEM_CFG_2, 0x00000003);
+ pci_set_long(pci_conf + MEM_CFG_4, 0x00100000);
+
+ memset(s->dev.wmask + PCI_CONFIG_HEADER_SIZE, 0, MEM_CFG_1 - PCI_CONFIG_HEADER_SIZE);
+ memset(s->dev.wmask + 0x70, 0xff, 2);
+ memset(s->dev.wmask + MEM_STA_03, 0xff, MEM_BANK_EN - MEM_STA_03 + 1);
+ memset(s->dev.wmask + PROC_CFG_A8, 0xff, 8);
+ pci_set_word(s->dev.wmask + ALT_OSV_1, 0xffff);
+ pci_set_byte(s->dev.wmask + ERR_EN_REG1, 0xff);
+ pci_set_byte(s->dev.w1cmask + ERR_DR1, 0xff);
+ pci_set_byte(s->dev.w1cmask + 0xc3, 0xff);
+ pci_set_byte(s->dev.wmask + ERR_EN_REG2, 0xff);
+ pci_set_byte(s->dev.w1cmask + 0xc5, 0xff);
+ pci_set_byte(s->dev.w1cmask + 0xc7, 0xff);
+
+ for (id = 0; id < 8; ++id) {
+ memory_region_set_enabled(&s->simm[id], false);
+ }
+}
+
+static void qdev_mpc105_reset(DeviceState *dev)
+{
+ Mpc105State *s = MPC105(dev);
+ mpc105_reset(s);
+}
+
+static const VMStateDescription vmstate_mpc105 = {
+ .name = "mpc105",
+ .version_id = 1,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField []) {
+ // FIXME
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static uint64_t mpc105_intack_read(void *opaque, hwaddr addr,
+ unsigned int size)
+{
+ return pic_read_irq(isa_pic);
+}
+
+static const MemoryRegionOps mpc105_intack_ops = {
+ .read = mpc105_intack_read,
+ .valid = {
+ .max_access_size = 1,
+ },
+};
+
+static int mpc105_initfn(PCIDevice *dev)
+{
+ Mpc105State *s = MPC105(dev);
+ char *filename;
+ int bios_size;
+ int i = 0;
+ uint32_t simm_size[8] = { 0 };
+
+ unsigned int ram_size = s->ram_size / (1024 * 1024);
+ while (i < 8) {
+ int idx = qemu_fls(ram_size);
+ if (idx < 5) {
+ /* Need at least 16 Mb for a slot */
+ break;
+ } else if (idx >= 8) {
+ /* Limit to 128 Mb by slot (at max) */
+ idx = 8;
+ }
+ simm_size[i] = 1 << (idx - 1);
+ ram_size -= simm_size[i];
+ i++;
+ }
+
+ for (i = 0; i < 8; i++) {
+ char name[] = "simm.?";
+ name[5] = i + '0';
+ if (simm_size[i]) {
+ trace_mpc105_simm_size(i, simm_size[i]);
+ memory_region_init_ram(&s->simm[i], name, simm_size[i] * 1024 * 1024);
+ vmstate_register_ram_global(&s->simm[i]);
+ } else {
+ memory_region_init(&s->simm[i], name, 0);
+ }
+ memory_region_init(&s->simm_sizer[i], "sizer", 0);
+ memory_region_add_subregion_overlap(get_system_memory(), 0, &s->simm[i], i);
+ memory_region_set_enabled(&s->simm[i], false);
+ }
+
+ memory_region_init_ram(&s->bios, "bios", BIOS_SIZE);
+ memory_region_set_readonly(&s->bios, true);
+ memory_region_add_subregion(get_system_memory(), (uint32_t)(-BIOS_SIZE), &s->bios);
+ vmstate_register_ram_global(&s->bios);
+ if (s->bios_name) {
+ filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, s->bios_name);
+ if (filename) {
+ bios_size = get_image_size(filename);
+ if (bios_size > 0 && bios_size <= BIOS_SIZE) {
+ hwaddr bios_addr;
+ bios_size = (bios_size + 0xfff) & ~0xfff;
+ bios_addr = (uint32_t)(-BIOS_SIZE);
+ bios_size = load_image_targphys(filename, bios_addr, bios_size);
+ }
+ } else {
+ bios_size = -1;
+ }
+ if (bios_size < 0 || bios_size > BIOS_SIZE) {
+ hw_error("qemu: could not load IBM 43p bios '%s'\n", s->bios_name);
+ }
+ if (filename) {
+ g_free(filename);
+ }
+ }
+
+ return 0;
+}
+
+static void mpc105_class_init(ObjectClass *klass, void *data)
+{
+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ k->init = mpc105_initfn;
+ k->vendor_id = PCI_VENDOR_ID_MOTOROLA;
+ k->device_id = PCI_DEVICE_ID_MOTOROLA_MPC105;
+ k->class_id = PCI_CLASS_BRIDGE_HOST;
+ k->config_write = mpc105_write_config;
+ dc->desc = "MPC105 PCI bridge/Memory controller";
+ dc->reset = qdev_mpc105_reset;
+ dc->vmsd = &vmstate_mpc105;
+ dc->no_user = 1;
+}
+
+static TypeInfo mpc105_info = {
+ .name = TYPE_MPC105,
+ .parent = TYPE_PCI_DEVICE,
+ .instance_size = sizeof(Mpc105State),
+ .class_init = mpc105_class_init,
+};
+
+typedef struct Mpc105HostState {
+ PCIHostState host_state;
+ uint32_t ram_size;
+ qemu_irq irq[PCI_NUM_PINS];
+ PCIBus pci_bus;
+ MemoryRegion pci_io;
+ MemoryRegion isa_io;
+ MemoryRegion pci_intack;
+ MemoryRegion pci_memory;
+ MemoryRegion rom;
+ Mpc105State pci_dev;
+} Mpc105HostState;
+
+static void mpc105_set_irq(void *opaque, int irq_num, int level)
+{
+ // FIXME
+}
+
+static int mpc105_map_irq(PCIDevice *dev, int irq_num)
+{
+ // FIXME
+ return 0;
+}
+
+static void mpc105_pcihost_realizefn(DeviceState *d, Error **errp)
+{
+ SysBusDevice *dev = SYS_BUS_DEVICE(d);
+ PCIHostState *h = PCI_HOST_BRIDGE(dev);
+ Mpc105HostState *s = MPC105_PCI_HOST_BRIDGE(dev);
+ int i;
+
+ for (i = 0; i < PCI_NUM_PINS; i++) {
+ sysbus_init_irq(dev, &s->irq[i]);
+ }
+
+ pci_bus_irqs(&s->pci_bus, mpc105_set_irq, mpc105_map_irq, s->irq, 4);
+
+ memory_region_init_io(&h->conf_mem, &pci_host_conf_le_ops, s,
+ "pci-conf-idx", 1);
+ memory_region_add_subregion(get_system_io(), 0xcf8, &h->conf_mem);
+
+ memory_region_init_io(&h->data_mem, &pci_host_data_le_ops, s,
+ "pci-conf-data", 4);
+ memory_region_add_subregion(get_system_io(), 0xcfc, &h->data_mem);
+
+ object_property_set_bool(OBJECT(&s->pci_dev), true, "realized", errp);
+}
+
+static void mpc105_pcihost_initfn(Object *obj)
+{
+ PCIHostState *h = PCI_HOST_BRIDGE(obj);
+ Mpc105HostState *s = MPC105_PCI_HOST_BRIDGE(obj);
+ DeviceState *pci_dev;
+
+ memory_region_init(&s->pci_io, "pci-io", 0x3f800000);
+ isa_mmio_setup(&s->isa_io, 0x800000); /* FIXME: should handle non-contiguous I/O */
+ memory_region_init(&s->pci_memory, "pci-memory", 0x3f000000);
+ memory_region_init_io(&s->pci_intack, &mpc105_intack_ops, &s->pci_dev,
+ "pci-intack", 0x10);
+
+ memory_region_init_io(get_system_memory(), &mpc105_unassigned_ops,
+ &s->pci_dev, "system", UINT32_MAX);
+ memory_region_add_subregion(get_system_memory(), 0x80000000, &s->pci_io);
+ memory_region_add_subregion(&s->pci_io, 0, &s->isa_io);
+ memory_region_add_subregion(get_system_memory(), 0xc0000000, &s->pci_memory);
+ memory_region_add_subregion(get_system_memory(), 0xbffffff0, &s->pci_intack);
+
+ pci_bus_new_inplace(&s->pci_bus, DEVICE(obj), NULL,
+ &s->pci_memory, get_system_io(), 0);
+ h->bus = &s->pci_bus;
+
+ object_initialize(&s->pci_dev, TYPE_MPC105);
+ pci_dev = DEVICE(&s->pci_dev);
+ qdev_set_parent_bus(pci_dev, BUS(&s->pci_bus));
+ object_property_set_int(OBJECT(&s->pci_dev), PCI_DEVFN(0, 0), "addr",
+ NULL);
+ qdev_prop_set_bit(pci_dev, "multifunction", false);
+}
+
+static Property mpc105_pcihost_properties[] = {
+ DEFINE_PROP_UINT32("ram-size", Mpc105HostState, pci_dev.ram_size, 0),
+ DEFINE_PROP_STRING("bios-name", Mpc105HostState, pci_dev.bios_name),
+ DEFINE_PROP_END_OF_LIST()
+};
+
+static void mpc105_pcihost_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->realize = mpc105_pcihost_realizefn;
+ dc->props = mpc105_pcihost_properties;
+ dc->no_user = 1;
+}
+
+static TypeInfo mpc105_pcihost_info = {
+ .name = TYPE_MPC105_PCI_HOST_BRIDGE,
+ .parent = TYPE_PCI_HOST_BRIDGE,
+ .instance_size = sizeof(Mpc105HostState),
+ .instance_init = mpc105_pcihost_initfn,
+ .class_init = mpc105_pcihost_class_init,
+};
+
+static void mpc105_register_types(void)
+{
+ type_register_static(&mpc105_pcihost_info);
+ type_register_static(&mpc105_info);
+}
+
+type_init(mpc105_register_types)
diff --git a/hw/pci/pci_ids.h b/hw/pci/pci_ids.h
index d8dc2f1..933b987 100644
--- a/hw/pci/pci_ids.h
+++ b/hw/pci/pci_ids.h
@@ -69,6 +69,7 @@
#define PCI_VENDOR_ID_TI 0x104c
#define PCI_VENDOR_ID_MOTOROLA 0x1057
+#define PCI_DEVICE_ID_MOTOROLA_MPC105 0x0001
#define PCI_DEVICE_ID_MOTOROLA_MPC106 0x0002
#define PCI_DEVICE_ID_MOTOROLA_RAVEN 0x4801
diff --git a/trace-events b/trace-events
index d6a847d..49ab9d5 100644
--- a/trace-events
+++ b/trace-events
@@ -757,6 +757,13 @@ pc87312_info_ide(uint32_t base) "base 0x%x"
pc87312_info_parallel(uint32_t base, uint32_t irq) "base 0x%x, irq %u"
pc87312_info_serial(int n, uint32_t base, uint32_t irq) "id=%d, base 0x%x, irq %u"
+# hw/mpc105.c
+mpc105_unassigned_mem_read(uint64_t addr) "Unassigned mem read %" PRIx64
+mpc105_unassigned_mem_write(uint64_t addr, uint64_t val) "Unassigned mem write %" PRIx64 " = 0x%" PRIx64
+mpc105_simm_enable(int id, uint32_t start, uint32_t end) "SIMM #%d 0x%08x-0x%08x"
+mpc105_simm_disable(int id) "SIMM #%d disabled"
+mpc105_simm_size(int id, uint32_t size) "SIMM #%d is %u MB"
+
# xen-all.c
xen_ram_alloc(unsigned long ram_addr, unsigned long size) "requested: %#lx, size %#lx"
xen_client_set_memory(uint64_t start_addr, unsigned long size, bool log_dirty) "%#"PRIx64" size %#lx, log_dirty %i"
--
1.7.10.4
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [RFC 2/6] prep: add IBM RS/6000 7248 (43p) machine emulation
2013-03-14 22:12 [Qemu-devel] [RFC 0/6] ppc/prep: add IBM RS/6000 43p machine Hervé Poussineau
2013-03-14 22:12 ` [Qemu-devel] [RFC 1/6] pci: add MPC105 PCI host bridge emulation Hervé Poussineau
@ 2013-03-14 22:12 ` Hervé Poussineau
2013-03-14 22:12 ` [Qemu-devel] [RFC 3/6] prep: add RS/6000 debug device Hervé Poussineau
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Hervé Poussineau @ 2013-03-14 22:12 UTC (permalink / raw)
To: qemu-devel; +Cc: Andreas Färber, Hervé Poussineau
Machine is very simple (only one PCI host bridge and an ISA bridge).
Provide a ibm_43p.cfg file to add more devices to this machine.
Syntax is:
qemu-system-ppc -M 43p -readconfig ibm_43p.cfg
---
docs/ibm_43p.cfg | 34 ++++++++++++++++++++
hw/ppc/prep.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 128 insertions(+)
create mode 100644 docs/ibm_43p.cfg
diff --git a/docs/ibm_43p.cfg b/docs/ibm_43p.cfg
new file mode 100644
index 0000000..cf80b89
--- /dev/null
+++ b/docs/ibm_43p.cfg
@@ -0,0 +1,34 @@
+############################################################################
+#
+# qemu-system-ppc -M 43p creates a bare machine with just the very essential
+# chipset devices being present:
+#
+# 00.0 - Host bridge
+# 0b.0 - ISA bridge
+#
+# This config file documents the other devices and how they are
+# created. You can simply use "-readconfig $thisfile" to create
+# them all.
+
+[device]
+ driver = "i8042"
+
+[device]
+ driver = "pc87312"
+ config = "12"
+
+[device]
+ driver = "pcnet"
+ addr = "12.0"
+
+[device]
+ driver = "isa-ide"
+ iobase = "0x1f0"
+ iobase2 = "0x3f6"
+ irq = "14"
+
+[device]
+ driver = "isa-ide"
+ iobase = "0x170"
+ iobase2 = "0x376"
+ irq = "15"
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index 2920911..6c5558e 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -30,6 +30,7 @@
#include "sysemu/sysemu.h"
#include "hw/isa.h"
#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
#include "hw/pci/pci_host.h"
#include "hw/ppc.h"
#include "hw/boards.h"
@@ -663,6 +664,91 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
audio_init(isa_bus, pci_bus);
}
+static int prep_set_cmos_checksum(DeviceState *dev, void *opaque)
+{
+ uint16_t checksum = *(uint16_t*)opaque;
+ ISADevice *rtc;
+
+ rtc = ISA_DEVICE(object_dynamic_cast(OBJECT(dev), "mc146818rtc"));
+ if (rtc) {
+ rtc_set_memory(rtc, 0x2e, checksum & 0xff);
+ rtc_set_memory(rtc, 0x3e, checksum & 0xff);
+ rtc_set_memory(rtc, 0x2f, checksum >> 8);
+ rtc_set_memory(rtc, 0x3f, checksum >> 8);
+ }
+ return 0;
+}
+
+static void ibm_43p_init(QEMUMachineInitArgs *args)
+{
+ CPUPPCState *env = NULL;
+ uint16_t cmos_checksum;
+ PowerPCCPU *cpu;
+ DeviceState *dev;
+ SysBusDevice *pcihost;
+ PCIBus *pci_bus;
+ ISABus *isa_bus;
+ qemu_irq *cpu_exit_irq;
+
+ /* init CPU */
+ if (!args->cpu_model)
+ args->cpu_model = "604";
+ {
+ cpu = cpu_ppc_init(args->cpu_model);
+ if (cpu == NULL) {
+ fprintf(stderr, "Unable to find PowerPC CPU definition\n");
+ exit(1);
+ }
+ env = &cpu->env;
+
+ if (env->flags & POWERPC_FLAG_RTC_CLK) {
+ /* POWER / PowerPC 601 RTC clock frequency is 7.8125 MHz */
+ cpu_ppc_tb_init(env, 7812500UL);
+ } else {
+ /* Set time-base frequency to 100 Mhz */
+ cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
+ }
+ qemu_register_reset(ppc_prep_reset, cpu);
+ }
+ if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
+ hw_error("Only 6xx bus is supported on PREP machine\n");
+ }
+
+ /* PCI host */
+ pcihost = SYS_BUS_DEVICE(qdev_create(NULL, "mpc105-pcihost"));
+ qdev_prop_set_uint32(DEVICE(pcihost), "ram-size", (uint32_t)args->ram_size);
+ if (bios_name == NULL)
+ bios_name = "P93H1904.IMG";
+ qdev_prop_set_string(DEVICE(pcihost), "bios-name", bios_name);
+ object_property_add_child(qdev_get_machine(), "eagle", OBJECT(pcihost), NULL);
+ qdev_init_nofail(DEVICE(pcihost));
+ pci_bus = PCI_BUS(qdev_get_child_bus(DEVICE(pcihost), "pci.0"));
+ if (pci_bus == NULL) {
+ fprintf(stderr, "Couldn't create PCI host controller.\n");
+ exit(1);
+ }
+
+ /* PCI -> ISA bridge */
+ dev = DEVICE(pci_create_simple(pci_bus, PCI_DEVFN(11, 0), "i82378"));
+ cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
+ qdev_connect_gpio_out(dev, 0,
+ first_cpu->irq_inputs[PPC6xx_INPUT_INT]);
+ qdev_connect_gpio_out(dev, 1, *cpu_exit_irq);
+ sysbus_connect_irq(pcihost, 0, qdev_get_gpio_in(dev, 9));
+ sysbus_connect_irq(pcihost, 1, qdev_get_gpio_in(dev, 11));
+ sysbus_connect_irq(pcihost, 2, qdev_get_gpio_in(dev, 9));
+ sysbus_connect_irq(pcihost, 3, qdev_get_gpio_in(dev, 11));
+ isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0"));
+
+ /* initialize CMOS checksums */
+ cmos_checksum = 0x6aa9;
+ qbus_walk_children(BUS(isa_bus), prep_set_cmos_checksum, NULL,
+ &cmos_checksum);
+
+ /* Now that we have PCI and ISA, initialize audio subsystem */
+ audio_init(isa_bus, pci_bus);
+}
+
static QEMUMachine prep_machine = {
.name = "prep",
.desc = "PowerPC PREP platform",
@@ -671,9 +757,17 @@ static QEMUMachine prep_machine = {
DEFAULT_MACHINE_OPTIONS,
};
+static QEMUMachine ibm_43p_machine = {
+ .name = "43p",
+ .desc = "IBM RS/6000 7248 (43p)",
+ .init = ibm_43p_init,
+ .max_cpus = 1,
+};
+
static void prep_machine_init(void)
{
qemu_register_machine(&prep_machine);
+ qemu_register_machine(&ibm_43p_machine);
}
machine_init(prep_machine_init);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [RFC 3/6] prep: add RS/6000 debug device
2013-03-14 22:12 [Qemu-devel] [RFC 0/6] ppc/prep: add IBM RS/6000 43p machine Hervé Poussineau
2013-03-14 22:12 ` [Qemu-devel] [RFC 1/6] pci: add MPC105 PCI host bridge emulation Hervé Poussineau
2013-03-14 22:12 ` [Qemu-devel] [RFC 2/6] prep: add IBM RS/6000 7248 (43p) machine emulation Hervé Poussineau
@ 2013-03-14 22:12 ` Hervé Poussineau
2013-03-14 22:12 ` [Qemu-devel] [RFC 4/6] m48t59: move ISA ports registration to QOM constructor Hervé Poussineau
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Hervé Poussineau @ 2013-03-14 22:12 UTC (permalink / raw)
To: qemu-devel; +Cc: Andreas Färber, Hervé Poussineau
Document it for the IBM 43p emulation.
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
docs/ibm_43p.cfg | 3 +
hw/ppc/Makefile.objs | 1 +
hw/ppc/rs6000_debug.c | 260 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 264 insertions(+)
create mode 100644 hw/ppc/rs6000_debug.c
diff --git a/docs/ibm_43p.cfg b/docs/ibm_43p.cfg
index cf80b89..92c9e8f 100644
--- a/docs/ibm_43p.cfg
+++ b/docs/ibm_43p.cfg
@@ -32,3 +32,6 @@
iobase = "0x170"
iobase2 = "0x376"
irq = "15"
+
+[device]
+ driver = "rs6000-debug"
diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
index 4de0209..8be8264 100644
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -23,6 +23,7 @@ obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o
obj-y += ppc405_boards.o ppc4xx_devs.o ppc405_uc.o ppc440_bamboo.o
# PReP
obj-y += prep.o
+obj-y += rs6000_debug.o
# OldWorld PowerMac
obj-y += mac_oldworld.o
# NewWorld PowerMac
diff --git a/hw/ppc/rs6000_debug.c b/hw/ppc/rs6000_debug.c
new file mode 100644
index 0000000..d7b8721
--- /dev/null
+++ b/hw/ppc/rs6000_debug.c
@@ -0,0 +1,260 @@
+/*
+ * QEMU IBM RS/6000 debug port emulation
+ *
+ * Copyright (c) 2011 Hervé Poussineau
+ *
+ * This program 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) version 3 or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "hw/isa.h"
+#include "char/char.h"
+
+#define TYPE_RS6000_DEBUG "rs6000-debug"
+#define RS6000(obj) \
+ OBJECT_CHECK(rs6000DebugState, (obj), TYPE_RS6000_DEBUG)
+
+static struct {
+ uint8_t code;
+ const char* message;
+} checkpoints[] = {
+ { 0x00, "Manufacturing - Reserved for Parallel port download protocol" },
+ { 0x01, "Clear the EPOW register 1. Memory modules 2. system board" },
+ { 0x02, "Determine system bus speed, set ISA advisor" },
+ { 0x04, "Set memory refresh" },
+ { 0x05, "Transfer control to Operating System ( normal boot )" },
+ { 0x06, "Jump to set environment or check flash" },
+ { 0x08, "Run recovery block base memory, test 2k, then set stack" },
+ { 0x09, "Copy CRC verification code to RAM" },
+ { 0x0A, "Turn on cache" },
+ { 0x0B, "Flush cache" },
+ { 0x0C, "Jump to CRC verification code in RAM" },
+ { 0x0D, "Compute composite image CRC" },
+ { 0x0E, "Jump back to ROM" },
+ { 0x0F, "Turn off cache" },
+ { 0x10, "Check if composite image CRC is valid" },
+ { 0x11, "Good CRC - jump to composite image" },
+ { 0x12, "Bad CRC - initialize base memory, stack" },
+ { 0x13, "Bad CRC - copy uncompressed recovery block code to RAM" },
+ { 0x14, "Bad CRC - jump to code in RAM" },
+ { 0x15, "Bad CRC - turn on cache" },
+ { 0x16, "Bad CRC - copy recovery block data section to RAM" },
+ { 0x17, "Bad CRC - invalidate and flush cache, set TOC" },
+ { 0x18, "Bad CRC - branch to high level recovery control routine" },
+ { 0x19, "Initialize base memory, stack" },
+ { 0x1A, "Copy uncompressed recovery block code to RAM" },
+ { 0x1B, "Jump to code in RAM" },
+ { 0x1C, "Turn on cache" },
+ { 0x1D, "Copy recovery block data section to RAM" },
+ { 0x1E, "Invalidate and flush cache, set TOC" },
+ { 0x1F, "Branch to high level control routine" },
+ { 0x20, "Initialize system I/O" },
+ { 0x21, "Run a console diagnostic routine" },
+ { 0x22, "No memory found" },
+ { 0x23, "No DIMM found in socket" },
+ { 0x24, "Remove bad DIMM found from DIMM information" },
+ { 0x25, "Unsupported DIMM detected" },
+ { 0x26, "Check valid image - start" },
+ { 0x27, "Check valid image - successful" },
+ { 0x28, "Wait for interrupt" },
+ { 0x29, "Transfers information to the business audio chip" },
+ { 0x2B, "Wait until sound chip has been initialized" },
+ { 0x2C, "Initialize the current input/pointer device" },
+ { 0x2D, "Initialize the current output" },
+ { 0x2E, "Register a console driver" },
+ { 0x30, "Set up early memory allocation heap, initialize Super I/O" },
+ { 0x31, "Determine system bus speed, set ISA driver" },
+ { 0x32, "Resync to SP (Console image)" },
+ { 0x33, "Set memory refresh" },
+ { 0x35, "Jump to set environment" },
+ { 0x40, "Initialize interrupt subsystem and 8259s" },
+ { 0x41, "SP command setup" },
+ { 0x42, "SP mailbox interface" },
+ { 0x43, "get_vpd entry" },
+ { 0x44, "init_sp entry" },
+ { 0x45, "sp_recovery -> resync SP & CPU" },
+ { 0x46, "IRQ13 stuck high Bad System Board or Service Processor" },
+ { 0x47, "Entry to error checking routine-No system board VPD, bad CRC Bad System Board" },
+ { 0x48, "Power supply or system board problem" },
+ { 0x49, "Voltage problem, system board, power supply or CPU 5V" },
+ { 0x4A, "Voltage problem, system board or power supply 12V" },
+ { 0x4B, "CPU over temperature or bad system board" },
+ { 0x4C, "start bit-map display function" },
+ { 0x4D, "Bit-map file read into memory, start processing" },
+ { 0x4E, "End bit-map display function" },
+ { 0x4F, "IO/MEM over termperature or bad system board" },
+ { 0x50, "Initialize CMOS RTC periodic interrupt" },
+ { 0x51, "System board or system over temperature, CPU card Critical " },
+ { 0x52, "Bad system board (fan fail reported)" },
+ { 0x53, "Bad system board or Fans" },
+ { 0x54, "Fan fail warning" },
+ { 0x55, "Bad system board (unsupported EPOW)" },
+ { 0x56, "Voltage problem, system board, power supply or CPU 3.3V/2.5V" },
+ { 0x57, "Bad or low battery" },
+ { 0x58, "IRQ13 test failure" },
+ { 0x59, "EPOW test failure" },
+ { 0x5A, "Spurious IRQ6 interrupt (i.e. interrupt glitch)" },
+ { 0x5B, "Fan failure warning" },
+ { 0x5B, "Transfer control to Operating System ( service mode bootlist )" },
+ { 0x5C, "Clear EPOW register failure" },
+ { 0x5D, "Clear EPOW register failure" },
+ { 0x60, "Initialize keyboard/mouse controller, and password" },
+ { 0x61, "Extended memory initialization command" },
+ { 0x62, "Diskette initialization command" },
+ { 0x64, "Test of day routine" },
+ { 0x6A, "SCSI initialization command" },
+ { 0x70, "Initialize debugger" },
+ { 0x71, "Start checking whether CMOS contents are valid" },
+ { 0x72, "End checking whether CMOS contents are valid" },
+ { 0x73, "Dumps contents of CMOS data area to a file" },
+ { 0x74, "Establishing Host conmnection" },
+ { 0x75, "BootP request" },
+ { 0x77, "Resync to SP (Recvoery image)" },
+ { 0x79, "Dupms contents of NVRAM data area to a file" },
+ { 0x7A, "NVRAM initialization" },
+ { 0x7B, "Check NVRAM validity CRC" },
+ { 0x7C, "Loads contents of CMOS from file" },
+ { 0x80, "Initialize system call table" },
+ { 0x82, "Register a manager for use by the system" },
+ { 0x88, "Halt. System locked by error condition - power off" },
+ { 0x90, "Initialize VDISK file system" },
+ { 0x91, "Low-level initialize VDISK file systems" },
+ { 0x94, "Start SCSI initialization" },
+ { 0x96, "SCSI bus scan start" },
+ { 0x97, "SCSI polling interrupt" },
+ { 0x98, "SCSI device detected" },
+ { 0x9E, "Real Time clock RTC initialization" },
+ { 0x9F, "Exit SCSI initialization" },
+ { 0xA0, "Start resident monitor, run V:autoexec.6md" },
+ { 0xA1, "Enter resident monitor" },
+ { 0xA2, "Resident monitor process" },
+ { 0xA3, "Resident monitor process" },
+ { 0xA4, "Exit resident monitor" },
+ { 0xA5, "ASCII terminal initialization" },
+ { 0xA6, "ASCII terminal initialization exit" },
+ { 0xA9, "p9 driver initialization" },
+ { 0xAA, "p9 driver exit" },
+ { 0xAB, "Keyboard driver initialization" },
+ { 0xAC, "Keyboard driver exit" },
+ { 0xAD, "Mouse driver initialization" },
+ { 0xAE, "Mouse driver exit" },
+ { 0xB0, "Initialize rest of file system" },
+ { 0xB1, "Diskette initialization" },
+ { 0xB2, "Diskette drive type determination" },
+ { 0xB3, "Diskette initialization complete" },
+ { 0xC0, "Check if flash ROM OK" },
+ { 0xCA, "Build boot table - Networks" },
+ { 0xCB, "Build boot table - DASD" },
+ { 0xCC, "Build boot table - CDROM" },
+ { 0xCD, "Build boot table - diskettes" },
+ { 0xCE, "No operating system boot, exit normal boot sequence" },
+ { 0xD0, "Start of boot sequence" },
+ { 0xD2, "No operating system boot - ensure CMOS RTC periodic clock updates displayed" },
+ { 0xD4, "Initialize console for loading diagnostics" },
+ { 0xD8, "Exit from diagnostic - run resident monitor" },
+ { 0xDA, "IRQ15" },
+ { 0xDB, "Unexpected processor exception" },
+ { 0xDC, "Dynamic console selection" },
+ { 0xDD, "Early processor exception" },
+ { 0xDE, "Alternating pattern of FDE and FDA indicates a processor exception has been detected." },
+ { 0xE1, "Test timeout" },
+ { 0xE2, "Initialize system I/O" },
+ { 0xE4, "Initialize super I/O with default values" },
+ { 0xE6, "Set up early memory allocation heap" },
+ { 0xE8, "Initialize primary diskette drive in polled mode" },
+ { 0xEA, "Try to load in recovery image from diskette" },
+ { 0xEB, "Verify recovery image is valid" },
+ { 0xEC, "Get recovery image entry point" },
+ { 0xED, "Invalidate instruction cache" },
+ { 0xEE, "Jump to composite image" },
+ { 0xF0, "Manufacturing - Check for parallel port hook" },
+ { 0xF4, "Manufacturing - Start flag not received" },
+ { 0xF5, "Manufacturing - Invalid start flag received" },
+ { 0xF6, "Manufacturing - Receive character timeout" },
+ { 0xF7, "Manufacturing - CRC value mismatch" },
+ { 0xFA, "Error during flash update" },
+ { 0xFC, "Operating system boot - no errors reported by IPL ROS" },
+ { 0xFD, "Operating system boot - non-critical errors reported by IPL ROS" },
+ { 0xFE, "No boot - critical error(s) reported by IPL ROS -or- F1 key pressed" },
+ { 0, NULL },
+};
+
+typedef struct rs6000DebugState {
+ ISADevice dev;
+ MemoryRegion io;
+ CharDriverState *chr;
+} rs6000DebugState;
+
+static void rs6000_debug_write(void *opaque, hwaddr addr, uint64_t val,
+ unsigned int size)
+{
+ rs6000DebugState *s = opaque;
+ uint8_t code = val & 0xff;
+ int i = 0;
+
+ while (checkpoints[i].message) {
+ if (checkpoints[i].code == code) {
+ qemu_chr_fe_printf(s->chr, "%s\r\n",
+ checkpoints[i].message);
+ return;
+ }
+ i++;
+ }
+
+ qemu_chr_fe_printf(s->chr, "unknown code 0x%02x\r\n", code);
+}
+
+static const MemoryRegionOps rs6000_debug_ops = {
+ .write = rs6000_debug_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static int rs6000_debug_init(ISADevice *dev)
+{
+ rs6000DebugState *s = RS6000(dev);
+
+ if (!s->chr) {
+ s->chr = qemu_chr_new("rs6000_debug", "vc", NULL);
+ }
+
+ memory_region_init_io(&s->io, &rs6000_debug_ops, s, "rs6000-debug", 4);
+ isa_register_ioport(dev, &s->io, 0x680);
+ return 0;
+}
+
+static Property rs6000_debug_properties[] = {
+ DEFINE_PROP_CHR("chardev", rs6000DebugState, chr),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void rs6000_debug_class_initfn(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+ ic->init = rs6000_debug_init;
+ dc->props = rs6000_debug_properties;
+}
+
+static TypeInfo rs6000_debug_isa_info = {
+ .name = TYPE_RS6000_DEBUG,
+ .parent = TYPE_ISA_DEVICE,
+ .instance_size = sizeof(rs6000DebugState),
+ .class_init = rs6000_debug_class_initfn,
+};
+
+static void rs6000_debug_register_types(void)
+{
+ type_register_static(&rs6000_debug_isa_info);
+}
+
+type_init(rs6000_debug_register_types)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [RFC 4/6] m48t59: move ISA ports registration to QOM constructor
2013-03-14 22:12 [Qemu-devel] [RFC 0/6] ppc/prep: add IBM RS/6000 43p machine Hervé Poussineau
` (2 preceding siblings ...)
2013-03-14 22:12 ` [Qemu-devel] [RFC 3/6] prep: add RS/6000 debug device Hervé Poussineau
@ 2013-03-14 22:12 ` Hervé Poussineau
2013-03-14 22:12 ` [Qemu-devel] [RFC 5/6] m48t59: hack(?) to make it work on IBM 43p Hervé Poussineau
2013-03-14 22:12 ` [Qemu-devel] [RFC 6/6] prep: QOM'ify System I/O Hervé Poussineau
5 siblings, 0 replies; 7+ messages in thread
From: Hervé Poussineau @ 2013-03-14 22:12 UTC (permalink / raw)
To: qemu-devel; +Cc: Andreas Färber, Hervé Poussineau
-device m48t59 can now be used to create a fully functional nvram,
and m48t59_init_isa() becomes a much simpler helper.
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
hw/m48t59.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/hw/m48t59.c b/hw/m48t59.c
index 39a9d80..1093716 100644
--- a/hw/m48t59.c
+++ b/hw/m48t59.c
@@ -676,11 +676,6 @@ M48t59State *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
d = DO_UPCAST(M48t59ISAState, busdev, dev);
s = &d->state;
- memory_region_init_io(&d->io, &m48t59_io_ops, s, "m48t59", 4);
- if (io_base != 0) {
- isa_register_ioport(dev, &d->io, io_base);
- }
-
return s;
}
@@ -703,6 +698,10 @@ static int m48t59_init_isa1(ISADevice *dev)
isa_init_irq(dev, &s->IRQ, 8);
m48t59_init_common(s);
+ memory_region_init_io(&d->io, &m48t59_io_ops, s, "m48t59", 4);
+ if (s->io_base != 0) {
+ isa_register_ioport(dev, &d->io, s->io_base);
+ }
return 0;
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [RFC 5/6] m48t59: hack(?) to make it work on IBM 43p
2013-03-14 22:12 [Qemu-devel] [RFC 0/6] ppc/prep: add IBM RS/6000 43p machine Hervé Poussineau
` (3 preceding siblings ...)
2013-03-14 22:12 ` [Qemu-devel] [RFC 4/6] m48t59: move ISA ports registration to QOM constructor Hervé Poussineau
@ 2013-03-14 22:12 ` Hervé Poussineau
2013-03-14 22:12 ` [Qemu-devel] [RFC 6/6] prep: QOM'ify System I/O Hervé Poussineau
5 siblings, 0 replies; 7+ messages in thread
From: Hervé Poussineau @ 2013-03-14 22:12 UTC (permalink / raw)
To: qemu-devel; +Cc: Andreas Färber, Hervé Poussineau
Document it for the IBM 43p emulation.
---
docs/ibm_43p.cfg | 6 ++++++
hw/m48t59.c | 2 ++
2 files changed, 8 insertions(+)
diff --git a/docs/ibm_43p.cfg b/docs/ibm_43p.cfg
index 92c9e8f..55329e3 100644
--- a/docs/ibm_43p.cfg
+++ b/docs/ibm_43p.cfg
@@ -11,6 +11,12 @@
# them all.
[device]
+ driver = "m48t59_isa"
+ io_base = "0x74"
+ model = "59"
+ size = "0x1000"
+
+[device]
driver = "i8042"
[device]
diff --git a/hw/m48t59.c b/hw/m48t59.c
index 1093716..c71ba7b 100644
--- a/hw/m48t59.c
+++ b/hw/m48t59.c
@@ -491,6 +491,7 @@ static void NVRAM_writeb(void *opaque, hwaddr addr, uint64_t val,
NVRAM->addr &= ~0xFF00;
NVRAM->addr |= val << 8;
break;
+ case 2:
case 3:
m48t59_write(NVRAM, NVRAM->addr, val);
NVRAM->addr = 0x0000;
@@ -506,6 +507,7 @@ static uint64_t NVRAM_readb(void *opaque, hwaddr addr, unsigned size)
uint32_t retval;
switch (addr) {
+ case 2:
case 3:
retval = m48t59_read(NVRAM, NVRAM->addr);
break;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [RFC 6/6] prep: QOM'ify System I/O
2013-03-14 22:12 [Qemu-devel] [RFC 0/6] ppc/prep: add IBM RS/6000 43p machine Hervé Poussineau
` (4 preceding siblings ...)
2013-03-14 22:12 ` [Qemu-devel] [RFC 5/6] m48t59: hack(?) to make it work on IBM 43p Hervé Poussineau
@ 2013-03-14 22:12 ` Hervé Poussineau
5 siblings, 0 replies; 7+ messages in thread
From: Hervé Poussineau @ 2013-03-14 22:12 UTC (permalink / raw)
To: qemu-devel; +Cc: Andreas Färber, Hervé Poussineau
Most of the functionality is extracted from hw/ppc/prep.c.
Also add support for board identification/equipment registers.
Document it for the IBM 43p emulation.
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
docs/ibm_43p.cfg | 5 +
hw/ppc/Makefile.objs | 1 +
hw/ppc/prep_systemio.c | 290 ++++++++++++++++++++++++++++++++++++++++++++++++
trace-events | 4 +
4 files changed, 300 insertions(+)
create mode 100644 hw/ppc/prep_systemio.c
diff --git a/docs/ibm_43p.cfg b/docs/ibm_43p.cfg
index 55329e3..2a97e3f 100644
--- a/docs/ibm_43p.cfg
+++ b/docs/ibm_43p.cfg
@@ -41,3 +41,8 @@
[device]
driver = "rs6000-debug"
+
+[device]
+ driver = "prep-systemio800"
+ ibm-planar-id = "0xc0"
+ equipment = "0xff"
diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
index 8be8264..b584902 100644
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -23,6 +23,7 @@ obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o
obj-y += ppc405_boards.o ppc4xx_devs.o ppc405_uc.o ppc440_bamboo.o
# PReP
obj-y += prep.o
+obj-y += prep_systemio.o
obj-y += rs6000_debug.o
# OldWorld PowerMac
obj-y += mac_oldworld.o
diff --git a/hw/ppc/prep_systemio.c b/hw/ppc/prep_systemio.c
new file mode 100644
index 0000000..ddd54d1
--- /dev/null
+++ b/hw/ppc/prep_systemio.c
@@ -0,0 +1,290 @@
+/*
+ * QEMU PReP System I/O emulation
+ *
+ * Copyright (c) 2003-2007 Jocelyn Mayer
+ * Copyright (c) 2010-2012 Herve Poussineau
+ * Copyright (c) 2010-2011 Andreas Faerber
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "hw/isa.h"
+#include "exec/address-spaces.h"
+#include "qemu/error-report.h" /* for error_report() */
+#include "sysemu/sysemu.h" /* for vm_stop() */
+#include "trace.h"
+
+/* Bit as defined in PowerPC Reference Plaform v1.1, sect. 6.1.5, p. 132 */
+#define BIT(n) (1 << (7 - (n)))
+
+typedef struct PrepIo800State {
+ ISADevice dev;
+ MemoryRegion ppc_parity_mem;
+
+ qemu_irq non_contiguous_io_map_irq;
+ uint8_t equipment; /* 0x080c */
+ uint8_t system_control; /* 0x081c */
+ uint8_t iomap_type; /* 0x0850 */
+ uint8_t ibm_planar_id; /* 0x0852 */
+ qemu_irq softreset_irq;
+} PrepIo800State;
+
+/* PORT 0092 -- Special Port 92 (Read/Write) */
+
+enum {
+ PORT0092_SOFTRESET = BIT(7),
+ PORT0092_LE_MODE = BIT(6),
+};
+
+static void prep_port0092_write(void *opaque, uint32_t addr, uint32_t val)
+{
+ PrepIo800State *s = opaque;
+
+ trace_prep_systemio_write(addr, val);
+
+ if ((val & PORT0092_SOFTRESET) != 0) {
+ qemu_irq_raise(s->softreset_irq);
+ } else {
+ qemu_irq_lower(s->softreset_irq);
+ }
+
+ if ((val & PORT0092_LE_MODE) != 0) {
+ /* XXX Not supported yet */
+ error_report("little-endian mode not supported");
+ vm_stop(RUN_STATE_PAUSED);
+ } else {
+ /* Nothing to do */
+ }
+}
+
+static uint32_t prep_port0092_read(void *opaque, uint32_t addr)
+{
+ /* XXX LE mode unsupported */
+ trace_prep_systemio_read(addr, 0);
+ return 0;
+}
+
+/* PORT 0808 -- Hardfile Light Register (Write Only) */
+
+enum {
+ PORT0808_HARDFILE_LIGHT_ON = BIT(7),
+};
+
+static void prep_port0808_write(void *opaque, uint32_t addr, uint32_t val)
+{
+ trace_prep_systemio_write(addr, val);
+}
+
+/* PORT 0810 -- Password Protect 1 Register (Write Only) */
+
+/* reset by port 0x4D in the SIO */
+static void prep_port0810_write(void *opaque, uint32_t addr, uint32_t val)
+{
+ trace_prep_systemio_write(addr, val);
+}
+
+/* PORT 0812 -- Password Protect 2 Register (Write Only) */
+
+/* reset by port 0x4D in the SIO */
+static void prep_port0812_write(void *opaque, uint32_t addr, uint32_t val)
+{
+ trace_prep_systemio_write(addr, val);
+}
+
+/* PORT 0814 -- L2 Invalidate Register (Write Only) */
+
+static void prep_port0814_write(void *opaque, uint32_t addr, uint32_t val)
+{
+ trace_prep_systemio_write(addr, val);
+}
+
+/* PORT 0818 -- Reserved for Keylock (Read Only) */
+
+enum {
+ PORT0818_KEYLOCK_SIGNAL_HIGH = BIT(7),
+};
+
+static uint32_t prep_port0818_read(void *opaque, uint32_t addr)
+{
+ uint32_t val = 0;
+ trace_prep_systemio_read(addr, val);
+ return val;
+}
+
+/* PORT 080C -- Equipment */
+
+enum {
+ PORT080C_SCSIFUSE = BIT(1),
+ PORT080C_L2_COPYBACK = BIT(4),
+ PORT080C_L2_256 = BIT(5),
+ PORT080C_UPGRADE_CPU = BIT(6),
+ PORT080C_L2 = BIT(7),
+};
+
+static uint32_t prep_port080c_read(void *opaque, uint32_t addr)
+{
+ PrepIo800State *s = opaque;
+ trace_prep_systemio_read(addr, s->equipment);
+ return s->equipment;
+}
+
+/* PORT 081C -- System Control Register (Read/Write) */
+
+enum {
+ PORT081C_FLOPPY_MOTOR_INHIBIT = BIT(3),
+ PORT081C_MASK_TEA = BIT(2),
+ PORT081C_L2_UPDATE_INHIBIT = BIT(1),
+ PORT081C_L2_CACHEMISS_INHIBIT = BIT(0),
+};
+
+static void prep_port081c_write(void *opaque, uint32_t addr, uint32_t val)
+{
+ PrepIo800State *s = opaque;
+ trace_prep_systemio_write(addr, val);
+ s->system_control = val;
+}
+
+static uint32_t prep_port081c_read(void *opaque, uint32_t addr)
+{
+ PrepIo800State *s = opaque;
+ trace_prep_systemio_read(addr, s->system_control);
+ return s->system_control;
+}
+
+/* System Board Identification */
+
+static uint32_t prep_port0852_read(void *opaque, uint32_t addr)
+{
+ PrepIo800State *s = opaque;
+ trace_prep_systemio_read(addr, s->ibm_planar_id);
+ return s->ibm_planar_id;
+}
+
+/* PORT 0850 -- I/O Map Type Register (Read/Write) */
+
+enum {
+ PORT0850_IOMAP_NONCONTIGUOUS = BIT(7),
+};
+
+static uint32_t prep_port0850_read(void *opaque, uint32_t addr)
+{
+ PrepIo800State *s = opaque;
+ trace_prep_systemio_read(addr, s->iomap_type);
+ return s->iomap_type;
+}
+
+static void prep_port0850_write(void *opaque, uint32_t addr, uint32_t val)
+{
+ PrepIo800State *s = opaque;
+
+ trace_prep_systemio_write(addr, val);
+ qemu_set_irq(s->non_contiguous_io_map_irq,
+ val & PORT0850_IOMAP_NONCONTIGUOUS ? 1 : 0);
+ s->iomap_type = val;
+}
+
+static const MemoryRegionPortio ppc_io800_port_list[] = {
+ { 0x092, 1, 1, .read = prep_port0092_read,
+ .write = prep_port0092_write, },
+ { 0x808, 1, 1, .write = prep_port0808_write, },
+ { 0x80c, 1, 1, .read = prep_port080c_read, },
+ { 0x810, 1, 1, .write = prep_port0810_write, },
+ { 0x812, 1, 1, .write = prep_port0812_write, },
+ { 0x814, 1, 1, .write = prep_port0814_write, },
+ { 0x818, 1, 1, .read = prep_port0818_read, },
+ { 0x81c, 1, 1, .read = prep_port081c_read,
+ .write = prep_port081c_write, },
+ { 0x850, 1, 1, .read = prep_port0850_read,
+ .write = prep_port0850_write, },
+ { 0x852, 1, 1, .read = prep_port0852_read, },
+ PORTIO_END_OF_LIST()
+};
+
+static uint64_t ppc_parity_error_readl(void *opaque, hwaddr addr,
+ unsigned int size)
+{
+ uint32_t val = 0;
+ trace_prep_systemio_read((unsigned int)addr, val);
+ return val;
+}
+
+static const MemoryRegionOps ppc_parity_error_ops = {
+ .read = ppc_parity_error_readl,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ },
+};
+
+static int prep_systemio_init(ISADevice *dev)
+{
+ PrepIo800State *s = DO_UPCAST(PrepIo800State, dev, dev);
+ qdev_init_gpio_out(&dev->qdev, &s->non_contiguous_io_map_irq, 1);
+ s->iomap_type = 0; /* contiguous mode XXX 0x1? */
+ s->softreset_irq = first_cpu->irq_inputs[PPC6xx_INPUT_HRESET];
+
+ isa_register_portio_list(dev, 0x0, ppc_io800_port_list, s, "systemio800");
+
+ memory_region_init_io(&s->ppc_parity_mem, &ppc_parity_error_ops, s,
+ "ppc-parity", 0x4);
+ memory_region_add_subregion(get_system_memory(), 0xbfffeff0,
+ &s->ppc_parity_mem);
+ return 0;
+}
+
+static const VMStateDescription vmstate_prep_systemio = {
+ .name = "prep_systemio",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT8(system_control, PrepIo800State),
+ VMSTATE_UINT8(iomap_type, PrepIo800State),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
+static Property prep_systemio_properties[] = {
+ DEFINE_PROP_UINT8("ibm-planar-id", PrepIo800State, ibm_planar_id, 0),
+ DEFINE_PROP_UINT8("equipment", PrepIo800State, equipment, 0),
+ DEFINE_PROP_END_OF_LIST()
+};
+
+static void prep_systemio_class_initfn(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+ ic->init = prep_systemio_init;
+ dc->vmsd = &vmstate_prep_systemio;
+ dc->props = prep_systemio_properties;
+ dc->no_user = 1;
+}
+
+static TypeInfo prep_systemio800_info = {
+ .name = "prep-systemio800",
+ .parent = TYPE_ISA_DEVICE,
+ .instance_size = sizeof(PrepIo800State),
+ .class_init = prep_systemio_class_initfn,
+};
+
+static void prep_systemio_register_types(void)
+{
+ type_register_static(&prep_systemio800_info);
+}
+
+type_init(prep_systemio_register_types)
diff --git a/trace-events b/trace-events
index 49ab9d5..8173da4 100644
--- a/trace-events
+++ b/trace-events
@@ -757,6 +757,10 @@ pc87312_info_ide(uint32_t base) "base 0x%x"
pc87312_info_parallel(uint32_t base, uint32_t irq) "base 0x%x, irq %u"
pc87312_info_serial(int n, uint32_t base, uint32_t irq) "id=%d, base 0x%x, irq %u"
+# hw/ppc/prep_systemio.c
+prep_systemio_read(uint32_t addr, uint32_t val) "read addr=%x val=%x"
+prep_systemio_write(uint32_t addr, uint32_t val) "write addr=%x val=%x"
+
# hw/mpc105.c
mpc105_unassigned_mem_read(uint64_t addr) "Unassigned mem read %" PRIx64
mpc105_unassigned_mem_write(uint64_t addr, uint64_t val) "Unassigned mem write %" PRIx64 " = 0x%" PRIx64
--
1.7.10.4
^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2013-03-14 22:11 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-14 22:12 [Qemu-devel] [RFC 0/6] ppc/prep: add IBM RS/6000 43p machine Hervé Poussineau
2013-03-14 22:12 ` [Qemu-devel] [RFC 1/6] pci: add MPC105 PCI host bridge emulation Hervé Poussineau
2013-03-14 22:12 ` [Qemu-devel] [RFC 2/6] prep: add IBM RS/6000 7248 (43p) machine emulation Hervé Poussineau
2013-03-14 22:12 ` [Qemu-devel] [RFC 3/6] prep: add RS/6000 debug device Hervé Poussineau
2013-03-14 22:12 ` [Qemu-devel] [RFC 4/6] m48t59: move ISA ports registration to QOM constructor Hervé Poussineau
2013-03-14 22:12 ` [Qemu-devel] [RFC 5/6] m48t59: hack(?) to make it work on IBM 43p Hervé Poussineau
2013-03-14 22:12 ` [Qemu-devel] [RFC 6/6] prep: QOM'ify System I/O Hervé Poussineau
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).