summaryrefslogtreecommitdiffstats
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/alpha/dp264.c2
-rw-r--r--hw/block/pflash_cfi01.c8
-rw-r--r--hw/block/pflash_cfi02.c5
-rw-r--r--hw/hppa/machine.c2
-rw-r--r--hw/i386/pc.c3
-rw-r--r--hw/i386/pc_piix.c5
-rw-r--r--hw/ide/macio.c1
-rw-r--r--hw/ide/piix.c5
-rw-r--r--hw/ide/via.c2
-rw-r--r--hw/intc/heathrow_pic.c1
-rw-r--r--hw/intc/openpic.c1
-rw-r--r--hw/isa/Kconfig9
-rw-r--r--hw/isa/lpc_ich9.c3
-rw-r--r--hw/isa/piix3.c28
-rw-r--r--hw/isa/piix4.c10
-rw-r--r--hw/isa/vt82c686.c120
-rw-r--r--hw/mips/bootloader.c28
-rw-r--r--hw/mips/boston.c14
-rw-r--r--hw/mips/fuloong2e.c48
-rw-r--r--hw/mips/malta.c147
-rw-r--r--hw/misc/macio/cuda.c1
-rw-r--r--hw/misc/macio/gpio.c1
-rw-r--r--hw/misc/macio/macio.c8
-rw-r--r--hw/misc/macio/pmu.c1
-rw-r--r--hw/net/e1000_regs.h1
-rw-r--r--hw/nvram/mac_nvram.c2
-rw-r--r--hw/pci-host/grackle.c15
-rw-r--r--hw/pci-host/uninorth.c1
-rw-r--r--hw/ppc/Kconfig2
-rw-r--r--hw/ppc/e500.c79
-rw-r--r--hw/ppc/mac.h105
-rw-r--r--hw/ppc/mac_newworld.c226
-rw-r--r--hw/ppc/mac_oldworld.c113
-rw-r--r--hw/ppc/meson.build3
-rw-r--r--hw/ppc/pegasos2.c25
-rw-r--r--hw/ppc/pnv_core.c1
-rw-r--r--hw/ppc/ppc.c17
-rw-r--r--hw/ppc/ppc440_uc.c332
-rw-r--r--hw/ppc/ppc4xx_devs.c414
-rw-r--r--hw/ppc/ppc4xx_sdram.c757
-rw-r--r--hw/ppc/prep.c2
-rw-r--r--hw/ppc/spapr_hcall.c6
-rw-r--r--hw/ppc/spapr_rtas.c2
-rw-r--r--hw/ppc/trace-events3
-rw-r--r--hw/s390x/pv.c2
-rw-r--r--hw/s390x/tod-kvm.c9
-rw-r--r--hw/sd/sdhci-internal.h20
-rw-r--r--hw/sd/sdhci.c63
-rw-r--r--hw/sparc64/sun4u.c1
-rw-r--r--hw/usb/dev-mtp.c4
-rw-r--r--hw/usb/vt82c686-uhci-pci.c4
51 files changed, 1347 insertions, 1315 deletions
diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c
index f4349eba83..c502c8c62a 100644
--- a/hw/alpha/dp264.c
+++ b/hw/alpha/dp264.c
@@ -20,8 +20,6 @@
#include "qemu/datadir.h"
#include "net/net.h"
-#define MAX_IDE_BUS 2
-
static uint64_t cpu_alpha_superpage_to_phys(void *opaque, uint64_t addr)
{
if (((addr >> 41) & 3) == 2) {
diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 0cbc2fb4cb..9c235bf66e 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -690,7 +690,7 @@ static const MemoryRegionOps pflash_cfi01_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
-static void pflash_cfi01_fill_cfi_table(PFlashCFI01 *pfl)
+static void pflash_cfi01_fill_cfi_table(PFlashCFI01 *pfl, Error **errp)
{
uint64_t blocks_per_device, sector_len_per_device, device_len;
int num_devices;
@@ -708,6 +708,10 @@ static void pflash_cfi01_fill_cfi_table(PFlashCFI01 *pfl)
sector_len_per_device = pfl->sector_len / num_devices;
}
device_len = sector_len_per_device * blocks_per_device;
+ if (!is_power_of_2(device_len)) {
+ error_setg(errp, "Device size must be a power of two.");
+ return;
+ }
/* Hardcoded CFI table */
/* Standard "QRY" string */
@@ -865,7 +869,7 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
*/
pfl->cmd = 0x00;
pfl->status = 0x80; /* WSM ready */
- pflash_cfi01_fill_cfi_table(pfl);
+ pflash_cfi01_fill_cfi_table(pfl, errp);
}
static void pflash_cfi01_system_reset(DeviceState *dev)
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 2a99b286b0..ff2fe154c1 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -880,6 +880,11 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
return;
}
+ if (!is_power_of_2(pfl->chip_len)) {
+ error_setg(errp, "Device size must be a power of two.");
+ return;
+ }
+
memory_region_init_rom_device(&pfl->orig_mem, OBJECT(pfl),
&pflash_cfi02_ops, pfl, pfl->name,
pfl->chip_len, errp);
diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index 19ea7c2c66..de1cc7ab71 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -30,8 +30,6 @@
#include "qemu/log.h"
#include "net/net.h"
-#define MAX_IDE_BUS 2
-
#define MIN_SEABIOS_HPPA_VERSION 6 /* require at least this fw version */
#define HPA_POWER_BUTTON (FIRMWARE_END - 0x10)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 3e86083db3..ef14da5094 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -47,7 +47,6 @@
#include "multiboot.h"
#include "hw/rtc/mc146818rtc.h"
#include "hw/intc/i8259.h"
-#include "hw/dma/i8257.h"
#include "hw/timer/i8254.h"
#include "hw/input/i8042.h"
#include "hw/irq.h"
@@ -1320,8 +1319,6 @@ void pc_basic_device_init(struct PCMachineState *pcms,
pcspk_init(pcms->pcspk, isa_bus, pit);
}
- i8257_dma_init(isa_bus, 0);
-
/* Super I/O */
pc_superio_init(isa_bus, create_fdctrl, pcms->i8042_enabled,
pcms->vmport != ON_OFF_AUTO_ON);
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 0b1a79c0fa..0ad0ed1603 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -26,6 +26,7 @@
#include CONFIG_DEVICES
#include "qemu/units.h"
+#include "hw/dma/i8257.h"
#include "hw/loader.h"
#include "hw/i386/x86.h"
#include "hw/i386/pc.h"
@@ -39,6 +40,7 @@
#include "hw/usb.h"
#include "net/net.h"
#include "hw/ide/pci.h"
+#include "hw/ide/piix.h"
#include "hw/irq.h"
#include "sysemu/kvm.h"
#include "hw/kvm/clock.h"
@@ -225,6 +227,7 @@ static void pc_init1(MachineState *machine,
pci_bus = NULL;
isa_bus = isa_bus_new(NULL, get_system_memory(), system_io,
&error_abort);
+ i8257_dma_init(isa_bus, 0);
pcms->hpet_enabled = false;
}
isa_bus_irqs(isa_bus, x86ms->gsi);
@@ -257,7 +260,7 @@ static void pc_init1(MachineState *machine,
if (pcmc->pci_enabled) {
PCIDevice *dev;
- dev = pci_create_simple(pci_bus, piix3_devfn + 1, "piix3-ide");
+ dev = pci_create_simple(pci_bus, piix3_devfn + 1, TYPE_PIIX3_IDE);
pci_ide_create_devs(dev);
idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0");
idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1");
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index 1c15c37ec5..e604466acb 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -24,7 +24,6 @@
*/
#include "qemu/osdep.h"
-#include "hw/ppc/mac.h"
#include "hw/ppc/mac_dbdma.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index de1f4f0efb..267dbf37db 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -36,6 +36,7 @@
#include "sysemu/blockdev.h"
#include "sysemu/dma.h"
+#include "hw/ide/piix.h"
#include "hw/ide/pci.h"
#include "trace.h"
@@ -202,7 +203,7 @@ static void piix3_ide_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo piix3_ide_info = {
- .name = "piix3-ide",
+ .name = TYPE_PIIX3_IDE,
.parent = TYPE_PCI_IDE,
.class_init = piix3_ide_class_init,
};
@@ -224,7 +225,7 @@ static void piix4_ide_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo piix4_ide_info = {
- .name = "piix4-ide",
+ .name = TYPE_PIIX4_IDE,
.parent = TYPE_PCI_IDE,
.class_init = piix4_ide_class_init,
};
diff --git a/hw/ide/via.c b/hw/ide/via.c
index 82def819c4..e1a429405d 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -230,7 +230,7 @@ static void via_ide_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo via_ide_info = {
- .name = "via-ide",
+ .name = TYPE_VIA_IDE,
.parent = TYPE_PCI_IDE,
.class_init = via_ide_class_init,
};
diff --git a/hw/intc/heathrow_pic.c b/hw/intc/heathrow_pic.c
index cb97c315da..13048a2735 100644
--- a/hw/intc/heathrow_pic.c
+++ b/hw/intc/heathrow_pic.c
@@ -24,7 +24,6 @@
*/
#include "qemu/osdep.h"
-#include "hw/ppc/mac.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
#include "hw/intc/heathrow_pic.h"
diff --git a/hw/intc/openpic.c b/hw/intc/openpic.c
index b0787e8ee7..c757adbe53 100644
--- a/hw/intc/openpic.c
+++ b/hw/intc/openpic.c
@@ -32,7 +32,6 @@
#include "qemu/osdep.h"
#include "hw/irq.h"
-#include "hw/ppc/mac.h"
#include "hw/pci/pci.h"
#include "hw/ppc/openpic.h"
#include "hw/ppc/ppc_e500.h"
diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig
index d42143a991..18b5c6bf3f 100644
--- a/hw/isa/Kconfig
+++ b/hw/isa/Kconfig
@@ -33,13 +33,20 @@ config PC87312
config PIIX3
bool
+ select I8257
select ISA_BUS
config PIIX4
bool
# For historical reasons, SuperIO devices are created in the board
# for PIIX4.
+ select ACPI_PIIX4
+ select I8254
+ select I8257
+ select I8259
+ select IDE_PIIX
select ISA_BUS
+ select MC146818RTC
select USB_UHCI
config VT82C686
@@ -53,6 +60,7 @@ config VT82C686
select I8254
select I8257
select I8259
+ select IDE_VIA
select MC146818RTC
select PARALLEL
@@ -67,6 +75,7 @@ config LPC_ICH9
bool
# For historical reasons, SuperIO devices are created in the board
# for ICH9.
+ select I8257
select ISA_BUS
select ACPI_SMBUS
select ACPI_X86_ICH
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index 4553b5925b..8694e58b21 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -34,6 +34,7 @@
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "qemu/range.h"
+#include "hw/dma/i8257.h"
#include "hw/isa/isa.h"
#include "migration/vmstate.h"
#include "hw/irq.h"
@@ -722,6 +723,8 @@ static void ich9_lpc_realize(PCIDevice *d, Error **errp)
qdev_init_gpio_out_named(dev, lpc->gsi, ICH9_GPIO_GSI, GSI_NUM_PINS);
isa_bus_irqs(isa_bus, lpc->gsi);
+
+ i8257_dma_init(isa_bus, 0);
}
static bool ich9_rst_cnt_needed(void *opaque)
diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c
index 48f9ab1096..808fd4eadf 100644
--- a/hw/isa/piix3.c
+++ b/hw/isa/piix3.c
@@ -25,12 +25,11 @@
#include "qemu/osdep.h"
#include "qemu/range.h"
#include "qapi/error.h"
+#include "hw/dma/i8257.h"
#include "hw/southbridge/piix.h"
#include "hw/irq.h"
#include "hw/isa/isa.h"
#include "hw/xen/xen.h"
-#include "sysemu/xen.h"
-#include "sysemu/reset.h"
#include "sysemu/runstate.h"
#include "migration/vmstate.h"
#include "hw/acpi/acpi_aml_interface.h"
@@ -155,9 +154,9 @@ static void piix3_write_config_xen(PCIDevice *dev,
piix3_write_config(dev, address, val, len);
}
-static void piix3_reset(void *opaque)
+static void piix3_reset(DeviceState *dev)
{
- PIIX3State *d = opaque;
+ PIIX3State *d = PIIX3_PCI_DEVICE(dev);
uint8_t *pci_conf = d->dev.config;
pci_conf[0x04] = 0x07; /* master, memory and I/O */
@@ -289,15 +288,21 @@ static uint64_t rcr_read(void *opaque, hwaddr addr, unsigned len)
static const MemoryRegionOps rcr_ops = {
.read = rcr_read,
.write = rcr_write,
- .endianness = DEVICE_LITTLE_ENDIAN
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .impl = {
+ .min_access_size = 1,
+ .max_access_size = 1,
+ },
};
static void pci_piix3_realize(PCIDevice *dev, Error **errp)
{
PIIX3State *d = PIIX3_PCI_DEVICE(dev);
+ ISABus *isa_bus;
- if (!isa_bus_new(DEVICE(d), get_system_memory(),
- pci_address_space_io(dev), errp)) {
+ isa_bus = isa_bus_new(DEVICE(d), pci_address_space(dev),
+ pci_address_space_io(dev), errp);
+ if (!isa_bus) {
return;
}
@@ -306,7 +311,7 @@ static void pci_piix3_realize(PCIDevice *dev, Error **errp)
memory_region_add_subregion_overlap(pci_address_space_io(dev),
PIIX_RCR_IOPORT, &d->rcr_mem, 1);
- qemu_register_reset(piix3_reset, d);
+ i8257_dma_init(isa_bus, 0);
}
static void build_pci_isa_aml(AcpiDevAmlIf *adev, Aml *scope)
@@ -328,6 +333,7 @@ static void pci_piix3_class_init(ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass);
+ dc->reset = piix3_reset;
dc->desc = "ISA bridge";
dc->vmsd = &vmstate_piix3;
dc->hotpluggable = false;
@@ -370,7 +376,7 @@ static void piix3_realize(PCIDevice *dev, Error **errp)
pci_bus_irqs(pci_bus, piix3_set_irq, pci_slot_get_pirq,
piix3, PIIX_NUM_PIRQS);
pci_bus_set_route_irq_fn(pci_bus, piix3_route_intx_pin_to_irq);
-};
+}
static void piix3_class_init(ObjectClass *klass, void *data)
{
@@ -405,7 +411,7 @@ static void piix3_xen_realize(PCIDevice *dev, Error **errp)
*/
pci_bus_irqs(pci_bus, xen_piix3_set_irq, xen_pci_slot_get_pirq,
piix3, XEN_PIIX_NUM_PIRQS);
-};
+}
static void piix3_xen_class_init(ObjectClass *klass, void *data)
{
@@ -413,7 +419,7 @@ static void piix3_xen_class_init(ObjectClass *klass, void *data)
k->config_write = piix3_write_config_xen;
k->realize = piix3_xen_realize;
-};
+}
static const TypeInfo piix3_xen_info = {
.name = TYPE_PIIX3_XEN_DEVICE,
diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 15f344dbb7..8fc1db6dc9 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -28,6 +28,7 @@
#include "hw/irq.h"
#include "hw/southbridge/piix.h"
#include "hw/pci/pci.h"
+#include "hw/ide/piix.h"
#include "hw/isa/isa.h"
#include "hw/intc/i8259.h"
#include "hw/dma/i8257.h"
@@ -139,9 +140,11 @@ static void piix4_isa_reset(DeviceState *dev)
pci_conf[0xab] = 0x00;
pci_conf[0xac] = 0x00;
pci_conf[0xae] = 0x00;
+
+ d->rcr = 0;
}
-static int piix4_ide_post_load(void *opaque, int version_id)
+static int piix4_post_load(void *opaque, int version_id)
{
PIIX4State *s = opaque;
@@ -156,7 +159,7 @@ static const VMStateDescription vmstate_piix4 = {
.name = "PIIX4",
.version_id = 3,
.minimum_version_id = 2,
- .post_load = piix4_ide_post_load,
+ .post_load = piix4_post_load,
.fields = (VMStateField[]) {
VMSTATE_PCI_DEVICE(dev, PIIX4State),
VMSTATE_UINT8_V(rcr, PIIX4State, 3),
@@ -254,7 +257,6 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
if (!qdev_realize(DEVICE(&s->ide), BUS(pci_bus), errp)) {
return;
}
- pci_ide_create_devs(PCI_DEVICE(&s->ide));
/* USB */
qdev_prop_set_int32(DEVICE(&s->uhci), "addr", dev->devfn + 2);
@@ -277,7 +279,7 @@ static void piix4_init(Object *obj)
PIIX4State *s = PIIX4_PCI_DEVICE(obj);
object_initialize_child(obj, "rtc", &s->rtc, TYPE_MC146818_RTC);
- object_initialize_child(obj, "ide", &s->ide, "piix4-ide");
+ object_initialize_child(obj, "ide", &s->ide, TYPE_PIIX4_IDE);
object_initialize_child(obj, "uhci", &s->uhci, "piix4-usb-uhci");
object_initialize_child(obj, "pm", &s->pm, TYPE_PIIX4_PM);
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 8f656251b8..3f9bd0c04d 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -17,11 +17,13 @@
#include "hw/isa/vt82c686.h"
#include "hw/pci/pci.h"
#include "hw/qdev-properties.h"
+#include "hw/ide/pci.h"
#include "hw/isa/isa.h"
#include "hw/isa/superio.h"
#include "hw/intc/i8259.h"
#include "hw/irq.h"
#include "hw/dma/i8257.h"
+#include "hw/usb/hcd-uhci.h"
#include "hw/timer/i8254.h"
#include "hw/rtc/mc146818rtc.h"
#include "migration/vmstate.h"
@@ -248,6 +250,8 @@ static const ViaPMInitInfo vt82c686b_pm_init_info = {
.device_id = PCI_DEVICE_ID_VIA_82C686B_PM,
};
+#define TYPE_VT82C686B_PM "vt82c686b-pm"
+
static const TypeInfo vt82c686b_pm_info = {
.name = TYPE_VT82C686B_PM,
.parent = TYPE_VIA_PM,
@@ -259,6 +263,8 @@ static const ViaPMInitInfo vt8231_pm_init_info = {
.device_id = PCI_DEVICE_ID_VIA_8231_PM,
};
+#define TYPE_VT8231_PM "vt8231-pm"
+
static const TypeInfo vt8231_pm_info = {
.name = TYPE_VT8231_PM,
.parent = TYPE_VIA_PM,
@@ -543,8 +549,13 @@ struct ViaISAState {
PCIDevice dev;
qemu_irq cpu_intr;
qemu_irq *isa_irqs;
- ISABus *isa_bus;
- ViaSuperIOState *via_sio;
+ ViaSuperIOState via_sio;
+ RTCState rtc;
+ PCIIDEState ide;
+ UHCIState uhci[2];
+ ViaPMState pm;
+ PCIDevice ac97;
+ PCIDevice mc97;
};
static const VMStateDescription vmstate_via = {
@@ -557,10 +568,23 @@ static const VMStateDescription vmstate_via = {
}
};
+static void via_isa_init(Object *obj)
+{
+ ViaISAState *s = VIA_ISA(obj);
+
+ object_initialize_child(obj, "rtc", &s->rtc, TYPE_MC146818_RTC);
+ object_initialize_child(obj, "ide", &s->ide, TYPE_VIA_IDE);
+ object_initialize_child(obj, "uhci1", &s->uhci[0], TYPE_VT82C686B_USB_UHCI);
+ object_initialize_child(obj, "uhci2", &s->uhci[1], TYPE_VT82C686B_USB_UHCI);
+ object_initialize_child(obj, "ac97", &s->ac97, TYPE_VIA_AC97);
+ object_initialize_child(obj, "mc97", &s->mc97, TYPE_VIA_MC97);
+}
+
static const TypeInfo via_isa_info = {
.name = TYPE_VIA_ISA,
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(ViaISAState),
+ .instance_init = via_isa_init,
.abstract = true,
.interfaces = (InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
@@ -584,24 +608,74 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
{
ViaISAState *s = VIA_ISA(d);
DeviceState *dev = DEVICE(d);
+ PCIBus *pci_bus = pci_get_bus(d);
qemu_irq *isa_irq;
+ ISABus *isa_bus;
int i;
qdev_init_gpio_out(dev, &s->cpu_intr, 1);
isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1);
- s->isa_bus = isa_bus_new(dev, get_system_memory(), pci_address_space_io(d),
- &error_fatal);
- s->isa_irqs = i8259_init(s->isa_bus, *isa_irq);
- isa_bus_irqs(s->isa_bus, s->isa_irqs);
- i8254_pit_init(s->isa_bus, 0x40, 0, NULL);
- i8257_dma_init(s->isa_bus, 0);
- mc146818_rtc_init(s->isa_bus, 2000, NULL);
+ isa_bus = isa_bus_new(dev, pci_address_space(d), pci_address_space_io(d),
+ errp);
+
+ if (!isa_bus) {
+ return;
+ }
+
+ s->isa_irqs = i8259_init(isa_bus, *isa_irq);
+ isa_bus_irqs(isa_bus, s->isa_irqs);
+ i8254_pit_init(isa_bus, 0x40, 0, NULL);
+ i8257_dma_init(isa_bus, 0);
+
+ /* RTC */
+ qdev_prop_set_int32(DEVICE(&s->rtc), "base_year", 2000);
+ if (!qdev_realize(DEVICE(&s->rtc), BUS(isa_bus), errp)) {
+ return;
+ }
+ isa_connect_gpio_out(ISA_DEVICE(&s->rtc), 0, s->rtc.isairq);
for (i = 0; i < PCI_CONFIG_HEADER_SIZE; i++) {
if (i < PCI_COMMAND || i >= PCI_REVISION_ID) {
d->wmask[i] = 0;
}
}
+
+ /* Super I/O */
+ if (!qdev_realize(DEVICE(&s->via_sio), BUS(isa_bus), errp)) {
+ return;
+ }
+
+ /* Function 1: IDE */
+ qdev_prop_set_int32(DEVICE(&s->ide), "addr", d->devfn + 1);
+ if (!qdev_realize(DEVICE(&s->ide), BUS(pci_bus), errp)) {
+ return;
+ }
+
+ /* Functions 2-3: USB Ports */
+ for (i = 0; i < ARRAY_SIZE(s->uhci); i++) {
+ qdev_prop_set_int32(DEVICE(&s->uhci[i]), "addr", d->devfn + 2 + i);
+ if (!qdev_realize(DEVICE(&s->uhci[i]), BUS(pci_bus), errp)) {
+ return;
+ }
+ }
+
+ /* Function 4: Power Management */
+ qdev_prop_set_int32(DEVICE(&s->pm), "addr", d->devfn + 4);
+ if (!qdev_realize(DEVICE(&s->pm), BUS(pci_bus), errp)) {
+ return;
+ }
+
+ /* Function 5: AC97 Audio */
+ qdev_prop_set_int32(DEVICE(&s->ac97), "addr", d->devfn + 5);
+ if (!qdev_realize(DEVICE(&s->ac97), BUS(pci_bus), errp)) {
+ return;
+ }
+
+ /* Function 6: MC97 Modem */
+ qdev_prop_set_int32(DEVICE(&s->mc97), "addr", d->devfn + 6);
+ if (!qdev_realize(DEVICE(&s->mc97), BUS(pci_bus), errp)) {
+ return;
+ }
}
/* TYPE_VT82C686B_ISA */
@@ -615,7 +689,7 @@ static void vt82c686b_write_config(PCIDevice *d, uint32_t addr,
pci_default_write_config(d, addr, val, len);
if (addr == 0x85) {
/* BIT(1): enable or disable superio config io ports */
- via_superio_io_enable(s->via_sio, val & BIT(1));
+ via_superio_io_enable(&s->via_sio, val & BIT(1));
}
}
@@ -639,13 +713,12 @@ static void vt82c686b_isa_reset(DeviceState *dev)
pci_conf[0x77] = 0x10; /* GPIO Control 1/2/3/4 */
}
-static void vt82c686b_realize(PCIDevice *d, Error **errp)
+static void vt82c686b_init(Object *obj)
{
- ViaISAState *s = VIA_ISA(d);
+ ViaISAState *s = VIA_ISA(obj);
- via_isa_realize(d, errp);
- s->via_sio = VIA_SUPERIO(isa_create_simple(s->isa_bus,
- TYPE_VT82C686B_SUPERIO));
+ object_initialize_child(obj, "sio", &s->via_sio, TYPE_VT82C686B_SUPERIO);
+ object_initialize_child(obj, "pm", &s->pm, TYPE_VT82C686B_PM);
}
static void vt82c686b_class_init(ObjectClass *klass, void *data)
@@ -653,7 +726,7 @@ static void vt82c686b_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->realize = vt82c686b_realize;
+ k->realize = via_isa_realize;
k->config_write = vt82c686b_write_config;
k->vendor_id = PCI_VENDOR_ID_VIA;
k->device_id = PCI_DEVICE_ID_VIA_82C686B_ISA;
@@ -670,6 +743,7 @@ static const TypeInfo vt82c686b_isa_info = {
.name = TYPE_VT82C686B_ISA,
.parent = TYPE_VIA_ISA,
.instance_size = sizeof(ViaISAState),
+ .instance_init = vt82c686b_init,
.class_init = vt82c686b_class_init,
};
@@ -684,7 +758,7 @@ static void vt8231_write_config(PCIDevice *d, uint32_t addr,
pci_default_write_config(d, addr, val, len);
if (addr == 0x50) {
/* BIT(2): enable or disable superio config io ports */
- via_superio_io_enable(s->via_sio, val & BIT(2));
+ via_superio_io_enable(&s->via_sio, val & BIT(2));
}
}
@@ -703,13 +777,12 @@ static void vt8231_isa_reset(DeviceState *dev)
pci_conf[0x6b] = 0x01; /* Fast IR I/O Base */
}
-static void vt8231_realize(PCIDevice *d, Error **errp)
+static void vt8231_init(Object *obj)
{
- ViaISAState *s = VIA_ISA(d);
+ ViaISAState *s = VIA_ISA(obj);
- via_isa_realize(d, errp);
- s->via_sio = VIA_SUPERIO(isa_create_simple(s->isa_bus,
- TYPE_VT8231_SUPERIO));
+ object_initialize_child(obj, "sio", &s->via_sio, TYPE_VT8231_SUPERIO);
+ object_initialize_child(obj, "pm", &s->pm, TYPE_VT8231_PM);
}
static void vt8231_class_init(ObjectClass *klass, void *data)
@@ -717,7 +790,7 @@ static void vt8231_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->realize = vt8231_realize;
+ k->realize = via_isa_realize;
k->config_write = vt8231_write_config;
k->vendor_id = PCI_VENDOR_ID_VIA;
k->device_id = PCI_DEVICE_ID_VIA_8231_ISA;
@@ -734,6 +807,7 @@ static const TypeInfo vt8231_isa_info = {
.name = TYPE_VT8231_ISA,
.parent = TYPE_VIA_ISA,
.instance_size = sizeof(ViaISAState),
+ .instance_init = vt8231_init,
.class_init = vt8231_class_init,
};
diff --git a/hw/mips/bootloader.c b/hw/mips/bootloader.c
index 99991f8b2b..f5f42f2bf2 100644
--- a/hw/mips/bootloader.c
+++ b/hw/mips/bootloader.c
@@ -165,15 +165,29 @@ void bl_gen_jump_to(uint32_t **p, target_ulong jump_addr)
bl_gen_nop(p); /* delay slot */
}
-void bl_gen_jump_kernel(uint32_t **p, target_ulong sp, target_ulong a0,
- target_ulong a1, target_ulong a2, target_ulong a3,
+void bl_gen_jump_kernel(uint32_t **p,
+ bool set_sp, target_ulong sp,
+ bool set_a0, target_ulong a0,
+ bool set_a1, target_ulong a1,
+ bool set_a2, target_ulong a2,
+ bool set_a3, target_ulong a3,
target_ulong kernel_addr)
{
- bl_gen_load_ulong(p, BL_REG_SP, sp);
- bl_gen_load_ulong(p, BL_REG_A0, a0);
- bl_gen_load_ulong(p, BL_REG_A1, a1);
- bl_gen_load_ulong(p, BL_REG_A2, a2);
- bl_gen_load_ulong(p, BL_REG_A3, a3);
+ if (set_sp) {
+ bl_gen_load_ulong(p, BL_REG_SP, sp);
+ }
+ if (set_a0) {
+ bl_gen_load_ulong(p, BL_REG_A0, a0);
+ }
+ if (set_a1) {
+ bl_gen_load_ulong(p, BL_REG_A1, a1);
+ }
+ if (set_a2) {
+ bl_gen_load_ulong(p, BL_REG_A2, a2);
+ }
+ if (set_a3) {
+ bl_gen_load_ulong(p, BL_REG_A3, a3);
+ }
bl_gen_jump_to(p, kernel_addr);
}
diff --git a/hw/mips/boston.c b/hw/mips/boston.c
index cab63f43bf..edda87e23c 100644
--- a/hw/mips/boston.c
+++ b/hw/mips/boston.c
@@ -352,7 +352,10 @@ static void gen_firmware(uint32_t *p, hwaddr kernel_entry, hwaddr fdt_addr)
* a2/$6 = 0
* a3/$7 = 0
*/
- bl_gen_jump_kernel(&p, 0, (int32_t)-2, fdt_addr, 0, 0, kernel_entry);
+ bl_gen_jump_kernel(&p,
+ true, 0, true, (int32_t)-2,
+ true, fdt_addr, true, 0, true, 0,
+ kernel_entry);
}
static const void *boston_fdt_filter(void *opaque, const void *fdt_orig,
@@ -425,7 +428,7 @@ static inline XilinxPCIEHost *
xilinx_pcie_init(MemoryRegion *sys_mem, uint32_t bus_nr,
hwaddr cfg_base, uint64_t cfg_size,
hwaddr mmio_base, uint64_t mmio_size,
- qemu_irq irq, bool link_up)
+ qemu_irq irq)
{
DeviceState *dev;
MemoryRegion *cfg, *mmio;
@@ -437,7 +440,6 @@ xilinx_pcie_init(MemoryRegion *sys_mem, uint32_t bus_nr,
qdev_prop_set_uint64(dev, "cfg_size", cfg_size);
qdev_prop_set_uint64(dev, "mmio_base", mmio_base);
qdev_prop_set_uint64(dev, "mmio_size", mmio_size);
- qdev_prop_set_bit(dev, "link_up", link_up);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
@@ -730,21 +732,21 @@ static void boston_mach_init(MachineState *machine)
boston_memmap[BOSTON_PCIE0].size,
boston_memmap[BOSTON_PCIE0_MMIO].base,
boston_memmap[BOSTON_PCIE0_MMIO].size,
- get_cps_irq(&s->cps, 2), false);
+ get_cps_irq(&s->cps, 2));
xilinx_pcie_init(sys_mem, 1,
boston_memmap[BOSTON_PCIE1].base,
boston_memmap[BOSTON_PCIE1].size,
boston_memmap[BOSTON_PCIE1_MMIO].base,
boston_memmap[BOSTON_PCIE1_MMIO].size,
- get_cps_irq(&s->cps, 1), false);
+ get_cps_irq(&s->cps, 1));
pcie2 = xilinx_pcie_init(sys_mem, 2,
boston_memmap[BOSTON_PCIE2].base,
boston_memmap[BOSTON_PCIE2].size,
boston_memmap[BOSTON_PCIE2_MMIO].base,
boston_memmap[BOSTON_PCIE2_MMIO].size,
- get_cps_irq(&s->cps, 0), true);
+ get_cps_irq(&s->cps, 0));
platreg = g_new(MemoryRegion, 1);
memory_region_init_io(platreg, NULL, &boston_platreg_ops, s,
diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index 5ee546f5f6..34befa5dd5 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -49,7 +49,6 @@
/* Fuloong 2e has a 512k flash: Winbond W39L040AP70Z */
#define BIOS_SIZE (512 * KiB)
-#define MAX_IDE_BUS 2
/*
* PMON is not part of qemu and released with BSD license, anyone
@@ -180,8 +179,12 @@ static void write_bootloader(CPUMIPSState *env, uint8_t *base,
/* Second part of the bootloader */
p = (uint32_t *)(base + 0x040);
- bl_gen_jump_kernel(&p, ENVP_VADDR - 64, 2, ENVP_VADDR, ENVP_VADDR + 8,
- loaderparams.ram_size, kernel_addr);
+ bl_gen_jump_kernel(&p,
+ true, ENVP_VADDR - 64,
+ true, 2, true, ENVP_VADDR,
+ true, ENVP_VADDR + 8,
+ true, loaderparams.ram_size,
+ kernel_addr);
}
static void main_cpu_reset(void *opaque)
@@ -196,29 +199,6 @@ static void main_cpu_reset(void *opaque)
}
}
-static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq intc,
- I2CBus **i2c_bus)
-{
- PCIDevice *dev;
-
- dev = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(slot, 0), true,
- TYPE_VT82C686B_ISA);
- qdev_connect_gpio_out(DEVICE(dev), 0, intc);
-
- dev = pci_create_simple(pci_bus, PCI_DEVFN(slot, 1), "via-ide");
- pci_ide_create_devs(dev);
-
- pci_create_simple(pci_bus, PCI_DEVFN(slot, 2), "vt82c686b-usb-uhci");
- pci_create_simple(pci_bus, PCI_DEVFN(slot, 3), "vt82c686b-usb-uhci");
-
- dev = pci_create_simple(pci_bus, PCI_DEVFN(slot, 4), TYPE_VT82C686B_PM);
- *i2c_bus = I2C_BUS(qdev_get_child_bus(DEVICE(dev), "i2c"));
-
- /* Audio support */
- pci_create_simple(pci_bus, PCI_DEVFN(slot, 5), TYPE_VIA_AC97);
- pci_create_simple(pci_bus, PCI_DEVFN(slot, 6), TYPE_VIA_MC97);
-}
-
/* Network support */
static void network_init(PCIBus *pci_bus)
{
@@ -315,8 +295,20 @@ static void mips_fuloong2e_init(MachineState *machine)
pci_bus = bonito_init((qemu_irq *)&(env->irq[2]));
/* South bridge -> IP5 */
- vt82c686b_southbridge_init(pci_bus, FULOONG2E_VIA_SLOT, env->irq[5],
- &smbus);
+ pci_dev = pci_create_simple_multifunction(pci_bus,
+ PCI_DEVFN(FULOONG2E_VIA_SLOT, 0),
+ true, TYPE_VT82C686B_ISA);
+ object_property_add_alias(OBJECT(machine), "rtc-time",
+ object_resolve_path_component(OBJECT(pci_dev),
+ "rtc"),
+ "date");
+ qdev_connect_gpio_out(DEVICE(pci_dev), 0, env->irq[5]);
+
+ dev = DEVICE(object_resolve_path_component(OBJECT(pci_dev), "ide"));
+ pci_ide_create_devs(PCI_DEVICE(dev));
+
+ dev = DEVICE(object_resolve_path_component(OBJECT(pci_dev), "pm"));
+ smbus = I2C_BUS(qdev_get_child_bus(dev, "i2c"));
/* GPU */
if (vga_interface_type != VGA_NONE) {
diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index 7c3ad0974b..c0a2e0ab04 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -36,11 +36,12 @@
#include "hw/i2c/smbus_eeprom.h"
#include "hw/block/flash.h"
#include "hw/mips/mips.h"
+#include "hw/mips/bootloader.h"
#include "hw/mips/cpudevs.h"
#include "hw/pci/pci.h"
#include "qemu/log.h"
#include "hw/mips/bios.h"
-#include "hw/ide.h"
+#include "hw/ide/pci.h"
#include "hw/irq.h"
#include "hw/loader.h"
#include "elf.h"
@@ -70,8 +71,6 @@
#define FLASH_SIZE 0x400000
-#define MAX_IDE_BUS 2
-
typedef struct {
MemoryRegion iomem;
MemoryRegion iomem_lo; /* 0 - 0x900 */
@@ -867,88 +866,63 @@ static void write_bootloader(uint8_t *base, uint64_t run_addr,
/* Second part of the bootloader */
p = (uint32_t *) (base + 0x580);
- if (semihosting_get_argc()) {
- /* Preserve a0 content as arguments have been passed */
- stl_p(p++, 0x00000000); /* nop */
- } else {
- stl_p(p++, 0x24040002); /* addiu a0, zero, 2 */
- }
-
- /* lui sp, high(ENVP_VADDR) */
- stl_p(p++, 0x3c1d0000 | (((ENVP_VADDR - 64) >> 16) & 0xffff));
- /* ori sp, sp, low(ENVP_VADDR) */
- stl_p(p++, 0x37bd0000 | ((ENVP_VADDR - 64) & 0xffff));
- /* lui a1, high(ENVP_VADDR) */
- stl_p(p++, 0x3c050000 | ((ENVP_VADDR >> 16) & 0xffff));
- /* ori a1, a1, low(ENVP_VADDR) */
- stl_p(p++, 0x34a50000 | (ENVP_VADDR & 0xffff));
- /* lui a2, high(ENVP_VADDR + 8) */
- stl_p(p++, 0x3c060000 | (((ENVP_VADDR + 8) >> 16) & 0xffff));
- /* ori a2, a2, low(ENVP_VADDR + 8) */
- stl_p(p++, 0x34c60000 | ((ENVP_VADDR + 8) & 0xffff));
- /* lui a3, high(ram_low_size) */
- stl_p(p++, 0x3c070000 | (loaderparams.ram_low_size >> 16));
- /* ori a3, a3, low(ram_low_size) */
- stl_p(p++, 0x34e70000 | (loaderparams.ram_low_size & 0xffff));
-
- /* Load BAR registers as done by YAMON */
- stl_p(p++, 0x3c09b400); /* lui t1, 0xb400 */
-
-#if TARGET_BIG_ENDIAN
- stl_p(p++, 0x3c08df00); /* lui t0, 0xdf00 */
-#else
- stl_p(p++, 0x340800df); /* ori t0, r0, 0x00df */
-#endif
- stl_p(p++, 0xad280068); /* sw t0, 0x0068(t1) */
-
- stl_p(p++, 0x3c09bbe0); /* lui t1, 0xbbe0 */
-
-#if TARGET_BIG_ENDIAN
- stl_p(p++, 0x3c08c000); /* lui t0, 0xc000 */
-#else
- stl_p(p++, 0x340800c0); /* ori t0, r0, 0x00c0 */
-#endif
- stl_p(p++, 0xad280048); /* sw t0, 0x0048(t1) */
-#if TARGET_BIG_ENDIAN
- stl_p(p++, 0x3c084000); /* lui t0, 0x4000 */
-#else
- stl_p(p++, 0x34080040); /* ori t0, r0, 0x0040 */
-#endif
- stl_p(p++, 0xad280050); /* sw t0, 0x0050(t1) */
-
-#if TARGET_BIG_ENDIAN
- stl_p(p++, 0x3c088000); /* lui t0, 0x8000 */
-#else
- stl_p(p++, 0x34080080); /* ori t0, r0, 0x0080 */
-#endif
- stl_p(p++, 0xad280058); /* sw t0, 0x0058(t1) */
-#if TARGET_BIG_ENDIAN
- stl_p(p++, 0x3c083f00); /* lui t0, 0x3f00 */
-#else
- stl_p(p++, 0x3408003f); /* ori t0, r0, 0x003f */
-#endif
- stl_p(p++, 0xad280060); /* sw t0, 0x0060(t1) */
+ /*
+ * Load BAR registers as done by YAMON:
+ *
+ * - set up PCI0 I/O BARs from 0x18000000 to 0x181fffff
+ * - set up PCI0 MEM0 at 0x10000000, size 0x7e00000
+ * - set up PCI0 MEM1 at 0x18200000, size 0xbc00000
+ *
+ */
+ /* Bus endianess is always reversed */
#if TARGET_BIG_ENDIAN
- stl_p(p++, 0x3c08c100); /* lui t0, 0xc100 */
+#define cpu_to_gt32 cpu_to_le32
#else
- stl_p(p++, 0x340800c1); /* ori t0, r0, 0x00c1 */
+#define cpu_to_gt32 cpu_to_be32
#endif
- stl_p(p++, 0xad280080); /* sw t0, 0x0080(t1) */
-#if TARGET_BIG_ENDIAN
- stl_p(p++, 0x3c085e00); /* lui t0, 0x5e00 */
-#else
- stl_p(p++, 0x3408005e); /* ori t0, r0, 0x005e */
-#endif
- stl_p(p++, 0xad280088); /* sw t0, 0x0088(t1) */
- /* Jump to kernel code */
- stl_p(p++, 0x3c1f0000 |
- ((kernel_entry >> 16) & 0xffff)); /* lui ra, high(kernel_entry) */
- stl_p(p++, 0x37ff0000 |
- (kernel_entry & 0xffff)); /* ori ra, ra, low(kernel_entry) */
- stl_p(p++, 0x03e00009); /* jalr ra */
- stl_p(p++, 0x00000000); /* nop */
+ /* move GT64120 registers from 0x14000000 to 0x1be00000 */
+ bl_gen_write_u32(&p, /* GT_ISD */
+ cpu_mips_phys_to_kseg1(NULL, 0x14000000 + 0x68),
+ cpu_to_gt32(0x1be00000 << 3));
+
+ /* setup MEM-to-PCI0 mapping */
+ /* setup PCI0 io window to 0x18000000-0x181fffff */
+ bl_gen_write_u32(&p, /* GT_PCI0IOLD */
+ cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x48),
+ cpu_to_gt32(0x18000000 << 3));
+ bl_gen_write_u32(&p, /* GT_PCI0IOHD */
+ cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x50),
+ cpu_to_gt32(0x08000000 << 3));
+ /* setup PCI0 mem windows */
+ bl_gen_write_u32(&p, /* GT_PCI0M0LD */
+ cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x58),
+ cpu_to_gt32(0x10000000 << 3));
+ bl_gen_write_u32(&p, /* GT_PCI0M0HD */
+ cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x60),
+ cpu_to_gt32(0x07e00000 << 3));
+
+ bl_gen_write_u32(&p, /* GT_PCI0M1LD */
+ cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x80),
+ cpu_to_gt32(0x18200000 << 3));
+ bl_gen_write_u32(&p, /* GT_PCI0M1HD */
+ cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x88),
+ cpu_to_gt32(0x0bc00000 << 3));
+
+#undef cpu_to_gt32
+
+ bl_gen_jump_kernel(&p,
+ true, ENVP_VADDR - 64,
+ /*
+ * If semihosting is used, arguments have already been
+ * passed, so we preserve $a0.
+ */
+ !semihosting_get_argc(), 2,
+ true, ENVP_VADDR,
+ true, ENVP_VADDR + 8,
+ true, loaderparams.ram_low_size,
+ kernel_entry);
/* YAMON subroutines */
p = (uint32_t *) (base + 0x800);
@@ -1266,7 +1240,6 @@ void mips_malta_init(MachineState *machine)
MaltaState *s;
PCIDevice *piix4;
DeviceState *dev;
- DeviceState *pm_dev;
s = MIPS_MALTA(qdev_new(TYPE_MIPS_MALTA));
sysbus_realize_and_unref(SYS_BUS_DEVICE(s), &error_fatal);
@@ -1430,15 +1403,17 @@ void mips_malta_init(MachineState *machine)
/* Southbridge */
piix4 = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(10, 0), true,
TYPE_PIIX4_PCI_DEVICE);
- dev = DEVICE(piix4);
- isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0"));
- pm_dev = DEVICE(object_resolve_path_component(OBJECT(dev), "pm"));
- smbus = I2C_BUS(qdev_get_child_bus(pm_dev, "i2c"));
+ isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(piix4), "isa.0"));
+
+ dev = DEVICE(object_resolve_path_component(OBJECT(piix4), "ide"));
+ pci_ide_create_devs(PCI_DEVICE(dev));
/* Interrupt controller */
- qdev_connect_gpio_out_named(dev, "intr", 0, i8259_irq);
+ qdev_connect_gpio_out_named(DEVICE(piix4), "intr", 0, i8259_irq);
/* generate SPD EEPROM data */
+ dev = DEVICE(object_resolve_path_component(OBJECT(piix4), "pm"));
+ smbus = I2C_BUS(qdev_get_child_bus(dev, "i2c"));
generate_eeprom_spd(&smbus_eeprom_buf[0 * 256], ram_size);
generate_eeprom_serial(&smbus_eeprom_buf[6 * 256]);
smbus_eeprom_init(smbus, 8, smbus_eeprom_buf, smbus_eeprom_size);
diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index 1498113cfc..0d4c13319a 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -25,7 +25,6 @@
#include "qemu/osdep.h"
#include "hw/irq.h"
-#include "hw/ppc/mac.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "hw/input/adb.h"
diff --git a/hw/misc/macio/gpio.c b/hw/misc/macio/gpio.c
index b1bcf830c3..c8ac5633b2 100644
--- a/hw/misc/macio/gpio.c
+++ b/hw/misc/macio/gpio.c
@@ -24,7 +24,6 @@
*/
#include "qemu/osdep.h"
-#include "hw/ppc/mac.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "hw/misc/macio/macio.h"
diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c
index c1fad43f6c..08dbdd7fc0 100644
--- a/hw/misc/macio/macio.c
+++ b/hw/misc/macio/macio.c
@@ -26,7 +26,6 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/module.h"
-#include "hw/ppc/mac.h"
#include "hw/misc/macio/cuda.h"
#include "hw/pci/pci.h"
#include "hw/ppc/mac_dbdma.h"
@@ -37,8 +36,9 @@
#include "hw/intc/heathrow_pic.h"
#include "trace.h"
-/* Note: this code is strongly inspirated from the corresponding code
- * in PearPC */
+#define ESCC_CLOCK 3686400
+
+/* Note: this code is strongly inspired by the corresponding code in PearPC */
/*
* The mac-io has two interfaces to the ESCC. One is called "escc-legacy",
@@ -226,7 +226,7 @@ static void macio_oldworld_init(Object *obj)
object_initialize_child(OBJECT(s), "nvram", &os->nvram, TYPE_MACIO_NVRAM);
dev = DEVICE(&os->nvram);
- qdev_prop_set_uint32(dev, "size", 0x2000);
+ qdev_prop_set_uint32(dev, "size", MACIO_NVRAM_SIZE);
qdev_prop_set_uint32(dev, "it_shift", 4);
for (i = 0; i < 2; i++) {
diff --git a/hw/misc/macio/pmu.c b/hw/misc/macio/pmu.c
index 336502a84b..70562ed8d0 100644
--- a/hw/misc/macio/pmu.c
+++ b/hw/misc/macio/pmu.c
@@ -29,7 +29,6 @@
*/
#include "qemu/osdep.h"
-#include "hw/ppc/mac.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "hw/input/adb.h"
diff --git a/hw/net/e1000_regs.h b/hw/net/e1000_regs.h
index ae99f58bab..9d423f6c09 100644
--- a/hw/net/e1000_regs.h
+++ b/hw/net/e1000_regs.h
@@ -793,6 +793,7 @@
#define E1000_CTRL_EXT_ASDCHK 0x00001000 /* auto speed detection check */
#define E1000_CTRL_EXT_EE_RST 0x00002000 /* EEPROM reset */
#define E1000_CTRL_EXT_LINK_EN 0x00010000 /* enable link status from external LINK_0 and LINK_1 pins */
+#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */
#define E1000_CTRL_EXT_EIAME 0x01000000
#define E1000_CTRL_EXT_IAME 0x08000000 /* Int ACK Auto-mask */
#define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */
diff --git a/hw/nvram/mac_nvram.c b/hw/nvram/mac_nvram.c
index 11f2d31cdb..3d9ddda217 100644
--- a/hw/nvram/mac_nvram.c
+++ b/hw/nvram/mac_nvram.c
@@ -25,7 +25,7 @@
#include "qemu/osdep.h"
#include "hw/nvram/chrp_nvram.h"
-#include "hw/ppc/mac.h"
+#include "hw/nvram/mac_nvram.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "qemu/cutils.h"
diff --git a/hw/pci-host/grackle.c b/hw/pci-host/grackle.c
index b05facf463..95945ac0f4 100644
--- a/hw/pci-host/grackle.c
+++ b/hw/pci-host/grackle.c
@@ -24,8 +24,6 @@
*/
#include "qemu/osdep.h"
-#include "hw/pci/pci_host.h"
-#include "hw/ppc/mac.h"
#include "hw/qdev-properties.h"
#include "hw/pci/pci.h"
#include "hw/irq.h"
@@ -33,18 +31,7 @@
#include "qemu/module.h"
#include "trace.h"
#include "qom/object.h"
-
-OBJECT_DECLARE_SIMPLE_TYPE(GrackleState, GRACKLE_PCI_HOST_BRIDGE)
-
-struct GrackleState {
- PCIHostState parent_obj;
-
- uint32_t ofw_addr;
- qemu_irq irqs[4];
- MemoryRegion pci_mmio;
- MemoryRegion pci_hole;
- MemoryRegion pci_io;
-};
+#include "hw/pci-host/grackle.h"
/* Don't know if this matches real hardware, but it agrees with OHW. */
static int pci_grackle_map_irq(PCIDevice *pci_dev, int irq_num)
diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c
index d25b62d6a5..aebd44d265 100644
--- a/hw/pci-host/uninorth.c
+++ b/hw/pci-host/uninorth.c
@@ -24,7 +24,6 @@
#include "qemu/osdep.h"
#include "hw/irq.h"
-#include "hw/ppc/mac.h"
#include "hw/qdev-properties.h"
#include "qemu/module.h"
#include "hw/pci/pci.h"
diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
index 791fe78a50..b8d2522f45 100644
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -74,7 +74,6 @@ config PEGASOS2
imply ATI_VGA
select MV64361
select VT82C686
- select IDE_VIA
select SMBUS_EEPROM
select VOF
# This should come with VT82C686
@@ -126,6 +125,7 @@ config E500
select ETSEC
select GPIO_MPC8XXX
select OPENPIC
+ select PFLASH_CFI01
select PLATFORM_BUS
select PPCE500_PCI
select SERIAL
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 3e950ea3ba..2fe496677c 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -23,8 +23,10 @@
#include "e500-ccsr.h"
#include "net/net.h"
#include "qemu/config-file.h"
+#include "hw/block/flash.h"
#include "hw/char/serial.h"
#include "hw/pci/pci.h"
+#include "sysemu/block-backend-io.h"
#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"
#include "sysemu/reset.h"
@@ -267,6 +269,31 @@ static void sysbus_device_create_devtree(SysBusDevice *sbdev, void *opaque)
}
}
+static void create_devtree_flash(SysBusDevice *sbdev,
+ PlatformDevtreeData *data)
+{
+ g_autofree char *name = NULL;
+ uint64_t num_blocks = object_property_get_uint(OBJECT(sbdev),
+ "num-blocks",
+ &error_fatal);
+ uint64_t sector_length = object_property_get_uint(OBJECT(sbdev),
+ "sector-length",
+ &error_fatal);
+ uint64_t bank_width = object_property_get_uint(OBJECT(sbdev),
+ "width",
+ &error_fatal);
+ hwaddr flashbase = 0;
+ hwaddr flashsize = num_blocks * sector_length;
+ void *fdt = data->fdt;
+
+ name = g_strdup_printf("%s/nor@%" PRIx64, data->node, flashbase);
+ qemu_fdt_add_subnode(fdt, name);
+ qemu_fdt_setprop_string(fdt, name, "compatible", "cfi-flash");
+ qemu_fdt_setprop_sized_cells(fdt, name, "reg",
+ 1, flashbase, 1, flashsize);
+ qemu_fdt_setprop_cell(fdt, name, "bank-width", bank_width);
+}
+
static void platform_bus_create_devtree(PPCE500MachineState *pms,
void *fdt, const char *mpic)
{
@@ -276,6 +303,8 @@ static void platform_bus_create_devtree(PPCE500MachineState *pms,
uint64_t addr = pmc->platform_bus_base;
uint64_t size = pmc->platform_bus_size;
int irq_start = pmc->platform_bus_first_irq;
+ SysBusDevice *sbdev;
+ bool ambiguous;
/* Create a /platform node that we can put all devices into */
@@ -302,6 +331,13 @@ static void platform_bus_create_devtree(PPCE500MachineState *pms,
/* Loop through all dynamic sysbus devices and create nodes for them */
foreach_dynamic_sysbus_device(sysbus_device_create_devtree, &data);
+ sbdev = SYS_BUS_DEVICE(object_resolve_path_type("", TYPE_PFLASH_CFI01,
+ &ambiguous));
+ if (sbdev) {
+ assert(!ambiguous);
+ create_devtree_flash(sbdev, &data);
+ }
+
g_free(node);
}
@@ -856,6 +892,7 @@ void ppce500_init(MachineState *machine)
unsigned int pci_irq_nrs[PCI_NUM_PINS] = {1, 2, 3, 4};
IrqLines *irqs;
DeviceState *dev, *mpicdev;
+ DriveInfo *dinfo;
CPUPPCState *firstenv = NULL;
MemoryRegion *ccsr_addr_space;
SysBusDevice *s;
@@ -1024,6 +1061,48 @@ void ppce500_init(MachineState *machine)
pmc->platform_bus_base,
&pms->pbus_dev->mmio);
+ dinfo = drive_get(IF_PFLASH, 0, 0);
+ if (dinfo) {
+ BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
+ BlockDriverState *bs = blk_bs(blk);
+ uint64_t mmio_size = memory_region_size(&pms->pbus_dev->mmio);
+ uint64_t size = bdrv_getlength(bs);
+ uint32_t sector_len = 64 * KiB;
+
+ if (!is_power_of_2(size)) {
+ error_report("Size of pflash file must be a power of two.");
+ exit(1);
+ }
+
+ if (size > mmio_size) {
+ error_report("Size of pflash file must not be bigger than %" PRIu64
+ " bytes.", mmio_size);
+ exit(1);
+ }
+
+ if (!QEMU_IS_ALIGNED(size, sector_len)) {
+ error_report("Size of pflash file must be a multiple of %" PRIu32
+ ".", sector_len);
+ exit(1);
+ }
+
+ dev = qdev_new(TYPE_PFLASH_CFI01);
+ qdev_prop_set_drive(dev, "drive", blk);
+ qdev_prop_set_uint32(dev, "num-blocks", size / sector_len);
+ qdev_prop_set_uint64(dev, "sector-length", sector_len);
+ qdev_prop_set_uint8(dev, "width", 2);
+ qdev_prop_set_bit(dev, "big-endian", true);
+ qdev_prop_set_uint16(dev, "id0", 0x89);
+ qdev_prop_set_uint16(dev, "id1", 0x18);
+ qdev_prop_set_uint16(dev, "id2", 0x0000);
+ qdev_prop_set_uint16(dev, "id3", 0x0);
+ qdev_prop_set_string(dev, "name", "e500.flash");
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+
+ memory_region_add_subregion(&pms->pbus_dev->mmio, 0,
+ pflash_cfi01_get_memory(PFLASH_CFI01(dev)));
+ }
+
/*
* Smart firmware defaults ahead!
*
diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h
deleted file mode 100644
index a1fa8f8e41..0000000000
--- a/hw/ppc/mac.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * QEMU PowerMac emulation shared definitions and prototypes
- *
- * Copyright (c) 2004-2007 Fabrice Bellard
- * Copyright (c) 2007 Jocelyn Mayer
- *
- * 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.
- */
-
-#ifndef PPC_MAC_H
-#define PPC_MAC_H
-
-#include "qemu/units.h"
-#include "exec/memory.h"
-#include "hw/boards.h"
-#include "hw/sysbus.h"
-#include "hw/input/adb.h"
-#include "hw/misc/mos6522.h"
-#include "hw/pci/pci_host.h"
-#include "hw/pci-host/uninorth.h"
-#include "qom/object.h"
-
-#define NVRAM_SIZE 0x2000
-#define PROM_FILENAME "openbios-ppc"
-
-#define KERNEL_LOAD_ADDR 0x01000000
-#define KERNEL_GAP 0x00100000
-
-#define ESCC_CLOCK 3686400
-
-/* Old World IRQs */
-#define OLDWORLD_CUDA_IRQ 0x12
-#define OLDWORLD_ESCCB_IRQ 0x10
-#define OLDWORLD_ESCCA_IRQ 0xf
-#define OLDWORLD_IDE0_IRQ 0xd
-#define OLDWORLD_IDE0_DMA_IRQ 0x2
-#define OLDWORLD_IDE1_IRQ 0xe
-#define OLDWORLD_IDE1_DMA_IRQ 0x3
-
-/* New World IRQs */
-#define NEWWORLD_CUDA_IRQ 0x19
-#define NEWWORLD_PMU_IRQ 0x19
-#define NEWWORLD_ESCCB_IRQ 0x24
-#define NEWWORLD_ESCCA_IRQ 0x25
-#define NEWWORLD_IDE0_IRQ 0xd
-#define NEWWORLD_IDE0_DMA_IRQ 0x2
-#define NEWWORLD_IDE1_IRQ 0xe
-#define NEWWORLD_IDE1_DMA_IRQ 0x3
-#define NEWWORLD_EXTING_GPIO1 0x2f
-#define NEWWORLD_EXTING_GPIO9 0x37
-
-/* Core99 machine */
-#define TYPE_CORE99_MACHINE MACHINE_TYPE_NAME("mac99")
-typedef struct Core99MachineState Core99MachineState;
-DECLARE_INSTANCE_CHECKER(Core99MachineState, CORE99_MACHINE,
- TYPE_CORE99_MACHINE)
-
-#define CORE99_VIA_CONFIG_CUDA 0x0
-#define CORE99_VIA_CONFIG_PMU 0x1
-#define CORE99_VIA_CONFIG_PMU_ADB 0x2
-
-struct Core99MachineState {
- /*< private >*/
- MachineState parent;
-
- uint8_t via_config;
-};
-
-/* Grackle PCI */
-#define TYPE_GRACKLE_PCI_HOST_BRIDGE "grackle-pcihost"
-
-/* Mac NVRAM */
-#define TYPE_MACIO_NVRAM "macio-nvram"
-OBJECT_DECLARE_SIMPLE_TYPE(MacIONVRAMState, MACIO_NVRAM)
-
-struct MacIONVRAMState {
- /*< private >*/
- SysBusDevice parent_obj;
- /*< public >*/
-
- uint32_t size;
- uint32_t it_shift;
-
- MemoryRegion mem;
- uint8_t *data;
-};
-
-void pmac_format_nvram_partition (MacIONVRAMState *nvr, int len);
-#endif /* PPC_MAC_H */
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index cf7eb72391..601ea518f8 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -48,10 +48,13 @@
#include "qemu/osdep.h"
#include "qemu/datadir.h"
+#include "qemu/units.h"
#include "qapi/error.h"
#include "hw/ppc/ppc.h"
#include "hw/qdev-properties.h"
-#include "hw/ppc/mac.h"
+#include "hw/nvram/mac_nvram.h"
+#include "hw/boards.h"
+#include "hw/pci-host/uninorth.h"
#include "hw/input/adb.h"
#include "hw/ppc/mac_dbdma.h"
#include "hw/pci/pci.h"
@@ -80,9 +83,31 @@
#define NDRV_VGA_FILENAME "qemu_vga.ndrv"
+#define PROM_FILENAME "openbios-ppc"
#define PROM_BASE 0xfff00000
#define PROM_SIZE (1 * MiB)
+#define KERNEL_LOAD_ADDR 0x01000000
+#define KERNEL_GAP 0x00100000
+
+#define TYPE_CORE99_MACHINE MACHINE_TYPE_NAME("mac99")
+typedef struct Core99MachineState Core99MachineState;
+DECLARE_INSTANCE_CHECKER(Core99MachineState, CORE99_MACHINE,
+ TYPE_CORE99_MACHINE)
+
+typedef enum {
+ CORE99_VIA_CONFIG_CUDA = 0,
+ CORE99_VIA_CONFIG_PMU,
+ CORE99_VIA_CONFIG_PMU_ADB
+} Core99ViaConfig;
+
+struct Core99MachineState {
+ /*< private >*/
+ MachineState parent;
+
+ Core99ViaConfig via_config;
+};
+
static void fw_cfg_boot_set(void *opaque, const char *boot_device,
Error **errp)
{
@@ -106,45 +131,32 @@ static void ppc_core99_reset(void *opaque)
/* PowerPC Mac99 hardware initialisation */
static void ppc_core99_init(MachineState *machine)
{
- ram_addr_t ram_size = machine->ram_size;
- const char *bios_name = machine->firmware ?: PROM_FILENAME;
- const char *kernel_filename = machine->kernel_filename;
- const char *kernel_cmdline = machine->kernel_cmdline;
- const char *initrd_filename = machine->initrd_filename;
- const char *boot_device = machine->boot_config.order;
Core99MachineState *core99_machine = CORE99_MACHINE(machine);
PowerPCCPU *cpu = NULL;
CPUPPCState *env = NULL;
char *filename;
IrqLines *openpic_irqs;
- int linux_boot, i, j, k;
+ int i, j, k, ppc_boot_device, machine_arch, bios_size = -1;
+ const char *bios_name = machine->firmware ?: PROM_FILENAME;
MemoryRegion *bios = g_new(MemoryRegion, 1);
- hwaddr kernel_base, initrd_base, cmdline_base = 0;
- long kernel_size, initrd_size;
- UNINHostState *uninorth_pci;
+ hwaddr kernel_base = 0, initrd_base = 0, cmdline_base = 0;
+ long kernel_size = 0, initrd_size = 0;
PCIBus *pci_bus;
- PCIDevice *macio;
- ESCCState *escc;
bool has_pmu, has_adb;
+ Object *macio;
MACIOIDEState *macio_ide;
BusState *adb_bus;
MacIONVRAMState *nvr;
- int bios_size;
- int ppc_boot_device;
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
void *fw_cfg;
- int machine_arch;
SysBusDevice *s;
- DeviceState *dev, *pic_dev;
+ DeviceState *dev, *pic_dev, *uninorth_pci_dev;
DeviceState *uninorth_internal_dev = NULL, *uninorth_agp_dev = NULL;
hwaddr nvram_addr = 0xFFF04000;
- uint64_t tbfreq;
- unsigned int smp_cpus = machine->smp.cpus;
-
- linux_boot = (kernel_filename != NULL);
+ uint64_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TBFREQ;
/* init CPUs */
- for (i = 0; i < smp_cpus; i++) {
+ for (i = 0; i < machine->smp.cpus; i++) {
cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
env = &cpu->env;
@@ -176,68 +188,62 @@ static void ppc_core99_init(MachineState *machine)
bios_size = load_image_targphys(filename, PROM_BASE, PROM_SIZE);
}
g_free(filename);
- } else {
- bios_size = -1;
}
if (bios_size < 0 || bios_size > PROM_SIZE) {
error_report("could not load PowerPC bios '%s'", bios_name);
exit(1);
}
- if (linux_boot) {
- int bswap_needed;
+ if (machine->kernel_filename) {
+ int bswap_needed = 0;
#ifdef BSWAP_NEEDED
bswap_needed = 1;
-#else
- bswap_needed = 0;
#endif
kernel_base = KERNEL_LOAD_ADDR;
-
- kernel_size = load_elf(kernel_filename, NULL,
+ kernel_size = load_elf(machine->kernel_filename, NULL,
translate_kernel_address, NULL, NULL, NULL,
NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0);
- if (kernel_size < 0)
- kernel_size = load_aout(kernel_filename, kernel_base,
- ram_size - kernel_base, bswap_needed,
- TARGET_PAGE_SIZE);
- if (kernel_size < 0)
- kernel_size = load_image_targphys(kernel_filename,
+ if (kernel_size < 0) {
+ kernel_size = load_aout(machine->kernel_filename, kernel_base,
+ machine->ram_size - kernel_base,
+ bswap_needed, TARGET_PAGE_SIZE);
+ }
+ if (kernel_size < 0) {
+ kernel_size = load_image_targphys(machine->kernel_filename,
kernel_base,
- ram_size - kernel_base);
+ machine->ram_size - kernel_base);
+ }
if (kernel_size < 0) {
- error_report("could not load kernel '%s'", kernel_filename);
+ error_report("could not load kernel '%s'",
+ machine->kernel_filename);
exit(1);
}
/* load initrd */
- if (initrd_filename) {
+ if (machine->initrd_filename) {
initrd_base = TARGET_PAGE_ALIGN(kernel_base + kernel_size + KERNEL_GAP);
- initrd_size = load_image_targphys(initrd_filename, initrd_base,
- ram_size - initrd_base);
+ initrd_size = load_image_targphys(machine->initrd_filename,
+ initrd_base,
+ machine->ram_size - initrd_base);
if (initrd_size < 0) {
error_report("could not load initial ram disk '%s'",
- initrd_filename);
+ machine->initrd_filename);
exit(1);
}
cmdline_base = TARGET_PAGE_ALIGN(initrd_base + initrd_size);
} else {
- initrd_base = 0;
- initrd_size = 0;
cmdline_base = TARGET_PAGE_ALIGN(kernel_base + kernel_size + KERNEL_GAP);
}
ppc_boot_device = 'm';
} else {
- kernel_base = 0;
- kernel_size = 0;
- initrd_base = 0;
- initrd_size = 0;
ppc_boot_device = '\0';
/* We consider that NewWorld PowerMac never have any floppy drive
* For now, OHW cannot boot from the network.
*/
- for (i = 0; boot_device[i] != '\0'; i++) {
- if (boot_device[i] >= 'c' && boot_device[i] <= 'f') {
- ppc_boot_device = boot_device[i];
+ for (i = 0; machine->boot_config.order[i] != '\0'; i++) {
+ if (machine->boot_config.order[i] >= 'c' &&
+ machine->boot_config.order[i] <= 'f') {
+ ppc_boot_device = machine->boot_config.order[i];
break;
}
}
@@ -247,45 +253,39 @@ static void ppc_core99_init(MachineState *machine)
}
}
- /* UniN init */
- dev = qdev_new(TYPE_UNI_NORTH);
- s = SYS_BUS_DEVICE(dev);
- sysbus_realize_and_unref(s, &error_fatal);
- memory_region_add_subregion(get_system_memory(), 0xf8000000,
- sysbus_mmio_get_region(s, 0));
-
- openpic_irqs = g_new0(IrqLines, smp_cpus);
- for (i = 0; i < smp_cpus; i++) {
+ openpic_irqs = g_new0(IrqLines, machine->smp.cpus);
+ dev = DEVICE(cpu);
+ for (i = 0; i < machine->smp.cpus; i++) {
/* Mac99 IRQ connection between OpenPIC outputs pins
* and PowerPC input pins
*/
switch (PPC_INPUT(env)) {
case PPC_FLAGS_INPUT_6xx:
openpic_irqs[i].irq[OPENPIC_OUTPUT_INT] =
- qdev_get_gpio_in(DEVICE(cpu), PPC6xx_INPUT_INT);
+ qdev_get_gpio_in(dev, PPC6xx_INPUT_INT);
openpic_irqs[i].irq[OPENPIC_OUTPUT_CINT] =
- qdev_get_gpio_in(DEVICE(cpu), PPC6xx_INPUT_INT);
+ qdev_get_gpio_in(dev, PPC6xx_INPUT_INT);
openpic_irqs[i].irq[OPENPIC_OUTPUT_MCK] =
- qdev_get_gpio_in(DEVICE(cpu), PPC6xx_INPUT_MCP);
+ qdev_get_gpio_in(dev, PPC6xx_INPUT_MCP);
/* Not connected ? */
openpic_irqs[i].irq[OPENPIC_OUTPUT_DEBUG] = NULL;
/* Check this */
openpic_irqs[i].irq[OPENPIC_OUTPUT_RESET] =
- qdev_get_gpio_in(DEVICE(cpu), PPC6xx_INPUT_HRESET);
+ qdev_get_gpio_in(dev, PPC6xx_INPUT_HRESET);
break;
#if defined(TARGET_PPC64)
case PPC_FLAGS_INPUT_970:
openpic_irqs[i].irq[OPENPIC_OUTPUT_INT] =
- qdev_get_gpio_in(DEVICE(cpu), PPC970_INPUT_INT);
+ qdev_get_gpio_in(dev, PPC970_INPUT_INT);
openpic_irqs[i].irq[OPENPIC_OUTPUT_CINT] =
- qdev_get_gpio_in(DEVICE(cpu), PPC970_INPUT_INT);
+ qdev_get_gpio_in(dev, PPC970_INPUT_INT);
openpic_irqs[i].irq[OPENPIC_OUTPUT_MCK] =
- qdev_get_gpio_in(DEVICE(cpu), PPC970_INPUT_MCP);
+ qdev_get_gpio_in(dev, PPC970_INPUT_MCP);
/* Not connected ? */
openpic_irqs[i].irq[OPENPIC_OUTPUT_DEBUG] = NULL;
/* Check this */
openpic_irqs[i].irq[OPENPIC_OUTPUT_RESET] =
- qdev_get_gpio_in(DEVICE(cpu), PPC970_INPUT_HRESET);
+ qdev_get_gpio_in(dev, PPC970_INPUT_HRESET);
break;
#endif /* defined(TARGET_PPC64) */
default:
@@ -294,24 +294,29 @@ static void ppc_core99_init(MachineState *machine)
}
}
+ /* UniN init */
+ s = SYS_BUS_DEVICE(qdev_new(TYPE_UNI_NORTH));
+ sysbus_realize_and_unref(s, &error_fatal);
+ memory_region_add_subregion(get_system_memory(), 0xf8000000,
+ sysbus_mmio_get_region(s, 0));
+
if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) {
+ machine_arch = ARCH_MAC99_U3;
/* 970 gets a U3 bus */
/* Uninorth AGP bus */
- dev = qdev_new(TYPE_U3_AGP_HOST_BRIDGE);
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
- uninorth_pci = U3_AGP_HOST_BRIDGE(dev);
- s = SYS_BUS_DEVICE(dev);
+ uninorth_pci_dev = qdev_new(TYPE_U3_AGP_HOST_BRIDGE);
+ s = SYS_BUS_DEVICE(uninorth_pci_dev);
+ sysbus_realize_and_unref(s, &error_fatal);
+ sysbus_mmio_map(s, 0, 0xf0800000);
+ sysbus_mmio_map(s, 1, 0xf0c00000);
/* PCI hole */
- memory_region_add_subregion(get_system_memory(), 0x80000000ULL,
+ memory_region_add_subregion(get_system_memory(), 0x80000000,
sysbus_mmio_get_region(s, 2));
/* Register 8 MB of ISA IO space */
memory_region_add_subregion(get_system_memory(), 0xf2000000,
sysbus_mmio_get_region(s, 3));
- sysbus_mmio_map(s, 0, 0xf0800000);
- sysbus_mmio_map(s, 1, 0xf0c00000);
-
- machine_arch = ARCH_MAC99_U3;
} else {
+ machine_arch = ARCH_MAC99;
/* Use values found on a real PowerMac */
/* Uninorth AGP bus */
uninorth_agp_dev = qdev_new(TYPE_UNI_NORTH_AGP_HOST_BRIDGE);
@@ -328,22 +333,19 @@ static void ppc_core99_init(MachineState *machine)
sysbus_mmio_map(s, 0, 0xf4800000);
sysbus_mmio_map(s, 1, 0xf4c00000);
- /* Uninorth main bus */
- dev = qdev_new(TYPE_UNI_NORTH_PCI_HOST_BRIDGE);
- qdev_prop_set_uint32(dev, "ofw-addr", 0xf2000000);
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
- uninorth_pci = UNI_NORTH_PCI_HOST_BRIDGE(dev);
- s = SYS_BUS_DEVICE(dev);
+ /* Uninorth main bus - this must be last to make it the default */
+ uninorth_pci_dev = qdev_new(TYPE_UNI_NORTH_PCI_HOST_BRIDGE);
+ qdev_prop_set_uint32(uninorth_pci_dev, "ofw-addr", 0xf2000000);
+ s = SYS_BUS_DEVICE(uninorth_pci_dev);
+ sysbus_realize_and_unref(s, &error_fatal);
+ sysbus_mmio_map(s, 0, 0xf2800000);
+ sysbus_mmio_map(s, 1, 0xf2c00000);
/* PCI hole */
- memory_region_add_subregion(get_system_memory(), 0x80000000ULL,
+ memory_region_add_subregion(get_system_memory(), 0x80000000,
sysbus_mmio_get_region(s, 2));
/* Register 8 MB of ISA IO space */
memory_region_add_subregion(get_system_memory(), 0xf2000000,
sysbus_mmio_get_region(s, 3));
- sysbus_mmio_map(s, 0, 0xf2800000);
- sysbus_mmio_map(s, 1, 0xf2c00000);
-
- machine_arch = ARCH_MAC99;
}
machine->usb |= defaults_enabled() && !machine->usb_disabled;
@@ -351,32 +353,25 @@ static void ppc_core99_init(MachineState *machine)
has_adb = (core99_machine->via_config == CORE99_VIA_CONFIG_CUDA ||
core99_machine->via_config == CORE99_VIA_CONFIG_PMU_ADB);
- /* Timebase Frequency */
- if (kvm_enabled()) {
- tbfreq = kvmppc_get_tbfreq();
- } else {
- tbfreq = TBFREQ;
- }
-
/* init basic PC hardware */
- pci_bus = PCI_HOST_BRIDGE(uninorth_pci)->bus;
+ pci_bus = PCI_HOST_BRIDGE(uninorth_pci_dev)->bus;
/* MacIO */
- macio = pci_new(-1, TYPE_NEWWORLD_MACIO);
+ macio = OBJECT(pci_new(-1, TYPE_NEWWORLD_MACIO));
dev = DEVICE(macio);
qdev_prop_set_uint64(dev, "frequency", tbfreq);
qdev_prop_set_bit(dev, "has-pmu", has_pmu);
qdev_prop_set_bit(dev, "has-adb", has_adb);
- escc = ESCC(object_resolve_path_component(OBJECT(macio), "escc"));
- qdev_prop_set_chr(DEVICE(escc), "chrA", serial_hd(0));
- qdev_prop_set_chr(DEVICE(escc), "chrB", serial_hd(1));
+ dev = DEVICE(object_resolve_path_component(macio, "escc"));
+ qdev_prop_set_chr(dev, "chrA", serial_hd(0));
+ qdev_prop_set_chr(dev, "chrB", serial_hd(1));
- pci_realize_and_unref(macio, pci_bus, &error_fatal);
+ pci_realize_and_unref(PCI_DEVICE(macio), pci_bus, &error_fatal);
- pic_dev = DEVICE(object_resolve_path_component(OBJECT(macio), "pic"));
+ pic_dev = DEVICE(object_resolve_path_component(macio, "pic"));
for (i = 0; i < 4; i++) {
- qdev_connect_gpio_out(DEVICE(uninorth_pci), i,
+ qdev_connect_gpio_out(uninorth_pci_dev, i,
qdev_get_gpio_in(pic_dev, 0x1b + i));
}
@@ -398,7 +393,7 @@ static void ppc_core99_init(MachineState *machine)
/* OpenPIC */
s = SYS_BUS_DEVICE(pic_dev);
k = 0;
- for (i = 0; i < smp_cpus; i++) {
+ for (i = 0; i < machine->smp.cpus; i++) {
for (j = 0; j < OPENPIC_OUTPUT_NB; j++) {
sysbus_connect_irq(s, k++, openpic_irqs[i].irq[j]);
}
@@ -408,19 +403,17 @@ static void ppc_core99_init(MachineState *machine)
/* We only emulate 2 out of 3 IDE controllers for now */
ide_drive_get(hd, ARRAY_SIZE(hd));
- macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
- "ide[0]"));
+ macio_ide = MACIO_IDE(object_resolve_path_component(macio, "ide[0]"));
macio_ide_init_drives(macio_ide, hd);
- macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
- "ide[1]"));
+ macio_ide = MACIO_IDE(object_resolve_path_component(macio, "ide[1]"));
macio_ide_init_drives(macio_ide, &hd[MAX_IDE_DEVS]);
if (has_adb) {
if (has_pmu) {
- dev = DEVICE(object_resolve_path_component(OBJECT(macio), "pmu"));
+ dev = DEVICE(object_resolve_path_component(macio, "pmu"));
} else {
- dev = DEVICE(object_resolve_path_component(OBJECT(macio), "cuda"));
+ dev = DEVICE(object_resolve_path_component(macio, "cuda"));
}
adb_bus = qdev_get_child_bus(dev, "adb.0");
@@ -461,12 +454,12 @@ static void ppc_core99_init(MachineState *machine)
nvram_addr = 0xFFE00000;
}
dev = qdev_new(TYPE_MACIO_NVRAM);
- qdev_prop_set_uint32(dev, "size", 0x2000);
+ qdev_prop_set_uint32(dev, "size", MACIO_NVRAM_SIZE);
qdev_prop_set_uint32(dev, "it_shift", 1);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, nvram_addr);
nvr = MACIO_NVRAM(dev);
- pmac_format_nvram_partition(nvr, 0x2000);
+ pmac_format_nvram_partition(nvr, MACIO_NVRAM_SIZE);
/* No PCI init: the BIOS will do it */
dev = qdev_new(TYPE_FW_CFG_MEM);
@@ -480,15 +473,16 @@ static void ppc_core99_init(MachineState *machine)
sysbus_mmio_map(s, 0, CFG_ADDR);
sysbus_mmio_map(s, 1, CFG_ADDR + 2);
- fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
+ fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)machine->smp.cpus);
fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)machine->smp.max_cpus);
- fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
+ fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)machine->ram_size);
fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, machine_arch);
fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base);
fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
- if (kernel_cmdline) {
+ if (machine->kernel_cmdline) {
fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, cmdline_base);
- pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline);
+ pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE,
+ machine->kernel_cmdline);
} else {
fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
}
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 03732ca7ed..558c639202 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -30,13 +30,14 @@
#include "qapi/error.h"
#include "hw/ppc/ppc.h"
#include "hw/qdev-properties.h"
-#include "mac.h"
+#include "hw/boards.h"
#include "hw/input/adb.h"
#include "sysemu/sysemu.h"
#include "net/net.h"
#include "hw/isa/isa.h"
#include "hw/pci/pci.h"
#include "hw/pci/pci_host.h"
+#include "hw/pci-host/grackle.h"
#include "hw/nvram/fw_cfg.h"
#include "hw/char/escc.h"
#include "hw/misc/macio/macio.h"
@@ -56,10 +57,15 @@
#define NDRV_VGA_FILENAME "qemu_vga.ndrv"
-#define GRACKLE_BASE 0xfec00000
+#define PROM_FILENAME "openbios-ppc"
#define PROM_BASE 0xffc00000
#define PROM_SIZE (4 * MiB)
+#define KERNEL_LOAD_ADDR 0x01000000
+#define KERNEL_GAP 0x00100000
+
+#define GRACKLE_BASE 0xfec00000
+
static void fw_cfg_boot_set(void *opaque, const char *boot_device,
Error **errp)
{
@@ -80,33 +86,28 @@ static void ppc_heathrow_reset(void *opaque)
static void ppc_heathrow_init(MachineState *machine)
{
- ram_addr_t ram_size = machine->ram_size;
const char *bios_name = machine->firmware ?: PROM_FILENAME;
- const char *boot_device = machine->boot_config.order;
PowerPCCPU *cpu = NULL;
CPUPPCState *env = NULL;
char *filename;
- int i;
+ int i, bios_size = -1;
MemoryRegion *bios = g_new(MemoryRegion, 1);
- uint32_t kernel_base, initrd_base, cmdline_base = 0;
- int32_t kernel_size, initrd_size;
+ uint64_t bios_addr;
+ uint32_t kernel_base = 0, initrd_base = 0, cmdline_base = 0;
+ int32_t kernel_size = 0, initrd_size = 0;
PCIBus *pci_bus;
- PCIDevice *macio;
+ Object *macio;
MACIOIDEState *macio_ide;
- ESCCState *escc;
SysBusDevice *s;
DeviceState *dev, *pic_dev, *grackle_dev;
BusState *adb_bus;
- uint64_t bios_addr;
- int bios_size;
- unsigned int smp_cpus = machine->smp.cpus;
uint16_t ppc_boot_device;
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
void *fw_cfg;
- uint64_t tbfreq;
+ uint64_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TBFREQ;
/* init CPUs */
- for (i = 0; i < smp_cpus; i++) {
+ for (i = 0; i < machine->smp.cpus; i++) {
cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
env = &cpu->env;
@@ -116,9 +117,9 @@ static void ppc_heathrow_init(MachineState *machine)
}
/* allocate RAM */
- if (ram_size > 2047 * MiB) {
+ if (machine->ram_size > 2047 * MiB) {
error_report("Too much memory for this machine: %" PRId64 " MB, "
- "maximum 2047 MB", ram_size / MiB);
+ "maximum 2047 MB", machine->ram_size / MiB);
exit(1);
}
@@ -143,8 +144,6 @@ static void ppc_heathrow_init(MachineState *machine)
bios_addr = PROM_BASE;
}
g_free(filename);
- } else {
- bios_size = -1;
}
if (bios_size < 0 || bios_addr - PROM_BASE + bios_size > PROM_SIZE) {
error_report("could not load PowerPC bios '%s'", bios_name);
@@ -152,25 +151,25 @@ static void ppc_heathrow_init(MachineState *machine)
}
if (machine->kernel_filename) {
- int bswap_needed;
+ int bswap_needed = 0;
#ifdef BSWAP_NEEDED
bswap_needed = 1;
-#else
- bswap_needed = 0;
#endif
kernel_base = KERNEL_LOAD_ADDR;
kernel_size = load_elf(machine->kernel_filename, NULL,
translate_kernel_address, NULL, NULL, NULL,
NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0);
- if (kernel_size < 0)
+ if (kernel_size < 0) {
kernel_size = load_aout(machine->kernel_filename, kernel_base,
- ram_size - kernel_base, bswap_needed,
- TARGET_PAGE_SIZE);
- if (kernel_size < 0)
+ machine->ram_size - kernel_base,
+ bswap_needed, TARGET_PAGE_SIZE);
+ }
+ if (kernel_size < 0) {
kernel_size = load_image_targphys(machine->kernel_filename,
kernel_base,
- ram_size - kernel_base);
+ machine->ram_size - kernel_base);
+ }
if (kernel_size < 0) {
error_report("could not load kernel '%s'",
machine->kernel_filename);
@@ -182,7 +181,7 @@ static void ppc_heathrow_init(MachineState *machine)
KERNEL_GAP);
initrd_size = load_image_targphys(machine->initrd_filename,
initrd_base,
- ram_size - initrd_base);
+ machine->ram_size - initrd_base);
if (initrd_size < 0) {
error_report("could not load initial ram disk '%s'",
machine->initrd_filename);
@@ -190,30 +189,27 @@ static void ppc_heathrow_init(MachineState *machine)
}
cmdline_base = TARGET_PAGE_ALIGN(initrd_base + initrd_size);
} else {
- initrd_base = 0;
- initrd_size = 0;
cmdline_base = TARGET_PAGE_ALIGN(kernel_base + kernel_size + KERNEL_GAP);
}
ppc_boot_device = 'm';
} else {
- kernel_base = 0;
- kernel_size = 0;
- initrd_base = 0;
- initrd_size = 0;
ppc_boot_device = '\0';
- for (i = 0; boot_device[i] != '\0'; i++) {
- /* TOFIX: for now, the second IDE channel is not properly
+ for (i = 0; machine->boot_config.order[i] != '\0'; i++) {
+ /*
+ * TOFIX: for now, the second IDE channel is not properly
* used by OHW. The Mac floppy disk are not emulated.
* For now, OHW cannot boot from the network.
*/
#if 0
- if (boot_device[i] >= 'a' && boot_device[i] <= 'f') {
- ppc_boot_device = boot_device[i];
+ if (machine->boot_config.order[i] >= 'a' &&
+ machine->boot_config.order[i] <= 'f') {
+ ppc_boot_device = machine->boot_config.order[i];
break;
}
#else
- if (boot_device[i] >= 'c' && boot_device[i] <= 'd') {
- ppc_boot_device = boot_device[i];
+ if (machine->boot_config.order[i] >= 'c' &&
+ machine->boot_config.order[i] <= 'd') {
+ ppc_boot_device = machine->boot_config.order[i];
break;
}
#endif
@@ -224,13 +220,6 @@ static void ppc_heathrow_init(MachineState *machine)
}
}
- /* Timebase Frequency */
- if (kvm_enabled()) {
- tbfreq = kvmppc_get_tbfreq();
- } else {
- tbfreq = TBFREQ;
- }
-
/* Grackle PCI host bridge */
grackle_dev = qdev_new(TYPE_GRACKLE_PCI_HOST_BRIDGE);
qdev_prop_set_uint32(grackle_dev, "ofw-addr", 0x80000000);
@@ -249,24 +238,23 @@ static void ppc_heathrow_init(MachineState *machine)
pci_bus = PCI_HOST_BRIDGE(grackle_dev)->bus;
/* MacIO */
- macio = pci_new(PCI_DEVFN(16, 0), TYPE_OLDWORLD_MACIO);
- dev = DEVICE(macio);
- qdev_prop_set_uint64(dev, "frequency", tbfreq);
+ macio = OBJECT(pci_new(PCI_DEVFN(16, 0), TYPE_OLDWORLD_MACIO));
+ qdev_prop_set_uint64(DEVICE(macio), "frequency", tbfreq);
- escc = ESCC(object_resolve_path_component(OBJECT(macio), "escc"));
- qdev_prop_set_chr(DEVICE(escc), "chrA", serial_hd(0));
- qdev_prop_set_chr(DEVICE(escc), "chrB", serial_hd(1));
+ dev = DEVICE(object_resolve_path_component(macio, "escc"));
+ qdev_prop_set_chr(dev, "chrA", serial_hd(0));
+ qdev_prop_set_chr(dev, "chrB", serial_hd(1));
- pci_realize_and_unref(macio, pci_bus, &error_fatal);
+ pci_realize_and_unref(PCI_DEVICE(macio), pci_bus, &error_fatal);
- pic_dev = DEVICE(object_resolve_path_component(OBJECT(macio), "pic"));
+ pic_dev = DEVICE(object_resolve_path_component(macio, "pic"));
for (i = 0; i < 4; i++) {
qdev_connect_gpio_out(grackle_dev, i,
qdev_get_gpio_in(pic_dev, 0x15 + i));
}
/* Connect the heathrow PIC outputs to the 6xx bus */
- for (i = 0; i < smp_cpus; i++) {
+ for (i = 0; i < machine->smp.cpus; i++) {
switch (PPC_INPUT(env)) {
case PPC_FLAGS_INPUT_6xx:
/* XXX: we register only 1 output pin for heathrow PIC */
@@ -287,16 +275,14 @@ static void ppc_heathrow_init(MachineState *machine)
/* MacIO IDE */
ide_drive_get(hd, ARRAY_SIZE(hd));
- macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
- "ide[0]"));
+ macio_ide = MACIO_IDE(object_resolve_path_component(macio, "ide[0]"));
macio_ide_init_drives(macio_ide, hd);
- macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
- "ide[1]"));
+ macio_ide = MACIO_IDE(object_resolve_path_component(macio, "ide[1]"));
macio_ide_init_drives(macio_ide, &hd[MAX_IDE_DEVS]);
/* MacIO CUDA/ADB */
- dev = DEVICE(object_resolve_path_component(OBJECT(macio), "cuda"));
+ dev = DEVICE(object_resolve_path_component(macio, "cuda"));
adb_bus = qdev_get_child_bus(dev, "adb.0");
dev = qdev_new(TYPE_ADB_KEYBOARD);
qdev_realize_and_unref(dev, adb_bus, &error_fatal);
@@ -307,8 +293,9 @@ static void ppc_heathrow_init(MachineState *machine)
pci_create_simple(pci_bus, -1, "pci-ohci");
}
- if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8)
+ if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8) {
graphic_depth = 15;
+ }
/* No PCI init: the BIOS will do it */
@@ -323,9 +310,9 @@ static void ppc_heathrow_init(MachineState *machine)
sysbus_mmio_map(s, 0, CFG_ADDR);
sysbus_mmio_map(s, 1, CFG_ADDR + 2);
- fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
+ fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)machine->smp.cpus);
fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)machine->smp.max_cpus);
- fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
+ fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)machine->ram_size);
fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, ARCH_HEATHROW);
fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base);
fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build
index 32babc9b48..c927337da0 100644
--- a/hw/ppc/meson.build
+++ b/hw/ppc/meson.build
@@ -59,8 +59,9 @@ ppc_ss.add(when: 'CONFIG_PPC440', if_true: files(
'ppc440_bamboo.c',
'ppc440_pcix.c', 'ppc440_uc.c'))
ppc_ss.add(when: 'CONFIG_PPC4XX', if_true: files(
+ 'ppc4xx_devs.c',
'ppc4xx_pci.c',
- 'ppc4xx_devs.c'))
+ 'ppc4xx_sdram.c'))
ppc_ss.add(when: 'CONFIG_SAM460EX', if_true: files('sam460ex.c'))
# PReP
ppc_ss.add(when: 'CONFIG_PREP', if_true: files('prep.c'))
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index bb4d008ba9..f46d4bf51d 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -102,7 +102,7 @@ static void pegasos2_init(MachineState *machine)
CPUPPCState *env;
MemoryRegion *rom = g_new(MemoryRegion, 1);
PCIBus *pci_bus;
- PCIDevice *dev;
+ PCIDevice *dev, *via;
I2CBus *i2c_bus;
const char *fwname = machine->firmware ?: PROM_FILENAME;
char *filename;
@@ -159,30 +159,23 @@ static void pegasos2_init(MachineState *machine)
pci_bus = mv64361_get_pci_bus(pm->mv, 1);
/* VIA VT8231 South Bridge (multifunction PCI device) */
- /* VT8231 function 0: PCI-to-ISA Bridge */
- dev = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0), true,
+ via = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0), true,
TYPE_VT8231_ISA);
- qdev_connect_gpio_out(DEVICE(dev), 0,
+ object_property_add_alias(OBJECT(machine), "rtc-time",
+ object_resolve_path_component(OBJECT(via),
+ "rtc"),
+ "date");
+ qdev_connect_gpio_out(DEVICE(via), 0,
qdev_get_gpio_in_named(pm->mv, "gpp", 31));
- /* VT8231 function 1: IDE Controller */
- dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 1), "via-ide");
+ dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "ide"));
pci_ide_create_devs(dev);
- /* VT8231 function 2-3: USB Ports */
- pci_create_simple(pci_bus, PCI_DEVFN(12, 2), "vt82c686b-usb-uhci");
- pci_create_simple(pci_bus, PCI_DEVFN(12, 3), "vt82c686b-usb-uhci");
-
- /* VT8231 function 4: Power Management Controller */
- dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 4), TYPE_VT8231_PM);
+ dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "pm"));
i2c_bus = I2C_BUS(qdev_get_child_bus(DEVICE(dev), "i2c"));
spd_data = spd_data_generate(DDR, machine->ram_size);
smbus_eeprom_init_one(i2c_bus, 0x57, spd_data);
- /* VT8231 function 5-6: AC97 Audio & Modem */
- pci_create_simple(pci_bus, PCI_DEVFN(12, 5), TYPE_VIA_AC97);
- pci_create_simple(pci_bus, PCI_DEVFN(12, 6), TYPE_VIA_MC97);
-
/* other PC hardware */
pci_vga_init(pci_bus);
diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index 19e8eb885f..9ee79192dd 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -58,6 +58,7 @@ static void pnv_core_cpu_reset(PnvCore *pc, PowerPCCPU *cpu)
env->msr |= MSR_HVB; /* Hypervisor mode */
env->spr[SPR_HRMOR] = pc->hrmor;
hreg_compute_hflags(env);
+ ppc_maybe_interrupt(env);
pcc->intc_reset(pc->chip, cpu);
}
diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index 690f448cb9..dc86c1c7db 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -40,9 +40,8 @@
static void cpu_ppc_tb_stop (CPUPPCState *env);
static void cpu_ppc_tb_start (CPUPPCState *env);
-void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level)
+void ppc_set_irq(PowerPCCPU *cpu, int irq, int level)
{
- CPUState *cs = CPU(cpu);
CPUPPCState *env = &cpu->env;
unsigned int old_pending;
bool locked = false;
@@ -56,21 +55,17 @@ void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level)
old_pending = env->pending_interrupts;
if (level) {
- env->pending_interrupts |= 1 << n_IRQ;
- cpu_interrupt(cs, CPU_INTERRUPT_HARD);
+ env->pending_interrupts |= irq;
} else {
- env->pending_interrupts &= ~(1 << n_IRQ);
- if (env->pending_interrupts == 0) {
- cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
- }
+ env->pending_interrupts &= ~irq;
}
if (old_pending != env->pending_interrupts) {
- kvmppc_set_interrupt(cpu, n_IRQ, level);
+ ppc_maybe_interrupt(env);
+ kvmppc_set_interrupt(cpu, irq, level);
}
-
- trace_ppc_irq_set_exit(env, n_IRQ, level, env->pending_interrupts,
+ trace_ppc_irq_set_exit(env, irq, level, env->pending_interrupts,
CPU(cpu)->interrupt_request);
if (locked) {
diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index 5fbf44009e..651263926e 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -10,21 +10,14 @@
#include "qemu/osdep.h"
#include "qemu/units.h"
-#include "qemu/error-report.h"
#include "qapi/error.h"
#include "qemu/log.h"
-#include "qemu/module.h"
#include "hw/irq.h"
-#include "exec/memory.h"
-#include "cpu.h"
#include "hw/ppc/ppc4xx.h"
#include "hw/qdev-properties.h"
#include "hw/pci/pci.h"
-#include "sysemu/block-backend.h"
#include "sysemu/reset.h"
#include "ppc440.h"
-#include "qom/object.h"
-#include "trace.h"
/*****************************************************************************/
/* L2 Cache as SRAM */
@@ -479,331 +472,6 @@ void ppc4xx_sdr_init(CPUPPCState *env)
}
/*****************************************************************************/
-/* SDRAM controller */
-enum {
- SDRAM0_CFGADDR = 0x10,
- SDRAM0_CFGDATA,
- SDRAM_R0BAS = 0x40,
- SDRAM_R1BAS,
- SDRAM_R2BAS,
- SDRAM_R3BAS,
- SDRAM_CONF1HB = 0x45,
- SDRAM_PLBADDULL = 0x4a,
- SDRAM_CONF1LL = 0x4b,
- SDRAM_CONFPATHB = 0x4f,
- SDRAM_PLBADDUHB = 0x50,
-};
-
-static uint32_t sdram_ddr2_bcr(hwaddr ram_base, hwaddr ram_size)
-{
- uint32_t bcr;
-
- switch (ram_size) {
- case 8 * MiB:
- bcr = 0xffc0;
- break;
- case 16 * MiB:
- bcr = 0xff80;
- break;
- case 32 * MiB:
- bcr = 0xff00;
- break;
- case 64 * MiB:
- bcr = 0xfe00;
- break;
- case 128 * MiB:
- bcr = 0xfc00;
- break;
- case 256 * MiB:
- bcr = 0xf800;
- break;
- case 512 * MiB:
- bcr = 0xf000;
- break;
- case 1 * GiB:
- bcr = 0xe000;
- break;
- case 2 * GiB:
- bcr = 0xc000;
- break;
- case 4 * GiB:
- bcr = 0x8000;
- break;
- default:
- error_report("invalid RAM size " TARGET_FMT_plx, ram_size);
- return 0;
- }
- bcr |= ram_base >> 2 & 0xffe00000;
- bcr |= 1;
-
- return bcr;
-}
-
-static inline hwaddr sdram_ddr2_base(uint32_t bcr)
-{
- return (bcr & 0xffe00000) << 2;
-}
-
-static uint64_t sdram_ddr2_size(uint32_t bcr)
-{
- uint64_t size;
- int sh;
-
- sh = 1024 - ((bcr >> 6) & 0x3ff);
- size = 8 * MiB * sh;
-
- return size;
-}
-
-static void sdram_bank_map(Ppc4xxSdramBank *bank)
-{
- memory_region_init(&bank->container, NULL, "sdram-container", bank->size);
- memory_region_add_subregion(&bank->container, 0, &bank->ram);
- memory_region_add_subregion(get_system_memory(), bank->base,
- &bank->container);
-}
-
-static void sdram_bank_unmap(Ppc4xxSdramBank *bank)
-{
- memory_region_del_subregion(get_system_memory(), &bank->container);
- memory_region_del_subregion(&bank->container, &bank->ram);
- object_unparent(OBJECT(&bank->container));
-}
-
-static void sdram_ddr2_set_bcr(Ppc4xxSdramDdr2State *sdram, int i,
- uint32_t bcr, int enabled)
-{
- if (sdram->bank[i].bcr & 1) {
- /* First unmap RAM if enabled */
- trace_ppc4xx_sdram_unmap(sdram_ddr2_base(sdram->bank[i].bcr),
- sdram_ddr2_size(sdram->bank[i].bcr));
- sdram_bank_unmap(&sdram->bank[i]);
- }
- sdram->bank[i].bcr = bcr & 0xffe0ffc1;
- if (enabled && (bcr & 1)) {
- trace_ppc4xx_sdram_map(sdram_ddr2_base(bcr), sdram_ddr2_size(bcr));
- sdram_bank_map(&sdram->bank[i]);
- }
-}
-
-static void sdram_ddr2_map_bcr(Ppc4xxSdramDdr2State *sdram)
-{
- int i;
-
- for (i = 0; i < sdram->nbanks; i++) {
- if (sdram->bank[i].size) {
- sdram_ddr2_set_bcr(sdram, i,
- sdram_ddr2_bcr(sdram->bank[i].base,
- sdram->bank[i].size), 1);
- } else {
- sdram_ddr2_set_bcr(sdram, i, 0, 0);
- }
- }
-}
-
-static void sdram_ddr2_unmap_bcr(Ppc4xxSdramDdr2State *sdram)
-{
- int i;
-
- for (i = 0; i < sdram->nbanks; i++) {
- if (sdram->bank[i].size) {
- sdram_ddr2_set_bcr(sdram, i, sdram->bank[i].bcr & ~1, 0);
- }
- }
-}
-
-static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn)
-{
- Ppc4xxSdramDdr2State *sdram = opaque;
- uint32_t ret = 0;
-
- switch (dcrn) {
- case SDRAM_R0BAS:
- case SDRAM_R1BAS:
- case SDRAM_R2BAS:
- case SDRAM_R3BAS:
- if (sdram->bank[dcrn - SDRAM_R0BAS].size) {
- ret = sdram_ddr2_bcr(sdram->bank[dcrn - SDRAM_R0BAS].base,
- sdram->bank[dcrn - SDRAM_R0BAS].size);
- }
- break;
- case SDRAM_CONF1HB:
- case SDRAM_CONF1LL:
- case SDRAM_CONFPATHB:
- case SDRAM_PLBADDULL:
- case SDRAM_PLBADDUHB:
- break;
- case SDRAM0_CFGADDR:
- ret = sdram->addr;
- break;
- case SDRAM0_CFGDATA:
- switch (sdram->addr) {
- case 0x14: /* SDRAM_MCSTAT (405EX) */
- case 0x1F:
- ret = 0x80000000;
- break;
- case 0x21: /* SDRAM_MCOPT2 */
- ret = sdram->mcopt2;
- break;
- case 0x40: /* SDRAM_MB0CF */
- ret = 0x00008001;
- break;
- case 0x7A: /* SDRAM_DLCR */
- ret = 0x02000000;
- break;
- case 0xE1: /* SDR0_DDR0 */
- ret = SDR0_DDR0_DDRM_ENCODE(1) | SDR0_DDR0_DDRM_DDR1;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
-
- return ret;
-}
-
-#define SDRAM_DDR2_MCOPT2_DCEN BIT(27)
-
-static void sdram_ddr2_dcr_write(void *opaque, int dcrn, uint32_t val)
-{
- Ppc4xxSdramDdr2State *sdram = opaque;
-
- switch (dcrn) {
- case SDRAM_R0BAS:
- case SDRAM_R1BAS:
- case SDRAM_R2BAS:
- case SDRAM_R3BAS:
- case SDRAM_CONF1HB:
- case SDRAM_CONF1LL:
- case SDRAM_CONFPATHB:
- case SDRAM_PLBADDULL:
- case SDRAM_PLBADDUHB:
- break;
- case SDRAM0_CFGADDR:
- sdram->addr = val;
- break;
- case SDRAM0_CFGDATA:
- switch (sdram->addr) {
- case 0x00: /* B0CR */
- break;
- case 0x21: /* SDRAM_MCOPT2 */
- if (!(sdram->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) &&
- (val & SDRAM_DDR2_MCOPT2_DCEN)) {
- trace_ppc4xx_sdram_enable("enable");
- /* validate all RAM mappings */
- sdram_ddr2_map_bcr(sdram);
- sdram->mcopt2 |= SDRAM_DDR2_MCOPT2_DCEN;
- } else if ((sdram->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) &&
- !(val & SDRAM_DDR2_MCOPT2_DCEN)) {
- trace_ppc4xx_sdram_enable("disable");
- /* invalidate all RAM mappings */
- sdram_ddr2_unmap_bcr(sdram);
- sdram->mcopt2 &= ~SDRAM_DDR2_MCOPT2_DCEN;
- }
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
-}
-
-static void ppc4xx_sdram_ddr2_reset(DeviceState *dev)
-{
- Ppc4xxSdramDdr2State *sdram = PPC4xx_SDRAM_DDR2(dev);
-
- sdram->addr = 0;
- sdram->mcopt2 = 0;
-}
-
-static void ppc4xx_sdram_ddr2_realize(DeviceState *dev, Error **errp)
-{
- Ppc4xxSdramDdr2State *s = PPC4xx_SDRAM_DDR2(dev);
- Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev);
- /*
- * SoC also has 4 GiB but that causes problem with 32 bit
- * builds (4*GiB overflows the 32 bit ram_addr_t).
- */
- const ram_addr_t valid_bank_sizes[] = {
- 2 * GiB, 1 * GiB, 512 * MiB, 256 * MiB, 128 * MiB,
- 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 0
- };
-
- if (s->nbanks < 1 || s->nbanks > 4) {
- error_setg(errp, "Invalid number of RAM banks");
- return;
- }
- if (!s->dram_mr) {
- error_setg(errp, "Missing dram memory region");
- return;
- }
- ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank, valid_bank_sizes);
-
- ppc4xx_dcr_register(dcr, SDRAM0_CFGADDR,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
- ppc4xx_dcr_register(dcr, SDRAM0_CFGDATA,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
-
- ppc4xx_dcr_register(dcr, SDRAM_R0BAS,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
- ppc4xx_dcr_register(dcr, SDRAM_R1BAS,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
- ppc4xx_dcr_register(dcr, SDRAM_R2BAS,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
- ppc4xx_dcr_register(dcr, SDRAM_R3BAS,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
- ppc4xx_dcr_register(dcr, SDRAM_CONF1HB,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
- ppc4xx_dcr_register(dcr, SDRAM_PLBADDULL,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
- ppc4xx_dcr_register(dcr, SDRAM_CONF1LL,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
- ppc4xx_dcr_register(dcr, SDRAM_CONFPATHB,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
- ppc4xx_dcr_register(dcr, SDRAM_PLBADDUHB,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
-}
-
-static Property ppc4xx_sdram_ddr2_props[] = {
- DEFINE_PROP_LINK("dram", Ppc4xxSdramDdr2State, dram_mr, TYPE_MEMORY_REGION,
- MemoryRegion *),
- DEFINE_PROP_UINT32("nbanks", Ppc4xxSdramDdr2State, nbanks, 4),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void ppc4xx_sdram_ddr2_class_init(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
-
- dc->realize = ppc4xx_sdram_ddr2_realize;
- dc->reset = ppc4xx_sdram_ddr2_reset;
- /* Reason: only works as function of a ppc4xx SoC */
- dc->user_creatable = false;
- device_class_set_props(dc, ppc4xx_sdram_ddr2_props);
-}
-
-void ppc4xx_sdram_ddr2_enable(Ppc4xxSdramDdr2State *s)
-{
- sdram_ddr2_dcr_write(s, SDRAM0_CFGADDR, 0x21);
- sdram_ddr2_dcr_write(s, SDRAM0_CFGDATA, 0x08000000);
-}
-
-static const TypeInfo ppc4xx_types[] = {
- {
- .name = TYPE_PPC4xx_SDRAM_DDR2,
- .parent = TYPE_PPC4xx_DCR_DEVICE,
- .instance_size = sizeof(Ppc4xxSdramDdr2State),
- .class_init = ppc4xx_sdram_ddr2_class_init,
- }
-};
-DEFINE_TYPES(ppc4xx_types)
-
-/*****************************************************************************/
/* PLB to AHB bridge */
enum {
AHB_TOP = 0xA4,
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index 12af90f244..c1d111465d 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -23,419 +23,10 @@
*/
#include "qemu/osdep.h"
-#include "qemu/units.h"
-#include "sysemu/reset.h"
#include "cpu.h"
-#include "hw/irq.h"
-#include "hw/ppc/ppc.h"
#include "hw/ppc/ppc4xx.h"
#include "hw/qdev-properties.h"
-#include "qemu/log.h"
-#include "exec/address-spaces.h"
-#include "qemu/error-report.h"
#include "qapi/error.h"
-#include "trace.h"
-
-/*****************************************************************************/
-/* SDRAM controller */
-enum {
- SDRAM0_CFGADDR = 0x010,
- SDRAM0_CFGDATA = 0x011,
-};
-
-/*
- * XXX: TOFIX: some patches have made this code become inconsistent:
- * there are type inconsistencies, mixing hwaddr, target_ulong
- * and uint32_t
- */
-static uint32_t sdram_ddr_bcr(hwaddr ram_base, hwaddr ram_size)
-{
- uint32_t bcr;
-
- switch (ram_size) {
- case 4 * MiB:
- bcr = 0;
- break;
- case 8 * MiB:
- bcr = 0x20000;
- break;
- case 16 * MiB:
- bcr = 0x40000;
- break;
- case 32 * MiB:
- bcr = 0x60000;
- break;
- case 64 * MiB:
- bcr = 0x80000;
- break;
- case 128 * MiB:
- bcr = 0xA0000;
- break;
- case 256 * MiB:
- bcr = 0xC0000;
- break;
- default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: invalid RAM size 0x%" HWADDR_PRIx "\n", __func__,
- ram_size);
- return 0;
- }
- bcr |= ram_base & 0xFF800000;
- bcr |= 1;
-
- return bcr;
-}
-
-static inline hwaddr sdram_ddr_base(uint32_t bcr)
-{
- return bcr & 0xFF800000;
-}
-
-static target_ulong sdram_ddr_size(uint32_t bcr)
-{
- target_ulong size;
- int sh;
-
- sh = (bcr >> 17) & 0x7;
- if (sh == 7) {
- size = -1;
- } else {
- size = (4 * MiB) << sh;
- }
-
- return size;
-}
-
-static void sdram_ddr_set_bcr(Ppc4xxSdramDdrState *sdram, int i,
- uint32_t bcr, int enabled)
-{
- if (sdram->bank[i].bcr & 1) {
- /* Unmap RAM */
- trace_ppc4xx_sdram_unmap(sdram_ddr_base(sdram->bank[i].bcr),
- sdram_ddr_size(sdram->bank[i].bcr));
- memory_region_del_subregion(get_system_memory(),
- &sdram->bank[i].container);
- memory_region_del_subregion(&sdram->bank[i].container,
- &sdram->bank[i].ram);
- object_unparent(OBJECT(&sdram->bank[i].container));
- }
- sdram->bank[i].bcr = bcr & 0xFFDEE001;
- if (enabled && (bcr & 1)) {
- trace_ppc4xx_sdram_map(sdram_ddr_base(bcr), sdram_ddr_size(bcr));
- memory_region_init(&sdram->bank[i].container, NULL, "sdram-container",
- sdram_ddr_size(bcr));
- memory_region_add_subregion(&sdram->bank[i].container, 0,
- &sdram->bank[i].ram);
- memory_region_add_subregion(get_system_memory(),
- sdram_ddr_base(bcr),
- &sdram->bank[i].container);
- }
-}
-
-static void sdram_ddr_map_bcr(Ppc4xxSdramDdrState *sdram)
-{
- int i;
-
- for (i = 0; i < sdram->nbanks; i++) {
- if (sdram->bank[i].size != 0) {
- sdram_ddr_set_bcr(sdram, i, sdram_ddr_bcr(sdram->bank[i].base,
- sdram->bank[i].size), 1);
- } else {
- sdram_ddr_set_bcr(sdram, i, 0, 0);
- }
- }
-}
-
-static void sdram_ddr_unmap_bcr(Ppc4xxSdramDdrState *sdram)
-{
- int i;
-
- for (i = 0; i < sdram->nbanks; i++) {
- trace_ppc4xx_sdram_unmap(sdram_ddr_base(sdram->bank[i].bcr),
- sdram_ddr_size(sdram->bank[i].bcr));
- memory_region_del_subregion(get_system_memory(),
- &sdram->bank[i].ram);
- }
-}
-
-static uint32_t sdram_ddr_dcr_read(void *opaque, int dcrn)
-{
- Ppc4xxSdramDdrState *sdram = opaque;
- uint32_t ret;
-
- switch (dcrn) {
- case SDRAM0_CFGADDR:
- ret = sdram->addr;
- break;
- case SDRAM0_CFGDATA:
- switch (sdram->addr) {
- case 0x00: /* SDRAM_BESR0 */
- ret = sdram->besr0;
- break;
- case 0x08: /* SDRAM_BESR1 */
- ret = sdram->besr1;
- break;
- case 0x10: /* SDRAM_BEAR */
- ret = sdram->bear;
- break;
- case 0x20: /* SDRAM_CFG */
- ret = sdram->cfg;
- break;
- case 0x24: /* SDRAM_STATUS */
- ret = sdram->status;
- break;
- case 0x30: /* SDRAM_RTR */
- ret = sdram->rtr;
- break;
- case 0x34: /* SDRAM_PMIT */
- ret = sdram->pmit;
- break;
- case 0x40: /* SDRAM_B0CR */
- ret = sdram->bank[0].bcr;
- break;
- case 0x44: /* SDRAM_B1CR */
- ret = sdram->bank[1].bcr;
- break;
- case 0x48: /* SDRAM_B2CR */
- ret = sdram->bank[2].bcr;
- break;
- case 0x4C: /* SDRAM_B3CR */
- ret = sdram->bank[3].bcr;
- break;
- case 0x80: /* SDRAM_TR */
- ret = -1; /* ? */
- break;
- case 0x94: /* SDRAM_ECCCFG */
- ret = sdram->ecccfg;
- break;
- case 0x98: /* SDRAM_ECCESR */
- ret = sdram->eccesr;
- break;
- default: /* Error */
- ret = -1;
- break;
- }
- break;
- default:
- /* Avoid gcc warning */
- ret = 0;
- break;
- }
-
- return ret;
-}
-
-static void sdram_ddr_dcr_write(void *opaque, int dcrn, uint32_t val)
-{
- Ppc4xxSdramDdrState *sdram = opaque;
-
- switch (dcrn) {
- case SDRAM0_CFGADDR:
- sdram->addr = val;
- break;
- case SDRAM0_CFGDATA:
- switch (sdram->addr) {
- case 0x00: /* SDRAM_BESR0 */
- sdram->besr0 &= ~val;
- break;
- case 0x08: /* SDRAM_BESR1 */
- sdram->besr1 &= ~val;
- break;
- case 0x10: /* SDRAM_BEAR */
- sdram->bear = val;
- break;
- case 0x20: /* SDRAM_CFG */
- val &= 0xFFE00000;
- if (!(sdram->cfg & 0x80000000) && (val & 0x80000000)) {
- trace_ppc4xx_sdram_enable("enable");
- /* validate all RAM mappings */
- sdram_ddr_map_bcr(sdram);
- sdram->status &= ~0x80000000;
- } else if ((sdram->cfg & 0x80000000) && !(val & 0x80000000)) {
- trace_ppc4xx_sdram_enable("disable");
- /* invalidate all RAM mappings */
- sdram_ddr_unmap_bcr(sdram);
- sdram->status |= 0x80000000;
- }
- if (!(sdram->cfg & 0x40000000) && (val & 0x40000000)) {
- sdram->status |= 0x40000000;
- } else if ((sdram->cfg & 0x40000000) && !(val & 0x40000000)) {
- sdram->status &= ~0x40000000;
- }
- sdram->cfg = val;
- break;
- case 0x24: /* SDRAM_STATUS */
- /* Read-only register */
- break;
- case 0x30: /* SDRAM_RTR */
- sdram->rtr = val & 0x3FF80000;
- break;
- case 0x34: /* SDRAM_PMIT */
- sdram->pmit = (val & 0xF8000000) | 0x07C00000;
- break;
- case 0x40: /* SDRAM_B0CR */
- sdram_ddr_set_bcr(sdram, 0, val, sdram->cfg & 0x80000000);
- break;
- case 0x44: /* SDRAM_B1CR */
- sdram_ddr_set_bcr(sdram, 1, val, sdram->cfg & 0x80000000);
- break;
- case 0x48: /* SDRAM_B2CR */
- sdram_ddr_set_bcr(sdram, 2, val, sdram->cfg & 0x80000000);
- break;
- case 0x4C: /* SDRAM_B3CR */
- sdram_ddr_set_bcr(sdram, 3, val, sdram->cfg & 0x80000000);
- break;
- case 0x80: /* SDRAM_TR */
- sdram->tr = val & 0x018FC01F;
- break;
- case 0x94: /* SDRAM_ECCCFG */
- sdram->ecccfg = val & 0x00F00000;
- break;
- case 0x98: /* SDRAM_ECCESR */
- val &= 0xFFF0F000;
- if (sdram->eccesr == 0 && val != 0) {
- qemu_irq_raise(sdram->irq);
- } else if (sdram->eccesr != 0 && val == 0) {
- qemu_irq_lower(sdram->irq);
- }
- sdram->eccesr = val;
- break;
- default: /* Error */
- break;
- }
- break;
- }
-}
-
-static void ppc4xx_sdram_ddr_reset(DeviceState *dev)
-{
- Ppc4xxSdramDdrState *sdram = PPC4xx_SDRAM_DDR(dev);
-
- sdram->addr = 0;
- sdram->bear = 0;
- sdram->besr0 = 0; /* No error */
- sdram->besr1 = 0; /* No error */
- sdram->cfg = 0;
- sdram->ecccfg = 0; /* No ECC */
- sdram->eccesr = 0; /* No error */
- sdram->pmit = 0x07C00000;
- sdram->rtr = 0x05F00000;
- sdram->tr = 0x00854009;
- /* We pre-initialize RAM banks */
- sdram->status = 0;
- sdram->cfg = 0x00800000;
-}
-
-static void ppc4xx_sdram_ddr_realize(DeviceState *dev, Error **errp)
-{
- Ppc4xxSdramDdrState *s = PPC4xx_SDRAM_DDR(dev);
- Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev);
- const ram_addr_t valid_bank_sizes[] = {
- 256 * MiB, 128 * MiB, 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 4 * MiB, 0
- };
-
- if (s->nbanks < 1 || s->nbanks > 4) {
- error_setg(errp, "Invalid number of RAM banks");
- return;
- }
- if (!s->dram_mr) {
- error_setg(errp, "Missing dram memory region");
- return;
- }
- ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank, valid_bank_sizes);
-
- sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
-
- ppc4xx_dcr_register(dcr, SDRAM0_CFGADDR,
- s, &sdram_ddr_dcr_read, &sdram_ddr_dcr_write);
- ppc4xx_dcr_register(dcr, SDRAM0_CFGDATA,
- s, &sdram_ddr_dcr_read, &sdram_ddr_dcr_write);
-}
-
-static Property ppc4xx_sdram_ddr_props[] = {
- DEFINE_PROP_LINK("dram", Ppc4xxSdramDdrState, dram_mr, TYPE_MEMORY_REGION,
- MemoryRegion *),
- DEFINE_PROP_UINT32("nbanks", Ppc4xxSdramDdrState, nbanks, 4),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void ppc4xx_sdram_ddr_class_init(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
-
- dc->realize = ppc4xx_sdram_ddr_realize;
- dc->reset = ppc4xx_sdram_ddr_reset;
- /* Reason: only works as function of a ppc4xx SoC */
- dc->user_creatable = false;
- device_class_set_props(dc, ppc4xx_sdram_ddr_props);
-}
-
-void ppc4xx_sdram_ddr_enable(Ppc4xxSdramDdrState *s)
-{
- sdram_ddr_dcr_write(s, SDRAM0_CFGADDR, 0x20);
- sdram_ddr_dcr_write(s, SDRAM0_CFGDATA, 0x80000000);
-}
-
-/*
- * Split RAM between SDRAM banks.
- *
- * sdram_bank_sizes[] must be in descending order, that is sizes[i] > sizes[i+1]
- * and must be 0-terminated.
- *
- * The 4xx SDRAM controller supports a small number of banks, and each bank
- * must be one of a small set of sizes. The number of banks and the supported
- * sizes varies by SoC.
- */
-void ppc4xx_sdram_banks(MemoryRegion *ram, int nr_banks,
- Ppc4xxSdramBank ram_banks[],
- const ram_addr_t sdram_bank_sizes[])
-{
- ram_addr_t size_left = memory_region_size(ram);
- ram_addr_t base = 0;
- ram_addr_t bank_size;
- int i;
- int j;
-
- for (i = 0; i < nr_banks; i++) {
- for (j = 0; sdram_bank_sizes[j] != 0; j++) {
- bank_size = sdram_bank_sizes[j];
- if (bank_size <= size_left) {
- char name[32];
-
- ram_banks[i].base = base;
- ram_banks[i].size = bank_size;
- base += bank_size;
- size_left -= bank_size;
- snprintf(name, sizeof(name), "ppc4xx.sdram%d", i);
- memory_region_init_alias(&ram_banks[i].ram, NULL, name, ram,
- ram_banks[i].base, ram_banks[i].size);
- break;
- }
- }
- if (!size_left) {
- /* No need to use the remaining banks. */
- break;
- }
- }
-
- if (size_left) {
- ram_addr_t used_size = memory_region_size(ram) - size_left;
- GString *s = g_string_new(NULL);
-
- for (i = 0; sdram_bank_sizes[i]; i++) {
- g_string_append_printf(s, "%" PRIi64 "%s",
- sdram_bank_sizes[i] / MiB,
- sdram_bank_sizes[i + 1] ? ", " : "");
- }
- error_report("at most %d bank%s of %s MiB each supported",
- nr_banks, nr_banks == 1 ? "" : "s", s->str);
- error_printf("Possible valid RAM size: %" PRIi64 " MiB\n",
- used_size ? used_size / MiB : sdram_bank_sizes[i - 1] / MiB);
-
- g_string_free(s, true);
- exit(EXIT_FAILURE);
- }
-}
/*****************************************************************************/
/* MAL */
@@ -963,11 +554,6 @@ static void ppc4xx_dcr_class_init(ObjectClass *oc, void *data)
static const TypeInfo ppc4xx_types[] = {
{
- .name = TYPE_PPC4xx_SDRAM_DDR,
- .parent = TYPE_PPC4xx_DCR_DEVICE,
- .instance_size = sizeof(Ppc4xxSdramDdrState),
- .class_init = ppc4xx_sdram_ddr_class_init,
- }, {
.name = TYPE_PPC4xx_MAL,
.parent = TYPE_PPC4xx_DCR_DEVICE,
.instance_size = sizeof(Ppc4xxMalState),
diff --git a/hw/ppc/ppc4xx_sdram.c b/hw/ppc/ppc4xx_sdram.c
new file mode 100644
index 0000000000..8d7137faf3
--- /dev/null
+++ b/hw/ppc/ppc4xx_sdram.c
@@ -0,0 +1,757 @@
+/*
+ * QEMU PowerPC 4xx embedded processors SDRAM controller emulation
+ *
+ * DDR SDRAM controller:
+ * Copyright (c) 2007 Jocelyn Mayer
+ *
+ * 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.
+ *
+ * DDR2 SDRAM controller:
+ * Copyright (c) 2012 François Revol
+ * Copyright (c) 2016-2019 BALATON Zoltan
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+#include "exec/address-spaces.h" /* get_system_memory() */
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "hw/ppc/ppc4xx.h"
+#include "trace.h"
+
+/*****************************************************************************/
+/* Shared functions */
+
+/*
+ * Split RAM between SDRAM banks.
+ *
+ * sdram_bank_sizes[] must be in descending order, that is sizes[i] > sizes[i+1]
+ * and must be 0-terminated.
+ *
+ * The 4xx SDRAM controller supports a small number of banks, and each bank
+ * must be one of a small set of sizes. The number of banks and the supported
+ * sizes varies by SoC.
+ */
+static bool ppc4xx_sdram_banks(MemoryRegion *ram, int nr_banks,
+ Ppc4xxSdramBank ram_banks[],
+ const ram_addr_t sdram_bank_sizes[],
+ Error **errp)
+{
+ ERRP_GUARD();
+ ram_addr_t size_left = memory_region_size(ram);
+ ram_addr_t base = 0;
+ ram_addr_t bank_size;
+ int i;
+ int j;
+
+ for (i = 0; i < nr_banks; i++) {
+ for (j = 0; sdram_bank_sizes[j] != 0; j++) {
+ bank_size = sdram_bank_sizes[j];
+ if (bank_size <= size_left) {
+ char name[32];
+
+ ram_banks[i].base = base;
+ ram_banks[i].size = bank_size;
+ base += bank_size;
+ size_left -= bank_size;
+ snprintf(name, sizeof(name), "ppc4xx.sdram%d", i);
+ memory_region_init_alias(&ram_banks[i].ram, NULL, name, ram,
+ ram_banks[i].base, ram_banks[i].size);
+ break;
+ }
+ }
+ if (!size_left) {
+ /* No need to use the remaining banks. */
+ break;
+ }
+ }
+
+ if (size_left) {
+ ram_addr_t used_size = memory_region_size(ram) - size_left;
+ GString *s = g_string_new(NULL);
+
+ for (i = 0; sdram_bank_sizes[i]; i++) {
+ g_string_append_printf(s, "%" PRIi64 "%s",
+ sdram_bank_sizes[i] / MiB,
+ sdram_bank_sizes[i + 1] ? ", " : "");
+ }
+ error_setg(errp, "Invalid SDRAM banks");
+ error_append_hint(errp, "at most %d bank%s of %s MiB each supported\n",
+ nr_banks, nr_banks == 1 ? "" : "s", s->str);
+ error_append_hint(errp, "Possible valid RAM size: %" PRIi64 " MiB\n",
+ used_size ? used_size / MiB : sdram_bank_sizes[i - 1] / MiB);
+
+ g_string_free(s, true);
+ return false;
+ }
+ return true;
+}
+
+static void sdram_bank_map(Ppc4xxSdramBank *bank)
+{
+ trace_ppc4xx_sdram_map(bank->base, bank->size);
+ memory_region_init(&bank->container, NULL, "sdram-container", bank->size);
+ memory_region_add_subregion(&bank->container, 0, &bank->ram);
+ memory_region_add_subregion(get_system_memory(), bank->base,
+ &bank->container);
+}
+
+static void sdram_bank_unmap(Ppc4xxSdramBank *bank)
+{
+ trace_ppc4xx_sdram_unmap(bank->base, bank->size);
+ memory_region_del_subregion(get_system_memory(), &bank->container);
+ memory_region_del_subregion(&bank->container, &bank->ram);
+ object_unparent(OBJECT(&bank->container));
+}
+
+static void sdram_bank_set_bcr(Ppc4xxSdramBank *bank, uint32_t bcr,
+ hwaddr base, hwaddr size, int enabled)
+{
+ if (memory_region_is_mapped(&bank->container)) {
+ sdram_bank_unmap(bank);
+ }
+ bank->bcr = bcr;
+ bank->base = base;
+ bank->size = size;
+ if (enabled && (bcr & 1)) {
+ sdram_bank_map(bank);
+ }
+}
+
+enum {
+ SDRAM0_CFGADDR = 0x010,
+ SDRAM0_CFGDATA = 0x011,
+};
+
+/*****************************************************************************/
+/* DDR SDRAM controller */
+#define SDRAM_DDR_BCR_MASK 0xFFDEE001
+
+static uint32_t sdram_ddr_bcr(hwaddr ram_base, hwaddr ram_size)
+{
+ uint32_t bcr;
+
+ switch (ram_size) {
+ case 4 * MiB:
+ bcr = 0;
+ break;
+ case 8 * MiB:
+ bcr = 0x20000;
+ break;
+ case 16 * MiB:
+ bcr = 0x40000;
+ break;
+ case 32 * MiB:
+ bcr = 0x60000;
+ break;
+ case 64 * MiB:
+ bcr = 0x80000;
+ break;
+ case 128 * MiB:
+ bcr = 0xA0000;
+ break;
+ case 256 * MiB:
+ bcr = 0xC0000;
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: invalid RAM size 0x%" HWADDR_PRIx "\n", __func__,
+ ram_size);
+ return 0;
+ }
+ bcr |= ram_base & 0xFF800000;
+ bcr |= 1;
+
+ return bcr;
+}
+
+static inline hwaddr sdram_ddr_base(uint32_t bcr)
+{
+ return bcr & 0xFF800000;
+}
+
+static hwaddr sdram_ddr_size(uint32_t bcr)
+{
+ hwaddr size;
+ int sh;
+
+ sh = (bcr >> 17) & 0x7;
+ if (sh == 7) {
+ size = -1;
+ } else {
+ size = (4 * MiB) << sh;
+ }
+
+ return size;
+}
+
+static uint32_t sdram_ddr_dcr_read(void *opaque, int dcrn)
+{
+ Ppc4xxSdramDdrState *s = opaque;
+ uint32_t ret;
+
+ switch (dcrn) {
+ case SDRAM0_CFGADDR:
+ ret = s->addr;
+ break;
+ case SDRAM0_CFGDATA:
+ switch (s->addr) {
+ case 0x00: /* SDRAM_BESR0 */
+ ret = s->besr0;
+ break;
+ case 0x08: /* SDRAM_BESR1 */
+ ret = s->besr1;
+ break;
+ case 0x10: /* SDRAM_BEAR */
+ ret = s->bear;
+ break;
+ case 0x20: /* SDRAM_CFG */
+ ret = s->cfg;
+ break;
+ case 0x24: /* SDRAM_STATUS */
+ ret = s->status;
+ break;
+ case 0x30: /* SDRAM_RTR */
+ ret = s->rtr;
+ break;
+ case 0x34: /* SDRAM_PMIT */
+ ret = s->pmit;
+ break;
+ case 0x40: /* SDRAM_B0CR */
+ ret = s->bank[0].bcr;
+ break;
+ case 0x44: /* SDRAM_B1CR */
+ ret = s->bank[1].bcr;
+ break;
+ case 0x48: /* SDRAM_B2CR */
+ ret = s->bank[2].bcr;
+ break;
+ case 0x4C: /* SDRAM_B3CR */
+ ret = s->bank[3].bcr;
+ break;
+ case 0x80: /* SDRAM_TR */
+ ret = -1; /* ? */
+ break;
+ case 0x94: /* SDRAM_ECCCFG */
+ ret = s->ecccfg;
+ break;
+ case 0x98: /* SDRAM_ECCESR */
+ ret = s->eccesr;
+ break;
+ default: /* Error */
+ ret = -1;
+ break;
+ }
+ break;
+ default:
+ /* Avoid gcc warning */
+ ret = 0;
+ break;
+ }
+
+ return ret;
+}
+
+static void sdram_ddr_dcr_write(void *opaque, int dcrn, uint32_t val)
+{
+ Ppc4xxSdramDdrState *s = opaque;
+ int i;
+
+ switch (dcrn) {
+ case SDRAM0_CFGADDR:
+ s->addr = val;
+ break;
+ case SDRAM0_CFGDATA:
+ switch (s->addr) {
+ case 0x00: /* SDRAM_BESR0 */
+ s->besr0 &= ~val;
+ break;
+ case 0x08: /* SDRAM_BESR1 */
+ s->besr1 &= ~val;
+ break;
+ case 0x10: /* SDRAM_BEAR */
+ s->bear = val;
+ break;
+ case 0x20: /* SDRAM_CFG */
+ val &= 0xFFE00000;
+ if (!(s->cfg & 0x80000000) && (val & 0x80000000)) {
+ trace_ppc4xx_sdram_enable("enable");
+ /* validate all RAM mappings */
+ for (i = 0; i < s->nbanks; i++) {
+ if (s->bank[i].size) {
+ sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr,
+ s->bank[i].base, s->bank[i].size,
+ 1);
+ }
+ }
+ s->status &= ~0x80000000;
+ } else if ((s->cfg & 0x80000000) && !(val & 0x80000000)) {
+ trace_ppc4xx_sdram_enable("disable");
+ /* invalidate all RAM mappings */
+ for (i = 0; i < s->nbanks; i++) {
+ if (s->bank[i].size) {
+ sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr,
+ s->bank[i].base, s->bank[i].size,
+ 0);
+ }
+ }
+ s->status |= 0x80000000;
+ }
+ if (!(s->cfg & 0x40000000) && (val & 0x40000000)) {
+ s->status |= 0x40000000;
+ } else if ((s->cfg & 0x40000000) && !(val & 0x40000000)) {
+ s->status &= ~0x40000000;
+ }
+ s->cfg = val;
+ break;
+ case 0x24: /* SDRAM_STATUS */
+ /* Read-only register */
+ break;
+ case 0x30: /* SDRAM_RTR */
+ s->rtr = val & 0x3FF80000;
+ break;
+ case 0x34: /* SDRAM_PMIT */
+ s->pmit = (val & 0xF8000000) | 0x07C00000;
+ break;
+ case 0x40: /* SDRAM_B0CR */
+ case 0x44: /* SDRAM_B1CR */
+ case 0x48: /* SDRAM_B2CR */
+ case 0x4C: /* SDRAM_B3CR */
+ i = (s->addr - 0x40) / 4;
+ val &= SDRAM_DDR_BCR_MASK;
+ if (s->bank[i].size) {
+ sdram_bank_set_bcr(&s->bank[i], val,
+ sdram_ddr_base(val), sdram_ddr_size(val),
+ s->cfg & 0x80000000);
+ }
+ break;
+ case 0x80: /* SDRAM_TR */
+ s->tr = val & 0x018FC01F;
+ break;
+ case 0x94: /* SDRAM_ECCCFG */
+ s->ecccfg = val & 0x00F00000;
+ break;
+ case 0x98: /* SDRAM_ECCESR */
+ val &= 0xFFF0F000;
+ if (s->eccesr == 0 && val != 0) {
+ qemu_irq_raise(s->irq);
+ } else if (s->eccesr != 0 && val == 0) {
+ qemu_irq_lower(s->irq);
+ }
+ s->eccesr = val;
+ break;
+ default: /* Error */
+ break;
+ }
+ break;
+ }
+}
+
+static void ppc4xx_sdram_ddr_reset(DeviceState *dev)
+{
+ Ppc4xxSdramDdrState *s = PPC4xx_SDRAM_DDR(dev);
+
+ s->addr = 0;
+ s->bear = 0;
+ s->besr0 = 0; /* No error */
+ s->besr1 = 0; /* No error */
+ s->cfg = 0;
+ s->ecccfg = 0; /* No ECC */
+ s->eccesr = 0; /* No error */
+ s->pmit = 0x07C00000;
+ s->rtr = 0x05F00000;
+ s->tr = 0x00854009;
+ /* We pre-initialize RAM banks */
+ s->status = 0;
+ s->cfg = 0x00800000;
+}
+
+static void ppc4xx_sdram_ddr_realize(DeviceState *dev, Error **errp)
+{
+ Ppc4xxSdramDdrState *s = PPC4xx_SDRAM_DDR(dev);
+ Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev);
+ const ram_addr_t valid_bank_sizes[] = {
+ 256 * MiB, 128 * MiB, 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 4 * MiB, 0
+ };
+ int i;
+
+ if (s->nbanks < 1 || s->nbanks > 4) {
+ error_setg(errp, "Invalid number of RAM banks");
+ return;
+ }
+ if (!s->dram_mr) {
+ error_setg(errp, "Missing dram memory region");
+ return;
+ }
+ if (!ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank,
+ valid_bank_sizes, errp)) {
+ return;
+ }
+ for (i = 0; i < s->nbanks; i++) {
+ if (s->bank[i].size) {
+ s->bank[i].bcr = sdram_ddr_bcr(s->bank[i].base, s->bank[i].size);
+ sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr,
+ s->bank[i].base, s->bank[i].size, 0);
+ } else {
+ sdram_bank_set_bcr(&s->bank[i], 0, 0, 0, 0);
+ }
+ trace_ppc4xx_sdram_init(sdram_ddr_base(s->bank[i].bcr),
+ sdram_ddr_size(s->bank[i].bcr),
+ s->bank[i].bcr);
+ }
+
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
+
+ ppc4xx_dcr_register(dcr, SDRAM0_CFGADDR,
+ s, &sdram_ddr_dcr_read, &sdram_ddr_dcr_write);
+ ppc4xx_dcr_register(dcr, SDRAM0_CFGDATA,
+ s, &sdram_ddr_dcr_read, &sdram_ddr_dcr_write);
+}
+
+static Property ppc4xx_sdram_ddr_props[] = {
+ DEFINE_PROP_LINK("dram", Ppc4xxSdramDdrState, dram_mr, TYPE_MEMORY_REGION,
+ MemoryRegion *),
+ DEFINE_PROP_UINT32("nbanks", Ppc4xxSdramDdrState, nbanks, 4),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ppc4xx_sdram_ddr_class_init(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+
+ dc->realize = ppc4xx_sdram_ddr_realize;
+ dc->reset = ppc4xx_sdram_ddr_reset;
+ /* Reason: only works as function of a ppc4xx SoC */
+ dc->user_creatable = false;
+ device_class_set_props(dc, ppc4xx_sdram_ddr_props);
+}
+
+void ppc4xx_sdram_ddr_enable(Ppc4xxSdramDdrState *s)
+{
+ sdram_ddr_dcr_write(s, SDRAM0_CFGADDR, 0x20);
+ sdram_ddr_dcr_write(s, SDRAM0_CFGDATA, 0x80000000);
+}
+
+/*****************************************************************************/
+/* DDR2 SDRAM controller */
+#define SDRAM_DDR2_BCR_MASK 0xffe0ffc1
+
+enum {
+ SDRAM_R0BAS = 0x40,
+ SDRAM_R1BAS,
+ SDRAM_R2BAS,
+ SDRAM_R3BAS,
+ SDRAM_CONF1HB = 0x45,
+ SDRAM_PLBADDULL = 0x4a,
+ SDRAM_CONF1LL = 0x4b,
+ SDRAM_CONFPATHB = 0x4f,
+ SDRAM_PLBADDUHB = 0x50,
+};
+
+static uint32_t sdram_ddr2_bcr(hwaddr ram_base, hwaddr ram_size)
+{
+ uint32_t bcr;
+
+ switch (ram_size) {
+ case 8 * MiB:
+ bcr = 0xffc0;
+ break;
+ case 16 * MiB:
+ bcr = 0xff80;
+ break;
+ case 32 * MiB:
+ bcr = 0xff00;
+ break;
+ case 64 * MiB:
+ bcr = 0xfe00;
+ break;
+ case 128 * MiB:
+ bcr = 0xfc00;
+ break;
+ case 256 * MiB:
+ bcr = 0xf800;
+ break;
+ case 512 * MiB:
+ bcr = 0xf000;
+ break;
+ case 1 * GiB:
+ bcr = 0xe000;
+ break;
+ case 2 * GiB:
+ bcr = 0xc000;
+ break;
+ case 4 * GiB:
+ bcr = 0x8000;
+ break;
+ default:
+ error_report("invalid RAM size " TARGET_FMT_plx, ram_size);
+ return 0;
+ }
+ bcr |= ram_base >> 2 & 0xffe00000;
+ bcr |= 1;
+
+ return bcr;
+}
+
+static inline hwaddr sdram_ddr2_base(uint32_t bcr)
+{
+ return (bcr & 0xffe00000) << 2;
+}
+
+static hwaddr sdram_ddr2_size(uint32_t bcr)
+{
+ hwaddr size;
+ int sh;
+
+ sh = 1024 - ((bcr >> 6) & 0x3ff);
+ size = 8 * MiB * sh;
+
+ return size;
+}
+
+static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn)
+{
+ Ppc4xxSdramDdr2State *s = opaque;
+ uint32_t ret = 0;
+
+ switch (dcrn) {
+ case SDRAM_R0BAS:
+ case SDRAM_R1BAS:
+ case SDRAM_R2BAS:
+ case SDRAM_R3BAS:
+ if (s->bank[dcrn - SDRAM_R0BAS].size) {
+ ret = sdram_ddr2_bcr(s->bank[dcrn - SDRAM_R0BAS].base,
+ s->bank[dcrn - SDRAM_R0BAS].size);
+ }
+ break;
+ case SDRAM_CONF1HB:
+ case SDRAM_CONF1LL:
+ case SDRAM_CONFPATHB:
+ case SDRAM_PLBADDULL:
+ case SDRAM_PLBADDUHB:
+ break;
+ case SDRAM0_CFGADDR:
+ ret = s->addr;
+ break;
+ case SDRAM0_CFGDATA:
+ switch (s->addr) {
+ case 0x14: /* SDRAM_MCSTAT (405EX) */
+ case 0x1F:
+ ret = 0x80000000;
+ break;
+ case 0x21: /* SDRAM_MCOPT2 */
+ ret = s->mcopt2;
+ break;
+ case 0x40: /* SDRAM_MB0CF */
+ ret = 0x00008001;
+ break;
+ case 0x7A: /* SDRAM_DLCR */
+ ret = 0x02000000;
+ break;
+ case 0xE1: /* SDR0_DDR0 */
+ ret = SDR0_DDR0_DDRM_ENCODE(1) | SDR0_DDR0_DDRM_DDR1;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+#define SDRAM_DDR2_MCOPT2_DCEN BIT(27)
+
+static void sdram_ddr2_dcr_write(void *opaque, int dcrn, uint32_t val)
+{
+ Ppc4xxSdramDdr2State *s = opaque;
+ int i;
+
+ switch (dcrn) {
+ case SDRAM_R0BAS:
+ case SDRAM_R1BAS:
+ case SDRAM_R2BAS:
+ case SDRAM_R3BAS:
+ case SDRAM_CONF1HB:
+ case SDRAM_CONF1LL:
+ case SDRAM_CONFPATHB:
+ case SDRAM_PLBADDULL:
+ case SDRAM_PLBADDUHB:
+ break;
+ case SDRAM0_CFGADDR:
+ s->addr = val;
+ break;
+ case SDRAM0_CFGDATA:
+ switch (s->addr) {
+ case 0x00: /* B0CR */
+ break;
+ case 0x21: /* SDRAM_MCOPT2 */
+ if (!(s->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) &&
+ (val & SDRAM_DDR2_MCOPT2_DCEN)) {
+ trace_ppc4xx_sdram_enable("enable");
+ /* validate all RAM mappings */
+ for (i = 0; i < s->nbanks; i++) {
+ if (s->bank[i].size) {
+ sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr,
+ s->bank[i].base, s->bank[i].size,
+ 1);
+ }
+ }
+ s->mcopt2 |= SDRAM_DDR2_MCOPT2_DCEN;
+ } else if ((s->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) &&
+ !(val & SDRAM_DDR2_MCOPT2_DCEN)) {
+ trace_ppc4xx_sdram_enable("disable");
+ /* invalidate all RAM mappings */
+ for (i = 0; i < s->nbanks; i++) {
+ if (s->bank[i].size) {
+ sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr,
+ s->bank[i].base, s->bank[i].size,
+ 0);
+ }
+ }
+ s->mcopt2 &= ~SDRAM_DDR2_MCOPT2_DCEN;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void ppc4xx_sdram_ddr2_reset(DeviceState *dev)
+{
+ Ppc4xxSdramDdr2State *s = PPC4xx_SDRAM_DDR2(dev);
+
+ s->addr = 0;
+ s->mcopt2 = 0;
+}
+
+static void ppc4xx_sdram_ddr2_realize(DeviceState *dev, Error **errp)
+{
+ Ppc4xxSdramDdr2State *s = PPC4xx_SDRAM_DDR2(dev);
+ Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev);
+ /*
+ * SoC also has 4 GiB but that causes problem with 32 bit
+ * builds (4*GiB overflows the 32 bit ram_addr_t).
+ */
+ const ram_addr_t valid_bank_sizes[] = {
+ 2 * GiB, 1 * GiB, 512 * MiB, 256 * MiB, 128 * MiB,
+ 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 0
+ };
+ int i;
+
+ if (s->nbanks < 1 || s->nbanks > 4) {
+ error_setg(errp, "Invalid number of RAM banks");
+ return;
+ }
+ if (!s->dram_mr) {
+ error_setg(errp, "Missing dram memory region");
+ return;
+ }
+ if (!ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank,
+ valid_bank_sizes, errp)) {
+ return;
+ }
+ for (i = 0; i < s->nbanks; i++) {
+ if (s->bank[i].size) {
+ s->bank[i].bcr = sdram_ddr2_bcr(s->bank[i].base, s->bank[i].size);
+ s->bank[i].bcr &= SDRAM_DDR2_BCR_MASK;
+ sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr,
+ s->bank[i].base, s->bank[i].size, 0);
+ } else {
+ sdram_bank_set_bcr(&s->bank[i], 0, 0, 0, 0);
+ }
+ trace_ppc4xx_sdram_init(sdram_ddr2_base(s->bank[i].bcr),
+ sdram_ddr2_size(s->bank[i].bcr),
+ s->bank[i].bcr);
+ }
+
+ ppc4xx_dcr_register(dcr, SDRAM0_CFGADDR,
+ s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
+ ppc4xx_dcr_register(dcr, SDRAM0_CFGDATA,
+ s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
+
+ ppc4xx_dcr_register(dcr, SDRAM_R0BAS,
+ s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
+ ppc4xx_dcr_register(dcr, SDRAM_R1BAS,
+ s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
+ ppc4xx_dcr_register(dcr, SDRAM_R2BAS,
+ s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
+ ppc4xx_dcr_register(dcr, SDRAM_R3BAS,
+ s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
+ ppc4xx_dcr_register(dcr, SDRAM_CONF1HB,
+ s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
+ ppc4xx_dcr_register(dcr, SDRAM_PLBADDULL,
+ s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
+ ppc4xx_dcr_register(dcr, SDRAM_CONF1LL,
+ s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
+ ppc4xx_dcr_register(dcr, SDRAM_CONFPATHB,
+ s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
+ ppc4xx_dcr_register(dcr, SDRAM_PLBADDUHB,
+ s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
+}
+
+static Property ppc4xx_sdram_ddr2_props[] = {
+ DEFINE_PROP_LINK("dram", Ppc4xxSdramDdr2State, dram_mr, TYPE_MEMORY_REGION,
+ MemoryRegion *),
+ DEFINE_PROP_UINT32("nbanks", Ppc4xxSdramDdr2State, nbanks, 4),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ppc4xx_sdram_ddr2_class_init(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+
+ dc->realize = ppc4xx_sdram_ddr2_realize;
+ dc->reset = ppc4xx_sdram_ddr2_reset;
+ /* Reason: only works as function of a ppc4xx SoC */
+ dc->user_creatable = false;
+ device_class_set_props(dc, ppc4xx_sdram_ddr2_props);
+}
+
+void ppc4xx_sdram_ddr2_enable(Ppc4xxSdramDdr2State *s)
+{
+ sdram_ddr2_dcr_write(s, SDRAM0_CFGADDR, 0x21);
+ sdram_ddr2_dcr_write(s, SDRAM0_CFGDATA, 0x08000000);
+}
+
+static const TypeInfo ppc4xx_sdram_types[] = {
+ {
+ .name = TYPE_PPC4xx_SDRAM_DDR,
+ .parent = TYPE_PPC4xx_DCR_DEVICE,
+ .instance_size = sizeof(Ppc4xxSdramDdrState),
+ .class_init = ppc4xx_sdram_ddr_class_init,
+ }, {
+ .name = TYPE_PPC4xx_SDRAM_DDR2,
+ .parent = TYPE_PPC4xx_DCR_DEVICE,
+ .instance_size = sizeof(Ppc4xxSdramDdr2State),
+ .class_init = ppc4xx_sdram_ddr2_class_init,
+ }
+};
+
+DEFINE_TYPES(ppc4xx_sdram_types)
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index f08714f2ec..fcbe4c5837 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -50,8 +50,6 @@
/* SMP is not enabled, for now */
#define MAX_CPUS 1
-#define MAX_IDE_BUS 2
-
#define CFG_ADDR 0xf0000510
#define KERNEL_LOAD_ADDR 0x01000000
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 891206e893..925ff523cc 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -490,6 +490,7 @@ static target_ulong h_cede(PowerPCCPU *cpu, SpaprMachineState *spapr,
env->msr |= (1ULL << MSR_EE);
hreg_compute_hflags(env);
+ ppc_maybe_interrupt(env);
if (spapr_cpu->prod) {
spapr_cpu->prod = false;
@@ -500,6 +501,7 @@ static target_ulong h_cede(PowerPCCPU *cpu, SpaprMachineState *spapr,
cs->halted = 1;
cs->exception_index = EXCP_HLT;
cs->exit_request = 1;
+ ppc_maybe_interrupt(env);
}
return H_SUCCESS;
@@ -521,6 +523,7 @@ static target_ulong h_confer_self(PowerPCCPU *cpu)
cs->halted = 1;
cs->exception_index = EXCP_HALTED;
cs->exit_request = 1;
+ ppc_maybe_interrupt(&cpu->env);
return H_SUCCESS;
}
@@ -633,6 +636,7 @@ static target_ulong h_prod(PowerPCCPU *cpu, SpaprMachineState *spapr,
spapr_cpu = spapr_cpu_state(tcpu);
spapr_cpu->prod = true;
cs->halted = 0;
+ ppc_maybe_interrupt(&cpu->env);
qemu_cpu_kick(cs);
return H_SUCCESS;
@@ -1669,6 +1673,7 @@ static target_ulong h_enter_nested(PowerPCCPU *cpu,
spapr_cpu->in_nested = true;
hreg_compute_hflags(env);
+ ppc_maybe_interrupt(env);
tlb_flush(cs);
env->reserve_addr = -1; /* Reset the reservation */
@@ -1810,6 +1815,7 @@ out_restore_l1:
spapr_cpu->in_nested = false;
hreg_compute_hflags(env);
+ ppc_maybe_interrupt(env);
tlb_flush(cs);
env->reserve_addr = -1; /* Reset the reservation */
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index d58b65e88f..3f664ea02c 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -214,9 +214,9 @@ static void rtas_stop_self(PowerPCCPU *cpu, SpaprMachineState *spapr,
* guest.
* For the same reason, set PSSCR_EC.
*/
- ppc_store_lpcr(cpu, env->spr[SPR_LPCR] & ~pcc->lpcr_pm);
env->spr[SPR_PSSCR] |= PSSCR_EC;
cs->halted = 1;
+ ppc_store_lpcr(cpu, env->spr[SPR_LPCR] & ~pcc->lpcr_pm);
kvmppc_set_reg_ppc_online(cpu, 0);
qemu_cpu_kick(cs);
}
diff --git a/hw/ppc/trace-events b/hw/ppc/trace-events
index a07d5aca0f..f670e8906c 100644
--- a/hw/ppc/trace-events
+++ b/hw/ppc/trace-events
@@ -127,7 +127,7 @@ ppc40x_set_tb_clk(uint32_t value) "new frequency %" PRIu32
ppc40x_timers_init(uint32_t value) "frequency %" PRIu32
ppc_irq_set(void *env, uint32_t pin, uint32_t level) "env [%p] pin %d level %d"
-ppc_irq_set_exit(void *env, uint32_t n_IRQ, uint32_t level, uint32_t pending, uint32_t request) "env [%p] n_IRQ %d level %d => pending 0x%08" PRIx32 " req 0x%08" PRIx32
+ppc_irq_set_exit(void *env, uint32_t irq, uint32_t level, uint32_t pending, uint32_t request) "env [%p] irq 0x%05" PRIx32 " level %d => pending 0x%08" PRIx32 " req 0x%08" PRIx32
ppc_irq_set_state(const char *name, uint32_t level) "\"%s\" level %d"
ppc_irq_reset(const char *name) "%s"
ppc_irq_cpu(const char *action) "%s"
@@ -179,3 +179,4 @@ ppc405ep_clocks_setup(const char *trace) "%s"
ppc4xx_sdram_enable(const char *trace) "%s SDRAM controller"
ppc4xx_sdram_unmap(uint64_t addr, uint64_t size) "Unmap RAM area 0x%" PRIx64 " size 0x%" PRIx64
ppc4xx_sdram_map(uint64_t addr, uint64_t size) "Map RAM area 0x%" PRIx64 " size 0x%" PRIx64
+ppc4xx_sdram_init(uint64_t base, uint64_t size, uint32_t bcr) "Init RAM area 0x%" PRIx64 " size 0x%" PRIx64 " bcr 0x%x"
diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c
index 728ba24547..8dfe92d8df 100644
--- a/hw/s390x/pv.c
+++ b/hw/s390x/pv.c
@@ -50,7 +50,7 @@ static int __s390_pv_cmd(uint32_t cmd, const char *cmdname, void *data)
* This macro lets us pass the command as a string to the function so
* we can print it on an error.
*/
-#define s390_pv_cmd(cmd, data) __s390_pv_cmd(cmd, #cmd, data);
+#define s390_pv_cmd(cmd, data) __s390_pv_cmd(cmd, #cmd, data)
#define s390_pv_cmd_exit(cmd, data) \
{ \
int rc; \
diff --git a/hw/s390x/tod-kvm.c b/hw/s390x/tod-kvm.c
index 9d0cbfbce2..e2202dae2d 100644
--- a/hw/s390x/tod-kvm.c
+++ b/hw/s390x/tod-kvm.c
@@ -13,6 +13,7 @@
#include "qemu/module.h"
#include "sysemu/runstate.h"
#include "hw/s390x/tod.h"
+#include "hw/s390x/pv.h"
#include "kvm/kvm_s390x.h"
static void kvm_s390_get_tod_raw(S390TOD *tod, Error **errp)
@@ -84,6 +85,14 @@ static void kvm_s390_tod_vm_state_change(void *opaque, bool running,
S390TODState *td = opaque;
Error *local_err = NULL;
+ /*
+ * Under PV, the clock is under ultravisor control, hence we cannot restore
+ * it on resume.
+ */
+ if (s390_is_pv()) {
+ return;
+ }
+
if (running && td->stopped) {
/* Set the old TOD when running the VM - start the TOD clock. */
kvm_s390_set_tod_raw(&td->base, &local_err);
diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
index e8c753d6d1..964570f8e8 100644
--- a/hw/sd/sdhci-internal.h
+++ b/hw/sd/sdhci-internal.h
@@ -288,26 +288,6 @@ enum {
extern const VMStateDescription sdhci_vmstate;
-
-#define ESDHC_MIX_CTRL 0x48
-
-#define ESDHC_VENDOR_SPEC 0xc0
-#define ESDHC_IMX_FRC_SDCLK_ON (1 << 8)
-
-#define ESDHC_DLL_CTRL 0x60
-
-#define ESDHC_TUNING_CTRL 0xcc
-#define ESDHC_TUNE_CTRL_STATUS 0x68
-#define ESDHC_WTMK_LVL 0x44
-
-/* Undocumented register used by guests working around erratum ERR004536 */
-#define ESDHC_UNDOCUMENTED_REG27 0x6c
-
-#define ESDHC_CTRL_4BITBUS (0x1 << 1)
-#define ESDHC_CTRL_8BITBUS (0x2 << 1)
-
-#define ESDHC_PRNSTS_SDSTB (1 << 3)
-
/*
* Default SD/MMC host controller features information, which will be
* presented in CAPABILITIES register of generic SD host controller at reset.
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 0e5e988927..306070c872 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1577,6 +1577,25 @@ static const TypeInfo sdhci_bus_info = {
/* --- qdev i.MX eSDHC --- */
+#define USDHC_MIX_CTRL 0x48
+
+#define USDHC_VENDOR_SPEC 0xc0
+#define USDHC_IMX_FRC_SDCLK_ON (1 << 8)
+
+#define USDHC_DLL_CTRL 0x60
+
+#define USDHC_TUNING_CTRL 0xcc
+#define USDHC_TUNE_CTRL_STATUS 0x68
+#define USDHC_WTMK_LVL 0x44
+
+/* Undocumented register used by guests working around erratum ERR004536 */
+#define USDHC_UNDOCUMENTED_REG27 0x6c
+
+#define USDHC_CTRL_4BITBUS (0x1 << 1)
+#define USDHC_CTRL_8BITBUS (0x2 << 1)
+
+#define USDHC_PRNSTS_SDSTB (1 << 3)
+
static uint64_t usdhc_read(void *opaque, hwaddr offset, unsigned size)
{
SDHCIState *s = SYSBUS_SDHCI(opaque);
@@ -1596,11 +1615,11 @@ static uint64_t usdhc_read(void *opaque, hwaddr offset, unsigned size)
hostctl1 = SDHC_DMA_TYPE(s->hostctl1) << (8 - 3);
if (s->hostctl1 & SDHC_CTRL_8BITBUS) {
- hostctl1 |= ESDHC_CTRL_8BITBUS;
+ hostctl1 |= USDHC_CTRL_8BITBUS;
}
if (s->hostctl1 & SDHC_CTRL_4BITBUS) {
- hostctl1 |= ESDHC_CTRL_4BITBUS;
+ hostctl1 |= USDHC_CTRL_4BITBUS;
}
ret = hostctl1;
@@ -1611,21 +1630,21 @@ static uint64_t usdhc_read(void *opaque, hwaddr offset, unsigned size)
case SDHC_PRNSTS:
/* Add SDSTB (SD Clock Stable) bit to PRNSTS */
- ret = sdhci_read(opaque, offset, size) & ~ESDHC_PRNSTS_SDSTB;
+ ret = sdhci_read(opaque, offset, size) & ~USDHC_PRNSTS_SDSTB;
if (s->clkcon & SDHC_CLOCK_INT_STABLE) {
- ret |= ESDHC_PRNSTS_SDSTB;
+ ret |= USDHC_PRNSTS_SDSTB;
}
break;
- case ESDHC_VENDOR_SPEC:
+ case USDHC_VENDOR_SPEC:
ret = s->vendor_spec;
break;
- case ESDHC_DLL_CTRL:
- case ESDHC_TUNE_CTRL_STATUS:
- case ESDHC_UNDOCUMENTED_REG27:
- case ESDHC_TUNING_CTRL:
- case ESDHC_MIX_CTRL:
- case ESDHC_WTMK_LVL:
+ case USDHC_DLL_CTRL:
+ case USDHC_TUNE_CTRL_STATUS:
+ case USDHC_UNDOCUMENTED_REG27:
+ case USDHC_TUNING_CTRL:
+ case USDHC_MIX_CTRL:
+ case USDHC_WTMK_LVL:
ret = 0;
break;
}
@@ -1641,18 +1660,18 @@ usdhc_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
uint32_t value = (uint32_t)val;
switch (offset) {
- case ESDHC_DLL_CTRL:
- case ESDHC_TUNE_CTRL_STATUS:
- case ESDHC_UNDOCUMENTED_REG27:
- case ESDHC_TUNING_CTRL:
- case ESDHC_WTMK_LVL:
+ case USDHC_DLL_CTRL:
+ case USDHC_TUNE_CTRL_STATUS:
+ case USDHC_UNDOCUMENTED_REG27:
+ case USDHC_TUNING_CTRL:
+ case USDHC_WTMK_LVL:
break;
- case ESDHC_VENDOR_SPEC:
+ case USDHC_VENDOR_SPEC:
s->vendor_spec = value;
switch (s->vendor) {
case SDHCI_VENDOR_IMX:
- if (value & ESDHC_IMX_FRC_SDCLK_ON) {
+ if (value & USDHC_IMX_FRC_SDCLK_ON) {
s->prnsts &= ~SDHC_IMX_CLOCK_GATE_OFF;
} else {
s->prnsts |= SDHC_IMX_CLOCK_GATE_OFF;
@@ -1721,12 +1740,12 @@ usdhc_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
* Second, split "Data Transfer Width" from bits 2 and 1 in to
* bits 5 and 1
*/
- if (value & ESDHC_CTRL_8BITBUS) {
+ if (value & USDHC_CTRL_8BITBUS) {
hostctl1 |= SDHC_CTRL_8BITBUS;
}
- if (value & ESDHC_CTRL_4BITBUS) {
- hostctl1 |= ESDHC_CTRL_4BITBUS;
+ if (value & USDHC_CTRL_4BITBUS) {
+ hostctl1 |= USDHC_CTRL_4BITBUS;
}
/*
@@ -1749,7 +1768,7 @@ usdhc_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
sdhci_write(opaque, offset, value, size);
break;
- case ESDHC_MIX_CTRL:
+ case USDHC_MIX_CTRL:
/*
* So, when SD/MMC stack in Linux tries to write to "Transfer
* Mode Register", ESDHC i.MX quirk code will translate it
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 0e27715ac4..387181ff77 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -66,7 +66,6 @@
#define PBM_PCI_IO_BASE (PBM_SPECIAL_BASE + 0x02000000ULL)
#define PROM_FILENAME "openbios-sparc64"
#define NVRAM_SIZE 0x2000
-#define MAX_IDE_BUS 2
#define BIOS_CFG_IOPORT 0x510
#define FW_CFG_SPARC64_WIDTH (FW_CFG_ARCH_LOCAL + 0x00)
#define FW_CFG_SPARC64_HEIGHT (FW_CFG_ARCH_LOCAL + 0x01)
diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
index 5831395cef..1cac1cd435 100644
--- a/hw/usb/dev-mtp.c
+++ b/hw/usb/dev-mtp.c
@@ -14,7 +14,7 @@
#include "qemu/error-report.h"
#include <wchar.h>
#include <dirent.h>
-
+#include <glib/gstdio.h>
#include <sys/statvfs.h>
@@ -1622,7 +1622,7 @@ static void usb_mtp_write_data(MTPState *s, uint32_t handle)
if (s->dataset.filename) {
path = g_strdup_printf("%s/%s", parent->path, s->dataset.filename);
if (s->dataset.format == FMT_ASSOCIATION) {
- ret = mkdir(path, mask);
+ ret = g_mkdir(path, mask);
if (!ret) {
usb_mtp_queue_result(s, RES_OK, d->trans, 3,
QEMU_STORAGE_ID,
diff --git a/hw/usb/vt82c686-uhci-pci.c b/hw/usb/vt82c686-uhci-pci.c
index 0bf2b72ff0..46a901f56f 100644
--- a/hw/usb/vt82c686-uhci-pci.c
+++ b/hw/usb/vt82c686-uhci-pci.c
@@ -31,7 +31,7 @@ static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error **errp)
static UHCIInfo uhci_info[] = {
{
- .name = "vt82c686b-usb-uhci",
+ .name = TYPE_VT82C686B_USB_UHCI,
.vendor_id = PCI_VENDOR_ID_VIA,
.device_id = PCI_DEVICE_ID_VIA_UHCI,
.revision = 0x01,
@@ -45,7 +45,7 @@ static UHCIInfo uhci_info[] = {
static const TypeInfo vt82c686b_usb_uhci_type_info = {
.parent = TYPE_UHCI,
- .name = "vt82c686b-usb-uhci",
+ .name = TYPE_VT82C686B_USB_UHCI,
.class_init = uhci_data_class_init,
.class_data = uhci_info,
};