* [Qemu-devel] [RFC v2 0/7] ppc/prep: add IBM RS/6000 43p machine
@ 2013-04-14 8:05 Hervé Poussineau
2013-04-14 8:05 ` [Qemu-devel] [RFC v2 1/7] pci: add MPC105 PCI host bridge emulation Hervé Poussineau
` (6 more replies)
0 siblings, 7 replies; 14+ messages in thread
From: Hervé Poussineau @ 2013-04-14 8:05 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.
Andreas did some preliminary patches for OpenBIOS to support PReP machines, available at
git://repo.or.cz/openbios/afaerber.git branch prep.
43p emulation has been tested with this firmware, and also with the official firmware,
named P93H1904.IMG.
Command line may look like
qemu-system-ppc -M 43p -readconfig ibm_43p.cfg
-device ide-hd,drive=hd0 -drive if=none,id=hd0,cache=writeback,file="hda.qcow2"
Changes RFC v1 -> RFC v2:
- rebased on master
- works with OpenBIOS
- rework on m48t59 patches
- remove rs6000 debug port emulation (not strictly required)
- checkpatch.pl doesn't complain anymore
Known bugs/missing parts:
- incomplete MPC105 (PCI host bridge) emulation (memory controller)
- no video card (should be a S3)
- QEMU can't change endianness at runtime
OpenBIOS status:
- detects CPU and memory, then freezes with a "Dictionary space overflow"
Official firmware status:
- can boot from a IDE hard disk containing a PReP boot partition
- 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 (detects the netcard, but doesn't use it)
- needs a hack to m48t59 device to work (patch 7/7)
Please comment.
Regards,
Hervé
Hervé Poussineau (7):
pci: add MPC105 PCI host bridge emulation
m48t59: move ISA ports registration to QOM constructor
m48t59: register a QOM type for each nvram type we support
m48t59: use DeviceState in public functions
prep: add IBM RS/6000 7248 (43p) machine emulation
prep: QOM'ify System I/O
m48t59: hack(?) to make it work on IBM 43p
default-configs/ppc-softmmu.mak | 1 +
docs/ibm_43p.cfg | 42 ++++
hw/pci-host/Makefile.objs | 1 +
hw/pci-host/mpc105.c | 487 +++++++++++++++++++++++++++++++++++++++
hw/ppc/Makefile.objs | 1 +
hw/ppc/prep.c | 223 +++++++++++++++++-
hw/ppc/prep_systemio.c | 290 +++++++++++++++++++++++
hw/sparc/sun4m.c | 7 +-
hw/sparc64/sun4u.c | 6 +-
hw/timer/m48t59.c | 257 +++++++++++++++------
include/hw/pci/pci_ids.h | 1 +
include/hw/timer/m48t59.h | 14 +-
trace-events | 11 +
13 files changed, 1248 insertions(+), 93 deletions(-)
create mode 100644 docs/ibm_43p.cfg
create mode 100644 hw/pci-host/mpc105.c
create mode 100644 hw/ppc/prep_systemio.c
--
1.7.10.4
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Qemu-devel] [RFC v2 1/7] pci: add MPC105 PCI host bridge emulation
2013-04-14 8:05 [Qemu-devel] [RFC v2 0/7] ppc/prep: add IBM RS/6000 43p machine Hervé Poussineau
@ 2013-04-14 8:05 ` Hervé Poussineau
2013-04-14 8:05 ` [Qemu-devel] [RFC v2 2/7] m48t59: move ISA ports registration to QOM constructor Hervé Poussineau
` (5 subsequent siblings)
6 siblings, 0 replies; 14+ messages in thread
From: Hervé Poussineau @ 2013-04-14 8:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Andreas Färber, Hervé Poussineau
Non-contiguous I/O is not implemented.
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.
Add x-auto-conf property, to automatically configure the memory
controller at startup. This will be required by OpenBIOS, which
doesn't know how to do it.
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
default-configs/ppc-softmmu.mak | 1 +
hw/pci-host/Makefile.objs | 1 +
hw/pci-host/mpc105.c | 487 +++++++++++++++++++++++++++++++++++++++
include/hw/pci/pci_ids.h | 1 +
trace-events | 7 +
5 files changed, 497 insertions(+)
create mode 100644 hw/pci-host/mpc105.c
diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak
index 50034fc..750d482 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/pci-host/Makefile.objs b/hw/pci-host/Makefile.objs
index 909e702..ec4427b 100644
--- a/hw/pci-host/Makefile.objs
+++ b/hw/pci-host/Makefile.objs
@@ -3,6 +3,7 @@ common-obj-y += pam.o
# PPC devices
common-obj-$(CONFIG_PREP_PCI) += prep.o
common-obj-$(CONFIG_GRACKLE_PCI) += grackle.o
+common-obj-$(CONFIG_MPC105_PCI) += mpc105.o
# NewWorld PowerMac
common-obj-$(CONFIG_UNIN_PCI) += uninorth.o
common-obj-$(CONFIG_DEC_PCI) += dec.o
diff --git a/hw/pci-host/mpc105.c b/hw/pci-host/mpc105.c
new file mode 100644
index 0000000..e02d7a4
--- /dev/null
+++ b/hw/pci-host/mpc105.c
@@ -0,0 +1,487 @@
+/*
+ * 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 "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
+#include "hw/pci/pci_host.h"
+#include "hw/i386/pc.h"
+#include "hw/loader.h"
+#include "exec/address-spaces.h"
+#include "elf.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 MEM_CFG_1_MEMGO (1 << 19)
+
+#define BIOS_SIZE (1024 * 1024)
+
+typedef struct Mpc105State {
+ PCIDevice dev;
+ uint32_t ram_size;
+ uint32_t elf_machine;
+ uint32_t x_auto_conf;
+ char *bios_name;
+ MemoryRegion bios;
+ MemoryRegion simm[8];
+ bool use_sizer[8];
+ /* use a sizer to allow access to only part of a simm */
+ MemoryRegion 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_update_memory_mappings(Mpc105State *s)
+{
+ uint32_t start_address, end_address;
+ uint32_t start, ext_start, end, ext_end;
+ uint32_t cfg1;
+ uint64_t simm_size;
+ uint8_t *pci_conf;
+ uint8_t en;
+ bool enabled;
+ int i;
+
+ pci_conf = s->dev.config;
+ cfg1 = pci_get_long(pci_conf + MEM_CFG_1);
+
+ memory_region_transaction_begin();
+ if (cfg1 & MEM_CFG_1_MEMGO) {
+ 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);
+ }
+
+ simm_size = memory_region_size(&s->simm[i]);
+ if (simm_size == 0) {
+ continue;
+ }
+
+ /* Clean links between system memory, sizer and simm */
+ if (s->use_sizer[i]) {
+ memory_region_del_subregion(get_system_memory(), &s->sizer[i]);
+ memory_region_del_subregion(&s->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 < simm_size) {
+ memory_region_init_io(&s->sizer[i], &mpc105_unassigned_ops,
+ s, memory_region_name(&s->sizer[i]),
+ end_address - start_address + 1);
+ memory_region_add_subregion(&s->sizer[i], 0, &s->simm[i]);
+ memory_region_add_subregion(get_system_memory(), start_address,
+ &s->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_write_config(PCIDevice *dev, uint32_t addr, uint32_t val,
+ int l)
+{
+ Mpc105State *s = MPC105(dev);
+
+ pci_default_write_config(dev, addr, val, l);
+ if ((addr >= MEM_STA_03 && addr <= MEM_BANK_EN) || addr == MEM_CFG_1) {
+ mpc105_update_memory_mappings(s);
+ }
+}
+
+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);
+ }
+
+ if (s->x_auto_conf) {
+ /* enable all memory banks, starting from address 0 */
+ uint32_t start_address = 0, end_address = 0;
+ uint8_t ext_start, ext_end, enabled = 0;
+ int i;
+ for (i = 0; i < 8; i++) {
+ if (!memory_region_size(&s->simm[i])) {
+ continue;
+ }
+ end_address += memory_region_size(&s->simm[i]);
+ ext_start = pci_get_byte(pci_conf + EXT_MEM_STA_03 + i) & ~0x3;
+ ext_end = pci_get_byte(pci_conf + EXT_MEM_STA_03 + i) & ~0x3;
+ ext_start |= (start_address >> 28) & 0x3;
+ ext_end |= ((end_address - 1) >> 28) & 0x3;
+ pci_set_byte(pci_conf + MEM_STA_03 + i, start_address >> 20);
+ pci_set_byte(pci_conf + EXT_MEM_STA_03 + i, ext_start);
+ pci_set_byte(pci_conf + MEM_END_03 + i, (end_address - 1) >> 20);
+ pci_set_byte(pci_conf + EXT_MEM_END_03 + i, ext_end);
+ start_address = end_address;
+ enabled |= 1 << i;
+ }
+ pci_set_byte(pci_conf + MEM_BANK_EN, enabled);
+ pci_long_test_and_set_mask(pci_conf + MEM_CFG_1, MEM_CFG_1_MEMGO);
+ mpc105_update_memory_mappings(s);
+ }
+}
+
+static void qdev_mpc105_reset(DeviceState *dev)
+{
+ Mpc105State *s = MPC105(dev);
+ mpc105_reset(s);
+}
+
+static int mpc105_post_load(void *opaque, int version_id)
+{
+ Mpc105State *s = opaque;
+ mpc105_update_memory_mappings(s);
+ return 0;
+}
+
+static const VMStateDescription vmstate_mpc105 = {
+ .name = "mpc105",
+ .version_id = 1,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 1,
+ .post_load = mpc105_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_PCI_DEVICE(dev, Mpc105State),
+ 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 = -1;
+ 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->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) {
+ if (s->elf_machine != EM_NONE) {
+ bios_size = load_elf(filename, NULL, NULL, NULL,
+ NULL, NULL, 1, s->elf_machine, 0);
+ }
+ if (bios_size < 0) {
+ 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);
+ }
+ }
+ }
+ if (bios_size < 0 || bios_size > BIOS_SIZE) {
+ hw_error("qemu: could not load bios image '%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)
+{
+ qemu_irq *pic = opaque;
+
+ qemu_set_irq(pic[irq_num] , level);
+}
+
+static int mpc105_map_irq(PCIDevice *pci_dev, int irq_num)
+{
+ return (irq_num + (pci_dev->devfn >> 3)) & 1;
+}
+
+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);
+ /* FIXME: should handle non-contiguous I/O */
+ isa_mmio_setup(&s->isa_io, 0x800000);
+ 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, TYPE_PCI_BUS);
+ 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_UINT32("elf-machine", Mpc105HostState, pci_dev.elf_machine,
+ EM_NONE),
+ DEFINE_PROP_BIT("x-auto-conf", Mpc105HostState, pci_dev.x_auto_conf, 0,
+ true),
+ 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/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
index d8dc2f1..933b987 100644
--- a/include/hw/pci/pci_ids.h
+++ b/include/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 412f7e4..8b0ad9c 100644
--- a/trace-events
+++ b/trace-events
@@ -761,6 +761,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] 14+ messages in thread
* [Qemu-devel] [RFC v2 2/7] m48t59: move ISA ports registration to QOM constructor
2013-04-14 8:05 [Qemu-devel] [RFC v2 0/7] ppc/prep: add IBM RS/6000 43p machine Hervé Poussineau
2013-04-14 8:05 ` [Qemu-devel] [RFC v2 1/7] pci: add MPC105 PCI host bridge emulation Hervé Poussineau
@ 2013-04-14 8:05 ` Hervé Poussineau
2013-04-14 8:05 ` [Qemu-devel] [RFC v2 3/7] m48t59: register a QOM type for each nvram type we support Hervé Poussineau
` (4 subsequent siblings)
6 siblings, 0 replies; 14+ messages in thread
From: Hervé Poussineau @ 2013-04-14 8:05 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/timer/m48t59.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c
index 5019e06..41022f2 100644
--- a/hw/timer/m48t59.c
+++ b/hw/timer/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] 14+ messages in thread
* [Qemu-devel] [RFC v2 3/7] m48t59: register a QOM type for each nvram type we support
2013-04-14 8:05 [Qemu-devel] [RFC v2 0/7] ppc/prep: add IBM RS/6000 43p machine Hervé Poussineau
2013-04-14 8:05 ` [Qemu-devel] [RFC v2 1/7] pci: add MPC105 PCI host bridge emulation Hervé Poussineau
2013-04-14 8:05 ` [Qemu-devel] [RFC v2 2/7] m48t59: move ISA ports registration to QOM constructor Hervé Poussineau
@ 2013-04-14 8:05 ` Hervé Poussineau
2013-04-14 21:41 ` Artyom Tarasenko
2013-04-14 8:05 ` [Qemu-devel] [RFC v2 4/7] m48t59: use DeviceState in public functions Hervé Poussineau
` (3 subsequent siblings)
6 siblings, 1 reply; 14+ messages in thread
From: Hervé Poussineau @ 2013-04-14 8:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Andreas Färber, Hervé Poussineau
As m48t59 devices can only be created with m48t59_init() or m48t59_init_isa(),
we know exactly which nvram types are required. Register only those three
types.
Remove .model and .size properties as they can be infered from nvram name.
Remove .io_base ISA address port as m48t59_init_isa() is always called with ioport 0x74.
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
hw/timer/m48t59.c | 187 ++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 126 insertions(+), 61 deletions(-)
diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c
index 41022f2..29ec462 100644
--- a/hw/timer/m48t59.c
+++ b/hw/timer/m48t59.c
@@ -43,6 +43,13 @@
* PPC platform there is also a nvram lock function.
*/
+typedef struct M48txxInfo {
+ const char *isa_name;
+ const char *sysbus_name;
+ uint32_t model; /* 2 = m48t02, 8 = m48t08, 59 = m48t59 */
+ uint32_t size;
+} M48txxInfo;
+
/*
* Chipset docs:
* http://www.st.com/stonline/products/literature/ds/2410/m48t02.pdf
@@ -54,7 +61,6 @@ struct M48t59State {
/* Hardware parameters */
qemu_irq IRQ;
MemoryRegion iomem;
- uint32_t io_base;
uint32_t size;
/* RTC management */
time_t time_offset;
@@ -78,12 +84,39 @@ typedef struct M48t59ISAState {
MemoryRegion io;
} M48t59ISAState;
+typedef struct M48txxISADeviceClass {
+ ISADeviceClass parent_class;
+ M48txxInfo info;
+} M48txxISADeviceClass;
+
typedef struct M48t59SysBusState {
SysBusDevice busdev;
M48t59State state;
MemoryRegion io;
} M48t59SysBusState;
+typedef struct M48txxSysBusDeviceClass {
+ SysBusDeviceClass parent_class;
+ M48txxInfo info;
+} M48txxSysBusDeviceClass;
+
+static M48txxInfo m48txx_info[] = {
+ {
+ .sysbus_name = "m48t02",
+ .model = 2,
+ .size = 0x800,
+ },{
+ .sysbus_name = "m48t08",
+ .model = 8,
+ .size = 0x2000,
+ },{
+ .isa_name = "m48t59_isa",
+ .model = 59,
+ .size = 0x2000,
+ }
+};
+
+
/* Fake timer functions */
/* Alarm management */
@@ -640,25 +673,34 @@ M48t59State *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
SysBusDevice *s;
M48t59SysBusState *d;
M48t59State *state;
+ int i;
- dev = qdev_create(NULL, "m48t59");
- qdev_prop_set_uint32(dev, "model", model);
- qdev_prop_set_uint32(dev, "size", size);
- qdev_prop_set_uint32(dev, "io_base", io_base);
- qdev_init_nofail(dev);
- s = SYS_BUS_DEVICE(dev);
- d = FROM_SYSBUS(M48t59SysBusState, s);
- state = &d->state;
- sysbus_connect_irq(s, 0, IRQ);
- memory_region_init_io(&d->io, &m48t59_io_ops, state, "m48t59", 4);
- if (io_base != 0) {
- memory_region_add_subregion(get_system_io(), io_base, &d->io);
- }
- if (mem_base != 0) {
- sysbus_mmio_map(s, 0, mem_base);
+ for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) {
+ if (!m48txx_info[i].sysbus_name ||
+ m48txx_info[i].size != size ||
+ m48txx_info[i].model != model) {
+ continue;
+ }
+
+ dev = qdev_create(NULL, m48txx_info[i].sysbus_name);
+ qdev_init_nofail(dev);
+ s = SYS_BUS_DEVICE(dev);
+ d = FROM_SYSBUS(M48t59SysBusState, s);
+ state = &d->state;
+ sysbus_connect_irq(s, 0, IRQ);
+ memory_region_init_io(&d->io, &m48t59_io_ops, state, "m48t59", 4);
+ if (io_base != 0) {
+ memory_region_add_subregion(get_system_io(), io_base, &d->io);
+ }
+ if (mem_base != 0) {
+ sysbus_mmio_map(s, 0, mem_base);
+ }
+
+ return state;
}
- return state;
+ assert(false);
+ return NULL;
}
M48t59State *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
@@ -667,16 +709,27 @@ M48t59State *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
M48t59ISAState *d;
ISADevice *dev;
M48t59State *s;
+ int i;
+
+ assert(io_base == 0x74);
+
+ for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) {
+ if (!m48txx_info[i].isa_name ||
+ m48txx_info[i].size != size ||
+ m48txx_info[i].model != model) {
+ continue;
+ }
- dev = isa_create(bus, "m48t59_isa");
- qdev_prop_set_uint32(&dev->qdev, "model", model);
- qdev_prop_set_uint32(&dev->qdev, "size", size);
- qdev_prop_set_uint32(&dev->qdev, "io_base", io_base);
- qdev_init_nofail(&dev->qdev);
- d = DO_UPCAST(M48t59ISAState, busdev, dev);
- s = &d->state;
+ dev = isa_create(bus, m48txx_info[i].isa_name);
+ qdev_init_nofail(&dev->qdev);
+ d = DO_UPCAST(M48t59ISAState, busdev, dev);
+ s = &d->state;
- return s;
+ return s;
+ }
+
+ assert(false);
+ return NULL;
}
static void m48t59_init_common(M48t59State *s)
@@ -693,24 +746,32 @@ static void m48t59_init_common(M48t59State *s)
static int m48t59_init_isa1(ISADevice *dev)
{
+ ISADeviceClass *ic = ISA_DEVICE_GET_CLASS(dev);
+ M48txxISADeviceClass *u = container_of(ic, M48txxISADeviceClass,
+ parent_class);
M48t59ISAState *d = DO_UPCAST(M48t59ISAState, busdev, dev);
M48t59State *s = &d->state;
+ s->model = u->info.model;
+ s->size = u->info.size;
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);
- }
+ isa_register_ioport(dev, &d->io, 0x74);
return 0;
}
static int m48t59_init1(SysBusDevice *dev)
{
+ SysBusDeviceClass *k = SYS_BUS_DEVICE_GET_CLASS(dev);
+ M48txxSysBusDeviceClass *u = container_of(k, M48txxSysBusDeviceClass,
+ parent_class);
M48t59SysBusState *d = FROM_SYSBUS(M48t59SysBusState, dev);
M48t59State *s = &d->state;
+ s->model = u->info.model;
+ s->size = u->info.size;
sysbus_init_irq(dev, &s->IRQ);
memory_region_init_io(&s->iomem, &nvram_ops, s, "m48t59.nvram", s->size);
@@ -720,58 +781,62 @@ static int m48t59_init1(SysBusDevice *dev)
return 0;
}
-static Property m48t59_isa_properties[] = {
- DEFINE_PROP_UINT32("size", M48t59ISAState, state.size, -1),
- DEFINE_PROP_UINT32("model", M48t59ISAState, state.model, -1),
- DEFINE_PROP_HEX32( "io_base", M48t59ISAState, state.io_base, 0),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void m48t59_init_class_isa1(ObjectClass *klass, void *data)
+static void m48t59_isa_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+ M48txxISADeviceClass *u = container_of(ic, M48txxISADeviceClass,
+ parent_class);
+ M48txxInfo *info = data;
+
ic->init = m48t59_init_isa1;
dc->no_user = 1;
dc->reset = m48t59_reset_isa;
- dc->props = m48t59_isa_properties;
+ u->info = *info;
}
-static const TypeInfo m48t59_isa_info = {
- .name = "m48t59_isa",
- .parent = TYPE_ISA_DEVICE,
- .instance_size = sizeof(M48t59ISAState),
- .class_init = m48t59_init_class_isa1,
-};
-
-static Property m48t59_properties[] = {
- DEFINE_PROP_UINT32("size", M48t59SysBusState, state.size, -1),
- DEFINE_PROP_UINT32("model", M48t59SysBusState, state.model, -1),
- DEFINE_PROP_HEX32( "io_base", M48t59SysBusState, state.io_base, 0),
- DEFINE_PROP_END_OF_LIST(),
-};
-
static void m48t59_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+ M48txxSysBusDeviceClass *u = container_of(k, M48txxSysBusDeviceClass,
+ parent_class);
+ M48txxInfo *info = data;
k->init = m48t59_init1;
dc->reset = m48t59_reset_sysbus;
- dc->props = m48t59_properties;
+ u->info = *info;
}
-static const TypeInfo m48t59_info = {
- .name = "m48t59",
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(M48t59SysBusState),
- .class_init = m48t59_class_init,
-};
-
static void m48t59_register_types(void)
{
- type_register_static(&m48t59_info);
- type_register_static(&m48t59_isa_info);
+ TypeInfo m48txx_type_info = {
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(M48t59SysBusState),
+ .class_size = sizeof(M48txxSysBusDeviceClass),
+ .class_init = m48t59_class_init,
+ };
+ TypeInfo m48txx_isa_type_info = {
+ .parent = TYPE_ISA_DEVICE,
+ .instance_size = sizeof(M48t59ISAState),
+ .class_size = sizeof(M48txxISADeviceClass),
+ .class_init = m48t59_isa_class_init,
+ };
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) {
+ if (m48txx_info[i].sysbus_name) {
+ m48txx_type_info.name = m48txx_info[i].sysbus_name;
+ m48txx_type_info.class_data = &m48txx_info[i];
+ type_register(&m48txx_type_info);
+ }
+
+ if (m48txx_info[i].isa_name) {
+ m48txx_isa_type_info.name = m48txx_info[i].isa_name;
+ m48txx_isa_type_info.class_data = &m48txx_info[i];
+ type_register(&m48txx_isa_type_info);
+ }
+ }
}
type_init(m48t59_register_types)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [RFC v2 4/7] m48t59: use DeviceState in public functions
2013-04-14 8:05 [Qemu-devel] [RFC v2 0/7] ppc/prep: add IBM RS/6000 43p machine Hervé Poussineau
` (2 preceding siblings ...)
2013-04-14 8:05 ` [Qemu-devel] [RFC v2 3/7] m48t59: register a QOM type for each nvram type we support Hervé Poussineau
@ 2013-04-14 8:05 ` Hervé Poussineau
2013-04-14 8:05 ` [Qemu-devel] [RFC v2 5/7] prep: add IBM RS/6000 7248 (43p) machine emulation Hervé Poussineau
` (2 subsequent siblings)
6 siblings, 0 replies; 14+ messages in thread
From: Hervé Poussineau @ 2013-04-14 8:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Andreas Färber, Hervé Poussineau
There is no reason to use a custom type (M48t59State) in public nvram functions.
Replace it by a DeviceState.
read/write/toggle_lock functions may later be added to some NVRAM interface.
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
hw/ppc/prep.c | 12 +++----
hw/sparc/sun4m.c | 7 ++--
hw/sparc64/sun4u.c | 6 ++--
hw/timer/m48t59.c | 79 ++++++++++++++++++++++++++++++++++-----------
include/hw/timer/m48t59.h | 14 ++++----
5 files changed, 81 insertions(+), 37 deletions(-)
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index cceab3e..8de8625 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -179,7 +179,7 @@ static const MemoryRegionOps PPC_XCSR_ops = {
/* Fake super-io ports for PREP platform (Intel 82378ZB) */
typedef struct sysctrl_t {
qemu_irq reset_irq;
- M48t59State *nvram;
+ DeviceState *nvram;
uint8_t state;
uint8_t syscontrol;
int contiguous_map;
@@ -233,12 +233,12 @@ static void PREP_io_800_writeb (void *opaque, uint32_t addr, uint32_t val)
case 0x0810:
/* Password protect 1 register */
if (sysctrl->nvram != NULL)
- m48t59_toggle_lock(sysctrl->nvram, 1);
+ m48txx_toggle_lock(sysctrl->nvram, 1);
break;
case 0x0812:
/* Password protect 2 register */
if (sysctrl->nvram != NULL)
- m48t59_toggle_lock(sysctrl->nvram, 2);
+ m48txx_toggle_lock(sysctrl->nvram, 2);
break;
case 0x0814:
/* L2 invalidate register */
@@ -443,7 +443,7 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
CPUPPCState *env = NULL;
char *filename;
nvram_t nvram;
- M48t59State *m48t59;
+ DeviceState *m48t59;
MemoryRegion *PPC_io_memory = g_new(MemoryRegion, 1);
#if 0
MemoryRegion *xcsr = g_new(MemoryRegion, 1);
@@ -646,8 +646,8 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
/* Initialise NVRAM */
nvram.opaque = m48t59;
- nvram.read_fn = &m48t59_read;
- nvram.write_fn = &m48t59_write;
+ nvram.read_fn = &m48txx_read;
+ nvram.write_fn = &m48txx_write;
PPC_NVRAM_set_params(&nvram, NVRAM_SIZE, "PREP", ram_size, ppc_boot_device,
kernel_base, kernel_size,
kernel_cmdline,
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 31beb32..7ba4576 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -167,7 +167,7 @@ static int fw_cfg_boot_set(void *opaque, const char *boot_device)
return 0;
}
-static void nvram_init(M48t59State *nvram, uint8_t *macaddr,
+static void nvram_init(DeviceState *nvram, uint8_t *macaddr,
const char *cmdline, const char *boot_devices,
ram_addr_t RAM_size, uint32_t kernel_size,
int width, int height, int depth,
@@ -211,7 +211,7 @@ static void nvram_init(M48t59State *nvram, uint8_t *macaddr,
nvram_machine_id);
for (i = 0; i < sizeof(image); i++)
- m48t59_write(nvram, i, image[i]);
+ m48txx_write(nvram, i, image[i]);
}
static DeviceState *slavio_intctl;
@@ -866,7 +866,8 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
const char *initrd_filename, const char *cpu_model)
{
unsigned int i;
- void *iommu, *espdma, *ledma, *nvram;
+ void *iommu, *espdma, *ledma;
+ DeviceState *nvram;
qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS],
espdma_irq, ledma_irq;
qemu_irq esp_reset, dma_enable;
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 0d29620..0197bfc 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -130,7 +130,7 @@ static int fw_cfg_boot_set(void *opaque, const char *boot_device)
return 0;
}
-static int sun4u_NVRAM_set_params(M48t59State *nvram, uint16_t NVRAM_size,
+static int sun4u_NVRAM_set_params(DeviceState *nvram, uint16_t NVRAM_size,
const char *arch, ram_addr_t RAM_size,
const char *boot_devices,
uint32_t kernel_image, uint32_t kernel_size,
@@ -177,7 +177,7 @@ static int sun4u_NVRAM_set_params(M48t59State *nvram, uint16_t NVRAM_size,
Sun_init_header((struct Sun_nvram *)&image[0x1fd8], macaddr, 0x80);
for (i = 0; i < sizeof(image); i++)
- m48t59_write(nvram, i, image[i]);
+ m48txx_write(nvram, i, image[i]);
return 0;
}
@@ -810,7 +810,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
const struct hwdef *hwdef)
{
SPARCCPU *cpu;
- M48t59State *nvram;
+ DeviceState *nvram;
unsigned int i;
uint64_t initrd_addr, initrd_size, kernel_addr, kernel_size, kernel_entry;
PCIBus *pci_bus, *pci_bus2, *pci_bus3;
diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c
index 29ec462..afcd5f5 100644
--- a/hw/timer/m48t59.c
+++ b/hw/timer/m48t59.c
@@ -222,9 +222,8 @@ static void set_up_watchdog(M48t59State *NVRAM, uint8_t value)
}
/* Direct access to NVRAM */
-void m48t59_write (void *opaque, uint32_t addr, uint32_t val)
+static void m48t59_write(M48t59State *NVRAM, uint32_t addr, uint32_t val)
{
- M48t59State *NVRAM = opaque;
struct tm tm;
int tmp;
@@ -392,9 +391,8 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val)
}
}
-uint32_t m48t59_read (void *opaque, uint32_t addr)
+static uint32_t m48t59_read(M48t59State *NVRAM, uint32_t addr)
{
- M48t59State *NVRAM = opaque;
struct tm tm;
uint32_t retval = 0xFF;
@@ -501,11 +499,60 @@ uint32_t m48t59_read (void *opaque, uint32_t addr)
return retval;
}
-void m48t59_toggle_lock (void *opaque, int lock)
+static M48t59State *m48txx_get_state(DeviceState *dev)
{
- M48t59State *NVRAM = opaque;
+ Object *o = OBJECT(dev);
+ Object *o2;
+ M48t59SysBusState *sysbus;
+ M48t59ISAState *isa;
+ int i;
- NVRAM->lock ^= 1 << lock;
+ for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) {
+ if (m48txx_info[i].sysbus_name) {
+ o2 = object_dynamic_cast(o, m48txx_info[i].sysbus_name);
+ if (o2) {
+ sysbus = FROM_SYSBUS(M48t59SysBusState, SYS_BUS_DEVICE(o2));
+ return &sysbus->state;
+ }
+ }
+ if (m48txx_info[i].isa_name) {
+ o2 = object_dynamic_cast(o, m48txx_info[i].isa_name);
+ if (o2) {
+ isa = FROM_SYSBUS(M48t59ISAState, ISA_DEVICE(o2));
+ return &isa->state;
+ }
+ }
+ }
+ return NULL;
+}
+
+void m48txx_write(DeviceState *dev, uint32_t addr, uint32_t val)
+{
+ M48t59State *NVRAM = m48txx_get_state(dev);
+
+ if (NVRAM) {
+ m48t59_write(NVRAM, addr, val);
+ }
+}
+
+uint32_t m48txx_read(DeviceState *dev, uint32_t addr)
+{
+ M48t59State *NVRAM = m48txx_get_state(dev);
+
+ if (NVRAM) {
+ return m48t59_read(NVRAM, addr);
+ } else {
+ return 0;
+ }
+}
+
+void m48txx_toggle_lock(DeviceState *dev, int lock)
+{
+ M48t59State *NVRAM = m48txx_get_state(dev);
+
+ if (NVRAM) {
+ NVRAM->lock ^= 1 << lock;
+ }
}
/* IO access to NVRAM */
@@ -666,7 +713,7 @@ static const MemoryRegionOps m48t59_io_ops = {
};
/* Initialisation routine */
-M48t59State *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
+DeviceState *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
uint32_t io_base, uint16_t size, int model)
{
DeviceState *dev;
@@ -696,19 +743,17 @@ M48t59State *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
sysbus_mmio_map(s, 0, mem_base);
}
- return state;
+ return dev;
}
assert(false);
return NULL;
}
-M48t59State *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
+DeviceState *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
int model)
{
- M48t59ISAState *d;
- ISADevice *dev;
- M48t59State *s;
+ DeviceState *dev;
int i;
assert(io_base == 0x74);
@@ -720,12 +765,10 @@ M48t59State *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
continue;
}
- dev = isa_create(bus, m48txx_info[i].isa_name);
- qdev_init_nofail(&dev->qdev);
- d = DO_UPCAST(M48t59ISAState, busdev, dev);
- s = &d->state;
+ dev = DEVICE(isa_create(bus, m48txx_info[i].isa_name));
+ qdev_init_nofail(dev);
- return s;
+ return dev;
}
assert(false);
diff --git a/include/hw/timer/m48t59.h b/include/hw/timer/m48t59.h
index 59337fa..7ec4173 100644
--- a/include/hw/timer/m48t59.h
+++ b/include/hw/timer/m48t59.h
@@ -2,8 +2,8 @@
#define NVRAM_H
/* NVRAM helpers */
-typedef uint32_t (*nvram_read_t)(void *private, uint32_t addr);
-typedef void (*nvram_write_t)(void *private, uint32_t addr, uint32_t val);
+typedef uint32_t (*nvram_read_t)(DeviceState *dev, uint32_t addr);
+typedef void (*nvram_write_t)(DeviceState *dev, uint32_t addr, uint32_t val);
typedef struct nvram_t {
void *opaque;
nvram_read_t read_fn;
@@ -23,12 +23,12 @@ int PPC_NVRAM_set_params (nvram_t *nvram, uint16_t NVRAM_size,
int width, int height, int depth);
typedef struct M48t59State M48t59State;
-void m48t59_write (void *private, uint32_t addr, uint32_t val);
-uint32_t m48t59_read (void *private, uint32_t addr);
-void m48t59_toggle_lock (void *private, int lock);
-M48t59State *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
+void m48txx_write(DeviceState *dev, uint32_t addr, uint32_t val);
+uint32_t m48txx_read(DeviceState *dev, uint32_t addr);
+void m48txx_toggle_lock(DeviceState *dev, int lock);
+DeviceState *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
int type);
-M48t59State *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
+DeviceState *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
uint32_t io_base, uint16_t size, int type);
#endif /* !NVRAM_H */
--
1.7.10.4
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [RFC v2 5/7] prep: add IBM RS/6000 7248 (43p) machine emulation
2013-04-14 8:05 [Qemu-devel] [RFC v2 0/7] ppc/prep: add IBM RS/6000 43p machine Hervé Poussineau
` (3 preceding siblings ...)
2013-04-14 8:05 ` [Qemu-devel] [RFC v2 4/7] m48t59: use DeviceState in public functions Hervé Poussineau
@ 2013-04-14 8:05 ` Hervé Poussineau
2013-04-14 8:05 ` [Qemu-devel] [RFC v2 6/7] prep: QOM'ify System I/O Hervé Poussineau
2013-04-14 8:06 ` [Qemu-devel] [RFC v2 7/7] m48t59: hack(?) to make it work on IBM 43p Hervé Poussineau
6 siblings, 0 replies; 14+ messages in thread
From: Hervé Poussineau @ 2013-04-14 8:05 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
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
docs/ibm_43p.cfg | 37 ++++++++++
hw/ppc/prep.c | 211 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 248 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..0950dd7
--- /dev/null
+++ b/docs/ibm_43p.cfg
@@ -0,0 +1,37 @@
+############################################################################
+#
+# 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 = "m48t59_isa"
+
+[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 8de8625..09aea2a 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -30,6 +30,7 @@
#include "sysemu/sysemu.h"
#include "hw/isa/isa.h"
#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
#include "hw/pci/pci_host.h"
#include "hw/ppc/ppc.h"
#include "hw/boards.h"
@@ -41,6 +42,9 @@
#include "sysemu/blockdev.h"
#include "sysemu/arch_init.h"
#include "exec/address-spaces.h"
+#include "elf.h"
+#include "hw/nvram/fw_cfg.h"
+#include "hw/sparc/firmware_abi.h"
//#define HARD_DEBUG_PPC_IO
//#define DEBUG_PPC_IO
@@ -50,6 +54,8 @@
#define MAX_IDE_BUS 2
+#define CFG_ADDR 0xf0000510
+
#define BIOS_SIZE (1024 * 1024)
#define BIOS_FILENAME "ppc_rom.bin"
#define KERNEL_LOAD_ADDR 0x01000000
@@ -413,6 +419,61 @@ static const MemoryRegionOps PPC_prep_io_ops = {
#define NVRAM_SIZE 0x2000
+static int fw_cfg_boot_set(void *opaque, const char *boot_device)
+{
+ fw_cfg_add_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]);
+ return 0;
+}
+
+#define DEF_SYSTEM_SIZE 0xc10
+
+static void nvram_init(DeviceState *nvram)
+{
+ uint8_t image[NVRAM_SIZE];
+ struct OpenBIOS_nvpart_v1 *part_header;
+ uint32_t start, end;
+ unsigned int i;
+
+ memset(image, '\0', sizeof(image));
+
+ start = 0;
+
+ /* OpenBIOS nvram variables */
+ /* Variable partition */
+ part_header = (struct OpenBIOS_nvpart_v1 *)&image[start];
+ part_header->signature = OPENBIOS_PART_SYSTEM;
+ pstrcpy(part_header->name, sizeof(part_header->name), "system");
+
+ end = start + sizeof(struct OpenBIOS_nvpart_v1);
+ for (i = 0; i < nb_prom_envs; i++) {
+ end = OpenBIOS_set_var(image, end, prom_envs[i]);
+ }
+
+ /* End marker */
+ image[end++] = '\0';
+
+ end = start + ((end - start + 15) & ~15);
+ /* XXX: OpenBIOS is not able to grow up a partition. Leave some space for
+ new variables. */
+ if (end < DEF_SYSTEM_SIZE) {
+ end = DEF_SYSTEM_SIZE;
+ }
+ OpenBIOS_finish_partition(part_header, end - start);
+
+ /* free partition */
+ start = end;
+ part_header = (struct OpenBIOS_nvpart_v1 *)&image[start];
+ part_header->signature = OPENBIOS_PART_FREE;
+ pstrcpy(part_header->name, sizeof(part_header->name), "free");
+
+ end = NVRAM_SIZE;
+ OpenBIOS_finish_partition(part_header, end - start);
+
+ for (i = 0; i < sizeof(image); i++) {
+ m48txx_write(nvram, i, image[i]);
+ }
+}
+
static void cpu_request_exit(void *opaque, int irq, int level)
{
CPUPPCState *env = cpu_single_env;
@@ -663,6 +724,148 @@ 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 int prep_init_m48t59(DeviceState *dev, void *opaque)
+{
+ if (object_dynamic_cast(OBJECT(dev), "m48t59_isa")) {
+ /* if nvram is initialized, we expect first word to be not null */
+ if (m48txx_read(dev, 0) == 0 && m48txx_read(dev, 1) == 0) {
+ nvram_init(dev);
+ }
+ }
+ return 0;
+}
+
+static void ppc_prep_init_m48t59(void *opaque)
+{
+ BusState *bus = opaque;
+ qbus_walk_children(bus, prep_init_m48t59, NULL, NULL);
+}
+
+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;
+ void *fw_cfg;
+
+ /* 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);
+ qdev_prop_set_uint32(DEVICE(pcihost), "elf-machine", ELF_MACHINE);
+ qdev_prop_set_bit(DEVICE(pcihost), "x-auto-conf", 1);
+ if (bios_name == NULL) {
+ bios_name = "openbios-ppc.elf";
+ }
+ 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);
+
+ /* Initialize NVRAM (if empty) at next reboot */
+ qemu_register_reset(ppc_prep_init_m48t59, BUS(isa_bus));
+
+ /* Prepare firmware configuration for OpenBIOS */
+ fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
+ fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
+ fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
+ fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)args->ram_size);
+ fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, ARCH_PREP);
+ fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, 0);
+ fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, 0);
+ fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
+ fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, 0);
+ fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, 0);
+ fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, '\0');
+
+ fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_WIDTH, graphic_width);
+ fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_HEIGHT, graphic_height);
+ fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_DEPTH, graphic_depth);
+
+ fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled());
+ if (kvm_enabled()) {
+#ifdef CONFIG_KVM
+ uint8_t *hypercall;
+
+ fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, kvmppc_get_tbfreq());
+ hypercall = g_malloc(16);
+ kvmppc_get_hypercall(env, hypercall, 16);
+ fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16);
+ fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid());
+#endif
+ } else {
+ fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, get_ticks_per_sec());
+ }
+ qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
+}
+
static QEMUMachine prep_machine = {
.name = "prep",
.desc = "PowerPC PREP platform",
@@ -671,9 +874,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] 14+ messages in thread
* [Qemu-devel] [RFC v2 6/7] prep: QOM'ify System I/O
2013-04-14 8:05 [Qemu-devel] [RFC v2 0/7] ppc/prep: add IBM RS/6000 43p machine Hervé Poussineau
` (4 preceding siblings ...)
2013-04-14 8:05 ` [Qemu-devel] [RFC v2 5/7] prep: add IBM RS/6000 7248 (43p) machine emulation Hervé Poussineau
@ 2013-04-14 8:05 ` Hervé Poussineau
2013-04-14 8:06 ` [Qemu-devel] [RFC v2 7/7] m48t59: hack(?) to make it work on IBM 43p Hervé Poussineau
6 siblings, 0 replies; 14+ messages in thread
From: Hervé Poussineau @ 2013-04-14 8:05 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 0950dd7..a265c01 100644
--- a/docs/ibm_43p.cfg
+++ b/docs/ibm_43p.cfg
@@ -35,3 +35,8 @@
iobase = "0x170"
iobase2 = "0x376"
irq = "15"
+
+[device]
+ driver = "prep-systemio800"
+ ibm-planar-id = "0xc0"
+ equipment = "0xff"
diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
index be00d1d..cd1eb1b 100644
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -9,6 +9,7 @@ obj-y += ppc405_boards.o ppc4xx_devs.o ppc405_uc.o ppc440_bamboo.o
obj-y += ppc4xx_pci.o
# PReP
obj-y += prep.o
+obj-y += prep_systemio.o
# OldWorld PowerMac
obj-y += 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..502338d
--- /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/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 8b0ad9c..ba5b71a 100644
--- a/trace-events
+++ b/trace-events
@@ -761,6 +761,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] 14+ messages in thread
* [Qemu-devel] [RFC v2 7/7] m48t59: hack(?) to make it work on IBM 43p
2013-04-14 8:05 [Qemu-devel] [RFC v2 0/7] ppc/prep: add IBM RS/6000 43p machine Hervé Poussineau
` (5 preceding siblings ...)
2013-04-14 8:05 ` [Qemu-devel] [RFC v2 6/7] prep: QOM'ify System I/O Hervé Poussineau
@ 2013-04-14 8:06 ` Hervé Poussineau
6 siblings, 0 replies; 14+ messages in thread
From: Hervé Poussineau @ 2013-04-14 8:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Andreas Färber, Hervé Poussineau
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
hw/timer/m48t59.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c
index afcd5f5..4956cd7 100644
--- a/hw/timer/m48t59.c
+++ b/hw/timer/m48t59.c
@@ -571,6 +571,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;
@@ -586,6 +587,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] 14+ messages in thread
* Re: [Qemu-devel] [RFC v2 3/7] m48t59: register a QOM type for each nvram type we support
2013-04-14 8:05 ` [Qemu-devel] [RFC v2 3/7] m48t59: register a QOM type for each nvram type we support Hervé Poussineau
@ 2013-04-14 21:41 ` Artyom Tarasenko
2013-04-15 5:52 ` Hervé Poussineau
2013-04-20 9:34 ` Blue Swirl
0 siblings, 2 replies; 14+ messages in thread
From: Artyom Tarasenko @ 2013-04-14 21:41 UTC (permalink / raw)
To: Hervé Poussineau; +Cc: Blue Swirl, Andreas Färber, qemu-devel
On Sun, Apr 14, 2013 at 10:05 AM, Hervé Poussineau <hpoussin@reactos.org> wrote:
> As m48t59 devices can only be created with m48t59_init() or m48t59_init_isa(),
> we know exactly which nvram types are required. Register only those three
> types.
> Remove .model and .size properties as they can be infered from nvram name.
> Remove .io_base ISA address port as m48t59_init_isa() is always called with ioport 0x74.
While this it indeed how it's currently called, this is wrong for the
sun4u emulation.
The isa (ebus) variant of the sun4u m48t59_init_isa() should be called
with a mem_base, not io_base.
Do you think it should be implemented as another device type?
> Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
> ---
> hw/timer/m48t59.c | 187 ++++++++++++++++++++++++++++++++++++-----------------
> 1 file changed, 126 insertions(+), 61 deletions(-)
>
> diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c
> index 41022f2..29ec462 100644
> --- a/hw/timer/m48t59.c
> +++ b/hw/timer/m48t59.c
> @@ -43,6 +43,13 @@
> * PPC platform there is also a nvram lock function.
> */
>
> +typedef struct M48txxInfo {
> + const char *isa_name;
> + const char *sysbus_name;
> + uint32_t model; /* 2 = m48t02, 8 = m48t08, 59 = m48t59 */
> + uint32_t size;
> +} M48txxInfo;
> +
> /*
> * Chipset docs:
> * http://www.st.com/stonline/products/literature/ds/2410/m48t02.pdf
> @@ -54,7 +61,6 @@ struct M48t59State {
> /* Hardware parameters */
> qemu_irq IRQ;
> MemoryRegion iomem;
> - uint32_t io_base;
> uint32_t size;
> /* RTC management */
> time_t time_offset;
> @@ -78,12 +84,39 @@ typedef struct M48t59ISAState {
> MemoryRegion io;
> } M48t59ISAState;
>
> +typedef struct M48txxISADeviceClass {
> + ISADeviceClass parent_class;
> + M48txxInfo info;
> +} M48txxISADeviceClass;
> +
> typedef struct M48t59SysBusState {
> SysBusDevice busdev;
> M48t59State state;
> MemoryRegion io;
> } M48t59SysBusState;
>
> +typedef struct M48txxSysBusDeviceClass {
> + SysBusDeviceClass parent_class;
> + M48txxInfo info;
> +} M48txxSysBusDeviceClass;
> +
> +static M48txxInfo m48txx_info[] = {
> + {
> + .sysbus_name = "m48t02",
> + .model = 2,
> + .size = 0x800,
> + },{
> + .sysbus_name = "m48t08",
> + .model = 8,
> + .size = 0x2000,
> + },{
> + .isa_name = "m48t59_isa",
> + .model = 59,
> + .size = 0x2000,
> + }
> +};
> +
> +
> /* Fake timer functions */
>
> /* Alarm management */
> @@ -640,25 +673,34 @@ M48t59State *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
> SysBusDevice *s;
> M48t59SysBusState *d;
> M48t59State *state;
> + int i;
>
> - dev = qdev_create(NULL, "m48t59");
> - qdev_prop_set_uint32(dev, "model", model);
> - qdev_prop_set_uint32(dev, "size", size);
> - qdev_prop_set_uint32(dev, "io_base", io_base);
> - qdev_init_nofail(dev);
> - s = SYS_BUS_DEVICE(dev);
> - d = FROM_SYSBUS(M48t59SysBusState, s);
> - state = &d->state;
> - sysbus_connect_irq(s, 0, IRQ);
> - memory_region_init_io(&d->io, &m48t59_io_ops, state, "m48t59", 4);
> - if (io_base != 0) {
> - memory_region_add_subregion(get_system_io(), io_base, &d->io);
> - }
> - if (mem_base != 0) {
> - sysbus_mmio_map(s, 0, mem_base);
> + for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) {
> + if (!m48txx_info[i].sysbus_name ||
> + m48txx_info[i].size != size ||
> + m48txx_info[i].model != model) {
> + continue;
> + }
> +
> + dev = qdev_create(NULL, m48txx_info[i].sysbus_name);
> + qdev_init_nofail(dev);
> + s = SYS_BUS_DEVICE(dev);
> + d = FROM_SYSBUS(M48t59SysBusState, s);
> + state = &d->state;
> + sysbus_connect_irq(s, 0, IRQ);
> + memory_region_init_io(&d->io, &m48t59_io_ops, state, "m48t59", 4);
> + if (io_base != 0) {
> + memory_region_add_subregion(get_system_io(), io_base, &d->io);
> + }
> + if (mem_base != 0) {
> + sysbus_mmio_map(s, 0, mem_base);
> + }
> +
> + return state;
> }
>
> - return state;
> + assert(false);
> + return NULL;
> }
>
> M48t59State *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
> @@ -667,16 +709,27 @@ M48t59State *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
> M48t59ISAState *d;
> ISADevice *dev;
> M48t59State *s;
> + int i;
> +
> + assert(io_base == 0x74);
> +
> + for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) {
> + if (!m48txx_info[i].isa_name ||
> + m48txx_info[i].size != size ||
> + m48txx_info[i].model != model) {
> + continue;
> + }
>
> - dev = isa_create(bus, "m48t59_isa");
> - qdev_prop_set_uint32(&dev->qdev, "model", model);
> - qdev_prop_set_uint32(&dev->qdev, "size", size);
> - qdev_prop_set_uint32(&dev->qdev, "io_base", io_base);
> - qdev_init_nofail(&dev->qdev);
> - d = DO_UPCAST(M48t59ISAState, busdev, dev);
> - s = &d->state;
> + dev = isa_create(bus, m48txx_info[i].isa_name);
> + qdev_init_nofail(&dev->qdev);
> + d = DO_UPCAST(M48t59ISAState, busdev, dev);
> + s = &d->state;
>
> - return s;
> + return s;
> + }
> +
> + assert(false);
> + return NULL;
> }
>
> static void m48t59_init_common(M48t59State *s)
> @@ -693,24 +746,32 @@ static void m48t59_init_common(M48t59State *s)
>
> static int m48t59_init_isa1(ISADevice *dev)
> {
> + ISADeviceClass *ic = ISA_DEVICE_GET_CLASS(dev);
> + M48txxISADeviceClass *u = container_of(ic, M48txxISADeviceClass,
> + parent_class);
> M48t59ISAState *d = DO_UPCAST(M48t59ISAState, busdev, dev);
> M48t59State *s = &d->state;
>
> + s->model = u->info.model;
> + s->size = u->info.size;
> 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);
> - }
> + isa_register_ioport(dev, &d->io, 0x74);
>
> return 0;
> }
>
> static int m48t59_init1(SysBusDevice *dev)
> {
> + SysBusDeviceClass *k = SYS_BUS_DEVICE_GET_CLASS(dev);
> + M48txxSysBusDeviceClass *u = container_of(k, M48txxSysBusDeviceClass,
> + parent_class);
> M48t59SysBusState *d = FROM_SYSBUS(M48t59SysBusState, dev);
> M48t59State *s = &d->state;
>
> + s->model = u->info.model;
> + s->size = u->info.size;
> sysbus_init_irq(dev, &s->IRQ);
>
> memory_region_init_io(&s->iomem, &nvram_ops, s, "m48t59.nvram", s->size);
> @@ -720,58 +781,62 @@ static int m48t59_init1(SysBusDevice *dev)
> return 0;
> }
>
> -static Property m48t59_isa_properties[] = {
> - DEFINE_PROP_UINT32("size", M48t59ISAState, state.size, -1),
> - DEFINE_PROP_UINT32("model", M48t59ISAState, state.model, -1),
> - DEFINE_PROP_HEX32( "io_base", M48t59ISAState, state.io_base, 0),
> - DEFINE_PROP_END_OF_LIST(),
> -};
> -
> -static void m48t59_init_class_isa1(ObjectClass *klass, void *data)
> +static void m48t59_isa_class_init(ObjectClass *klass, void *data)
> {
> DeviceClass *dc = DEVICE_CLASS(klass);
> ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
> + M48txxISADeviceClass *u = container_of(ic, M48txxISADeviceClass,
> + parent_class);
> + M48txxInfo *info = data;
> +
> ic->init = m48t59_init_isa1;
> dc->no_user = 1;
> dc->reset = m48t59_reset_isa;
> - dc->props = m48t59_isa_properties;
> + u->info = *info;
> }
>
> -static const TypeInfo m48t59_isa_info = {
> - .name = "m48t59_isa",
> - .parent = TYPE_ISA_DEVICE,
> - .instance_size = sizeof(M48t59ISAState),
> - .class_init = m48t59_init_class_isa1,
> -};
> -
> -static Property m48t59_properties[] = {
> - DEFINE_PROP_UINT32("size", M48t59SysBusState, state.size, -1),
> - DEFINE_PROP_UINT32("model", M48t59SysBusState, state.model, -1),
> - DEFINE_PROP_HEX32( "io_base", M48t59SysBusState, state.io_base, 0),
> - DEFINE_PROP_END_OF_LIST(),
> -};
> -
> static void m48t59_class_init(ObjectClass *klass, void *data)
> {
> DeviceClass *dc = DEVICE_CLASS(klass);
> SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
> + M48txxSysBusDeviceClass *u = container_of(k, M48txxSysBusDeviceClass,
> + parent_class);
> + M48txxInfo *info = data;
>
> k->init = m48t59_init1;
> dc->reset = m48t59_reset_sysbus;
> - dc->props = m48t59_properties;
> + u->info = *info;
> }
>
> -static const TypeInfo m48t59_info = {
> - .name = "m48t59",
> - .parent = TYPE_SYS_BUS_DEVICE,
> - .instance_size = sizeof(M48t59SysBusState),
> - .class_init = m48t59_class_init,
> -};
> -
> static void m48t59_register_types(void)
> {
> - type_register_static(&m48t59_info);
> - type_register_static(&m48t59_isa_info);
> + TypeInfo m48txx_type_info = {
> + .parent = TYPE_SYS_BUS_DEVICE,
> + .instance_size = sizeof(M48t59SysBusState),
> + .class_size = sizeof(M48txxSysBusDeviceClass),
> + .class_init = m48t59_class_init,
> + };
> + TypeInfo m48txx_isa_type_info = {
> + .parent = TYPE_ISA_DEVICE,
> + .instance_size = sizeof(M48t59ISAState),
> + .class_size = sizeof(M48txxISADeviceClass),
> + .class_init = m48t59_isa_class_init,
> + };
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) {
> + if (m48txx_info[i].sysbus_name) {
> + m48txx_type_info.name = m48txx_info[i].sysbus_name;
> + m48txx_type_info.class_data = &m48txx_info[i];
> + type_register(&m48txx_type_info);
> + }
> +
> + if (m48txx_info[i].isa_name) {
> + m48txx_isa_type_info.name = m48txx_info[i].isa_name;
> + m48txx_isa_type_info.class_data = &m48txx_info[i];
> + type_register(&m48txx_isa_type_info);
> + }
> + }
> }
>
> type_init(m48t59_register_types)
> --
> 1.7.10.4
>
>
--
Regards,
Artyom Tarasenko
linux/sparc and solaris/sparc under qemu blog:
http://tyom.blogspot.com/search/label/qemu
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [RFC v2 3/7] m48t59: register a QOM type for each nvram type we support
2013-04-14 21:41 ` Artyom Tarasenko
@ 2013-04-15 5:52 ` Hervé Poussineau
2013-04-20 9:34 ` Blue Swirl
1 sibling, 0 replies; 14+ messages in thread
From: Hervé Poussineau @ 2013-04-15 5:52 UTC (permalink / raw)
To: Artyom Tarasenko; +Cc: Blue Swirl, Andreas Färber, qemu-devel
Artyom Tarasenko a écrit :
> On Sun, Apr 14, 2013 at 10:05 AM, Hervé Poussineau <hpoussin@reactos.org> wrote:
>> As m48t59 devices can only be created with m48t59_init() or m48t59_init_isa(),
>> we know exactly which nvram types are required. Register only those three
>> types.
>> Remove .model and .size properties as they can be infered from nvram name.
>> Remove .io_base ISA address port as m48t59_init_isa() is always called with ioport 0x74.
>
> While this it indeed how it's currently called, this is wrong for the
> sun4u emulation.
> The isa (ebus) variant of the sun4u m48t59_init_isa() should be called
> with a mem_base, not io_base.
> Do you think it should be implemented as another device type?
>
I don't know EBUS, but I think it should be implemented either as a
completly new bus (1), or as a child of the ISA bus type (2).
For 1), you'll need to add a another device type to be plugged on EBUS.
For 2), I let experts answer :)
In all cases, maybe the m48t59_init() wrapper is what you need? You can
already give him a membase.
Otherwise, you can maybe use sysbus_create_simple("m48t59"), get the
resulting MemoryRegion from the device, and add it in whatever MemoryRegion.
Hervé
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [RFC v2 3/7] m48t59: register a QOM type for each nvram type we support
2013-04-14 21:41 ` Artyom Tarasenko
2013-04-15 5:52 ` Hervé Poussineau
@ 2013-04-20 9:34 ` Blue Swirl
2013-04-20 9:56 ` Artyom Tarasenko
1 sibling, 1 reply; 14+ messages in thread
From: Blue Swirl @ 2013-04-20 9:34 UTC (permalink / raw)
To: Artyom Tarasenko; +Cc: Andreas Färber, Hervé Poussineau, qemu-devel
On Sun, Apr 14, 2013 at 9:41 PM, Artyom Tarasenko <atar4qemu@gmail.com> wrote:
> On Sun, Apr 14, 2013 at 10:05 AM, Hervé Poussineau <hpoussin@reactos.org> wrote:
>> As m48t59 devices can only be created with m48t59_init() or m48t59_init_isa(),
>> we know exactly which nvram types are required. Register only those three
>> types.
>> Remove .model and .size properties as they can be infered from nvram name.
>> Remove .io_base ISA address port as m48t59_init_isa() is always called with ioport 0x74.
>
> While this it indeed how it's currently called, this is wrong for the
> sun4u emulation.
> The isa (ebus) variant of the sun4u m48t59_init_isa() should be called
> with a mem_base, not io_base.
Why? I don't see much difference between EBUS and ISA and with the
memory API, the difference between PIO and MMIO is almost nonexistent
anyway.
But it should be possible to change the base to match real HW, whatever it is:
http://git.kernel.org/cgit/linux/kernel/git/davem/prtconfs.git/tree/ultra5#n273
So NACK for the original patch.
> Do you think it should be implemented as another device type?
>
>
>> Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
>> ---
>> hw/timer/m48t59.c | 187 ++++++++++++++++++++++++++++++++++++-----------------
>> 1 file changed, 126 insertions(+), 61 deletions(-)
>>
>> diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c
>> index 41022f2..29ec462 100644
>> --- a/hw/timer/m48t59.c
>> +++ b/hw/timer/m48t59.c
>> @@ -43,6 +43,13 @@
>> * PPC platform there is also a nvram lock function.
>> */
>>
>> +typedef struct M48txxInfo {
>> + const char *isa_name;
>> + const char *sysbus_name;
>> + uint32_t model; /* 2 = m48t02, 8 = m48t08, 59 = m48t59 */
>> + uint32_t size;
>> +} M48txxInfo;
>> +
>> /*
>> * Chipset docs:
>> * http://www.st.com/stonline/products/literature/ds/2410/m48t02.pdf
>> @@ -54,7 +61,6 @@ struct M48t59State {
>> /* Hardware parameters */
>> qemu_irq IRQ;
>> MemoryRegion iomem;
>> - uint32_t io_base;
>> uint32_t size;
>> /* RTC management */
>> time_t time_offset;
>> @@ -78,12 +84,39 @@ typedef struct M48t59ISAState {
>> MemoryRegion io;
>> } M48t59ISAState;
>>
>> +typedef struct M48txxISADeviceClass {
>> + ISADeviceClass parent_class;
>> + M48txxInfo info;
>> +} M48txxISADeviceClass;
>> +
>> typedef struct M48t59SysBusState {
>> SysBusDevice busdev;
>> M48t59State state;
>> MemoryRegion io;
>> } M48t59SysBusState;
>>
>> +typedef struct M48txxSysBusDeviceClass {
>> + SysBusDeviceClass parent_class;
>> + M48txxInfo info;
>> +} M48txxSysBusDeviceClass;
>> +
>> +static M48txxInfo m48txx_info[] = {
>> + {
>> + .sysbus_name = "m48t02",
>> + .model = 2,
>> + .size = 0x800,
>> + },{
>> + .sysbus_name = "m48t08",
>> + .model = 8,
>> + .size = 0x2000,
>> + },{
>> + .isa_name = "m48t59_isa",
>> + .model = 59,
>> + .size = 0x2000,
>> + }
>> +};
>> +
>> +
>> /* Fake timer functions */
>>
>> /* Alarm management */
>> @@ -640,25 +673,34 @@ M48t59State *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
>> SysBusDevice *s;
>> M48t59SysBusState *d;
>> M48t59State *state;
>> + int i;
>>
>> - dev = qdev_create(NULL, "m48t59");
>> - qdev_prop_set_uint32(dev, "model", model);
>> - qdev_prop_set_uint32(dev, "size", size);
>> - qdev_prop_set_uint32(dev, "io_base", io_base);
>> - qdev_init_nofail(dev);
>> - s = SYS_BUS_DEVICE(dev);
>> - d = FROM_SYSBUS(M48t59SysBusState, s);
>> - state = &d->state;
>> - sysbus_connect_irq(s, 0, IRQ);
>> - memory_region_init_io(&d->io, &m48t59_io_ops, state, "m48t59", 4);
>> - if (io_base != 0) {
>> - memory_region_add_subregion(get_system_io(), io_base, &d->io);
>> - }
>> - if (mem_base != 0) {
>> - sysbus_mmio_map(s, 0, mem_base);
>> + for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) {
>> + if (!m48txx_info[i].sysbus_name ||
>> + m48txx_info[i].size != size ||
>> + m48txx_info[i].model != model) {
>> + continue;
>> + }
>> +
>> + dev = qdev_create(NULL, m48txx_info[i].sysbus_name);
>> + qdev_init_nofail(dev);
>> + s = SYS_BUS_DEVICE(dev);
>> + d = FROM_SYSBUS(M48t59SysBusState, s);
>> + state = &d->state;
>> + sysbus_connect_irq(s, 0, IRQ);
>> + memory_region_init_io(&d->io, &m48t59_io_ops, state, "m48t59", 4);
>> + if (io_base != 0) {
>> + memory_region_add_subregion(get_system_io(), io_base, &d->io);
>> + }
>> + if (mem_base != 0) {
>> + sysbus_mmio_map(s, 0, mem_base);
>> + }
>> +
>> + return state;
>> }
>>
>> - return state;
>> + assert(false);
>> + return NULL;
>> }
>>
>> M48t59State *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
>> @@ -667,16 +709,27 @@ M48t59State *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
>> M48t59ISAState *d;
>> ISADevice *dev;
>> M48t59State *s;
>> + int i;
>> +
>> + assert(io_base == 0x74);
>> +
>> + for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) {
>> + if (!m48txx_info[i].isa_name ||
>> + m48txx_info[i].size != size ||
>> + m48txx_info[i].model != model) {
>> + continue;
>> + }
>>
>> - dev = isa_create(bus, "m48t59_isa");
>> - qdev_prop_set_uint32(&dev->qdev, "model", model);
>> - qdev_prop_set_uint32(&dev->qdev, "size", size);
>> - qdev_prop_set_uint32(&dev->qdev, "io_base", io_base);
>> - qdev_init_nofail(&dev->qdev);
>> - d = DO_UPCAST(M48t59ISAState, busdev, dev);
>> - s = &d->state;
>> + dev = isa_create(bus, m48txx_info[i].isa_name);
>> + qdev_init_nofail(&dev->qdev);
>> + d = DO_UPCAST(M48t59ISAState, busdev, dev);
>> + s = &d->state;
>>
>> - return s;
>> + return s;
>> + }
>> +
>> + assert(false);
>> + return NULL;
>> }
>>
>> static void m48t59_init_common(M48t59State *s)
>> @@ -693,24 +746,32 @@ static void m48t59_init_common(M48t59State *s)
>>
>> static int m48t59_init_isa1(ISADevice *dev)
>> {
>> + ISADeviceClass *ic = ISA_DEVICE_GET_CLASS(dev);
>> + M48txxISADeviceClass *u = container_of(ic, M48txxISADeviceClass,
>> + parent_class);
>> M48t59ISAState *d = DO_UPCAST(M48t59ISAState, busdev, dev);
>> M48t59State *s = &d->state;
>>
>> + s->model = u->info.model;
>> + s->size = u->info.size;
>> 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);
>> - }
>> + isa_register_ioport(dev, &d->io, 0x74);
>>
>> return 0;
>> }
>>
>> static int m48t59_init1(SysBusDevice *dev)
>> {
>> + SysBusDeviceClass *k = SYS_BUS_DEVICE_GET_CLASS(dev);
>> + M48txxSysBusDeviceClass *u = container_of(k, M48txxSysBusDeviceClass,
>> + parent_class);
>> M48t59SysBusState *d = FROM_SYSBUS(M48t59SysBusState, dev);
>> M48t59State *s = &d->state;
>>
>> + s->model = u->info.model;
>> + s->size = u->info.size;
>> sysbus_init_irq(dev, &s->IRQ);
>>
>> memory_region_init_io(&s->iomem, &nvram_ops, s, "m48t59.nvram", s->size);
>> @@ -720,58 +781,62 @@ static int m48t59_init1(SysBusDevice *dev)
>> return 0;
>> }
>>
>> -static Property m48t59_isa_properties[] = {
>> - DEFINE_PROP_UINT32("size", M48t59ISAState, state.size, -1),
>> - DEFINE_PROP_UINT32("model", M48t59ISAState, state.model, -1),
>> - DEFINE_PROP_HEX32( "io_base", M48t59ISAState, state.io_base, 0),
>> - DEFINE_PROP_END_OF_LIST(),
>> -};
>> -
>> -static void m48t59_init_class_isa1(ObjectClass *klass, void *data)
>> +static void m48t59_isa_class_init(ObjectClass *klass, void *data)
>> {
>> DeviceClass *dc = DEVICE_CLASS(klass);
>> ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
>> + M48txxISADeviceClass *u = container_of(ic, M48txxISADeviceClass,
>> + parent_class);
>> + M48txxInfo *info = data;
>> +
>> ic->init = m48t59_init_isa1;
>> dc->no_user = 1;
>> dc->reset = m48t59_reset_isa;
>> - dc->props = m48t59_isa_properties;
>> + u->info = *info;
>> }
>>
>> -static const TypeInfo m48t59_isa_info = {
>> - .name = "m48t59_isa",
>> - .parent = TYPE_ISA_DEVICE,
>> - .instance_size = sizeof(M48t59ISAState),
>> - .class_init = m48t59_init_class_isa1,
>> -};
>> -
>> -static Property m48t59_properties[] = {
>> - DEFINE_PROP_UINT32("size", M48t59SysBusState, state.size, -1),
>> - DEFINE_PROP_UINT32("model", M48t59SysBusState, state.model, -1),
>> - DEFINE_PROP_HEX32( "io_base", M48t59SysBusState, state.io_base, 0),
>> - DEFINE_PROP_END_OF_LIST(),
>> -};
>> -
>> static void m48t59_class_init(ObjectClass *klass, void *data)
>> {
>> DeviceClass *dc = DEVICE_CLASS(klass);
>> SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
>> + M48txxSysBusDeviceClass *u = container_of(k, M48txxSysBusDeviceClass,
>> + parent_class);
>> + M48txxInfo *info = data;
>>
>> k->init = m48t59_init1;
>> dc->reset = m48t59_reset_sysbus;
>> - dc->props = m48t59_properties;
>> + u->info = *info;
>> }
>>
>> -static const TypeInfo m48t59_info = {
>> - .name = "m48t59",
>> - .parent = TYPE_SYS_BUS_DEVICE,
>> - .instance_size = sizeof(M48t59SysBusState),
>> - .class_init = m48t59_class_init,
>> -};
>> -
>> static void m48t59_register_types(void)
>> {
>> - type_register_static(&m48t59_info);
>> - type_register_static(&m48t59_isa_info);
>> + TypeInfo m48txx_type_info = {
>> + .parent = TYPE_SYS_BUS_DEVICE,
>> + .instance_size = sizeof(M48t59SysBusState),
>> + .class_size = sizeof(M48txxSysBusDeviceClass),
>> + .class_init = m48t59_class_init,
>> + };
>> + TypeInfo m48txx_isa_type_info = {
>> + .parent = TYPE_ISA_DEVICE,
>> + .instance_size = sizeof(M48t59ISAState),
>> + .class_size = sizeof(M48txxISADeviceClass),
>> + .class_init = m48t59_isa_class_init,
>> + };
>> + int i;
>> +
>> + for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) {
>> + if (m48txx_info[i].sysbus_name) {
>> + m48txx_type_info.name = m48txx_info[i].sysbus_name;
>> + m48txx_type_info.class_data = &m48txx_info[i];
>> + type_register(&m48txx_type_info);
>> + }
>> +
>> + if (m48txx_info[i].isa_name) {
>> + m48txx_isa_type_info.name = m48txx_info[i].isa_name;
>> + m48txx_isa_type_info.class_data = &m48txx_info[i];
>> + type_register(&m48txx_isa_type_info);
>> + }
>> + }
>> }
>>
>> type_init(m48t59_register_types)
>> --
>> 1.7.10.4
>>
>>
>
>
>
> --
> Regards,
> Artyom Tarasenko
>
> linux/sparc and solaris/sparc under qemu blog:
> http://tyom.blogspot.com/search/label/qemu
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [RFC v2 3/7] m48t59: register a QOM type for each nvram type we support
2013-04-20 9:34 ` Blue Swirl
@ 2013-04-20 9:56 ` Artyom Tarasenko
2013-04-20 10:39 ` Blue Swirl
0 siblings, 1 reply; 14+ messages in thread
From: Artyom Tarasenko @ 2013-04-20 9:56 UTC (permalink / raw)
To: Blue Swirl; +Cc: Andreas Färber, Hervé Poussineau, qemu-devel
On Sat, Apr 20, 2013 at 11:34 AM, Blue Swirl <blauwirbel@gmail.com> wrote:
> On Sun, Apr 14, 2013 at 9:41 PM, Artyom Tarasenko <atar4qemu@gmail.com> wrote:
>> On Sun, Apr 14, 2013 at 10:05 AM, Hervé Poussineau <hpoussin@reactos.org> wrote:
>>> As m48t59 devices can only be created with m48t59_init() or m48t59_init_isa(),
>>> we know exactly which nvram types are required. Register only those three
>>> types.
>>> Remove .model and .size properties as they can be infered from nvram name.
>>> Remove .io_base ISA address port as m48t59_init_isa() is always called with ioport 0x74.
>>
>> While this it indeed how it's currently called, this is wrong for the
>> sun4u emulation.
>> The isa (ebus) variant of the sun4u m48t59_init_isa() should be called
>> with a mem_base, not io_base.
>
> Why? I don't see much difference between EBUS and ISA and with the
> memory API, the difference between PIO and MMIO is almost nonexistent
> anyway.
Can you elaborate? Do you mean we just need to change the io_base?
> But it should be possible to change the base to match real HW, whatever it is:
> http://git.kernel.org/cgit/linux/kernel/git/davem/prtconfs.git/tree/ultra5#n273
Yes, I know where it is supposed to be, I'm just asking how to achieve
this best with our current tooling.
> So NACK for the original patch.
>
>> Do you think it should be implemented as another device type?
>>
>>
>>> Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
>>> ---
>>> hw/timer/m48t59.c | 187 ++++++++++++++++++++++++++++++++++++-----------------
>>> 1 file changed, 126 insertions(+), 61 deletions(-)
>>>
>>> diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c
>>> index 41022f2..29ec462 100644
>>> --- a/hw/timer/m48t59.c
>>> +++ b/hw/timer/m48t59.c
>>> @@ -43,6 +43,13 @@
>>> * PPC platform there is also a nvram lock function.
>>> */
>>>
>>> +typedef struct M48txxInfo {
>>> + const char *isa_name;
>>> + const char *sysbus_name;
>>> + uint32_t model; /* 2 = m48t02, 8 = m48t08, 59 = m48t59 */
>>> + uint32_t size;
>>> +} M48txxInfo;
>>> +
>>> /*
>>> * Chipset docs:
>>> * http://www.st.com/stonline/products/literature/ds/2410/m48t02.pdf
>>> @@ -54,7 +61,6 @@ struct M48t59State {
>>> /* Hardware parameters */
>>> qemu_irq IRQ;
>>> MemoryRegion iomem;
>>> - uint32_t io_base;
>>> uint32_t size;
>>> /* RTC management */
>>> time_t time_offset;
>>> @@ -78,12 +84,39 @@ typedef struct M48t59ISAState {
>>> MemoryRegion io;
>>> } M48t59ISAState;
>>>
>>> +typedef struct M48txxISADeviceClass {
>>> + ISADeviceClass parent_class;
>>> + M48txxInfo info;
>>> +} M48txxISADeviceClass;
>>> +
>>> typedef struct M48t59SysBusState {
>>> SysBusDevice busdev;
>>> M48t59State state;
>>> MemoryRegion io;
>>> } M48t59SysBusState;
>>>
>>> +typedef struct M48txxSysBusDeviceClass {
>>> + SysBusDeviceClass parent_class;
>>> + M48txxInfo info;
>>> +} M48txxSysBusDeviceClass;
>>> +
>>> +static M48txxInfo m48txx_info[] = {
>>> + {
>>> + .sysbus_name = "m48t02",
>>> + .model = 2,
>>> + .size = 0x800,
>>> + },{
>>> + .sysbus_name = "m48t08",
>>> + .model = 8,
>>> + .size = 0x2000,
>>> + },{
>>> + .isa_name = "m48t59_isa",
>>> + .model = 59,
>>> + .size = 0x2000,
>>> + }
>>> +};
>>> +
>>> +
>>> /* Fake timer functions */
>>>
>>> /* Alarm management */
>>> @@ -640,25 +673,34 @@ M48t59State *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
>>> SysBusDevice *s;
>>> M48t59SysBusState *d;
>>> M48t59State *state;
>>> + int i;
>>>
>>> - dev = qdev_create(NULL, "m48t59");
>>> - qdev_prop_set_uint32(dev, "model", model);
>>> - qdev_prop_set_uint32(dev, "size", size);
>>> - qdev_prop_set_uint32(dev, "io_base", io_base);
>>> - qdev_init_nofail(dev);
>>> - s = SYS_BUS_DEVICE(dev);
>>> - d = FROM_SYSBUS(M48t59SysBusState, s);
>>> - state = &d->state;
>>> - sysbus_connect_irq(s, 0, IRQ);
>>> - memory_region_init_io(&d->io, &m48t59_io_ops, state, "m48t59", 4);
>>> - if (io_base != 0) {
>>> - memory_region_add_subregion(get_system_io(), io_base, &d->io);
>>> - }
>>> - if (mem_base != 0) {
>>> - sysbus_mmio_map(s, 0, mem_base);
>>> + for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) {
>>> + if (!m48txx_info[i].sysbus_name ||
>>> + m48txx_info[i].size != size ||
>>> + m48txx_info[i].model != model) {
>>> + continue;
>>> + }
>>> +
>>> + dev = qdev_create(NULL, m48txx_info[i].sysbus_name);
>>> + qdev_init_nofail(dev);
>>> + s = SYS_BUS_DEVICE(dev);
>>> + d = FROM_SYSBUS(M48t59SysBusState, s);
>>> + state = &d->state;
>>> + sysbus_connect_irq(s, 0, IRQ);
>>> + memory_region_init_io(&d->io, &m48t59_io_ops, state, "m48t59", 4);
>>> + if (io_base != 0) {
>>> + memory_region_add_subregion(get_system_io(), io_base, &d->io);
>>> + }
>>> + if (mem_base != 0) {
>>> + sysbus_mmio_map(s, 0, mem_base);
>>> + }
>>> +
>>> + return state;
>>> }
>>>
>>> - return state;
>>> + assert(false);
>>> + return NULL;
>>> }
>>>
>>> M48t59State *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
>>> @@ -667,16 +709,27 @@ M48t59State *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
>>> M48t59ISAState *d;
>>> ISADevice *dev;
>>> M48t59State *s;
>>> + int i;
>>> +
>>> + assert(io_base == 0x74);
>>> +
>>> + for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) {
>>> + if (!m48txx_info[i].isa_name ||
>>> + m48txx_info[i].size != size ||
>>> + m48txx_info[i].model != model) {
>>> + continue;
>>> + }
>>>
>>> - dev = isa_create(bus, "m48t59_isa");
>>> - qdev_prop_set_uint32(&dev->qdev, "model", model);
>>> - qdev_prop_set_uint32(&dev->qdev, "size", size);
>>> - qdev_prop_set_uint32(&dev->qdev, "io_base", io_base);
>>> - qdev_init_nofail(&dev->qdev);
>>> - d = DO_UPCAST(M48t59ISAState, busdev, dev);
>>> - s = &d->state;
>>> + dev = isa_create(bus, m48txx_info[i].isa_name);
>>> + qdev_init_nofail(&dev->qdev);
>>> + d = DO_UPCAST(M48t59ISAState, busdev, dev);
>>> + s = &d->state;
>>>
>>> - return s;
>>> + return s;
>>> + }
>>> +
>>> + assert(false);
>>> + return NULL;
>>> }
>>>
>>> static void m48t59_init_common(M48t59State *s)
>>> @@ -693,24 +746,32 @@ static void m48t59_init_common(M48t59State *s)
>>>
>>> static int m48t59_init_isa1(ISADevice *dev)
>>> {
>>> + ISADeviceClass *ic = ISA_DEVICE_GET_CLASS(dev);
>>> + M48txxISADeviceClass *u = container_of(ic, M48txxISADeviceClass,
>>> + parent_class);
>>> M48t59ISAState *d = DO_UPCAST(M48t59ISAState, busdev, dev);
>>> M48t59State *s = &d->state;
>>>
>>> + s->model = u->info.model;
>>> + s->size = u->info.size;
>>> 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);
>>> - }
>>> + isa_register_ioport(dev, &d->io, 0x74);
>>>
>>> return 0;
>>> }
>>>
>>> static int m48t59_init1(SysBusDevice *dev)
>>> {
>>> + SysBusDeviceClass *k = SYS_BUS_DEVICE_GET_CLASS(dev);
>>> + M48txxSysBusDeviceClass *u = container_of(k, M48txxSysBusDeviceClass,
>>> + parent_class);
>>> M48t59SysBusState *d = FROM_SYSBUS(M48t59SysBusState, dev);
>>> M48t59State *s = &d->state;
>>>
>>> + s->model = u->info.model;
>>> + s->size = u->info.size;
>>> sysbus_init_irq(dev, &s->IRQ);
>>>
>>> memory_region_init_io(&s->iomem, &nvram_ops, s, "m48t59.nvram", s->size);
>>> @@ -720,58 +781,62 @@ static int m48t59_init1(SysBusDevice *dev)
>>> return 0;
>>> }
>>>
>>> -static Property m48t59_isa_properties[] = {
>>> - DEFINE_PROP_UINT32("size", M48t59ISAState, state.size, -1),
>>> - DEFINE_PROP_UINT32("model", M48t59ISAState, state.model, -1),
>>> - DEFINE_PROP_HEX32( "io_base", M48t59ISAState, state.io_base, 0),
>>> - DEFINE_PROP_END_OF_LIST(),
>>> -};
>>> -
>>> -static void m48t59_init_class_isa1(ObjectClass *klass, void *data)
>>> +static void m48t59_isa_class_init(ObjectClass *klass, void *data)
>>> {
>>> DeviceClass *dc = DEVICE_CLASS(klass);
>>> ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
>>> + M48txxISADeviceClass *u = container_of(ic, M48txxISADeviceClass,
>>> + parent_class);
>>> + M48txxInfo *info = data;
>>> +
>>> ic->init = m48t59_init_isa1;
>>> dc->no_user = 1;
>>> dc->reset = m48t59_reset_isa;
>>> - dc->props = m48t59_isa_properties;
>>> + u->info = *info;
>>> }
>>>
>>> -static const TypeInfo m48t59_isa_info = {
>>> - .name = "m48t59_isa",
>>> - .parent = TYPE_ISA_DEVICE,
>>> - .instance_size = sizeof(M48t59ISAState),
>>> - .class_init = m48t59_init_class_isa1,
>>> -};
>>> -
>>> -static Property m48t59_properties[] = {
>>> - DEFINE_PROP_UINT32("size", M48t59SysBusState, state.size, -1),
>>> - DEFINE_PROP_UINT32("model", M48t59SysBusState, state.model, -1),
>>> - DEFINE_PROP_HEX32( "io_base", M48t59SysBusState, state.io_base, 0),
>>> - DEFINE_PROP_END_OF_LIST(),
>>> -};
>>> -
>>> static void m48t59_class_init(ObjectClass *klass, void *data)
>>> {
>>> DeviceClass *dc = DEVICE_CLASS(klass);
>>> SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
>>> + M48txxSysBusDeviceClass *u = container_of(k, M48txxSysBusDeviceClass,
>>> + parent_class);
>>> + M48txxInfo *info = data;
>>>
>>> k->init = m48t59_init1;
>>> dc->reset = m48t59_reset_sysbus;
>>> - dc->props = m48t59_properties;
>>> + u->info = *info;
>>> }
>>>
>>> -static const TypeInfo m48t59_info = {
>>> - .name = "m48t59",
>>> - .parent = TYPE_SYS_BUS_DEVICE,
>>> - .instance_size = sizeof(M48t59SysBusState),
>>> - .class_init = m48t59_class_init,
>>> -};
>>> -
>>> static void m48t59_register_types(void)
>>> {
>>> - type_register_static(&m48t59_info);
>>> - type_register_static(&m48t59_isa_info);
>>> + TypeInfo m48txx_type_info = {
>>> + .parent = TYPE_SYS_BUS_DEVICE,
>>> + .instance_size = sizeof(M48t59SysBusState),
>>> + .class_size = sizeof(M48txxSysBusDeviceClass),
>>> + .class_init = m48t59_class_init,
>>> + };
>>> + TypeInfo m48txx_isa_type_info = {
>>> + .parent = TYPE_ISA_DEVICE,
>>> + .instance_size = sizeof(M48t59ISAState),
>>> + .class_size = sizeof(M48txxISADeviceClass),
>>> + .class_init = m48t59_isa_class_init,
>>> + };
>>> + int i;
>>> +
>>> + for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) {
>>> + if (m48txx_info[i].sysbus_name) {
>>> + m48txx_type_info.name = m48txx_info[i].sysbus_name;
>>> + m48txx_type_info.class_data = &m48txx_info[i];
>>> + type_register(&m48txx_type_info);
>>> + }
>>> +
>>> + if (m48txx_info[i].isa_name) {
>>> + m48txx_isa_type_info.name = m48txx_info[i].isa_name;
>>> + m48txx_isa_type_info.class_data = &m48txx_info[i];
>>> + type_register(&m48txx_isa_type_info);
>>> + }
>>> + }
>>> }
>>>
>>> type_init(m48t59_register_types)
>>> --
>>> 1.7.10.4
>>>
>>>
>>
>>
>>
>> --
>> Regards,
>> Artyom Tarasenko
>>
>> linux/sparc and solaris/sparc under qemu blog:
>> http://tyom.blogspot.com/search/label/qemu
--
Regards,
Artyom Tarasenko
linux/sparc and solaris/sparc under qemu blog:
http://tyom.blogspot.com/search/label/qemu
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [RFC v2 3/7] m48t59: register a QOM type for each nvram type we support
2013-04-20 9:56 ` Artyom Tarasenko
@ 2013-04-20 10:39 ` Blue Swirl
2013-04-27 6:55 ` Artyom Tarasenko
0 siblings, 1 reply; 14+ messages in thread
From: Blue Swirl @ 2013-04-20 10:39 UTC (permalink / raw)
To: Artyom Tarasenko; +Cc: Andreas Färber, Hervé Poussineau, qemu-devel
On Sat, Apr 20, 2013 at 9:56 AM, Artyom Tarasenko <atar4qemu@gmail.com> wrote:
> On Sat, Apr 20, 2013 at 11:34 AM, Blue Swirl <blauwirbel@gmail.com> wrote:
>> On Sun, Apr 14, 2013 at 9:41 PM, Artyom Tarasenko <atar4qemu@gmail.com> wrote:
>>> On Sun, Apr 14, 2013 at 10:05 AM, Hervé Poussineau <hpoussin@reactos.org> wrote:
>>>> As m48t59 devices can only be created with m48t59_init() or m48t59_init_isa(),
>>>> we know exactly which nvram types are required. Register only those three
>>>> types.
>>>> Remove .model and .size properties as they can be infered from nvram name.
>>>> Remove .io_base ISA address port as m48t59_init_isa() is always called with ioport 0x74.
>>>
>>> While this it indeed how it's currently called, this is wrong for the
>>> sun4u emulation.
>>> The isa (ebus) variant of the sun4u m48t59_init_isa() should be called
>>> with a mem_base, not io_base.
>>
>> Why? I don't see much difference between EBUS and ISA and with the
>> memory API, the difference between PIO and MMIO is almost nonexistent
>> anyway.
>
> Can you elaborate? Do you mean we just need to change the io_base?
Why wouldn't that work?
>> But it should be possible to change the base to match real HW, whatever it is:
>> http://git.kernel.org/cgit/linux/kernel/git/davem/prtconfs.git/tree/ultra5#n273
>
> Yes, I know where it is supposed to be, I'm just asking how to achieve
> this best with our current tooling.
>
>> So NACK for the original patch.
>>
>>> Do you think it should be implemented as another device type?
>>>
>>>
>>>> Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
>>>> ---
>>>> hw/timer/m48t59.c | 187 ++++++++++++++++++++++++++++++++++++-----------------
>>>> 1 file changed, 126 insertions(+), 61 deletions(-)
>>>>
>>>> diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c
>>>> index 41022f2..29ec462 100644
>>>> --- a/hw/timer/m48t59.c
>>>> +++ b/hw/timer/m48t59.c
>>>> @@ -43,6 +43,13 @@
>>>> * PPC platform there is also a nvram lock function.
>>>> */
>>>>
>>>> +typedef struct M48txxInfo {
>>>> + const char *isa_name;
>>>> + const char *sysbus_name;
>>>> + uint32_t model; /* 2 = m48t02, 8 = m48t08, 59 = m48t59 */
>>>> + uint32_t size;
>>>> +} M48txxInfo;
>>>> +
>>>> /*
>>>> * Chipset docs:
>>>> * http://www.st.com/stonline/products/literature/ds/2410/m48t02.pdf
>>>> @@ -54,7 +61,6 @@ struct M48t59State {
>>>> /* Hardware parameters */
>>>> qemu_irq IRQ;
>>>> MemoryRegion iomem;
>>>> - uint32_t io_base;
>>>> uint32_t size;
>>>> /* RTC management */
>>>> time_t time_offset;
>>>> @@ -78,12 +84,39 @@ typedef struct M48t59ISAState {
>>>> MemoryRegion io;
>>>> } M48t59ISAState;
>>>>
>>>> +typedef struct M48txxISADeviceClass {
>>>> + ISADeviceClass parent_class;
>>>> + M48txxInfo info;
>>>> +} M48txxISADeviceClass;
>>>> +
>>>> typedef struct M48t59SysBusState {
>>>> SysBusDevice busdev;
>>>> M48t59State state;
>>>> MemoryRegion io;
>>>> } M48t59SysBusState;
>>>>
>>>> +typedef struct M48txxSysBusDeviceClass {
>>>> + SysBusDeviceClass parent_class;
>>>> + M48txxInfo info;
>>>> +} M48txxSysBusDeviceClass;
>>>> +
>>>> +static M48txxInfo m48txx_info[] = {
>>>> + {
>>>> + .sysbus_name = "m48t02",
>>>> + .model = 2,
>>>> + .size = 0x800,
>>>> + },{
>>>> + .sysbus_name = "m48t08",
>>>> + .model = 8,
>>>> + .size = 0x2000,
>>>> + },{
>>>> + .isa_name = "m48t59_isa",
>>>> + .model = 59,
>>>> + .size = 0x2000,
>>>> + }
>>>> +};
>>>> +
>>>> +
>>>> /* Fake timer functions */
>>>>
>>>> /* Alarm management */
>>>> @@ -640,25 +673,34 @@ M48t59State *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
>>>> SysBusDevice *s;
>>>> M48t59SysBusState *d;
>>>> M48t59State *state;
>>>> + int i;
>>>>
>>>> - dev = qdev_create(NULL, "m48t59");
>>>> - qdev_prop_set_uint32(dev, "model", model);
>>>> - qdev_prop_set_uint32(dev, "size", size);
>>>> - qdev_prop_set_uint32(dev, "io_base", io_base);
>>>> - qdev_init_nofail(dev);
>>>> - s = SYS_BUS_DEVICE(dev);
>>>> - d = FROM_SYSBUS(M48t59SysBusState, s);
>>>> - state = &d->state;
>>>> - sysbus_connect_irq(s, 0, IRQ);
>>>> - memory_region_init_io(&d->io, &m48t59_io_ops, state, "m48t59", 4);
>>>> - if (io_base != 0) {
>>>> - memory_region_add_subregion(get_system_io(), io_base, &d->io);
>>>> - }
>>>> - if (mem_base != 0) {
>>>> - sysbus_mmio_map(s, 0, mem_base);
>>>> + for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) {
>>>> + if (!m48txx_info[i].sysbus_name ||
>>>> + m48txx_info[i].size != size ||
>>>> + m48txx_info[i].model != model) {
>>>> + continue;
>>>> + }
>>>> +
>>>> + dev = qdev_create(NULL, m48txx_info[i].sysbus_name);
>>>> + qdev_init_nofail(dev);
>>>> + s = SYS_BUS_DEVICE(dev);
>>>> + d = FROM_SYSBUS(M48t59SysBusState, s);
>>>> + state = &d->state;
>>>> + sysbus_connect_irq(s, 0, IRQ);
>>>> + memory_region_init_io(&d->io, &m48t59_io_ops, state, "m48t59", 4);
>>>> + if (io_base != 0) {
>>>> + memory_region_add_subregion(get_system_io(), io_base, &d->io);
>>>> + }
>>>> + if (mem_base != 0) {
>>>> + sysbus_mmio_map(s, 0, mem_base);
>>>> + }
>>>> +
>>>> + return state;
>>>> }
>>>>
>>>> - return state;
>>>> + assert(false);
>>>> + return NULL;
>>>> }
>>>>
>>>> M48t59State *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
>>>> @@ -667,16 +709,27 @@ M48t59State *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
>>>> M48t59ISAState *d;
>>>> ISADevice *dev;
>>>> M48t59State *s;
>>>> + int i;
>>>> +
>>>> + assert(io_base == 0x74);
>>>> +
>>>> + for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) {
>>>> + if (!m48txx_info[i].isa_name ||
>>>> + m48txx_info[i].size != size ||
>>>> + m48txx_info[i].model != model) {
>>>> + continue;
>>>> + }
>>>>
>>>> - dev = isa_create(bus, "m48t59_isa");
>>>> - qdev_prop_set_uint32(&dev->qdev, "model", model);
>>>> - qdev_prop_set_uint32(&dev->qdev, "size", size);
>>>> - qdev_prop_set_uint32(&dev->qdev, "io_base", io_base);
>>>> - qdev_init_nofail(&dev->qdev);
>>>> - d = DO_UPCAST(M48t59ISAState, busdev, dev);
>>>> - s = &d->state;
>>>> + dev = isa_create(bus, m48txx_info[i].isa_name);
>>>> + qdev_init_nofail(&dev->qdev);
>>>> + d = DO_UPCAST(M48t59ISAState, busdev, dev);
>>>> + s = &d->state;
>>>>
>>>> - return s;
>>>> + return s;
>>>> + }
>>>> +
>>>> + assert(false);
>>>> + return NULL;
>>>> }
>>>>
>>>> static void m48t59_init_common(M48t59State *s)
>>>> @@ -693,24 +746,32 @@ static void m48t59_init_common(M48t59State *s)
>>>>
>>>> static int m48t59_init_isa1(ISADevice *dev)
>>>> {
>>>> + ISADeviceClass *ic = ISA_DEVICE_GET_CLASS(dev);
>>>> + M48txxISADeviceClass *u = container_of(ic, M48txxISADeviceClass,
>>>> + parent_class);
>>>> M48t59ISAState *d = DO_UPCAST(M48t59ISAState, busdev, dev);
>>>> M48t59State *s = &d->state;
>>>>
>>>> + s->model = u->info.model;
>>>> + s->size = u->info.size;
>>>> 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);
>>>> - }
>>>> + isa_register_ioport(dev, &d->io, 0x74);
>>>>
>>>> return 0;
>>>> }
>>>>
>>>> static int m48t59_init1(SysBusDevice *dev)
>>>> {
>>>> + SysBusDeviceClass *k = SYS_BUS_DEVICE_GET_CLASS(dev);
>>>> + M48txxSysBusDeviceClass *u = container_of(k, M48txxSysBusDeviceClass,
>>>> + parent_class);
>>>> M48t59SysBusState *d = FROM_SYSBUS(M48t59SysBusState, dev);
>>>> M48t59State *s = &d->state;
>>>>
>>>> + s->model = u->info.model;
>>>> + s->size = u->info.size;
>>>> sysbus_init_irq(dev, &s->IRQ);
>>>>
>>>> memory_region_init_io(&s->iomem, &nvram_ops, s, "m48t59.nvram", s->size);
>>>> @@ -720,58 +781,62 @@ static int m48t59_init1(SysBusDevice *dev)
>>>> return 0;
>>>> }
>>>>
>>>> -static Property m48t59_isa_properties[] = {
>>>> - DEFINE_PROP_UINT32("size", M48t59ISAState, state.size, -1),
>>>> - DEFINE_PROP_UINT32("model", M48t59ISAState, state.model, -1),
>>>> - DEFINE_PROP_HEX32( "io_base", M48t59ISAState, state.io_base, 0),
>>>> - DEFINE_PROP_END_OF_LIST(),
>>>> -};
>>>> -
>>>> -static void m48t59_init_class_isa1(ObjectClass *klass, void *data)
>>>> +static void m48t59_isa_class_init(ObjectClass *klass, void *data)
>>>> {
>>>> DeviceClass *dc = DEVICE_CLASS(klass);
>>>> ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
>>>> + M48txxISADeviceClass *u = container_of(ic, M48txxISADeviceClass,
>>>> + parent_class);
>>>> + M48txxInfo *info = data;
>>>> +
>>>> ic->init = m48t59_init_isa1;
>>>> dc->no_user = 1;
>>>> dc->reset = m48t59_reset_isa;
>>>> - dc->props = m48t59_isa_properties;
>>>> + u->info = *info;
>>>> }
>>>>
>>>> -static const TypeInfo m48t59_isa_info = {
>>>> - .name = "m48t59_isa",
>>>> - .parent = TYPE_ISA_DEVICE,
>>>> - .instance_size = sizeof(M48t59ISAState),
>>>> - .class_init = m48t59_init_class_isa1,
>>>> -};
>>>> -
>>>> -static Property m48t59_properties[] = {
>>>> - DEFINE_PROP_UINT32("size", M48t59SysBusState, state.size, -1),
>>>> - DEFINE_PROP_UINT32("model", M48t59SysBusState, state.model, -1),
>>>> - DEFINE_PROP_HEX32( "io_base", M48t59SysBusState, state.io_base, 0),
>>>> - DEFINE_PROP_END_OF_LIST(),
>>>> -};
>>>> -
>>>> static void m48t59_class_init(ObjectClass *klass, void *data)
>>>> {
>>>> DeviceClass *dc = DEVICE_CLASS(klass);
>>>> SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
>>>> + M48txxSysBusDeviceClass *u = container_of(k, M48txxSysBusDeviceClass,
>>>> + parent_class);
>>>> + M48txxInfo *info = data;
>>>>
>>>> k->init = m48t59_init1;
>>>> dc->reset = m48t59_reset_sysbus;
>>>> - dc->props = m48t59_properties;
>>>> + u->info = *info;
>>>> }
>>>>
>>>> -static const TypeInfo m48t59_info = {
>>>> - .name = "m48t59",
>>>> - .parent = TYPE_SYS_BUS_DEVICE,
>>>> - .instance_size = sizeof(M48t59SysBusState),
>>>> - .class_init = m48t59_class_init,
>>>> -};
>>>> -
>>>> static void m48t59_register_types(void)
>>>> {
>>>> - type_register_static(&m48t59_info);
>>>> - type_register_static(&m48t59_isa_info);
>>>> + TypeInfo m48txx_type_info = {
>>>> + .parent = TYPE_SYS_BUS_DEVICE,
>>>> + .instance_size = sizeof(M48t59SysBusState),
>>>> + .class_size = sizeof(M48txxSysBusDeviceClass),
>>>> + .class_init = m48t59_class_init,
>>>> + };
>>>> + TypeInfo m48txx_isa_type_info = {
>>>> + .parent = TYPE_ISA_DEVICE,
>>>> + .instance_size = sizeof(M48t59ISAState),
>>>> + .class_size = sizeof(M48txxISADeviceClass),
>>>> + .class_init = m48t59_isa_class_init,
>>>> + };
>>>> + int i;
>>>> +
>>>> + for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) {
>>>> + if (m48txx_info[i].sysbus_name) {
>>>> + m48txx_type_info.name = m48txx_info[i].sysbus_name;
>>>> + m48txx_type_info.class_data = &m48txx_info[i];
>>>> + type_register(&m48txx_type_info);
>>>> + }
>>>> +
>>>> + if (m48txx_info[i].isa_name) {
>>>> + m48txx_isa_type_info.name = m48txx_info[i].isa_name;
>>>> + m48txx_isa_type_info.class_data = &m48txx_info[i];
>>>> + type_register(&m48txx_isa_type_info);
>>>> + }
>>>> + }
>>>> }
>>>>
>>>> type_init(m48t59_register_types)
>>>> --
>>>> 1.7.10.4
>>>>
>>>>
>>>
>>>
>>>
>>> --
>>> Regards,
>>> Artyom Tarasenko
>>>
>>> linux/sparc and solaris/sparc under qemu blog:
>>> http://tyom.blogspot.com/search/label/qemu
>
>
>
> --
> Regards,
> Artyom Tarasenko
>
> linux/sparc and solaris/sparc under qemu blog:
> http://tyom.blogspot.com/search/label/qemu
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [RFC v2 3/7] m48t59: register a QOM type for each nvram type we support
2013-04-20 10:39 ` Blue Swirl
@ 2013-04-27 6:55 ` Artyom Tarasenko
0 siblings, 0 replies; 14+ messages in thread
From: Artyom Tarasenko @ 2013-04-27 6:55 UTC (permalink / raw)
To: Blue Swirl; +Cc: Andreas Färber, Hervé Poussineau, qemu-devel
On Sat, Apr 20, 2013 at 12:39 PM, Blue Swirl <blauwirbel@gmail.com> wrote:
> On Sat, Apr 20, 2013 at 9:56 AM, Artyom Tarasenko <atar4qemu@gmail.com> wrote:
>> On Sat, Apr 20, 2013 at 11:34 AM, Blue Swirl <blauwirbel@gmail.com> wrote:
>>> On Sun, Apr 14, 2013 at 9:41 PM, Artyom Tarasenko <atar4qemu@gmail.com> wrote:
>>>> On Sun, Apr 14, 2013 at 10:05 AM, Hervé Poussineau <hpoussin@reactos.org> wrote:
>>>>> As m48t59 devices can only be created with m48t59_init() or m48t59_init_isa(),
>>>>> we know exactly which nvram types are required. Register only those three
>>>>> types.
>>>>> Remove .model and .size properties as they can be infered from nvram name.
>>>>> Remove .io_base ISA address port as m48t59_init_isa() is always called with ioport 0x74.
>>>>
>>>> While this it indeed how it's currently called, this is wrong for the
>>>> sun4u emulation.
>>>> The isa (ebus) variant of the sun4u m48t59_init_isa() should be called
>>>> with a mem_base, not io_base.
>>>
>>> Why? I don't see much difference between EBUS and ISA and with the
>>> memory API, the difference between PIO and MMIO is almost nonexistent
>>> anyway.
>>
>> Can you elaborate? Do you mean we just need to change the io_base?
>
> Why wouldn't that work?
Because the PIO variant registers just 4 ports, whereas MMIO registers
the whole device (0x2000 bytes).
The sun4u machines use a slightly different modification of the ISA Mostek chip.
It has MMIO, 1968 as a base year and no IRQ line. Since it matches our m48t08,
I'll send a patch fixing it.
>>> But it should be possible to change the base to match real HW, whatever it is:
>>> http://git.kernel.org/cgit/linux/kernel/git/davem/prtconfs.git/tree/ultra5#n273
>>
>> Yes, I know where it is supposed to be, I'm just asking how to achieve
>> this best with our current tooling.
>>
>>> So NACK for the original patch.
>>>
>>>> Do you think it should be implemented as another device type?
>>>>
>>>>
>>>>> Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
>>>>> ---
>>>>> hw/timer/m48t59.c | 187 ++++++++++++++++++++++++++++++++++++-----------------
>>>>> 1 file changed, 126 insertions(+), 61 deletions(-)
>>>>>
>>>>> diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c
>>>>> index 41022f2..29ec462 100644
>>>>> --- a/hw/timer/m48t59.c
>>>>> +++ b/hw/timer/m48t59.c
>>>>> @@ -43,6 +43,13 @@
>>>>> * PPC platform there is also a nvram lock function.
>>>>> */
>>>>>
>>>>> +typedef struct M48txxInfo {
>>>>> + const char *isa_name;
>>>>> + const char *sysbus_name;
>>>>> + uint32_t model; /* 2 = m48t02, 8 = m48t08, 59 = m48t59 */
>>>>> + uint32_t size;
>>>>> +} M48txxInfo;
>>>>> +
>>>>> /*
>>>>> * Chipset docs:
>>>>> * http://www.st.com/stonline/products/literature/ds/2410/m48t02.pdf
>>>>> @@ -54,7 +61,6 @@ struct M48t59State {
>>>>> /* Hardware parameters */
>>>>> qemu_irq IRQ;
>>>>> MemoryRegion iomem;
>>>>> - uint32_t io_base;
>>>>> uint32_t size;
>>>>> /* RTC management */
>>>>> time_t time_offset;
>>>>> @@ -78,12 +84,39 @@ typedef struct M48t59ISAState {
>>>>> MemoryRegion io;
>>>>> } M48t59ISAState;
>>>>>
>>>>> +typedef struct M48txxISADeviceClass {
>>>>> + ISADeviceClass parent_class;
>>>>> + M48txxInfo info;
>>>>> +} M48txxISADeviceClass;
>>>>> +
>>>>> typedef struct M48t59SysBusState {
>>>>> SysBusDevice busdev;
>>>>> M48t59State state;
>>>>> MemoryRegion io;
>>>>> } M48t59SysBusState;
>>>>>
>>>>> +typedef struct M48txxSysBusDeviceClass {
>>>>> + SysBusDeviceClass parent_class;
>>>>> + M48txxInfo info;
>>>>> +} M48txxSysBusDeviceClass;
>>>>> +
>>>>> +static M48txxInfo m48txx_info[] = {
>>>>> + {
>>>>> + .sysbus_name = "m48t02",
>>>>> + .model = 2,
>>>>> + .size = 0x800,
>>>>> + },{
>>>>> + .sysbus_name = "m48t08",
>>>>> + .model = 8,
>>>>> + .size = 0x2000,
>>>>> + },{
>>>>> + .isa_name = "m48t59_isa",
>>>>> + .model = 59,
>>>>> + .size = 0x2000,
>>>>> + }
>>>>> +};
>>>>> +
>>>>> +
>>>>> /* Fake timer functions */
>>>>>
>>>>> /* Alarm management */
>>>>> @@ -640,25 +673,34 @@ M48t59State *m48t59_init(qemu_irq IRQ, hwaddr mem_base,
>>>>> SysBusDevice *s;
>>>>> M48t59SysBusState *d;
>>>>> M48t59State *state;
>>>>> + int i;
>>>>>
>>>>> - dev = qdev_create(NULL, "m48t59");
>>>>> - qdev_prop_set_uint32(dev, "model", model);
>>>>> - qdev_prop_set_uint32(dev, "size", size);
>>>>> - qdev_prop_set_uint32(dev, "io_base", io_base);
>>>>> - qdev_init_nofail(dev);
>>>>> - s = SYS_BUS_DEVICE(dev);
>>>>> - d = FROM_SYSBUS(M48t59SysBusState, s);
>>>>> - state = &d->state;
>>>>> - sysbus_connect_irq(s, 0, IRQ);
>>>>> - memory_region_init_io(&d->io, &m48t59_io_ops, state, "m48t59", 4);
>>>>> - if (io_base != 0) {
>>>>> - memory_region_add_subregion(get_system_io(), io_base, &d->io);
>>>>> - }
>>>>> - if (mem_base != 0) {
>>>>> - sysbus_mmio_map(s, 0, mem_base);
>>>>> + for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) {
>>>>> + if (!m48txx_info[i].sysbus_name ||
>>>>> + m48txx_info[i].size != size ||
>>>>> + m48txx_info[i].model != model) {
>>>>> + continue;
>>>>> + }
>>>>> +
>>>>> + dev = qdev_create(NULL, m48txx_info[i].sysbus_name);
>>>>> + qdev_init_nofail(dev);
>>>>> + s = SYS_BUS_DEVICE(dev);
>>>>> + d = FROM_SYSBUS(M48t59SysBusState, s);
>>>>> + state = &d->state;
>>>>> + sysbus_connect_irq(s, 0, IRQ);
>>>>> + memory_region_init_io(&d->io, &m48t59_io_ops, state, "m48t59", 4);
>>>>> + if (io_base != 0) {
>>>>> + memory_region_add_subregion(get_system_io(), io_base, &d->io);
>>>>> + }
>>>>> + if (mem_base != 0) {
>>>>> + sysbus_mmio_map(s, 0, mem_base);
>>>>> + }
>>>>> +
>>>>> + return state;
>>>>> }
>>>>>
>>>>> - return state;
>>>>> + assert(false);
>>>>> + return NULL;
>>>>> }
>>>>>
>>>>> M48t59State *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
>>>>> @@ -667,16 +709,27 @@ M48t59State *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
>>>>> M48t59ISAState *d;
>>>>> ISADevice *dev;
>>>>> M48t59State *s;
>>>>> + int i;
>>>>> +
>>>>> + assert(io_base == 0x74);
>>>>> +
>>>>> + for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) {
>>>>> + if (!m48txx_info[i].isa_name ||
>>>>> + m48txx_info[i].size != size ||
>>>>> + m48txx_info[i].model != model) {
>>>>> + continue;
>>>>> + }
>>>>>
>>>>> - dev = isa_create(bus, "m48t59_isa");
>>>>> - qdev_prop_set_uint32(&dev->qdev, "model", model);
>>>>> - qdev_prop_set_uint32(&dev->qdev, "size", size);
>>>>> - qdev_prop_set_uint32(&dev->qdev, "io_base", io_base);
>>>>> - qdev_init_nofail(&dev->qdev);
>>>>> - d = DO_UPCAST(M48t59ISAState, busdev, dev);
>>>>> - s = &d->state;
>>>>> + dev = isa_create(bus, m48txx_info[i].isa_name);
>>>>> + qdev_init_nofail(&dev->qdev);
>>>>> + d = DO_UPCAST(M48t59ISAState, busdev, dev);
>>>>> + s = &d->state;
>>>>>
>>>>> - return s;
>>>>> + return s;
>>>>> + }
>>>>> +
>>>>> + assert(false);
>>>>> + return NULL;
>>>>> }
>>>>>
>>>>> static void m48t59_init_common(M48t59State *s)
>>>>> @@ -693,24 +746,32 @@ static void m48t59_init_common(M48t59State *s)
>>>>>
>>>>> static int m48t59_init_isa1(ISADevice *dev)
>>>>> {
>>>>> + ISADeviceClass *ic = ISA_DEVICE_GET_CLASS(dev);
>>>>> + M48txxISADeviceClass *u = container_of(ic, M48txxISADeviceClass,
>>>>> + parent_class);
>>>>> M48t59ISAState *d = DO_UPCAST(M48t59ISAState, busdev, dev);
>>>>> M48t59State *s = &d->state;
>>>>>
>>>>> + s->model = u->info.model;
>>>>> + s->size = u->info.size;
>>>>> 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);
>>>>> - }
>>>>> + isa_register_ioport(dev, &d->io, 0x74);
>>>>>
>>>>> return 0;
>>>>> }
>>>>>
>>>>> static int m48t59_init1(SysBusDevice *dev)
>>>>> {
>>>>> + SysBusDeviceClass *k = SYS_BUS_DEVICE_GET_CLASS(dev);
>>>>> + M48txxSysBusDeviceClass *u = container_of(k, M48txxSysBusDeviceClass,
>>>>> + parent_class);
>>>>> M48t59SysBusState *d = FROM_SYSBUS(M48t59SysBusState, dev);
>>>>> M48t59State *s = &d->state;
>>>>>
>>>>> + s->model = u->info.model;
>>>>> + s->size = u->info.size;
>>>>> sysbus_init_irq(dev, &s->IRQ);
>>>>>
>>>>> memory_region_init_io(&s->iomem, &nvram_ops, s, "m48t59.nvram", s->size);
>>>>> @@ -720,58 +781,62 @@ static int m48t59_init1(SysBusDevice *dev)
>>>>> return 0;
>>>>> }
>>>>>
>>>>> -static Property m48t59_isa_properties[] = {
>>>>> - DEFINE_PROP_UINT32("size", M48t59ISAState, state.size, -1),
>>>>> - DEFINE_PROP_UINT32("model", M48t59ISAState, state.model, -1),
>>>>> - DEFINE_PROP_HEX32( "io_base", M48t59ISAState, state.io_base, 0),
>>>>> - DEFINE_PROP_END_OF_LIST(),
>>>>> -};
>>>>> -
>>>>> -static void m48t59_init_class_isa1(ObjectClass *klass, void *data)
>>>>> +static void m48t59_isa_class_init(ObjectClass *klass, void *data)
>>>>> {
>>>>> DeviceClass *dc = DEVICE_CLASS(klass);
>>>>> ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
>>>>> + M48txxISADeviceClass *u = container_of(ic, M48txxISADeviceClass,
>>>>> + parent_class);
>>>>> + M48txxInfo *info = data;
>>>>> +
>>>>> ic->init = m48t59_init_isa1;
>>>>> dc->no_user = 1;
>>>>> dc->reset = m48t59_reset_isa;
>>>>> - dc->props = m48t59_isa_properties;
>>>>> + u->info = *info;
>>>>> }
>>>>>
>>>>> -static const TypeInfo m48t59_isa_info = {
>>>>> - .name = "m48t59_isa",
>>>>> - .parent = TYPE_ISA_DEVICE,
>>>>> - .instance_size = sizeof(M48t59ISAState),
>>>>> - .class_init = m48t59_init_class_isa1,
>>>>> -};
>>>>> -
>>>>> -static Property m48t59_properties[] = {
>>>>> - DEFINE_PROP_UINT32("size", M48t59SysBusState, state.size, -1),
>>>>> - DEFINE_PROP_UINT32("model", M48t59SysBusState, state.model, -1),
>>>>> - DEFINE_PROP_HEX32( "io_base", M48t59SysBusState, state.io_base, 0),
>>>>> - DEFINE_PROP_END_OF_LIST(),
>>>>> -};
>>>>> -
>>>>> static void m48t59_class_init(ObjectClass *klass, void *data)
>>>>> {
>>>>> DeviceClass *dc = DEVICE_CLASS(klass);
>>>>> SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
>>>>> + M48txxSysBusDeviceClass *u = container_of(k, M48txxSysBusDeviceClass,
>>>>> + parent_class);
>>>>> + M48txxInfo *info = data;
>>>>>
>>>>> k->init = m48t59_init1;
>>>>> dc->reset = m48t59_reset_sysbus;
>>>>> - dc->props = m48t59_properties;
>>>>> + u->info = *info;
>>>>> }
>>>>>
>>>>> -static const TypeInfo m48t59_info = {
>>>>> - .name = "m48t59",
>>>>> - .parent = TYPE_SYS_BUS_DEVICE,
>>>>> - .instance_size = sizeof(M48t59SysBusState),
>>>>> - .class_init = m48t59_class_init,
>>>>> -};
>>>>> -
>>>>> static void m48t59_register_types(void)
>>>>> {
>>>>> - type_register_static(&m48t59_info);
>>>>> - type_register_static(&m48t59_isa_info);
>>>>> + TypeInfo m48txx_type_info = {
>>>>> + .parent = TYPE_SYS_BUS_DEVICE,
>>>>> + .instance_size = sizeof(M48t59SysBusState),
>>>>> + .class_size = sizeof(M48txxSysBusDeviceClass),
>>>>> + .class_init = m48t59_class_init,
>>>>> + };
>>>>> + TypeInfo m48txx_isa_type_info = {
>>>>> + .parent = TYPE_ISA_DEVICE,
>>>>> + .instance_size = sizeof(M48t59ISAState),
>>>>> + .class_size = sizeof(M48txxISADeviceClass),
>>>>> + .class_init = m48t59_isa_class_init,
>>>>> + };
>>>>> + int i;
>>>>> +
>>>>> + for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) {
>>>>> + if (m48txx_info[i].sysbus_name) {
>>>>> + m48txx_type_info.name = m48txx_info[i].sysbus_name;
>>>>> + m48txx_type_info.class_data = &m48txx_info[i];
>>>>> + type_register(&m48txx_type_info);
>>>>> + }
>>>>> +
>>>>> + if (m48txx_info[i].isa_name) {
>>>>> + m48txx_isa_type_info.name = m48txx_info[i].isa_name;
>>>>> + m48txx_isa_type_info.class_data = &m48txx_info[i];
>>>>> + type_register(&m48txx_isa_type_info);
>>>>> + }
>>>>> + }
>>>>> }
>>>>>
>>>>> type_init(m48t59_register_types)
>>>>> --
>>>>> 1.7.10.4
>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Regards,
>>>> Artyom Tarasenko
>>>>
>>>> linux/sparc and solaris/sparc under qemu blog:
>>>> http://tyom.blogspot.com/search/label/qemu
>>
>>
>>
>> --
>> Regards,
>> Artyom Tarasenko
>>
>> linux/sparc and solaris/sparc under qemu blog:
>> http://tyom.blogspot.com/search/label/qemu
--
Regards,
Artyom Tarasenko
linux/sparc and solaris/sparc under qemu blog:
http://tyom.blogspot.com/search/label/qemu
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2013-04-27 6:56 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-04-14 8:05 [Qemu-devel] [RFC v2 0/7] ppc/prep: add IBM RS/6000 43p machine Hervé Poussineau
2013-04-14 8:05 ` [Qemu-devel] [RFC v2 1/7] pci: add MPC105 PCI host bridge emulation Hervé Poussineau
2013-04-14 8:05 ` [Qemu-devel] [RFC v2 2/7] m48t59: move ISA ports registration to QOM constructor Hervé Poussineau
2013-04-14 8:05 ` [Qemu-devel] [RFC v2 3/7] m48t59: register a QOM type for each nvram type we support Hervé Poussineau
2013-04-14 21:41 ` Artyom Tarasenko
2013-04-15 5:52 ` Hervé Poussineau
2013-04-20 9:34 ` Blue Swirl
2013-04-20 9:56 ` Artyom Tarasenko
2013-04-20 10:39 ` Blue Swirl
2013-04-27 6:55 ` Artyom Tarasenko
2013-04-14 8:05 ` [Qemu-devel] [RFC v2 4/7] m48t59: use DeviceState in public functions Hervé Poussineau
2013-04-14 8:05 ` [Qemu-devel] [RFC v2 5/7] prep: add IBM RS/6000 7248 (43p) machine emulation Hervé Poussineau
2013-04-14 8:05 ` [Qemu-devel] [RFC v2 6/7] prep: QOM'ify System I/O Hervé Poussineau
2013-04-14 8:06 ` [Qemu-devel] [RFC v2 7/7] m48t59: hack(?) to make it work on IBM 43p 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).