qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/4] PPC IBM 40p PReP emulation
@ 2015-06-10 21:18 Hervé Poussineau
  2015-06-10 21:18 ` [Qemu-devel] [PATCH 1/4] prep: QOM'ify System I/O Hervé Poussineau
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Hervé Poussineau @ 2015-06-10 21:18 UTC (permalink / raw)
  To: qemu-devel
  Cc: Hervé Poussineau, Andreas Färber, qemu-ppc,
	Artyom Tarasenko

Hi,

This patchset adds the emulation of the IBM RS/6000 7020 (40p). The real machine is
able to run AIX (up to 4.3.3), Windows NT (up to 4.0 SP1), the beta of OS/2 PowerPC,
Solaris, Linux, NetBSD/PReP ...

I've tested current emulation with Open Firmware PReP and with official firmware.
Patch 2 has been of a great help when using official firmware. However, if required,
I can drop it.

Linux kernel runs.
Windows NT starts up to the point where it wants to change endianness.
Other OSes have not been tested.

To test, download firmware a http://tyom.de/qprepofw-serial-svn-3738.rom . Thanks Artyom!
Then, run:
qemu-system-ppc -M 40p -bios qprepofw-serial-svn-3738.rom -readconfig ibm_40p.cfg -serial stdio

Note that you can't natively boot from a hard disk using Open Firmware, as 40p storage is SCSI.

Hervé

Hervé Poussineau (4):
  prep: QOM'ify System I/O
  prep: add RS/6000 debug device
  prep: add IBM RS/6000 7020 (40p) memory controller
  prep: add IBM RS/6000 7020 (40p) machine emulation

 default-configs/ppc-softmmu.mak |   4 +
 docs/ibm_40p.cfg                |  42 ++++++
 hw/ppc/Makefile.objs            |   3 +
 hw/ppc/prep.c                   |  99 +++++++++++++
 hw/ppc/prep_systemio.c          | 300 ++++++++++++++++++++++++++++++++++++++++
 hw/ppc/rs6000_debug.c           | 260 ++++++++++++++++++++++++++++++++++
 hw/ppc/rs6000_mc.c              | 229 ++++++++++++++++++++++++++++++
 trace-events                    |  11 ++
 8 files changed, 948 insertions(+)
 create mode 100644 docs/ibm_40p.cfg
 create mode 100644 hw/ppc/prep_systemio.c
 create mode 100644 hw/ppc/rs6000_debug.c
 create mode 100644 hw/ppc/rs6000_mc.c

-- 
2.1.4

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

* [Qemu-devel] [PATCH 1/4] prep: QOM'ify System I/O
  2015-06-10 21:18 [Qemu-devel] [PATCH 0/4] PPC IBM 40p PReP emulation Hervé Poussineau
@ 2015-06-10 21:18 ` Hervé Poussineau
  2015-06-10 21:18 ` [Qemu-devel] [PATCH 2/4] prep: add RS/6000 debug device Hervé Poussineau
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Hervé Poussineau @ 2015-06-10 21:18 UTC (permalink / raw)
  To: qemu-devel
  Cc: Hervé Poussineau, Andreas Färber, qemu-ppc,
	Alexander Graf, Artyom Tarasenko

Part of the functionality is extracted from hw/ppc/prep.c.
Also add support for board identification/equipment registers.

Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
 hw/ppc/Makefile.objs   |   1 +
 hw/ppc/prep_systemio.c | 300 +++++++++++++++++++++++++++++++++++++++++++++++++
 trace-events           |   4 +
 3 files changed, 305 insertions(+)
 create mode 100644 hw/ppc/prep_systemio.c

diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
index c8ab06e..4369571 100644
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -12,6 +12,7 @@ obj-y += ppc405_boards.o ppc4xx_devs.o ppc405_uc.o ppc440_bamboo.o
 obj-y += ppc4xx_pci.o
 # PReP
 obj-$(CONFIG_PREP) += prep.o
+obj-$(CONFIG_PREP) += prep_systemio.o
 # OldWorld PowerMac
 obj-$(CONFIG_MAC) += mac_oldworld.o
 # NewWorld PowerMac
diff --git a/hw/ppc/prep_systemio.c b/hw/ppc/prep_systemio.c
new file mode 100644
index 0000000..832b53e
--- /dev/null
+++ b/hw/ppc/prep_systemio.c
@@ -0,0 +1,300 @@
+/*
+ * 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/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"
+
+#define TYPE_PREP_SYSTEMIO "prep-systemio"
+#define PREP_SYSTEMIO(obj) \
+    OBJECT_CHECK(PrepSystemIoState, (obj), TYPE_PREP_SYSTEMIO)
+
+/* Bit as defined in PowerPC Reference Plaform v1.1, sect. 6.1.5, p. 132 */
+#define PREP_BIT(n) (1 << (7 - (n)))
+
+typedef struct PrepSystemIoState {
+    ISADevice parent_obj;
+    MemoryRegion ppc_parity_mem;
+
+    qemu_irq non_contiguous_io_map_irq;
+    uint8_t sreset; /* 0x0092 */
+    uint8_t equipment; /* 0x080c */
+    uint8_t system_control; /* 0x081c */
+    uint8_t iomap_type; /* 0x0850 */
+    uint8_t ibm_planar_id; /* 0x0852 */
+    qemu_irq softreset_irq;
+} PrepSystemIoState;
+
+/* PORT 0092 -- Special Port 92 (Read/Write) */
+
+enum {
+    PORT0092_SOFTRESET  = PREP_BIT(7),
+    PORT0092_LE_MODE    = PREP_BIT(6),
+};
+
+static void prep_port0092_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    PrepSystemIoState *s = opaque;
+
+    trace_prep_systemio_write(addr, val);
+
+    if ((val & PORT0092_SOFTRESET) != 0) {
+        qemu_irq_raise(s->softreset_irq);
+        s->sreset = 1;
+    } else {
+        qemu_irq_lower(s->softreset_irq);
+        s->sreset = 0;
+    }
+
+    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)
+{
+    PrepSystemIoState *s = opaque;
+    /* XXX LE mode unsupported */
+    trace_prep_systemio_read(addr, 0);
+    return s->sreset;
+}
+
+/* PORT 0808 -- Hardfile Light Register (Write Only) */
+
+enum {
+    PORT0808_HARDFILE_LIGHT_ON  = PREP_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    = PREP_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               = PREP_BIT(1),
+    PORT080C_L2_COPYBACK            = PREP_BIT(4),
+    PORT080C_L2_256                 = PREP_BIT(5),
+    PORT080C_UPGRADE_CPU            = PREP_BIT(6),
+    PORT080C_L2                     = PREP_BIT(7),
+};
+
+static uint32_t prep_port080c_read(void *opaque, uint32_t addr)
+{
+    PrepSystemIoState *s = opaque;
+    trace_prep_systemio_read(addr, s->equipment);
+    return s->equipment;
+}
+
+/* PORT 081C -- System Control Register (Read/Write) */
+
+enum {
+    PORT081C_FLOPPY_MOTOR_INHIBIT   = PREP_BIT(3),
+    PORT081C_MASK_TEA               = PREP_BIT(2),
+    PORT081C_L2_UPDATE_INHIBIT      = PREP_BIT(1),
+    PORT081C_L2_CACHEMISS_INHIBIT   = PREP_BIT(0),
+};
+
+static void prep_port081c_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    PrepSystemIoState *s = opaque;
+    trace_prep_systemio_write(addr, val);
+    s->system_control = val;
+}
+
+static uint32_t prep_port081c_read(void *opaque, uint32_t addr)
+{
+    PrepSystemIoState *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)
+{
+    PrepSystemIoState *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    = PREP_BIT(7),
+};
+
+static uint32_t prep_port0850_read(void *opaque, uint32_t addr)
+{
+    PrepSystemIoState *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)
+{
+    PrepSystemIoState *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 void prep_systemio_realize(DeviceState *dev, Error **errp)
+{
+    ISADevice *isa = ISA_DEVICE(dev);
+    PrepSystemIoState *s = PREP_SYSTEMIO(dev);
+    PowerPCCPU *cpu;
+
+    qdev_init_gpio_out(dev, &s->non_contiguous_io_map_irq, 1);
+    s->iomap_type = 0; /* contiguous mode XXX 0x1? */
+    cpu = POWERPC_CPU(first_cpu);
+    s->softreset_irq = cpu->env.irq_inputs[PPC6xx_INPUT_HRESET];
+
+    isa_register_portio_list(isa, 0x0, ppc_io800_port_list, s, "systemio800");
+
+    memory_region_init_io(&s->ppc_parity_mem, OBJECT(dev),
+                          &ppc_parity_error_ops, s, "ppc-parity", 0x4);
+    memory_region_add_subregion(get_system_memory(), 0xbfffeff0,
+                                &s->ppc_parity_mem);
+}
+
+static const VMStateDescription vmstate_prep_systemio = {
+    .name = "prep_systemio",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT8(system_control, PrepSystemIoState),
+        VMSTATE_UINT8(iomap_type, PrepSystemIoState),
+        VMSTATE_END_OF_LIST()
+    },
+};
+
+static Property prep_systemio_properties[] = {
+    DEFINE_PROP_UINT8("ibm-planar-id", PrepSystemIoState, ibm_planar_id, 0),
+    DEFINE_PROP_UINT8("equipment", PrepSystemIoState, equipment, 0),
+    DEFINE_PROP_END_OF_LIST()
+};
+
+static void prep_systemio_class_initfn(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = prep_systemio_realize;
+    dc->vmsd = &vmstate_prep_systemio;
+    dc->props = prep_systemio_properties;
+}
+
+static TypeInfo prep_systemio800_info = {
+    .name          = TYPE_PREP_SYSTEMIO,
+    .parent        = TYPE_ISA_DEVICE,
+    .instance_size = sizeof(PrepSystemIoState),
+    .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 2662ffa..463c35b 100644
--- a/trace-events
+++ b/trace-events
@@ -883,6 +883,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/scsi/vmw_pvscsi.c
 pvscsi_ring_init_data(uint32_t txr_len_log2, uint32_t rxr_len_log2) "TX/RX rings logarithms set to %d/%d"
 pvscsi_ring_init_msg(uint32_t len_log2) "MSG ring logarithm set to %d"
-- 
2.1.4

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

* [Qemu-devel] [PATCH 2/4] prep: add RS/6000 debug device
  2015-06-10 21:18 [Qemu-devel] [PATCH 0/4] PPC IBM 40p PReP emulation Hervé Poussineau
  2015-06-10 21:18 ` [Qemu-devel] [PATCH 1/4] prep: QOM'ify System I/O Hervé Poussineau
@ 2015-06-10 21:18 ` Hervé Poussineau
  2015-06-10 21:18 ` [Qemu-devel] [PATCH 3/4] prep: add IBM RS/6000 7020 (40p) memory controller Hervé Poussineau
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Hervé Poussineau @ 2015-06-10 21:18 UTC (permalink / raw)
  To: qemu-devel
  Cc: Hervé Poussineau, Andreas Färber, qemu-ppc,
	Alexander Graf, Artyom Tarasenko

Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
 default-configs/ppc-softmmu.mak |   1 +
 hw/ppc/Makefile.objs            |   1 +
 hw/ppc/rs6000_debug.c           | 260 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 262 insertions(+)
 create mode 100644 hw/ppc/rs6000_debug.c

diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak
index 4befde3..57f15e3 100644
--- a/default-configs/ppc-softmmu.mak
+++ b/default-configs/ppc-softmmu.mak
@@ -47,4 +47,5 @@ CONFIG_ETSEC=y
 CONFIG_LIBDECNUMBER=y
 # For PReP
 CONFIG_MC146818RTC=y
+CONFIG_RS6000_DEBUG=y
 CONFIG_ISA_TESTDEV=y
diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
index 4369571..db7d467 100644
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -13,6 +13,7 @@ obj-y += ppc4xx_pci.o
 # PReP
 obj-$(CONFIG_PREP) += prep.o
 obj-$(CONFIG_PREP) += prep_systemio.o
+obj-${CONFIG_RS6000_DEBUG} += rs6000_debug.o
 # OldWorld PowerMac
 obj-$(CONFIG_MAC) += 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..5c53fa1
--- /dev/null
+++ b/hw/ppc/rs6000_debug.c
@@ -0,0 +1,260 @@
+/*
+ * QEMU IBM RS/6000 debug port emulation
+ *
+ * Copyright (c) 2015 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/isa.h"
+#include "sysemu/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 parent_obj;
+    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 void rs6000_debug_realize(DeviceState *dev, Error **errp)
+{
+    rs6000DebugState *s = RS6000(dev);
+
+    if (!s->chr) {
+        s->chr = qemu_chr_new("rs6000_debug", "vc", NULL);
+    }
+
+    memory_region_init_io(&s->io, OBJECT(dev), &rs6000_debug_ops, s,
+                          "rs6000-debug", 4);
+    isa_register_ioport(ISA_DEVICE(dev), &s->io, 0x680);
+}
+
+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);
+
+    dc->realize = rs6000_debug_realize;
+    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)
-- 
2.1.4

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

* [Qemu-devel] [PATCH 3/4] prep: add IBM RS/6000 7020 (40p) memory controller
  2015-06-10 21:18 [Qemu-devel] [PATCH 0/4] PPC IBM 40p PReP emulation Hervé Poussineau
  2015-06-10 21:18 ` [Qemu-devel] [PATCH 1/4] prep: QOM'ify System I/O Hervé Poussineau
  2015-06-10 21:18 ` [Qemu-devel] [PATCH 2/4] prep: add RS/6000 debug device Hervé Poussineau
@ 2015-06-10 21:18 ` Hervé Poussineau
  2015-06-10 21:18 ` [Qemu-devel] [PATCH 4/4] prep: add IBM RS/6000 7020 (40p) machine emulation Hervé Poussineau
  2015-06-11  8:02 ` [Qemu-devel] [PATCH 0/4] PPC IBM 40p PReP emulation Artyom Tarasenko
  4 siblings, 0 replies; 7+ messages in thread
From: Hervé Poussineau @ 2015-06-10 21:18 UTC (permalink / raw)
  To: qemu-devel
  Cc: Hervé Poussineau, Andreas Färber, qemu-ppc,
	Alexander Graf, Artyom Tarasenko

Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
 default-configs/ppc-softmmu.mak |   1 +
 hw/ppc/Makefile.objs            |   1 +
 hw/ppc/rs6000_mc.c              | 229 ++++++++++++++++++++++++++++++++++++++++
 trace-events                    |   7 ++
 4 files changed, 238 insertions(+)
 create mode 100644 hw/ppc/rs6000_mc.c

diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak
index 57f15e3..070803c 100644
--- a/default-configs/ppc-softmmu.mak
+++ b/default-configs/ppc-softmmu.mak
@@ -48,4 +48,5 @@ CONFIG_LIBDECNUMBER=y
 # For PReP
 CONFIG_MC146818RTC=y
 CONFIG_RS6000_DEBUG=y
+CONFIG_RS6000_MC=y
 CONFIG_ISA_TESTDEV=y
diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
index db7d467..c7edbce 100644
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -14,6 +14,7 @@ obj-y += ppc4xx_pci.o
 obj-$(CONFIG_PREP) += prep.o
 obj-$(CONFIG_PREP) += prep_systemio.o
 obj-${CONFIG_RS6000_DEBUG} += rs6000_debug.o
+obj-${CONFIG_RS6000_MC} += rs6000_mc.o
 # OldWorld PowerMac
 obj-$(CONFIG_MAC) += mac_oldworld.o
 # NewWorld PowerMac
diff --git a/hw/ppc/rs6000_mc.c b/hw/ppc/rs6000_mc.c
new file mode 100644
index 0000000..9ec85ca
--- /dev/null
+++ b/hw/ppc/rs6000_mc.c
@@ -0,0 +1,229 @@
+/*
+ * QEMU RS6000 memory controller
+ *
+ * Copyright (c) 2015 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/isa.h"
+#include "exec/address-spaces.h"
+#include "hw/boards.h"
+#include "trace.h"
+
+#define TYPE_RS6000MC "rs6000-mc"
+#define RS6000MC_DEVICE(obj) \
+    OBJECT_CHECK(RS6000MCState, (obj), TYPE_RS6000MC)
+
+typedef struct RS6000MCState {
+    ISADevice parent_obj;
+    /* see US patent 5,684,979 for details (expired 2001-11-04) */
+    uint32_t ram_size;
+    bool autoconfigure;
+    MemoryRegion simm[6];
+    unsigned int simm_size[6];
+    uint32_t end_address[8];
+    uint8_t port0820_index;
+} RS6000MCState;
+
+/* P0RT 0803 -- SIMM ID Register (32/8 MB) (Read Only) */
+
+static uint32_t rs6000mc_port0803_read(void *opaque, uint32_t addr)
+{
+    RS6000MCState *s = opaque;
+    uint32_t val = 0;
+    int socket;
+
+    /* (1 << socket) indicates 32 MB SIMM at given socket */
+    for (socket = 0; socket < 6; socket++) {
+        if (s->simm_size[socket] == 32) {
+            val |= (1 << socket);
+        }
+    }
+
+    trace_rs6000mc_id_read(addr, val);
+    return val;
+}
+
+/* PORT 0804 -- SIMM Presence Register (Read Only) */
+
+static uint32_t rs6000mc_port0804_read(void *opaque, uint32_t addr)
+{
+    RS6000MCState *s = opaque;
+    uint32_t val = 0xff;
+    int socket;
+
+    /* (1 << socket) indicates SIMM absence at given socket */
+    for (socket = 0; socket < 6; socket++) {
+        if (s->simm_size[socket]) {
+            val &= ~(1 << socket);
+        }
+    }
+    s->port0820_index = 0;
+
+    trace_rs6000mc_presence_read(addr, val);
+    return val;
+}
+
+/* Memory Controller Size Programming Register */
+
+static uint32_t rs6000mc_port0820_read(void *opaque, uint32_t addr)
+{
+    RS6000MCState *s = opaque;
+    uint32_t val = s->end_address[s->port0820_index] & 0x1f;
+    s->port0820_index = (s->port0820_index + 1) & 7;
+    trace_rs6000mc_size_read(addr, val);
+    return val;
+}
+
+static void rs6000mc_port0820_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    RS6000MCState *s = opaque;
+    uint8_t socket = val >> 5;
+    uint32_t end_address = val & 0x1f;
+
+    trace_rs6000mc_size_write(addr, val);
+    s->end_address[socket] = end_address;
+    if (socket > 0 && socket < 7) {
+        if (s->simm_size[socket - 1]) {
+            uint32_t size;
+            uint32_t start_address = 0;
+            if (socket > 1) {
+                start_address = s->end_address[socket - 1];
+            }
+
+            size = end_address - start_address;
+            memory_region_set_enabled(&s->simm[socket - 1], size != 0);
+            memory_region_set_address(&s->simm[socket - 1],
+                                      start_address * 8 * 1024 * 1024);
+        }
+    }
+}
+
+/* Read Memory Parity Error */
+
+enum {
+    PORT0841_NO_ERROR_DETECTED = 0x01,
+};
+
+static uint32_t rs6000mc_port0841_read(void *opaque, uint32_t addr)
+{
+    uint32_t val = PORT0841_NO_ERROR_DETECTED;
+    trace_rs6000mc_parity_read(addr, val);
+    return val;
+}
+
+static const MemoryRegionPortio rs6000mc_port_list[] = {
+    { 0x803, 1, 1, .read = rs6000mc_port0803_read },
+    { 0x804, 1, 1, .read = rs6000mc_port0804_read },
+    { 0x820, 1, 1, .read = rs6000mc_port0820_read,
+                   .write = rs6000mc_port0820_write, },
+    { 0x841, 1, 1, .read = rs6000mc_port0841_read },
+    PORTIO_END_OF_LIST()
+};
+
+static void rs6000mc_realize(DeviceState *dev, Error **errp)
+{
+    RS6000MCState *s = RS6000MC_DEVICE(dev);
+    int socket = 0;
+    unsigned int ram_size = s->ram_size / (1024 * 1024);
+
+    while (socket < 6) {
+        if (ram_size >= 64) {
+            s->simm_size[socket] = 32;
+            s->simm_size[socket + 1] = 32;
+            ram_size -= 64;
+        } else if (ram_size >= 16) {
+            s->simm_size[socket] = 8;
+            s->simm_size[socket + 1] = 8;
+            ram_size -= 16;
+        } else {
+            /* Not enough memory */
+            break;
+        }
+        socket += 2;
+    }
+
+    for (socket = 0; socket < 6; socket++) {
+        if (s->simm_size[socket]) {
+            char name[] = "simm.?";
+            name[5] = socket + '0';
+            memory_region_allocate_system_memory(&s->simm[socket], OBJECT(dev),
+                                                 name, s->simm_size[socket]
+                                                 * 1024 * 1024);
+            memory_region_add_subregion_overlap(get_system_memory(), 0,
+                                                &s->simm[socket], socket);
+        }
+    }
+    if (ram_size) {
+        /* unable to push all requested RAM in SIMMs */
+        error_setg(errp, "RAM size incompatible with this board. "
+                   "Try again with something else, like %d MB\n",
+                   s->ram_size / 1024 / 1024 - ram_size);
+        return;
+    }
+
+    if (s->autoconfigure) {
+        uint32_t start_address = 0;
+        for (socket = 0; socket < 6; socket++) {
+            if (s->simm_size[socket]) {
+                memory_region_set_enabled(&s->simm[socket], true);
+                memory_region_set_address(&s->simm[socket], start_address);
+                start_address += memory_region_size(&s->simm[socket]);
+            }
+        }
+    }
+
+    isa_register_portio_list(ISA_DEVICE(dev), 0x0, rs6000mc_port_list, s,
+                             "rs6000mc");
+}
+
+static const VMStateDescription vmstate_rs6000mc = {
+    .name = "rs6000-mc",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT8(port0820_index, RS6000MCState),
+        VMSTATE_END_OF_LIST()
+    },
+};
+
+static Property rs6000mc_properties[] = {
+    DEFINE_PROP_UINT32("ram-size", RS6000MCState, ram_size, 0),
+    DEFINE_PROP_BOOL("auto-configure", RS6000MCState, autoconfigure, true),
+    DEFINE_PROP_END_OF_LIST()
+};
+
+static void rs6000mc_class_initfn(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = rs6000mc_realize;
+    dc->vmsd = &vmstate_rs6000mc;
+    dc->props = rs6000mc_properties;
+}
+
+static const TypeInfo rs6000mc_info = {
+    .name          = TYPE_RS6000MC,
+    .parent        = TYPE_ISA_DEVICE,
+    .instance_size = sizeof(RS6000MCState),
+    .class_init    = rs6000mc_class_initfn,
+};
+
+static void rs6000mc_types(void)
+{
+    type_register_static(&rs6000mc_info);
+}
+
+type_init(rs6000mc_types)
diff --git a/trace-events b/trace-events
index 463c35b..7670d1a 100644
--- a/trace-events
+++ b/trace-events
@@ -887,6 +887,13 @@ pc87312_info_serial(int n, uint32_t base, uint32_t irq) "id=%d, base 0x%x, irq %
 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/ppc/rs6000_mc.c
+rs6000mc_id_read(uint32_t addr, uint32_t val) "read addr=%x val=%x"
+rs6000mc_presence_read(uint32_t addr, uint32_t val) "read addr=%x val=%x"
+rs6000mc_size_read(uint32_t addr, uint32_t val) "read addr=%x val=%x"
+rs6000mc_size_write(uint32_t addr, uint32_t val) "write addr=%x val=%x"
+rs6000mc_parity_read(uint32_t addr, uint32_t val) "read addr=%x val=%x"
+
 # hw/scsi/vmw_pvscsi.c
 pvscsi_ring_init_data(uint32_t txr_len_log2, uint32_t rxr_len_log2) "TX/RX rings logarithms set to %d/%d"
 pvscsi_ring_init_msg(uint32_t len_log2) "MSG ring logarithm set to %d"
-- 
2.1.4

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

* [Qemu-devel] [PATCH 4/4] prep: add IBM RS/6000 7020 (40p) machine emulation
  2015-06-10 21:18 [Qemu-devel] [PATCH 0/4] PPC IBM 40p PReP emulation Hervé Poussineau
                   ` (2 preceding siblings ...)
  2015-06-10 21:18 ` [Qemu-devel] [PATCH 3/4] prep: add IBM RS/6000 7020 (40p) memory controller Hervé Poussineau
@ 2015-06-10 21:18 ` Hervé Poussineau
  2015-06-11  8:02 ` [Qemu-devel] [PATCH 0/4] PPC IBM 40p PReP emulation Artyom Tarasenko
  4 siblings, 0 replies; 7+ messages in thread
From: Hervé Poussineau @ 2015-06-10 21:18 UTC (permalink / raw)
  To: qemu-devel
  Cc: Hervé Poussineau, Andreas Färber, qemu-ppc,
	Alexander Graf, Artyom Tarasenko

Machine is very simple (only one PCI host bridge and an ISA bridge).
Provide a ibm_40p.cfg file to add more devices to this machine.

Syntax is:
qemu-system-ppc -M 40p -readconfig ibm_40p.cfg

Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
 default-configs/ppc-softmmu.mak |  2 +
 docs/ibm_40p.cfg                | 42 +++++++++++++++++
 hw/ppc/prep.c                   | 99 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 143 insertions(+)
 create mode 100644 docs/ibm_40p.cfg

diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak
index 070803c..260dfb9 100644
--- a/default-configs/ppc-softmmu.mak
+++ b/default-configs/ppc-softmmu.mak
@@ -19,6 +19,7 @@ CONFIG_I82378=y
 CONFIG_PC87312=y
 CONFIG_MACIO=y
 CONFIG_PCSPK=y
+CONFIG_CS4231A=y
 CONFIG_CUDA=y
 CONFIG_ADB=y
 CONFIG_MAC_NVRAM=y
@@ -46,6 +47,7 @@ CONFIG_PLATFORM_BUS=y
 CONFIG_ETSEC=y
 CONFIG_LIBDECNUMBER=y
 # For PReP
+CONFIG_VGA_S3=y
 CONFIG_MC146818RTC=y
 CONFIG_RS6000_DEBUG=y
 CONFIG_RS6000_MC=y
diff --git a/docs/ibm_40p.cfg b/docs/ibm_40p.cfg
new file mode 100644
index 0000000..a7e21b5
--- /dev/null
+++ b/docs/ibm_40p.cfg
@@ -0,0 +1,42 @@
+############################################################################
+#
+# qemu-system-ppc -M 40 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 = "cs4231a"
+  iobase = "0x830"
+  irq = "10"
+
+[device]
+  driver = "pc87312"
+  config = "12"
+
+[device]
+  driver = "lsi53c810"
+  addr = "01.0"
+
+[device]
+  driver = "pcnet"
+  addr = "03.0"
+
+[device]
+  driver = "isa-m48t59"
+  iobase = "0x74"
+
+[device]
+  driver = "prep-systemio"
+  ibm-planar-id = "0xfc"
+  equipment = "0xc0"
+
+[device]
+  driver = "rs6000-debug"
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index 998ee2d..d051fba 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -699,6 +699,97 @@ static void ppc_prep_init(MachineState *machine)
                          graphic_width, graphic_height, graphic_depth);
 }
 
+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_40p_init(MachineState *machine)
+{
+    CPUPPCState *env = NULL;
+    uint16_t cmos_checksum;
+    PowerPCCPU *cpu;
+    DeviceState *dev;
+    SysBusDevice *pcihost;
+    PCIBus *pci_bus;
+    BusState *isa_bus;
+
+    /* init CPU */
+    if (!machine->cpu_model) {
+        machine->cpu_model = "604";
+    }
+    cpu = cpu_ppc_init(machine->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 */
+    dev = qdev_create(NULL, "raven-pcihost");
+    if (bios_name == NULL) {
+        bios_name = "P12H0456.IMG";
+    }
+    qdev_prop_set_string(dev, "bios-name", bios_name);
+    qdev_prop_set_uint32(dev, "elf-machine", ELF_MACHINE);
+    pcihost = SYS_BUS_DEVICE(dev);
+    object_property_add_child(qdev_get_machine(), "raven", OBJECT(dev), NULL);
+    qdev_init_nofail(dev);
+    pci_bus = PCI_BUS(qdev_get_child_bus(dev, "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 = POWERPC_CPU(first_cpu);
+    qdev_connect_gpio_out(dev, 0,
+                          cpu->env.irq_inputs[PPC6xx_INPUT_INT]);
+    qdev_connect_gpio_out(dev, 1,
+                          qemu_allocate_irq(cpu_request_exit, NULL, 0));
+    sysbus_connect_irq(pcihost, 0, qdev_get_gpio_in(dev, 15));
+    sysbus_connect_irq(pcihost, 1, qdev_get_gpio_in(dev, 13));
+    sysbus_connect_irq(pcihost, 2, qdev_get_gpio_in(dev, 15));
+    sysbus_connect_irq(pcihost, 3, qdev_get_gpio_in(dev, 13));
+    isa_bus = qdev_get_child_bus(dev, "isa.0");
+
+    /* Memory controller */
+    dev = DEVICE(isa_create(ISA_BUS(isa_bus), "rs6000-mc"));
+    qdev_prop_set_uint32(dev, "ram-size", machine->ram_size);
+    qdev_init_nofail(dev);
+
+    /* initialize CMOS checksums */
+    cmos_checksum = 0x6aa9;
+    qbus_walk_children(isa_bus, prep_set_cmos_checksum, NULL, NULL, NULL,
+                       &cmos_checksum);
+
+    /* initialize audio subsystem */
+    audio_init();
+}
+
 static QEMUMachine prep_machine = {
     .name = "prep",
     .desc = "PowerPC PREP platform",
@@ -707,9 +798,17 @@ static QEMUMachine prep_machine = {
     .default_boot_order = "cad",
 };
 
+static QEMUMachine ibm_40p_machine = {
+    .name = "40p",
+    .desc = "IBM RS/6000 7020 (40p)",
+    .init = ibm_40p_init,
+    .max_cpus = 1,
+};
+
 static void prep_machine_init(void)
 {
     qemu_register_machine(&prep_machine);
+    qemu_register_machine(&ibm_40p_machine);
 }
 
 machine_init(prep_machine_init);
-- 
2.1.4

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

* Re: [Qemu-devel] [PATCH 0/4] PPC IBM 40p PReP emulation
  2015-06-10 21:18 [Qemu-devel] [PATCH 0/4] PPC IBM 40p PReP emulation Hervé Poussineau
                   ` (3 preceding siblings ...)
  2015-06-10 21:18 ` [Qemu-devel] [PATCH 4/4] prep: add IBM RS/6000 7020 (40p) machine emulation Hervé Poussineau
@ 2015-06-11  8:02 ` Artyom Tarasenko
  2015-06-11 19:00   ` Hervé Poussineau
  4 siblings, 1 reply; 7+ messages in thread
From: Artyom Tarasenko @ 2015-06-11  8:02 UTC (permalink / raw)
  To: Hervé Poussineau; +Cc: Andreas Färber, qemu-ppc, qemu-devel

Hi Hervé,

On Wed, Jun 10, 2015 at 11:18 PM, Hervé Poussineau <hpoussin@reactos.org> wrote:
> Hi,
>
> This patchset adds the emulation of the IBM RS/6000 7020 (40p).

Well done! Congratulations on a good job!

> The real machine is
> able to run AIX (up to 4.3.3), Windows NT (up to 4.0 SP1), the beta of OS/2 PowerPC,
> Solaris, Linux, NetBSD/PReP ...

> I've tested current emulation with Open Firmware PReP and with official firmware.
> Patch 2 has been of a great help when using official firmware. However, if required,
> I can drop it.
>
> Linux kernel runs.
> Windows NT starts up to the point where it wants to change endianness.
> Other OSes have not been tested.

Solaris would likely have the same problem: it's little-endian on PReP.

> To test, download firmware a http://tyom.de/qprepofw-serial-svn-3738.rom . Thanks Artyom!

You are welcome. I see your machine is using a S3 graphic card. If you
like I can add a driver for it.
Not within the next days though. Out of curiosity: is the proprietary
firmware also able to use a Cirrus Logic card?

Regards,
Artyom

> Then, run:
> qemu-system-ppc -M 40p -bios qprepofw-serial-svn-3738.rom -readconfig ibm_40p.cfg -serial stdio
>
> Note that you can't natively boot from a hard disk using Open Firmware, as 40p storage is SCSI.
>
> Hervé
>
> Hervé Poussineau (4):
>   prep: QOM'ify System I/O
>   prep: add RS/6000 debug device
>   prep: add IBM RS/6000 7020 (40p) memory controller
>   prep: add IBM RS/6000 7020 (40p) machine emulation
>
>  default-configs/ppc-softmmu.mak |   4 +
>  docs/ibm_40p.cfg                |  42 ++++++
>  hw/ppc/Makefile.objs            |   3 +
>  hw/ppc/prep.c                   |  99 +++++++++++++
>  hw/ppc/prep_systemio.c          | 300 ++++++++++++++++++++++++++++++++++++++++
>  hw/ppc/rs6000_debug.c           | 260 ++++++++++++++++++++++++++++++++++
>  hw/ppc/rs6000_mc.c              | 229 ++++++++++++++++++++++++++++++
>  trace-events                    |  11 ++
>  8 files changed, 948 insertions(+)
>  create mode 100644 docs/ibm_40p.cfg
>  create mode 100644 hw/ppc/prep_systemio.c
>  create mode 100644 hw/ppc/rs6000_debug.c
>  create mode 100644 hw/ppc/rs6000_mc.c
>
> --
> 2.1.4
>



-- 
Regards,
Artyom Tarasenko

SPARC and PPC PReP under qemu blog: http://tyom.blogspot.com/search/label/qemu

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

* Re: [Qemu-devel] [PATCH 0/4] PPC IBM 40p PReP emulation
  2015-06-11  8:02 ` [Qemu-devel] [PATCH 0/4] PPC IBM 40p PReP emulation Artyom Tarasenko
@ 2015-06-11 19:00   ` Hervé Poussineau
  0 siblings, 0 replies; 7+ messages in thread
From: Hervé Poussineau @ 2015-06-11 19:00 UTC (permalink / raw)
  To: Artyom Tarasenko; +Cc: Andreas Färber, qemu-ppc, qemu-devel

Hi Artyom,

Le 11/06/2015 10:02, Artyom Tarasenko a écrit :
> Hi Hervé,
>
> On Wed, Jun 10, 2015 at 11:18 PM, Hervé Poussineau <hpoussin@reactos.org> wrote:
>> Hi,
>>
>> This patchset adds the emulation of the IBM RS/6000 7020 (40p).
>
> Well done! Congratulations on a good job!
>
>> The real machine is
>> able to run AIX (up to 4.3.3), Windows NT (up to 4.0 SP1), the beta of OS/2 PowerPC,
>> Solaris, Linux, NetBSD/PReP ...
>
>> I've tested current emulation with Open Firmware PReP and with official firmware.
>> Patch 2 has been of a great help when using official firmware. However, if required,
>> I can drop it.
>>
>> Linux kernel runs.
>> Windows NT starts up to the point where it wants to change endianness.
>> Other OSes have not been tested.
>
> Solaris would likely have the same problem: it's little-endian on PReP.
>
>> To test, download firmware a http://tyom.de/qprepofw-serial-svn-3738.rom . Thanks Artyom!
>
> You are welcome. I see your machine is using a S3 graphic card. If you
> like I can add a driver for it.
> Not within the next days though. Out of curiosity: is the proprietary
> firmware also able to use a Cirrus Logic card?

No, it only handles S3 graphic cards, as is using some IBM/8514 commands.
It would probably be more interesting to add support for LSI 53c810 SCSI card, if possible.

Regards,

Hervé

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

end of thread, other threads:[~2015-06-11 19:04 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-06-10 21:18 [Qemu-devel] [PATCH 0/4] PPC IBM 40p PReP emulation Hervé Poussineau
2015-06-10 21:18 ` [Qemu-devel] [PATCH 1/4] prep: QOM'ify System I/O Hervé Poussineau
2015-06-10 21:18 ` [Qemu-devel] [PATCH 2/4] prep: add RS/6000 debug device Hervé Poussineau
2015-06-10 21:18 ` [Qemu-devel] [PATCH 3/4] prep: add IBM RS/6000 7020 (40p) memory controller Hervé Poussineau
2015-06-10 21:18 ` [Qemu-devel] [PATCH 4/4] prep: add IBM RS/6000 7020 (40p) machine emulation Hervé Poussineau
2015-06-11  8:02 ` [Qemu-devel] [PATCH 0/4] PPC IBM 40p PReP emulation Artyom Tarasenko
2015-06-11 19:00   ` 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).