aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules3
-rw-r--r--device-hotplug.c4
-rw-r--r--docs/qemupciserial.inf167
-rw-r--r--hw/arm/spitz.c13
-rw-r--r--hw/block/m25p80.c9
-rw-r--r--hw/char/virtio-console.c57
-rw-r--r--hw/char/virtio-serial-bus.c51
-rw-r--r--hw/core/Makefile.objs2
-rw-r--r--hw/core/machine.c28
-rw-r--r--hw/core/qdev.c87
-rw-r--r--hw/display/ads7846.c7
-rw-r--r--hw/display/ssd0323.c11
-rw-r--r--hw/misc/max111x.c54
-rw-r--r--hw/pci/pci.c51
-rw-r--r--hw/ppc/spapr_pci.c23
-rw-r--r--hw/sd/ssi-sd.c7
-rw-r--r--hw/ssi/ssi.c11
-rw-r--r--include/hw/boards.h55
-rw-r--r--include/hw/qdev-core.h6
-rw-r--r--include/hw/ssi.h3
-rw-r--r--include/hw/virtio/virtio-serial.h8
-rw-r--r--net/tap.c7
-rw-r--r--pc-bios/README2
-rw-r--r--pc-bios/ohw.diff1843
-rw-r--r--pc-bios/ppc_rom.binbin524288 -> 524288 bytes
-rw-r--r--qdev-monitor.c15
-rw-r--r--qmp.c7
-rw-r--r--qom/object.c14
m---------roms/openhackware0
-rw-r--r--tests/Makefile28
-rw-r--r--tests/libqtest.c33
-rw-r--r--tests/libqtest.h20
-rw-r--r--tests/qdev-monitor-test.c8
-rw-r--r--tests/qom-test.c39
-rw-r--r--tests/spapr-phb-test.c35
-rw-r--r--tests/virtio-balloon-test.c33
-rw-r--r--tests/virtio-blk-test.c34
-rw-r--r--tests/virtio-console-test.c34
-rw-r--r--tests/virtio-rng-test.c33
-rw-r--r--tests/virtio-scsi-test.c35
-rw-r--r--tests/virtio-serial-test.c33
-rw-r--r--trace/control-internal.h10
-rw-r--r--vl.c121
43 files changed, 869 insertions, 2172 deletions
diff --git a/.gitmodules b/.gitmodules
index 45e51e79be..444c24a993 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -13,6 +13,9 @@
[submodule "roms/openbios"]
path = roms/openbios
url = git://git.qemu-project.org/openbios.git
+[submodule "roms/openhackware"]
+ path = roms/openhackware
+ url = git://git.qemu-project.org/openhackware.git
[submodule "roms/qemu-palcode"]
path = roms/qemu-palcode
url = git://github.com/rth7680/qemu-palcode.git
diff --git a/device-hotplug.c b/device-hotplug.c
index 103d34ac45..ebfa6b1016 100644
--- a/device-hotplug.c
+++ b/device-hotplug.c
@@ -33,12 +33,14 @@ DriveInfo *add_init_drive(const char *optstr)
{
DriveInfo *dinfo;
QemuOpts *opts;
+ MachineClass *mc;
opts = drive_def(optstr);
if (!opts)
return NULL;
- dinfo = drive_init(opts, current_machine->block_default_type);
+ mc = MACHINE_GET_CLASS(current_machine);
+ dinfo = drive_init(opts, mc->qemu_machine->block_default_type);
if (!dinfo) {
qemu_opts_del(opts);
return NULL;
diff --git a/docs/qemupciserial.inf b/docs/qemupciserial.inf
index 3474310a4b..6f7eef49cc 100644
--- a/docs/qemupciserial.inf
+++ b/docs/qemupciserial.inf
@@ -11,99 +11,92 @@
; (Com+Lpt)" from the list. Click "Have a disk". Select this file.
; Procedure may vary a bit depending on the windows version.
-; FIXME: This file covers the single port version only.
+; This file covers all options: pci-serial, pci-serial-2x, pci-serial-4x
+; for both 32 and 64 bit platforms.
[Version]
-Signature="$CHICAGO$"
-Class=Ports
-ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
+Signature="$Windows NT$"
+Class=MultiFunction
+ClassGUID={4d36e971-e325-11ce-bfc1-08002be10318}
Provider=%QEMU%
-DriverVer=09/24/2012,1.3.0
-
-[SourceDisksNames]
-3426=windows cd
-
-[SourceDisksFiles]
-serial.sys = 3426
-serenum.sys = 3426
-
-[DestinationDirs]
-DefaultDestDir = 11 ;LDID_SYS
-ComPort.NT.Copy = 12 ;DIRID_DRIVERS
-SerialEnumerator.NT.Copy=12 ;DIRID_DRIVERS
-
-; Drivers
-;----------------------------------------------------------
+DriverVer=12/29/2013,1.3.0
+[ControlFlags]
+ExcludeFromSelect=*
[Manufacturer]
-%QEMU%=QEMU,NTx86
+%QEMU%=QEMU,NTx86,NTAMD64
[QEMU.NTx86]
-%QEMU-PCI_SERIAL.DeviceDesc% = ComPort, "PCI\VEN_1b36&DEV_0002&CC_0700"
-
-; COM sections
-;----------------------------------------------------------
-[ComPort.AddReg]
-HKR,,PortSubClass,1,01
-
-[ComPort.NT]
-AddReg=ComPort.AddReg, ComPort.NT.AddReg
-LogConfig=caa
-SyssetupPnPFlags = 1
-
-[ComPort.NT.HW]
-AddReg=ComPort.NT.HW.AddReg
-
-[ComPort.NT.AddReg]
-HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
-
-[ComPort.NT.HW.AddReg]
-HKR,,"UpperFilters",0x00010000,"serenum"
-
-;-------------- Service installation
-; Port Driver (function driver for this device)
-[ComPort.NT.Services]
-AddService = Serial, 0x00000002, Serial_Service_Inst, Serial_EventLog_Inst
-AddService = Serenum,,Serenum_Service_Inst
-
-; -------------- Serial Port Driver install sections
-[Serial_Service_Inst]
-DisplayName = %Serial.SVCDESC%
-ServiceType = 1 ; SERVICE_KERNEL_DRIVER
-StartType = 1 ; SERVICE_SYSTEM_START (this driver may do detection)
-ErrorControl = 0 ; SERVICE_ERROR_IGNORE
-ServiceBinary = %12%\serial.sys
-LoadOrderGroup = Extended base
-
-; -------------- Serenum Driver install section
-[Serenum_Service_Inst]
-DisplayName = %Serenum.SVCDESC%
-ServiceType = 1 ; SERVICE_KERNEL_DRIVER
-StartType = 3 ; SERVICE_DEMAND_START
-ErrorControl = 1 ; SERVICE_ERROR_NORMAL
-ServiceBinary = %12%\serenum.sys
-LoadOrderGroup = PNP Filter
-
-[Serial_EventLog_Inst]
-AddReg = Serial_EventLog_AddReg
-
-[Serial_EventLog_AddReg]
-HKR,,EventMessageFile,0x00020000,"%%SystemRoot%%\System32\IoLogMsg.dll;%%SystemRoot%%\System32\drivers\serial.sys"
-HKR,,TypesSupported,0x00010001,7
-
-; The following sections are COM port resource configs.
-; Section name format means:
-; Char 1 = c (COM port)
-; Char 2 = I/O config: 1 (3f8), 2 (2f8), 3 (3e8), 4 (2e8), a (any)
-; Char 3 = IRQ config: #, a (any)
-
-[caa] ; Any base, any IRQ
-ConfigPriority=HARDRECONFIG
-IOConfig=8@100-ffff%fff8(3ff::)
-IRQConfig=S:3,4,5,7,9,10,11,12,14,15
+%QEMU-PCI_SERIAL_1_PORT%=ComPort_inst1, PCI\VEN_1B36&DEV_0002
+%QEMU-PCI_SERIAL_2_PORT%=ComPort_inst2, PCI\VEN_1B36&DEV_0003
+%QEMU-PCI_SERIAL_4_PORT%=ComPort_inst4, PCI\VEN_1B36&DEV_0004
+
+[QEMU.NTAMD64]
+%QEMU-PCI_SERIAL_1_PORT%=ComPort_inst1, PCI\VEN_1B36&DEV_0002
+%QEMU-PCI_SERIAL_2_PORT%=ComPort_inst2, PCI\VEN_1B36&DEV_0003
+%QEMU-PCI_SERIAL_4_PORT%=ComPort_inst4, PCI\VEN_1B36&DEV_0004
+
+[ComPort_inst1]
+Include=mf.inf
+Needs=MFINSTALL.mf
+
+[ComPort_inst2]
+Include=mf.inf
+Needs=MFINSTALL.mf
+
+[ComPort_inst4]
+Include=mf.inf
+Needs=MFINSTALL.mf
+
+[ComPort_inst1.HW]
+AddReg=ComPort_inst1.RegHW
+
+[ComPort_inst2.HW]
+AddReg=ComPort_inst2.RegHW
+
+[ComPort_inst4.HW]
+AddReg=ComPort_inst4.RegHW
+
+[ComPort_inst1.Services]
+Include=mf.inf
+Needs=MFINSTALL.mf.Services
+
+[ComPort_inst2.Services]
+Include=mf.inf
+Needs=MFINSTALL.mf.Services
+
+[ComPort_inst4.Services]
+Include=mf.inf
+Needs=MFINSTALL.mf.Services
+
+[ComPort_inst1.RegHW]
+HKR,Child0000,HardwareID,,*PNP0501
+HKR,Child0000,VaryingResourceMap,1,00, 00,00,00,00, 08,00,00,00
+HKR,Child0000,ResourceMap,1,02
+
+[ComPort_inst2.RegHW]
+HKR,Child0000,HardwareID,,*PNP0501
+HKR,Child0000,VaryingResourceMap,1,00, 00,00,00,00, 08,00,00,00
+HKR,Child0000,ResourceMap,1,02
+HKR,Child0001,HardwareID,,*PNP0501
+HKR,Child0001,VaryingResourceMap,1,00, 08,00,00,00, 08,00,00,00
+HKR,Child0001,ResourceMap,1,02
+
+[ComPort_inst4.RegHW]
+HKR,Child0000,HardwareID,,*PNP0501
+HKR,Child0000,VaryingResourceMap,1,00, 00,00,00,00, 08,00,00,00
+HKR,Child0000,ResourceMap,1,02
+HKR,Child0001,HardwareID,,*PNP0501
+HKR,Child0001,VaryingResourceMap,1,00, 08,00,00,00, 08,00,00,00
+HKR,Child0001,ResourceMap,1,02
+HKR,Child0002,HardwareID,,*PNP0501
+HKR,Child0002,VaryingResourceMap,1,00, 10,00,00,00, 08,00,00,00
+HKR,Child0002,ResourceMap,1,02
+HKR,Child0003,HardwareID,,*PNP0501
+HKR,Child0003,VaryingResourceMap,1,00, 18,00,00,00, 08,00,00,00
+HKR,Child0003,ResourceMap,1,02
[Strings]
QEMU="QEMU"
-QEMU-PCI_SERIAL.DeviceDesc="QEMU Serial PCI Card"
-
-Serial.SVCDESC = "Serial port driver"
-Serenum.SVCDESC = "Serenum Filter Driver"
+QEMU-PCI_SERIAL_1_PORT="1x QEMU PCI Serial Card"
+QEMU-PCI_SERIAL_2_PORT="2x QEMU PCI Serial Card"
+QEMU-PCI_SERIAL_4_PORT="4x QEMU PCI Serial Card"
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
index 2decff170f..392ca84c81 100644
--- a/hw/arm/spitz.c
+++ b/hw/arm/spitz.c
@@ -658,14 +658,15 @@ static void spitz_adc_temp_on(void *opaque, int line, int level)
max111x_set_input(max1111, MAX1111_BATT_TEMP, 0);
}
-static int corgi_ssp_init(SSISlave *dev)
+static int corgi_ssp_init(SSISlave *d)
{
- CorgiSSPState *s = FROM_SSI_SLAVE(CorgiSSPState, dev);
+ DeviceState *dev = DEVICE(d);
+ CorgiSSPState *s = FROM_SSI_SLAVE(CorgiSSPState, d);
- qdev_init_gpio_in(&dev->qdev, corgi_ssp_gpio_cs, 3);
- s->bus[0] = ssi_create_bus(&dev->qdev, "ssi0");
- s->bus[1] = ssi_create_bus(&dev->qdev, "ssi1");
- s->bus[2] = ssi_create_bus(&dev->qdev, "ssi2");
+ qdev_init_gpio_in(dev, corgi_ssp_gpio_cs, 3);
+ s->bus[0] = ssi_create_bus(dev, "ssi0");
+ s->bus[1] = ssi_create_bus(dev, "ssi1");
+ s->bus[2] = ssi_create_bus(dev, "ssi2");
return 0;
}
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index 02a15441fa..e29a738d23 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -241,7 +241,8 @@ typedef enum {
} CMDState;
typedef struct Flash {
- SSISlave ssidev;
+ SSISlave parent_obj;
+
uint32_t r;
BlockDriverState *bdrv;
@@ -545,7 +546,7 @@ static void decode_new_cmd(Flash *s, uint32_t value)
static int m25p80_cs(SSISlave *ss, bool select)
{
- Flash *s = FROM_SSI_SLAVE(Flash, ss);
+ Flash *s = M25P80(ss);
if (select) {
s->len = 0;
@@ -561,7 +562,7 @@ static int m25p80_cs(SSISlave *ss, bool select)
static uint32_t m25p80_transfer8(SSISlave *ss, uint32_t tx)
{
- Flash *s = FROM_SSI_SLAVE(Flash, ss);
+ Flash *s = M25P80(ss);
uint32_t r = 0;
switch (s->state) {
@@ -610,7 +611,7 @@ static uint32_t m25p80_transfer8(SSISlave *ss, uint32_t tx)
static int m25p80_init(SSISlave *ss)
{
DriveInfo *dinfo;
- Flash *s = FROM_SSI_SLAVE(Flash, ss);
+ Flash *s = M25P80(ss);
M25P80Class *mc = M25P80_GET_CLASS(s);
s->pi = mc->pi;
diff --git a/hw/char/virtio-console.c b/hw/char/virtio-console.c
index 2e00ad2a7c..ffd29a80bc 100644
--- a/hw/char/virtio-console.c
+++ b/hw/char/virtio-console.c
@@ -15,8 +15,13 @@
#include "trace.h"
#include "hw/virtio/virtio-serial.h"
+#define TYPE_VIRTIO_CONSOLE "virtconsole"
+#define VIRTIO_CONSOLE(obj) \
+ OBJECT_CHECK(VirtConsole, (obj), TYPE_VIRTIO_CONSOLE)
+
typedef struct VirtConsole {
- VirtIOSerialPort port;
+ VirtIOSerialPort parent_obj;
+
CharDriverState *chr;
guint watch;
} VirtConsole;
@@ -31,7 +36,7 @@ static gboolean chr_write_unblocked(GIOChannel *chan, GIOCondition cond,
VirtConsole *vcon = opaque;
vcon->watch = 0;
- virtio_serial_throttle_port(&vcon->port, false);
+ virtio_serial_throttle_port(VIRTIO_SERIAL_PORT(vcon), false);
return FALSE;
}
@@ -39,7 +44,7 @@ static gboolean chr_write_unblocked(GIOChannel *chan, GIOCondition cond,
static ssize_t flush_buf(VirtIOSerialPort *port,
const uint8_t *buf, ssize_t len)
{
- VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
+ VirtConsole *vcon = VIRTIO_CONSOLE(port);
ssize_t ret;
if (!vcon->chr) {
@@ -75,7 +80,7 @@ static ssize_t flush_buf(VirtIOSerialPort *port,
/* Callback function that's called when the guest opens/closes the port */
static void set_guest_connected(VirtIOSerialPort *port, int guest_connected)
{
- VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
+ VirtConsole *vcon = VIRTIO_CONSOLE(port);
if (!vcon->chr) {
return;
@@ -88,45 +93,49 @@ static int chr_can_read(void *opaque)
{
VirtConsole *vcon = opaque;
- return virtio_serial_guest_ready(&vcon->port);
+ return virtio_serial_guest_ready(VIRTIO_SERIAL_PORT(vcon));
}
/* Send data from a char device over to the guest */
static void chr_read(void *opaque, const uint8_t *buf, int size)
{
VirtConsole *vcon = opaque;
+ VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(vcon);
- trace_virtio_console_chr_read(vcon->port.id, size);
- virtio_serial_write(&vcon->port, buf, size);
+ trace_virtio_console_chr_read(port->id, size);
+ virtio_serial_write(port, buf, size);
}
static void chr_event(void *opaque, int event)
{
VirtConsole *vcon = opaque;
+ VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(vcon);
- trace_virtio_console_chr_event(vcon->port.id, event);
+ trace_virtio_console_chr_event(port->id, event);
switch (event) {
case CHR_EVENT_OPENED:
- virtio_serial_open(&vcon->port);
+ virtio_serial_open(port);
break;
case CHR_EVENT_CLOSED:
if (vcon->watch) {
g_source_remove(vcon->watch);
vcon->watch = 0;
}
- virtio_serial_close(&vcon->port);
+ virtio_serial_close(port);
break;
}
}
-static int virtconsole_initfn(VirtIOSerialPort *port)
+static void virtconsole_realize(DeviceState *dev, Error **errp)
{
- VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
- VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(port);
+ VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
+ VirtConsole *vcon = VIRTIO_CONSOLE(dev);
+ VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(dev);
if (port->id == 0 && !k->is_console) {
- error_report("Port number 0 on virtio-serial devices reserved for virtconsole devices for backward compatibility.");
- return -1;
+ error_setg(errp, "Port number 0 on virtio-serial devices reserved "
+ "for virtconsole devices for backward compatibility.");
+ return;
}
if (vcon->chr) {
@@ -134,19 +143,15 @@ static int virtconsole_initfn(VirtIOSerialPort *port)
qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event,
vcon);
}
-
- return 0;
}
-static int virtconsole_exitfn(VirtIOSerialPort *port)
+static void virtconsole_unrealize(DeviceState *dev, Error **errp)
{
- VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
+ VirtConsole *vcon = VIRTIO_CONSOLE(dev);
if (vcon->watch) {
g_source_remove(vcon->watch);
}
-
- return 0;
}
static Property virtconsole_properties[] = {
@@ -160,15 +165,15 @@ static void virtconsole_class_init(ObjectClass *klass, void *data)
VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_CLASS(klass);
k->is_console = true;
- k->init = virtconsole_initfn;
- k->exit = virtconsole_exitfn;
+ k->realize = virtconsole_realize;
+ k->unrealize = virtconsole_unrealize;
k->have_data = flush_buf;
k->set_guest_connected = set_guest_connected;
dc->props = virtconsole_properties;
}
static const TypeInfo virtconsole_info = {
- .name = "virtconsole",
+ .name = TYPE_VIRTIO_CONSOLE,
.parent = TYPE_VIRTIO_SERIAL_PORT,
.instance_size = sizeof(VirtConsole),
.class_init = virtconsole_class_init,
@@ -184,8 +189,8 @@ static void virtserialport_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_CLASS(klass);
- k->init = virtconsole_initfn;
- k->exit = virtconsole_exitfn;
+ k->realize = virtconsole_realize;
+ k->unrealize = virtconsole_unrealize;
k->have_data = flush_buf;
k->set_guest_connected = set_guest_connected;
dc->props = virtserialport_properties;
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index 226e9f9a3c..2b647b68d5 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -808,13 +808,14 @@ static void remove_port(VirtIOSerial *vser, uint32_t port_id)
send_control_event(vser, port->id, VIRTIO_CONSOLE_PORT_REMOVE, 1);
}
-static int virtser_port_qdev_init(DeviceState *qdev)
+static void virtser_port_device_realize(DeviceState *dev, Error **errp)
{
- VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, qdev);
+ VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
VirtIOSerialPortClass *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
- VirtIOSerialBus *bus = DO_UPCAST(VirtIOSerialBus, qbus, qdev->parent_bus);
- int ret, max_nr_ports;
+ VirtIOSerialBus *bus = VIRTIO_SERIAL_BUS(qdev_get_parent_bus(dev));
+ int max_nr_ports;
bool plugging_port0;
+ Error *err = NULL;
port->vser = bus->vser;
port->bh = qemu_bh_new(flush_queued_data_bh, port);
@@ -829,9 +830,9 @@ static int virtser_port_qdev_init(DeviceState *qdev)
plugging_port0 = vsc->is_console && !find_port_by_id(port->vser, 0);
if (find_port_by_id(port->vser, port->id)) {
- error_report("virtio-serial-bus: A port already exists at id %u",
- port->id);
- return -1;
+ error_setg(errp, "virtio-serial-bus: A port already exists at id %u",
+ port->id);
+ return;
}
if (port->id == VIRTIO_CONSOLE_BAD_ID) {
@@ -840,22 +841,24 @@ static int virtser_port_qdev_init(DeviceState *qdev)
} else {
port->id = find_free_port_id(port->vser);
if (port->id == VIRTIO_CONSOLE_BAD_ID) {
- error_report("virtio-serial-bus: Maximum port limit for this device reached");
- return -1;
+ error_setg(errp, "virtio-serial-bus: Maximum port limit for "
+ "this device reached");
+ return;
}
}
}
max_nr_ports = tswap32(port->vser->config.max_nr_ports);
if (port->id >= max_nr_ports) {
- error_report("virtio-serial-bus: Out-of-range port id specified, max. allowed: %u",
- max_nr_ports - 1);
- return -1;
+ error_setg(errp, "virtio-serial-bus: Out-of-range port id specified, "
+ "max. allowed: %u", max_nr_ports - 1);
+ return;
}
- ret = vsc->init(port);
- if (ret) {
- return ret;
+ vsc->realize(dev, &err);
+ if (err != NULL) {
+ error_propagate(errp, err);
+ return;
}
port->elem.out_num = 0;
@@ -868,14 +871,12 @@ static int virtser_port_qdev_init(DeviceState *qdev)
/* Send an update to the guest about this new port added */
virtio_notify_config(VIRTIO_DEVICE(port->vser));
-
- return ret;
}
-static int virtser_port_qdev_exit(DeviceState *qdev)
+static void virtser_port_device_unrealize(DeviceState *dev, Error **errp)
{
- VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, qdev);
- VirtIOSerialPortClass *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
+ VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
+ VirtIOSerialPortClass *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(dev);
VirtIOSerial *vser = port->vser;
qemu_bh_delete(port->bh);
@@ -883,10 +884,9 @@ static int virtser_port_qdev_exit(DeviceState *qdev)
QTAILQ_REMOVE(&vser->ports, port, next);
- if (vsc->exit) {
- vsc->exit(port);
+ if (vsc->unrealize) {
+ vsc->unrealize(dev, errp);
}
- return 0;
}
static void virtio_serial_device_realize(DeviceState *dev, Error **errp)
@@ -971,10 +971,11 @@ static void virtio_serial_device_realize(DeviceState *dev, Error **errp)
static void virtio_serial_port_class_init(ObjectClass *klass, void *data)
{
DeviceClass *k = DEVICE_CLASS(klass);
- k->init = virtser_port_qdev_init;
+
set_bit(DEVICE_CATEGORY_INPUT, k->categories);
k->bus_type = TYPE_VIRTIO_SERIAL_BUS;
- k->exit = virtser_port_qdev_exit;
+ k->realize = virtser_port_device_realize;
+ k->unrealize = virtser_port_device_unrealize;
k->unplug = qdev_simple_unplug_cb;
k->props = virtser_props;
}
diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
index 9e324befd6..981593c7e6 100644
--- a/hw/core/Makefile.objs
+++ b/hw/core/Makefile.objs
@@ -8,7 +8,7 @@ common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
common-obj-$(CONFIG_XILINX_AXI) += stream.o
common-obj-$(CONFIG_PTIMER) += ptimer.o
common-obj-$(CONFIG_SOFTMMU) += sysbus.o
+common-obj-$(CONFIG_SOFTMMU) += machine.o
common-obj-$(CONFIG_SOFTMMU) += null-machine.o
common-obj-$(CONFIG_SOFTMMU) += loader.o
common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o
-
diff --git a/hw/core/machine.c b/hw/core/machine.c
new file mode 100644
index 0000000000..d3ffef7e07
--- /dev/null
+++ b/hw/core/machine.c
@@ -0,0 +1,28 @@
+/*
+ * QEMU Machine
+ *
+ * Copyright (C) 2014 Red Hat Inc
+ *
+ * Authors:
+ * Marcel Apfelbaum <marcel.a@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "hw/boards.h"
+
+static const TypeInfo machine_info = {
+ .name = TYPE_MACHINE,
+ .parent = TYPE_OBJECT,
+ .abstract = true,
+ .class_size = sizeof(MachineClass),
+ .instance_size = sizeof(MachineState),
+};
+
+static void machine_register_types(void)
+{
+ type_register_static(&machine_info);
+}
+
+type_init(machine_register_types)
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 380976a066..9f0a522ee8 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -501,6 +501,45 @@ static void bus_unparent(Object *obj)
}
}
+static bool bus_get_realized(Object *obj, Error **err)
+{
+ BusState *bus = BUS(obj);
+
+ return bus->realized;
+}
+
+static void bus_set_realized(Object *obj, bool value, Error **err)
+{
+ BusState *bus = BUS(obj);
+ BusClass *bc = BUS_GET_CLASS(bus);
+ Error *local_err = NULL;
+
+ if (value && !bus->realized) {
+ if (bc->realize) {
+ bc->realize(bus, &local_err);
+
+ if (local_err != NULL) {
+ goto error;
+ }
+
+ }
+ } else if (!value && bus->realized) {
+ if (bc->unrealize) {
+ bc->unrealize(bus, &local_err);
+
+ if (local_err != NULL) {
+ goto error;
+ }
+ }
+ }
+
+ bus->realized = value;
+ return;
+
+error:
+ error_propagate(err, local_err);
+}
+
void qbus_create_inplace(void *bus, size_t size, const char *typename,
DeviceState *parent, const char *name)
{
@@ -677,6 +716,7 @@ static void device_set_realized(Object *obj, bool value, Error **err)
{
DeviceState *dev = DEVICE(obj);
DeviceClass *dc = DEVICE_GET_CLASS(dev);
+ BusState *bus;
Error *local_err = NULL;
if (dev->hotplugged && !dc->hotpluggable) {
@@ -710,14 +750,30 @@ static void device_set_realized(Object *obj, bool value, Error **err)
dev->instance_id_alias,
dev->alias_required_for_version);
}
+ if (local_err == NULL) {
+ QLIST_FOREACH(bus, &dev->child_bus, sibling) {
+ object_property_set_bool(OBJECT(bus), true, "realized",
+ &local_err);
+ if (local_err != NULL) {
+ break;
+ }
+ }
+ }
if (dev->hotplugged && local_err == NULL) {
device_reset(dev);
}
} else if (!value && dev->realized) {
- if (qdev_get_vmsd(dev)) {
+ QLIST_FOREACH(bus, &dev->child_bus, sibling) {
+ object_property_set_bool(OBJECT(bus), false, "realized",
+ &local_err);
+ if (local_err != NULL) {
+ break;
+ }
+ }
+ if (qdev_get_vmsd(dev) && local_err == NULL) {
vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
}
- if (dc->unrealize) {
+ if (dc->unrealize && local_err == NULL) {
dc->unrealize(dev, &local_err);
}
}
@@ -735,7 +791,8 @@ static bool device_get_hotpluggable(Object *obj, Error **err)
DeviceClass *dc = DEVICE_GET_CLASS(obj);
DeviceState *dev = DEVICE(obj);
- return dc->hotpluggable && dev->parent_bus->allow_hotplug;
+ return dc->hotpluggable && (dev->parent_bus == NULL ||
+ dev->parent_bus->allow_hotplug);
}
static void device_initfn(Object *obj)
@@ -792,14 +849,6 @@ static void device_class_base_init(ObjectClass *class, void *data)
* so do not propagate them to the subclasses.
*/
klass->props = NULL;
-
- /* by default all devices were considered as hotpluggable,
- * so with intent to check it in generic qdev_unplug() /
- * device_set_realized() functions make every device
- * hotpluggable. Devices that shouldn't be hotpluggable,
- * should override it in their class_init()
- */
- klass->hotpluggable = true;
}
static void device_unparent(Object *obj)
@@ -809,13 +858,13 @@ static void device_unparent(Object *obj)
QObject *event_data;
bool have_realized = dev->realized;
+ if (dev->realized) {
+ object_property_set_bool(obj, false, "realized", NULL);
+ }
while (dev->num_child_bus) {
bus = QLIST_FIRST(&dev->child_bus);
object_unparent(OBJECT(bus));
}
- if (dev->realized) {
- object_property_set_bool(obj, false, "realized", NULL);
- }
if (dev->parent_bus) {
bus_remove_child(dev->parent_bus, dev);
object_unref(OBJECT(dev->parent_bus));
@@ -845,6 +894,14 @@ static void device_class_init(ObjectClass *class, void *data)
class->unparent = device_unparent;
dc->realize = device_realize;
dc->unrealize = device_unrealize;
+
+ /* by default all devices were considered as hotpluggable,
+ * so with intent to check it in generic qdev_unplug() /
+ * device_set_realized() functions make every device
+ * hotpluggable. Devices that shouldn't be hotpluggable,
+ * should override it in their class_init()
+ */
+ dc->hotpluggable = true;
}
void device_reset(DeviceState *dev)
@@ -888,6 +945,8 @@ static void qbus_initfn(Object *obj)
object_property_add_link(obj, QDEV_HOTPLUG_HANDLER_PROPERTY,
TYPE_HOTPLUG_HANDLER,
(Object **)&bus->hotplug_handler, NULL);
+ object_property_add_bool(obj, "realized",
+ bus_get_realized, bus_set_realized, NULL);
}
static char *default_bus_get_fw_dev_path(DeviceState *dev)
diff --git a/hw/display/ads7846.c b/hw/display/ads7846.c
index 5da3dc5b2c..85252a2329 100644
--- a/hw/display/ads7846.c
+++ b/hw/display/ads7846.c
@@ -133,11 +133,12 @@ static const VMStateDescription vmstate_ads7846 = {
}
};
-static int ads7846_init(SSISlave *dev)
+static int ads7846_init(SSISlave *d)
{
- ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, dev);
+ DeviceState *dev = DEVICE(d);
+ ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, d);
- qdev_init_gpio_out(&dev->qdev, &s->interrupt, 1);
+ qdev_init_gpio_out(dev, &s->interrupt, 1);
s->input[0] = ADS_TEMP0; /* TEMP0 */
s->input[2] = ADS_VBAT; /* VBAT */
diff --git a/hw/display/ssd0323.c b/hw/display/ssd0323.c
index 46c3b40c79..971152edbd 100644
--- a/hw/display/ssd0323.c
+++ b/hw/display/ssd0323.c
@@ -336,18 +336,19 @@ static const GraphicHwOps ssd0323_ops = {
.gfx_update = ssd0323_update_display,
};
-static int ssd0323_init(SSISlave *dev)
+static int ssd0323_init(SSISlave *d)
{
- ssd0323_state *s = FROM_SSI_SLAVE(ssd0323_state, dev);
+ DeviceState *dev = DEVICE(d);
+ ssd0323_state *s = FROM_SSI_SLAVE(ssd0323_state, d);
s->col_end = 63;
s->row_end = 79;
- s->con = graphic_console_init(DEVICE(dev), 0, &ssd0323_ops, s);
+ s->con = graphic_console_init(dev, 0, &ssd0323_ops, s);
qemu_console_resize(s->con, 128 * MAGNIFY, 64 * MAGNIFY);
- qdev_init_gpio_in(&dev->qdev, ssd0323_cd, 1);
+ qdev_init_gpio_in(dev, ssd0323_cd, 1);
- register_savevm(&dev->qdev, "ssd0323_oled", -1, 1,
+ register_savevm(dev, "ssd0323_oled", -1, 1,
ssd0323_save, ssd0323_load, s);
return 0;
}
diff --git a/hw/misc/max111x.c b/hw/misc/max111x.c
index d477ecdb29..bba87c2ec5 100644
--- a/hw/misc/max111x.c
+++ b/hw/misc/max111x.c
@@ -13,7 +13,8 @@
#include "hw/ssi.h"
typedef struct {
- SSISlave ssidev;
+ SSISlave parent_obj;
+
qemu_irq interrupt;
uint8_t tb1, rb2, rb3;
int cycle;
@@ -22,6 +23,14 @@ typedef struct {
int inputs, com;
} MAX111xState;
+#define TYPE_MAX_111X "max111x"
+
+#define MAX_111X(obj) \
+ OBJECT_CHECK(MAX111xState, (obj), TYPE_MAX_111X)
+
+#define TYPE_MAX_1110 "max1110"
+#define TYPE_MAX_1111 "max1111"
+
/* Control-byte bitfields */
#define CB_PD0 (1 << 0)
#define CB_PD1 (1 << 1)
@@ -92,7 +101,7 @@ static void max111x_write(MAX111xState *s, uint32_t value)
static uint32_t max111x_transfer(SSISlave *dev, uint32_t value)
{
- MAX111xState *s = FROM_SSI_SLAVE(MAX111xState, dev);
+ MAX111xState *s = MAX_111X(dev);
max111x_write(s, value);
return max111x_read(s);
}
@@ -103,7 +112,7 @@ static const VMStateDescription vmstate_max111x = {
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
- VMSTATE_SSI_SLAVE(ssidev, MAX111xState),
+ VMSTATE_SSI_SLAVE(parent_obj, MAX111xState),
VMSTATE_UINT8(tb1, MAX111xState),
VMSTATE_UINT8(rb2, MAX111xState),
VMSTATE_UINT8(rb3, MAX111xState),
@@ -115,11 +124,12 @@ static const VMStateDescription vmstate_max111x = {
}
};
-static int max111x_init(SSISlave *dev, int inputs)
+static int max111x_init(SSISlave *d, int inputs)
{
- MAX111xState *s = FROM_SSI_SLAVE(MAX111xState, dev);
+ DeviceState *dev = DEVICE(d);
+ MAX111xState *s = MAX_111X(dev);
- qdev_init_gpio_out(&dev->qdev, &s->interrupt, 1);
+ qdev_init_gpio_out(dev, &s->interrupt, 1);
s->inputs = inputs;
/* TODO: add a user interface for setting these */
@@ -133,7 +143,7 @@ static int max111x_init(SSISlave *dev, int inputs)
s->input[7] = 0x80;
s->com = 0;
- vmstate_register(&dev->qdev, -1, &vmstate_max111x, s);
+ vmstate_register(dev, -1, &vmstate_max111x, s);
return 0;
}
@@ -149,23 +159,36 @@ static int max1111_init(SSISlave *dev)
void max111x_set_input(DeviceState *dev, int line, uint8_t value)
{
- MAX111xState *s = FROM_SSI_SLAVE(MAX111xState, SSI_SLAVE_FROM_QDEV(dev));
+ MAX111xState *s = MAX_111X(dev);
assert(line >= 0 && line < s->inputs);
s->input[line] = value;
}
-static void max1110_class_init(ObjectClass *klass, void *data)
+static void max111x_class_init(ObjectClass *klass, void *data)
{
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
- k->init = max1110_init;
k->transfer = max111x_transfer;
}
-static const TypeInfo max1110_info = {
- .name = "max1110",
+static const TypeInfo max111x_info = {
+ .name = TYPE_MAX_111X,
.parent = TYPE_SSI_SLAVE,
.instance_size = sizeof(MAX111xState),
+ .class_init = max111x_class_init,
+ .abstract = true,
+};
+
+static void max1110_class_init(ObjectClass *klass, void *data)
+{
+ SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+
+ k->init = max1110_init;
+}
+
+static const TypeInfo max1110_info = {
+ .name = TYPE_MAX_1110,
+ .parent = TYPE_MAX_111X,
.class_init = max1110_class_init,
};
@@ -174,18 +197,17 @@ static void max1111_class_init(ObjectClass *klass, void *data)
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
k->init = max1111_init;
- k->transfer = max111x_transfer;
}
static const TypeInfo max1111_info = {
- .name = "max1111",
- .parent = TYPE_SSI_SLAVE,
- .instance_size = sizeof(MAX111xState),
+ .name = TYPE_MAX_1111,
+ .parent = TYPE_MAX_111X,
.class_init = max1111_class_init,
};
static void max111x_register_types(void)
{
+ type_register_static(&max111x_info);
type_register_static(&max1110_info);
type_register_static(&max1111_info);
}
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 4e0701df38..8f722dd961 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -48,7 +48,6 @@ static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent);
static char *pcibus_get_dev_path(DeviceState *dev);
static char *pcibus_get_fw_dev_path(DeviceState *dev);
static void pcibus_reset(BusState *qbus);
-static void pci_bus_finalize(Object *obj);
static Property pci_props[] = {
DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
@@ -61,6 +60,34 @@ static Property pci_props[] = {
DEFINE_PROP_END_OF_LIST()
};
+static const VMStateDescription vmstate_pcibus = {
+ .name = "PCIBUS",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_INT32_EQUAL(nirq, PCIBus),
+ VMSTATE_VARRAY_INT32(irq_count, PCIBus,
+ nirq, 0, vmstate_info_int32,
+ int32_t),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void pci_bus_realize(BusState *qbus, Error **errp)
+{
+ PCIBus *bus = PCI_BUS(qbus);
+
+ vmstate_register(NULL, -1, &vmstate_pcibus, bus);
+}
+
+static void pci_bus_unrealize(BusState *qbus, Error **errp)
+{
+ PCIBus *bus = PCI_BUS(qbus);
+
+ vmstate_unregister(NULL, &vmstate_pcibus, bus);
+}
+
static void pci_bus_class_init(ObjectClass *klass, void *data)
{
BusClass *k = BUS_CLASS(klass);
@@ -68,6 +95,8 @@ static void pci_bus_class_init(ObjectClass *klass, void *data)
k->print_dev = pcibus_dev_print;
k->get_dev_path = pcibus_get_dev_path;
k->get_fw_dev_path = pcibus_get_fw_dev_path;
+ k->realize = pci_bus_realize;
+ k->unrealize = pci_bus_unrealize;
k->reset = pcibus_reset;
}
@@ -75,7 +104,6 @@ static const TypeInfo pci_bus_info = {
.name = TYPE_PCI_BUS,
.parent = TYPE_BUS,
.instance_size = sizeof(PCIBus),
- .instance_finalize = pci_bus_finalize,
.class_init = pci_bus_class_init,
};
@@ -95,17 +123,6 @@ static uint16_t pci_default_sub_device_id = PCI_SUBDEVICE_ID_QEMU;
static QLIST_HEAD(, PCIHostState) pci_host_bridges;
-static const VMStateDescription vmstate_pcibus = {
- .name = "PCIBUS",
- .version_id = 1,
- .minimum_version_id = 1,
- .minimum_version_id_old = 1,
- .fields = (VMStateField []) {
- VMSTATE_INT32_EQUAL(nirq, PCIBus),
- VMSTATE_VARRAY_INT32(irq_count, PCIBus, nirq, 0, vmstate_info_int32, int32_t),
- VMSTATE_END_OF_LIST()
- }
-};
static int pci_bar(PCIDevice *d, int reg)
{
uint8_t type;
@@ -299,8 +316,6 @@ static void pci_bus_init(PCIBus *bus, DeviceState *parent,
QLIST_INIT(&bus->child);
pci_host_bus_register(bus, parent);
-
- vmstate_register(NULL, -1, &vmstate_pcibus, bus);
}
bool pci_bus_is_express(PCIBus *bus)
@@ -369,12 +384,6 @@ int pci_bus_num(PCIBus *s)
return s->parent_dev->config[PCI_SECONDARY_BUS];
}
-static void pci_bus_finalize(Object *obj)
-{
- PCIBus *bus = PCI_BUS(obj);
- vmstate_unregister(NULL, &vmstate_pcibus, bus);
-}
-
static int get_pci_config_device(QEMUFile *f, void *pv, size_t size)
{
PCIDevice *s = container_of(pv, PCIDevice, config);
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 3c54399d9d..cbef095935 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -511,7 +511,6 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
SysBusDevice *s = SYS_BUS_DEVICE(dev);
sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(s);
PCIHostState *phb = PCI_HOST_BRIDGE(s);
- const char *busname;
char *namebuf;
int i;
PCIBus *bus;
@@ -595,26 +594,8 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
get_system_io(), 0, SPAPR_PCI_IO_WIN_SIZE);
memory_region_add_subregion(get_system_memory(), sphb->io_win_addr,
&sphb->iowindow);
- /*
- * Selecting a busname is more complex than you'd think, due to
- * interacting constraints. If the user has specified an id
- * explicitly for the phb , then we want to use the qdev default
- * of naming the bus based on the bridge device (so the user can
- * then assign devices to it in the way they expect). For the
- * first / default PCI bus (index=0) we want to use just "pci"
- * because libvirt expects there to be a bus called, simply,
- * "pci". Otherwise, we use the same name as in the device tree,
- * since it's unique by construction, and makes the guest visible
- * BUID clear.
- */
- if (dev->id) {
- busname = NULL;
- } else if (sphb->index == 0) {
- busname = "pci";
- } else {
- busname = sphb->dtbusname;
- }
- bus = pci_register_bus(dev, busname,
+
+ bus = pci_register_bus(dev, NULL,
pci_spapr_set_irq, pci_spapr_map_irq, sphb,
&sphb->memspace, &sphb->iospace,
PCI_DEVFN(0, 0), PCI_NUM_PINS, TYPE_PCI_BUS);
diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
index 1bb56c4d54..3273c8a31f 100644
--- a/hw/sd/ssi-sd.c
+++ b/hw/sd/ssi-sd.c
@@ -238,9 +238,10 @@ static int ssi_sd_load(QEMUFile *f, void *opaque, int version_id)
return 0;
}
-static int ssi_sd_init(SSISlave *dev)
+static int ssi_sd_init(SSISlave *d)
{
- ssi_sd_state *s = FROM_SSI_SLAVE(ssi_sd_state, dev);
+ DeviceState *dev = DEVICE(d);
+ ssi_sd_state *s = FROM_SSI_SLAVE(ssi_sd_state, d);
DriveInfo *dinfo;
s->mode = SSI_SD_CMD;
@@ -249,7 +250,7 @@ static int ssi_sd_init(SSISlave *dev)
if (s->sd == NULL) {
return -1;
}
- register_savevm(&dev->qdev, "ssi_sd", -1, 1, ssi_sd_save, ssi_sd_load, s);
+ register_savevm(dev, "ssi_sd", -1, 1, ssi_sd_save, ssi_sd_load, s);
return 0;
}
diff --git a/hw/ssi/ssi.c b/hw/ssi/ssi.c
index 2c25260875..017f0221fb 100644
--- a/hw/ssi/ssi.c
+++ b/hw/ssi/ssi.c
@@ -15,7 +15,7 @@
#include "hw/ssi.h"
struct SSIBus {
- BusState qbus;
+ BusState parent_obj;
};
#define TYPE_SSI_BUS "SSI"
@@ -60,7 +60,7 @@ static int ssi_slave_init(DeviceState *dev)
if (ssc->transfer_raw == ssi_transfer_raw_default &&
ssc->cs_polarity != SSI_CS_NONE) {
- qdev_init_gpio_in(&s->qdev, ssi_cs_default, 1);
+ qdev_init_gpio_in(dev, ssi_cs_default, 1);
}
return ssc->init(s);
@@ -88,7 +88,7 @@ static const TypeInfo ssi_slave_info = {
DeviceState *ssi_create_slave_no_init(SSIBus *bus, const char *name)
{
- return qdev_create(&bus->qbus, name);
+ return qdev_create(BUS(bus), name);
}
DeviceState *ssi_create_slave(SSIBus *bus, const char *name)
@@ -108,11 +108,12 @@ SSIBus *ssi_create_bus(DeviceState *parent, const char *name)
uint32_t ssi_transfer(SSIBus *bus, uint32_t val)
{
+ BusState *b = BUS(bus);
BusChild *kid;
SSISlaveClass *ssc;
uint32_t r = 0;
- QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) {
+ QTAILQ_FOREACH(kid, &b->children, sibling) {
SSISlave *slave = SSI_SLAVE(kid->child);
ssc = SSI_SLAVE_GET_CLASS(slave);
r |= ssc->transfer_raw(slave, val);
@@ -156,7 +157,7 @@ static int ssi_auto_connect_slave(Object *child, void *opaque)
}
cs_line = qdev_get_gpio_in(DEVICE(dev), 0);
- qdev_set_parent_bus(DEVICE(dev), &arg->bus->qbus);
+ qdev_set_parent_bus(DEVICE(dev), BUS(arg->bus));
**arg->cs_linep = cs_line;
(*arg->cs_linep)++;
return 0;
diff --git a/include/hw/boards.h b/include/hw/boards.h
index fd9388c695..7bd2ea7736 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -5,6 +5,7 @@
#include "sysemu/blockdev.h"
#include "hw/qdev.h"
+#include "qom/object.h"
typedef struct QEMUMachineInitArgs {
const QEMUMachine *machine;
@@ -49,9 +50,59 @@ struct QEMUMachine {
const char *hw_version;
};
+#define TYPE_MACHINE_SUFFIX "-machine"
int qemu_register_machine(QEMUMachine *m);
-QEMUMachine *find_default_machine(void);
-extern QEMUMachine *current_machine;
+#define TYPE_MACHINE "machine"
+#define MACHINE(obj) \
+ OBJECT_CHECK(MachineState, (obj), TYPE_MACHINE)
+#define MACHINE_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(MachineClass, (obj), TYPE_MACHINE)
+#define MACHINE_CLASS(klass) \
+ OBJECT_CLASS_CHECK(MachineClass, (klass), TYPE_MACHINE)
+
+typedef struct MachineState MachineState;
+typedef struct MachineClass MachineClass;
+
+MachineClass *find_default_machine(void);
+extern MachineState *current_machine;
+
+/**
+ * MachineClass:
+ * @qemu_machine: #QEMUMachine
+ */
+struct MachineClass {
+ /*< private >*/
+ ObjectClass parent_class;
+ /*< public >*/
+
+ QEMUMachine *qemu_machine;
+};
+
+/**
+ * MachineState:
+ */
+struct MachineState {
+ /*< private >*/
+ Object parent_obj;
+ /*< public >*/
+
+ char *accel;
+ bool kernel_irqchip;
+ int kvm_shadow_mem;
+ char *kernel;
+ char *initrd;
+ char *append;
+ char *dtb;
+ char *dumpdtb;
+ int phandle_start;
+ char *dt_compatible;
+ bool dump_guest_core;
+ bool mem_merge;
+ bool usb;
+ char *firmware;
+
+ QEMUMachineInitArgs init_args;
+};
#endif
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 1ed0691716..dbe473c344 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -36,6 +36,8 @@ typedef int (*qdev_event)(DeviceState *dev);
typedef void (*qdev_resetfn)(DeviceState *dev);
typedef void (*DeviceRealize)(DeviceState *dev, Error **errp);
typedef void (*DeviceUnrealize)(DeviceState *dev, Error **errp);
+typedef void (*BusRealize)(BusState *bus, Error **errp);
+typedef void (*BusUnrealize)(BusState *bus, Error **errp);
struct VMStateDescription;
@@ -174,6 +176,9 @@ struct BusClass {
*/
char *(*get_fw_dev_path)(DeviceState *dev);
void (*reset)(BusState *bus);
+ BusRealize realize;
+ BusUnrealize unrealize;
+
/* maximum devices allowed on the bus, 0: no limit. */
int max_dev;
/* number of automatically allocated bus ids (e.g. ide.0) */
@@ -199,6 +204,7 @@ struct BusState {
int allow_hotplug;
HotplugHandler *hotplug_handler;
int max_index;
+ bool realized;
QTAILQ_HEAD(ChildrenHead, BusChild) children;
QLIST_ENTRY(BusState) sibling;
};
diff --git a/include/hw/ssi.h b/include/hw/ssi.h
index fdae317295..6c13fb2e44 100644
--- a/include/hw/ssi.h
+++ b/include/hw/ssi.h
@@ -56,13 +56,12 @@ typedef struct SSISlaveClass {
} SSISlaveClass;
struct SSISlave {
- DeviceState qdev;
+ DeviceState parent_obj;
/* Chip select state */
bool cs;
};
-#define SSI_SLAVE_FROM_QDEV(dev) DO_UPCAST(SSISlave, qdev, dev)
#define FROM_SSI_SLAVE(type, dev) DO_UPCAST(type, ssidev, dev)
extern const VMStateDescription vmstate_ssi_slave;
diff --git a/include/hw/virtio/virtio-serial.h b/include/hw/virtio/virtio-serial.h
index 1d2040b245..4746312a83 100644
--- a/include/hw/virtio/virtio-serial.h
+++ b/include/hw/virtio/virtio-serial.h
@@ -81,15 +81,15 @@ typedef struct VirtIOSerialPortClass {
bool is_console;
/*
- * The per-port (or per-app) init function that's called when a
+ * The per-port (or per-app) realize function that's called when a
* new device is found on the bus.
*/
- int (*init)(VirtIOSerialPort *port);
+ DeviceRealize realize;
/*
- * Per-port exit function that's called when a port gets
+ * Per-port unrealize function that's called when a port gets
* hot-unplugged or removed.
*/
- int (*exit)(VirtIOSerialPort *port);
+ DeviceUnrealize unrealize;
/* Callbacks for guest events */
/* Guest opened/closed device. */
diff --git a/net/tap.c b/net/tap.c
index 2d5099b9be..8847ce100a 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -190,7 +190,7 @@ static void tap_send(void *opaque)
TAPState *s = opaque;
int size;
- do {
+ while (qemu_can_send_packet(&s->nc)) {
uint8_t *buf = s->buf;
size = tap_read_packet(s->fd, s->buf, sizeof(s->buf));
@@ -206,8 +206,11 @@ static void tap_send(void *opaque)
size = qemu_send_packet_async(&s->nc, buf, size, tap_send_completed);
if (size == 0) {
tap_read_poll(s, false);
+ break;
+ } else if (size < 0) {
+ break;
}
- } while (size > 0 && qemu_can_send_packet(&s->nc));
+ }
}
static bool tap_has_ufo(NetClientState *nc)
diff --git a/pc-bios/README b/pc-bios/README
index 8b22080187..ef6008d814 100644
--- a/pc-bios/README
+++ b/pc-bios/README
@@ -5,7 +5,7 @@
project (http://www.nongnu.org/vgabios/).
- The PowerPC Open Hack'Ware Open Firmware Compatible BIOS is
- available at http://perso.magic.fr/l_indien/OpenHackWare/index.htm.
+ available at http://repo.or.cz/w/openhackware.git.
- OpenBIOS (http://www.openbios.org/) is a free (GPL v2) portable
firmware implementation. The goal is to implement a 100% IEEE
diff --git a/pc-bios/ohw.diff b/pc-bios/ohw.diff
deleted file mode 100644
index c6b6623f2f..0000000000
--- a/pc-bios/ohw.diff
+++ /dev/null
@@ -1,1843 +0,0 @@
-diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/bios.h OpenHackWare-release-0.4/src/bios.h
---- OpenHackWare-release-0.4.org/src/bios.h 2005-04-06 23:20:22.000000000 +0200
-+++ OpenHackWare-release-0.4/src/bios.h 2005-07-07 01:10:20.000000000 +0200
-@@ -64,6 +64,7 @@
- ARCH_CHRP,
- ARCH_MAC99,
- ARCH_POP,
-+ ARCH_HEATHROW,
- };
-
- /* Hardware definition(s) */
-@@ -174,6 +175,7 @@
- int bd_ioctl (bloc_device_t *bd, int func, void *args);
- uint32_t bd_seclen (bloc_device_t *bd);
- void bd_close (bloc_device_t *bd);
-+void bd_reset_all(void);
- uint32_t bd_seclen (bloc_device_t *bd);
- uint32_t bd_maxbloc (bloc_device_t *bd);
- void bd_sect2CHS (bloc_device_t *bd, uint32_t secnum,
-@@ -183,12 +185,12 @@
- part_t *bd_probe (int boot_device);
- bloc_device_t *bd_get (int device);
- void bd_put (bloc_device_t *bd);
--void bd_set_boot_part (bloc_device_t *bd, part_t *partition);
-+void bd_set_boot_part (bloc_device_t *bd, part_t *partition, int partnum);
- part_t **_bd_parts (bloc_device_t *bd);
-
- void ide_pci_pc_register (uint32_t io_base0, uint32_t io_base1,
- uint32_t io_base2, uint32_t io_base3,
-- void *OF_private);
-+ void *OF_private0, void *OF_private1);
- void ide_pci_pmac_register (uint32_t io_base0, uint32_t io_base1,
- void *OF_private);
-
-@@ -399,17 +401,23 @@
- uint16_t min_grant, uint16_t max_latency);
- void OF_finalize_pci_host (void *dev, int first_bus, int nb_busses);
- void OF_finalize_pci_device (void *dev, uint8_t bus, uint8_t devfn,
-- uint32_t *regions, uint32_t *sizes);
-+ uint32_t *regions, uint32_t *sizes,
-+ int irq_line);
- void OF_finalize_pci_macio (void *dev, uint32_t base_address, uint32_t size,
- void *private_data);
-+void OF_finalize_pci_ide (void *dev,
-+ uint32_t io_base0, uint32_t io_base1,
-+ uint32_t io_base2, uint32_t io_base3);
- int OF_register_bus (const unsigned char *name, uint32_t address,
- const unsigned char *type);
- int OF_register_serial (const unsigned char *bus, const unsigned char *name,
- uint32_t io_base, int irq);
- int OF_register_stdio (const unsigned char *dev_in,
- const unsigned char *dev_out);
--void OF_vga_register (const unsigned char *name, uint32_t address,
-- int width, int height, int depth);
-+void OF_vga_register (const unsigned char *name, unused uint32_t address,
-+ int width, int height, int depth,
-+ unsigned long vga_bios_addr,
-+ unsigned long vga_bios_size);
- void *OF_blockdev_register (void *parent, void *private,
- const unsigned char *type,
- const unsigned char *name, int devnum,
-diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/bloc.c OpenHackWare-release-0.4/src/bloc.c
---- OpenHackWare-release-0.4.org/src/bloc.c 2005-04-06 23:21:00.000000000 +0200
-+++ OpenHackWare-release-0.4/src/bloc.c 2005-07-08 00:28:26.000000000 +0200
-@@ -55,6 +55,7 @@
- /* Partitions */
- part_t *parts, *bparts;
- part_t *boot_part;
-+ int bpartnum;
- /* Chain */
- bloc_device_t *next;
- };
-@@ -66,6 +67,7 @@
-
- static int ide_initialize (bloc_device_t *bd, int device);
- static int ide_read_sector (bloc_device_t *bd, void *buffer, int secnum);
-+static int ide_reset (bloc_device_t *bd);
-
- static int mem_initialize (bloc_device_t *bd, int device);
- static int mem_read_sector (bloc_device_t *bd, void *buffer, int secnum);
-@@ -212,6 +214,17 @@
- {
- }
-
-+void bd_reset_all(void)
-+{
-+ bloc_device_t *bd;
-+ for (bd = bd_list; bd != NULL; bd = bd->next) {
-+ if (bd->init == &ide_initialize) {
-+ /* reset IDE drive because Darwin wants all IDE devices to be reset */
-+ ide_reset(bd);
-+ }
-+ }
-+}
-+
- uint32_t bd_seclen (bloc_device_t *bd)
- {
- return bd->seclen;
-@@ -223,10 +236,12 @@
- }
-
- /* XXX: to be suppressed */
--void bd_set_boot_part (bloc_device_t *bd, part_t *partition)
-+void bd_set_boot_part (bloc_device_t *bd, part_t *partition, int partnum)
- {
-+ dprintf("%s: part %p (%p) %d\n", __func__, partition, bd->boot_part, partnum);
- if (bd->boot_part == NULL) {
- bd->boot_part = partition;
-+ bd->bpartnum = partnum;
- }
- }
-
-@@ -240,6 +255,13 @@
- return &bd->bparts;
- }
-
-+void bd_set_boot_device (bloc_device_t *bd)
-+{
-+#if defined (USE_OPENFIRMWARE)
-+ OF_blockdev_set_boot_device(bd->OF_private, bd->bpartnum, "\\\\ofwboot");
-+#endif
-+}
-+
- part_t *bd_probe (int boot_device)
- {
- char devices[] = { /*'a', 'b',*/ 'c', 'd', 'e', 'f', 'm', '\0', };
-@@ -272,9 +294,7 @@
- tmp = part_probe(bd, force_raw);
- if (boot_device == bd->device) {
- boot_part = tmp;
--#if defined (USE_OPENFIRMWARE)
-- OF_blockdev_set_boot_device(bd->OF_private, 2, "\\\\ofwboot");
--#endif
-+ bd_set_boot_device(bd);
- }
- }
-
-@@ -717,34 +737,29 @@
- /* IDE PCI access for pc */
- static uint8_t ide_pci_port_read (bloc_device_t *bd, int port)
- {
-- eieio();
--
-- return *(uint8_t *)(bd->io_base + port);
-+ uint8_t value;
-+ value = inb(bd->io_base + port);
-+ return value;
- }
-
- static void ide_pci_port_write (bloc_device_t *bd, int port, uint8_t value)
- {
-- *(uint8_t *)(bd->io_base + port) = value;
-- eieio();
-+ outb(bd->io_base + port, value);
- }
-
- static uint32_t ide_pci_data_readl (bloc_device_t *bd)
- {
-- eieio();
--
-- return *((uint32_t *)bd->io_base);
-+ return inl(bd->io_base);
- }
-
- static void ide_pci_data_writel (bloc_device_t *bd, uint32_t val)
- {
-- *(uint32_t *)(bd->io_base) = val;
-- eieio();
-+ outl(bd->io_base, val);
- }
-
- static void ide_pci_control_write (bloc_device_t *bd, uint32_t val)
- {
-- *((uint8_t *)bd->tmp) = val;
-- eieio();
-+ outb(bd->tmp + 2, val);
- }
-
- static ide_ops_t ide_pci_pc_ops = {
-@@ -761,7 +776,7 @@
-
- void ide_pci_pc_register (uint32_t io_base0, uint32_t io_base1,
- uint32_t io_base2, uint32_t io_base3,
-- unused void *OF_private)
-+ void *OF_private0, void *OF_private1)
- {
- if (ide_pci_ops == NULL) {
- ide_pci_ops = malloc(sizeof(ide_ops_t));
-@@ -770,19 +785,19 @@
- memcpy(ide_pci_ops, &ide_pci_pc_ops, sizeof(ide_ops_t));
- }
- if ((io_base0 != 0 || io_base1 != 0) &&
-- ide_pci_ops->base[0] == 0 && ide_pci_ops->base[1] == 0) {
-+ ide_pci_ops->base[0] == 0 && ide_pci_ops->base[2] == 0) {
- ide_pci_ops->base[0] = io_base0;
-- ide_pci_ops->base[1] = io_base1;
-+ ide_pci_ops->base[2] = io_base1;
- #ifdef USE_OPENFIRMWARE
-- ide_pci_ops->OF_private[0] = OF_private;
-+ ide_pci_ops->OF_private[0] = OF_private0;
- #endif
- }
- if ((io_base2 != 0 || io_base3 != 0) &&
-- ide_pci_ops->base[2] == 0 && ide_pci_ops->base[3] == 0) {
-- ide_pci_ops->base[2] = io_base2;
-+ ide_pci_ops->base[1] == 0 && ide_pci_ops->base[3] == 0) {
-+ ide_pci_ops->base[1] = io_base2;
- ide_pci_ops->base[3] = io_base3;
- #ifdef USE_OPENFIRMWARE
-- ide_pci_ops->OF_private[1] = OF_private;
-+ ide_pci_ops->OF_private[1] = OF_private1;
- #endif
- }
- }
-@@ -935,6 +950,8 @@
- }
-
- static void atapi_pad_req (void *buffer, int len);
-+static void atapi_make_req (bloc_device_t *bd, uint32_t *buffer,
-+ int maxlen);
- static int atapi_read_sector (bloc_device_t *bd, void *buffer, int secnum);
-
- static int ide_initialize (bloc_device_t *bd, int device)
-@@ -1035,9 +1052,7 @@
- DPRINTF("INQUIRY\n");
- len = spc_inquiry_req(&atapi_buffer, 36);
- atapi_pad_req(&atapi_buffer, len);
-- ide_port_write(bd, 0x07, 0xA0);
-- for (i = 0; i < 3; i++)
-- ide_data_writel(bd, ldswap32(&atapi_buffer[i]));
-+ atapi_make_req(bd, atapi_buffer, 36);
- status = ide_port_read(bd, 0x07);
- if (status != 0x48) {
- ERROR("ATAPI INQUIRY : status %0x != 0x48\n", status);
-@@ -1053,9 +1068,7 @@
- DPRINTF("READ_CAPACITY\n");
- len = mmc_read_capacity_req(&atapi_buffer);
- atapi_pad_req(&atapi_buffer, len);
-- ide_port_write(bd, 0x07, 0xA0);
-- for (i = 0; i < 3; i++)
-- ide_data_writel(bd, ldswap32(&atapi_buffer[i]));
-+ atapi_make_req(bd, atapi_buffer, 8);
- status = ide_port_read(bd, 0x07);
- if (status != 0x48) {
- ERROR("ATAPI READ_CAPACITY : status %0x != 0x48\n", status);
-@@ -1105,6 +1118,22 @@
- memset(p + len, 0, 12 - len);
- }
-
-+static void atapi_make_req (bloc_device_t *bd, uint32_t *buffer,
-+ int maxlen)
-+{
-+ int i;
-+ /* select drive */
-+ if (bd->drv == 0)
-+ ide_port_write(bd, 0x06, 0x40);
-+ else
-+ ide_port_write(bd, 0x06, 0x50);
-+ ide_port_write(bd, 0x04, maxlen & 0xff);
-+ ide_port_write(bd, 0x05, (maxlen >> 8) & 0xff);
-+ ide_port_write(bd, 0x07, 0xA0);
-+ for (i = 0; i < 3; i++)
-+ ide_data_writel(bd, ldswap32(&buffer[i]));
-+}
-+
- static int atapi_read_sector (bloc_device_t *bd, void *buffer, int secnum)
- {
- uint32_t atapi_buffer[4];
-@@ -1112,16 +1141,9 @@
- uint32_t status, value;
- int i, len;
-
-- /* select drive */
-- if (bd->drv == 0)
-- ide_port_write(bd, 0x06, 0x40);
-- else
-- ide_port_write(bd, 0x06, 0x50);
- len = mmc_read12_req(atapi_buffer, secnum, 1);
- atapi_pad_req(&atapi_buffer, len);
-- ide_port_write(bd, 0x07, 0xA0);
-- for (i = 0; i < 3; i++)
-- ide_data_writel(bd, ldswap32(&atapi_buffer[i]));
-+ atapi_make_req(bd, atapi_buffer, bd->seclen);
- status = ide_port_read(bd, 0x07);
- if (status != 0x48) {
- ERROR("ATAPI READ12 : status %0x != 0x48\n", status);
-diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/libpart/apple.c OpenHackWare-release-0.4/src/libpart/apple.c
---- OpenHackWare-release-0.4.org/src/libpart/apple.c 2005-03-31 09:23:33.000000000 +0200
-+++ OpenHackWare-release-0.4/src/libpart/apple.c 2005-07-03 16:17:41.000000000 +0200
-@@ -199,14 +199,18 @@
- if (len == 0) {
- /* Place holder. Skip it */
- DPRINTF("%s placeholder part\t%d\n", __func__, i);
-+ part->flags = PART_TYPE_APPLE | PART_FLAG_DUMMY;
-+ part_register(bd, part, name, i);
- } else if (strncmp("Apple_Void", type, 32) == 0) {
- /* Void partition. Skip it */
- DPRINTF("%s Void part\t%d [%s]\n", __func__, i, type);
-+ part->flags = PART_TYPE_APPLE | PART_FLAG_DUMMY;
-+ part_register(bd, part, name, i);
- } else if (strncmp("Apple_Free", type, 32) == 0) {
- /* Free space. Skip it */
- DPRINTF("%s Free part (%d)\n", __func__, i);
- part->flags = PART_TYPE_APPLE | PART_FLAG_DUMMY;
-- part_register(bd, part, name);
-+ part_register(bd, part, name, i);
- } else if (strncmp("Apple_partition_map", type, 32) == 0 ||
- strncmp("Apple_Partition_Map", type, 32) == 0
- #if 0 // Is this really used or is it just a mistake ?
-@@ -226,7 +230,7 @@
- */
- }
- part->flags = PART_TYPE_APPLE | PART_FLAG_DUMMY;
-- part_register(bd, part, name);
-+ part_register(bd, part, name, i);
- } else if (strncmp("Apple_Driver", type, 32) == 0 ||
- strncmp("Apple_Driver43", type, 32) == 0 ||
- strncmp("Apple_Driver43_CD", type, 32) == 0 ||
-@@ -236,8 +240,12 @@
- strncmp("Apple_Driver_IOKit", type, 32) == 0) {
- /* Drivers. don't care for now */
- DPRINTF("%s Drivers part\t%d [%s]\n", __func__, i, type);
-+ part->flags = PART_TYPE_APPLE | PART_FLAG_DRIVER;
-+ part_register(bd, part, name, i);
- } else if (strncmp("Apple_Patches", type, 32) == 0) {
- /* Patches: don't care for now */
-+ part->flags = PART_TYPE_APPLE | PART_FLAG_PATCH;
-+ part_register(bd, part, name, i);
- DPRINTF("%s Patches part\t%d [%s]\n", __func__, i, type);
- } else if (strncmp("Apple_HFS", type, 32) == 0 ||
- strncmp("Apple_MFS", type, 32) == 0 ||
-@@ -256,9 +264,8 @@
- count = partmap->bloc_cnt * HFS_BLOCSIZE;
- if (partmap->boot_size == 0 || partmap->boot_load == 0) {
- printf("Not a bootable partition %d %d (%p %p)\n",
-- partmap->boot_size, partmap->boot_load,boot_part, part);
-- if (boot_part == NULL)
-- boot_part = part;
-+ partmap->boot_size, partmap->boot_load,
-+ boot_part, part);
- part->flags = PART_TYPE_APPLE | PART_FLAG_FS;
- } else {
- part->boot_start.bloc = partmap->boot_start;
-@@ -278,8 +285,8 @@
- boot_part = part;
- part->flags = PART_TYPE_APPLE | PART_FLAG_FS | PART_FLAG_BOOT;
- }
-- printf("Partition: %d %s st %0x size %0x",
-- i, name, partmap->start_bloc, partmap->bloc_cnt);
-+ printf("Partition: %d '%s' '%s' st %0x size %0x",
-+ i, name, type, partmap->start_bloc, partmap->bloc_cnt);
- #ifndef DEBUG
- printf("\n");
- #endif
-@@ -290,11 +297,13 @@
- part->boot_load, part->boot_entry);
- DPRINTF(" load %0x entry %0x %0x\n",
- partmap->boot_load2, partmap->boot_entry2, HFS_BLOCSIZE);
-- part_register(bd, part, name);
-+ part_register(bd, part, name, i);
- } else {
- memcpy(tmp, type, 32);
- tmp[32] = '\0';
- ERROR("Unknown partition type [%s]\n", tmp);
-+ part->flags = PART_TYPE_APPLE | PART_FLAG_DUMMY;
-+ part_register(bd, part, name, i);
- }
- }
- error:
-diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/libpart/core.c OpenHackWare-release-0.4/src/libpart/core.c
---- OpenHackWare-release-0.4.org/src/libpart/core.c 2005-03-31 09:23:33.000000000 +0200
-+++ OpenHackWare-release-0.4/src/libpart/core.c 2005-07-03 16:17:41.000000000 +0200
-@@ -126,7 +126,7 @@
- }
-
- int part_register (bloc_device_t *bd, part_t *partition,
-- const unsigned char *name)
-+ const unsigned char *name, int partnum)
- {
- part_t **cur;
-
-@@ -134,6 +134,7 @@
- partition->bd = bd;
- partition->next = NULL;
- partition->name = strdup(name);
-+ partition->partnum = partnum;
- for (cur = _bd_parts(bd); *cur != NULL; cur = &(*cur)->next)
- continue;
- *cur = partition;
-@@ -141,29 +142,15 @@
- return 0;
- }
-
--static inline int set_boot_part (bloc_device_t *bd, int partnum)
--{
-- part_t *cur;
--
-- cur = part_get(bd, partnum);
-- if (cur == NULL)
-- return -1;
-- bd_set_boot_part(bd, cur);
--
-- return 0;
--}
--
- part_t *part_get (bloc_device_t *bd, int partnum)
- {
- part_t **listp, *cur;
-- int i;
-
- listp = _bd_parts(bd);
-- cur = *listp;
-- for (i = 0; i != partnum; i++) {
-- if (cur == NULL)
-+
-+ for (cur = *listp; cur != NULL; cur = cur->next) {
-+ if (cur->partnum == partnum)
- break;
-- cur = cur->next;
- }
-
- return cur;
-@@ -192,17 +179,20 @@
- part_set_blocsize(bd, part, 512);
- part->bd = bd;
- part->flags = PART_TYPE_RAW | PART_FLAG_BOOT;
-- part_register(bd, part, "Raw");
-+ part_register(bd, part, "Raw", 0);
-
- return part;
- }
-
-+bloc_device_t *part_get_bd (part_t *part)
-+{
-+ return part->bd;
-+}
-+
- part_t *part_probe (bloc_device_t *bd, int set_raw)
- {
-- part_t *part0, *boot_part, **cur;
-+ part_t *part0 = NULL, *boot_part, **cur;
-
-- /* Register the 0 partition: raw partition containing the whole disk */
-- part0 = part_get_raw(bd);
- /* Try to find a valid boot partition */
- boot_part = Apple_probe_partitions(bd);
- if (boot_part == NULL) {
-@@ -210,10 +200,13 @@
- if (boot_part == NULL && arch == ARCH_PREP)
- boot_part = PREP_find_partition(bd);
- if (boot_part == NULL && set_raw != 0) {
-- boot_part = part0;
-- set_boot_part(bd, 0);
-+ dprintf("Use bloc device as raw partition\n");
- }
- }
-+ if (_bd_parts(bd) == NULL) {
-+ /* Register the 0 partition: raw partition containing the whole disk */
-+ part0 = part_get_raw(bd);
-+ }
- /* Probe filesystem on each found partition */
- for (cur = _bd_parts(bd); *cur != NULL; cur = &(*cur)->next) {
- const unsigned char *map, *type;
-@@ -248,23 +241,28 @@
- type = "unknown";
- break;
- }
-- DPRINTF("Probe filesystem on %s %s partition '%s' %s\n",
-+ dprintf("Probe filesystem on %s %s partition '%s' %s %p\n",
- type, map, (*cur)->name,
-- ((*cur)->flags) & PART_FLAG_BOOT ? "(bootable)" : "");
-+ ((*cur)->flags) & PART_FLAG_BOOT ? "(bootable)" : "", *cur);
- if (((*cur)->flags) & PART_FLAG_FS) {
- if (((*cur)->flags) & PART_FLAG_BOOT)
- (*cur)->fs = fs_probe(*cur, 1);
- else
- (*cur)->fs = fs_probe(*cur, 0);
-+ } else if (((*cur)->flags) & PART_TYPE_RAW) {
-+ (*cur)->fs = fs_probe(*cur, 2);
- } else {
- (*cur)->fs = fs_probe(*cur, 2);
- }
-- if (((*cur)->flags) & PART_FLAG_BOOT) {
-- bd_set_boot_part(bd, *cur);
- fs_get_bootfile((*cur)->fs);
-+ if (((*cur)->flags) & PART_FLAG_BOOT) {
-+ dprintf("Partition is bootable (%d)\n", (*cur)->partnum);
-+ bd_set_boot_part(bd, *cur, (*cur)->partnum);
-+ if (boot_part == NULL)
-+ boot_part = *cur;
- }
- }
-- DPRINTF("Boot partition: %p %p %p %p\n", boot_part, boot_part->fs,
-+ dprintf("Boot partition: %p %p %p %p\n", boot_part, boot_part->fs,
- part_fs(boot_part), part0);
-
- return boot_part;
-@@ -279,6 +277,7 @@
- part->boot_size.offset = 0;
- part->boot_load = 0;
- part->boot_entry = 0;
-+ part->flags |= PART_FLAG_BOOT;
-
- return 0;
- }
-diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/libpart/isofs.c OpenHackWare-release-0.4/src/libpart/isofs.c
---- OpenHackWare-release-0.4.org/src/libpart/isofs.c 2005-03-31 09:23:33.000000000 +0200
-+++ OpenHackWare-release-0.4/src/libpart/isofs.c 2005-07-03 16:17:41.000000000 +0200
-@@ -242,7 +242,7 @@
- part->boot_start.bloc, part->boot_size.bloc,
- part->boot_load, part->boot_entry);
- part->flags = PART_TYPE_ISO9660 | PART_FLAG_BOOT;
-- part_register(bd, part, name);
-+ part_register(bd, part, name, i + 1);
- fs_raw_set_bootfile(part, part->boot_start.bloc,
- part->boot_start.offset,
- part->boot_size.bloc,
-diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/libpart/libpart.h OpenHackWare-release-0.4/src/libpart/libpart.h
---- OpenHackWare-release-0.4.org/src/libpart/libpart.h 2005-03-31 09:23:33.000000000 +0200
-+++ OpenHackWare-release-0.4/src/libpart/libpart.h 2005-07-03 16:17:41.000000000 +0200
-@@ -30,6 +30,7 @@
-
- struct part_t {
- bloc_device_t *bd;
-+ int partnum;
- uint32_t start; /* Partition first bloc */
- uint32_t size; /* Partition size, in blocs */
- uint32_t spb;
-@@ -54,7 +55,7 @@
- };
-
- int part_register (bloc_device_t *bd, part_t *partition,
-- const unsigned char *name);
-+ const unsigned char *name, int partnum);
- void part_set_blocsize (bloc_device_t *bd, part_t *part, uint32_t blocsize);
- void part_private_set (part_t *part, void *private);
- void *part_private_get (part_t *part);
-diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/libpart/prep.c OpenHackWare-release-0.4/src/libpart/prep.c
---- OpenHackWare-release-0.4.org/src/libpart/prep.c 2005-03-31 09:23:33.000000000 +0200
-+++ OpenHackWare-release-0.4/src/libpart/prep.c 2005-07-03 16:17:41.000000000 +0200
-@@ -164,7 +164,7 @@
- part->boot_load = 0;
- part->boot_entry = boot_offset - part->bloc_size;
- part->flags = PART_TYPE_PREP | PART_FLAG_BOOT;
-- part_register(bd, part, "PREP boot");
-+ part_register(bd, part, "PREP boot", i);
- fs_raw_set_bootfile(part, part->boot_start.bloc,
- part->boot_start.offset,
- part->boot_size.bloc,
-diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/main.c OpenHackWare-release-0.4/src/main.c
---- OpenHackWare-release-0.4.org/src/main.c 2005-03-31 09:23:33.000000000 +0200
-+++ OpenHackWare-release-0.4/src/main.c 2005-06-07 23:48:39.000000000 +0200
-@@ -364,20 +364,24 @@
- void *load_base, *load_entry, *last_alloc, *load_end;
- uint32_t memsize, boot_image_size, cmdline_size, ramdisk_size;
- uint32_t boot_base, boot_nb;
-- int boot_device;
-+ int boot_device, i;
-+ static const uint32_t isa_base_tab[3] = {
-+ 0x80000000, /* PREP */
-+ 0xFE000000, /* Grackle (Heathrow) */
-+ 0xF2000000, /* UniNorth (Mac99) */
-+ };
-
- /* Retrieve NVRAM configuration */
-- nvram_retry:
-+ for(i = 0; i < 3; i++) {
-+ isa_io_base = isa_base_tab[i];
- nvram = NVRAM_get_config(&memsize, &boot_device,
- &boot_image, &boot_image_size,
- &cmdline, &cmdline_size,
- &ramdisk, &ramdisk_size);
-- if (nvram == NULL) {
-- /* Retry with another isa_io_base */
-- if (isa_io_base == 0x80000000) {
-- isa_io_base = 0xF2000000;
-- goto nvram_retry;
-+ if (nvram)
-+ break;
- }
-+ if (i == 3) {
- ERROR("Unable to load configuration from NVRAM. Aborting...\n");
- return -1;
- }
-@@ -402,7 +406,7 @@
- cpu_name = CPU_get_name(pvr);
- OF_register_cpu(cpu_name, 0, pvr,
- 200 * 1000 * 1000, 200 * 1000 * 1000,
-- 100 * 1000 * 1000, 10 * 1000 * 1000,
-+ 100 * 1000 * 1000, 100 * 1000 * 1000,
- 0x0092);
- }
- OF_register_memory(memsize, 512 * 1024 /* TOFIX */);
-@@ -433,9 +437,12 @@
- vga_puts(copyright);
- vga_puts("\n");
-
-+#if 0
- /* QEMU is quite incoherent: d is cdrom, not second drive */
-+ /* XXX: should probe CD-ROM position */
- if (boot_device == 'd')
- boot_device = 'e';
-+#endif
- /* Open boot device */
- boot_part = bd_probe(boot_device);
- if (boot_device == 'm') {
-diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/nvram.c OpenHackWare-release-0.4/src/nvram.c
---- OpenHackWare-release-0.4.org/src/nvram.c 2005-03-31 09:23:33.000000000 +0200
-+++ OpenHackWare-release-0.4/src/nvram.c 2005-06-04 23:44:03.000000000 +0200
-@@ -334,6 +334,7 @@
- ret = NVRAM_chrp_format(nvram);
- break;
- case ARCH_MAC99:
-+ case ARCH_HEATHROW: /* XXX: may be incorrect */
- ret = NVRAM_mac99_format(nvram);
- break;
- case ARCH_POP:
-@@ -409,13 +410,12 @@
- arch = ARCH_MAC99;
- } else if (strcmp(sign, "POP") == 0) {
- arch = ARCH_POP;
-+ } else if (strcmp(sign, "HEATHROW") == 0) {
-+ arch = ARCH_HEATHROW;
- } else {
- ERROR("Unknown PPC architecture: '%s'\n", sign);
- return NULL;
- }
-- /* HACK */
-- if (arch == ARCH_CHRP)
-- arch = ARCH_MAC99;
- lword = NVRAM_get_lword(nvram, 0x30);
- *RAM_size = lword;
- byte = NVRAM_get_byte(nvram, 0x34);
-diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/of.c OpenHackWare-release-0.4/src/of.c
---- OpenHackWare-release-0.4.org/src/of.c 2005-04-06 23:17:26.000000000 +0200
-+++ OpenHackWare-release-0.4/src/of.c 2005-07-07 23:30:08.000000000 +0200
-@@ -489,7 +489,7 @@
- ERROR("%s can't alloc new node '%s' name\n", __func__, name);
- return NULL;
- }
-- new->prop_address = OF_prop_int_new(env, new, "address", address);
-+ new->prop_address = OF_prop_int_new(env, new, "unit-address", address);
- if (new->prop_address == NULL) {
- free(new->prop_name->value);
- free(new->prop_name);
-@@ -1017,6 +1017,33 @@
- string, strlen(string) + 1);
- }
-
-+/* convert '\1' char to '\0' */
-+static OF_prop_t *OF_prop_string_new1 (OF_env_t *env, OF_node_t *node,
-+ const unsigned char *name,
-+ const unsigned char *string)
-+{
-+ int len, i;
-+ OF_prop_t *ret;
-+ unsigned char *str;
-+
-+ if (strchr(string, '\1') == NULL) {
-+ return OF_prop_string_new(env, node, name, string);
-+ } else {
-+ len = strlen(string) + 1;
-+ str = malloc(len);
-+ if (!str)
-+ return NULL;
-+ memcpy(str, string, len);
-+ for(i = 0; i < len; i++)
-+ if (str[i] == '\1')
-+ str[i] = '\0';
-+ ret = OF_property_new(env, node, name,
-+ str, len);
-+ free(str);
-+ return ret;
-+ }
-+}
-+
- __attribute__ (( section (".OpenFirmware") ))
- static OF_prop_t *OF_prop_int_new (OF_env_t *env, OF_node_t *node,
- const unsigned char *name, uint32_t value)
-@@ -1421,15 +1448,12 @@
- __attribute__ (( section (".OpenFirmware") ))
- int OF_init (void)
- {
-- const unsigned char compat_str[] =
- #if 0
- "PowerMac3,1\0MacRISC\0Power Macintosh\0";
- "PowerMac1,2\0MacRISC\0Power Macintosh\0";
- "AAPL,PowerMac G3\0PowerMac G3\0MacRISC\0Power Macintosh\0";
- "AAPL,PowerMac3,0\0MacRISC\0Power Macintosh\0";
- "AAPL,Gossamer\0MacRISC\0Power Macintosh\0";
--#else
-- "AAPL,PowerMac G3\0PowerMac G3\0MacRISC\0Power Macintosh\0";
- #endif
- OF_env_t *OF_env;
- OF_node_t *als, *opt, *chs, *pks;
-@@ -1455,15 +1479,21 @@
- return -1;
- }
- OF_prop_string_new(OF_env, OF_node_root, "device_type", "bootrom");
--#if 0
-- OF_prop_string_new(OF_env, OF_node_root,
-- "model", "PPC Open Hack'Ware " BIOS_VERSION);
--#else
-+ if (arch == ARCH_HEATHROW) {
-+ const unsigned char compat_str[] =
-+ "PowerMac1,1\0MacRISC\0Power Macintosh";
-+ OF_property_new(OF_env, OF_node_root, "compatible",
-+ compat_str, sizeof(compat_str));
- OF_prop_string_new(OF_env, OF_node_root,
-- "model", compat_str);
--#endif
-+ "model", "Power Macintosh");
-+ } else {
-+ const unsigned char compat_str[] =
-+ "PowerMac3,1\0MacRISC\0Power Macintosh";
- OF_property_new(OF_env, OF_node_root, "compatible",
- compat_str, sizeof(compat_str));
-+ OF_prop_string_new(OF_env, OF_node_root,
-+ "model", "PowerMac3,1");
-+ }
- #if 0
- OF_prop_string_new(OF_env, OF_node_root, "copyright", copyright);
- #else
-@@ -1561,14 +1591,15 @@
- range.size = 0x00800000;
- OF_property_new(OF_env, rom, "ranges", &range, sizeof(OF_range_t));
- OF_prop_int_new(OF_env, rom, "#address-cells", 1);
-+
- /* "/rom/boot-rom@fff00000" node */
-- brom = OF_node_new(OF_env, OF_node_root, "boot-rom", 0xfff00000);
-+ brom = OF_node_new(OF_env, rom, "boot-rom", 0xfff00000);
- if (brom == NULL) {
- ERROR("Cannot create 'boot-rom'\n");
- return -1;
- }
- regs.address = 0xFFF00000;
-- regs.size = 0x00010000;
-+ regs.size = 0x00100000;
- OF_property_new(OF_env, brom, "reg", &regs, sizeof(OF_regprop_t));
- OF_prop_string_new(OF_env, brom, "write-characteristic", "flash");
- OF_prop_string_new(OF_env, brom, "BootROM-build-date",
-@@ -1577,7 +1608,7 @@
- OF_prop_string_new(OF_env, brom, "copyright", copyright);
- OF_prop_string_new(OF_env, brom, "model", BIOS_str);
- OF_prop_int_new(OF_env, brom, "result", 0);
--#if 0
-+#if 1
- {
- /* Hack taken 'as-is' from PearPC */
- unsigned char info[] = {
-@@ -1596,7 +1627,9 @@
- OF_node_put(OF_env, brom);
- OF_node_put(OF_env, rom);
- }
-+#if 0
- /* From here, hardcoded hacks to get a Mac-like machine */
-+ /* XXX: Core99 does not seem to like this NVRAM tree */
- /* "/nvram@fff04000" node */
- {
- OF_regprop_t regs;
-@@ -1617,6 +1650,7 @@
- OF_prop_int_new(OF_env, chs, "nvram", OF_pack_handle(OF_env, nvr));
- OF_node_put(OF_env, nvr);
- }
-+#endif
- /* "/pseudo-hid" : hid emulation as Apple does */
- {
- OF_node_t *hid;
-@@ -1663,7 +1697,27 @@
- }
- OF_node_put(OF_env, hid);
- }
-+ if (arch == ARCH_MAC99) {
-+ OF_node_t *unin;
-+ OF_regprop_t regs;
-
-+ unin = OF_node_new(OF_env, OF_node_root,
-+ "uni-n", 0xf8000000);
-+ if (unin == NULL) {
-+ ERROR("Cannot create 'uni-n'\n");
-+ return -1;
-+ }
-+ OF_prop_string_new(OF_env, unin, "device-type", "memory-controller");
-+ OF_prop_string_new(OF_env, unin, "model", "AAPL,UniNorth");
-+ OF_prop_string_new(OF_env, unin, "compatible", "uni-north");
-+ regs.address = 0xf8000000;
-+ regs.size = 0x01000000;
-+ OF_property_new(OF_env, unin, "reg", &regs, sizeof(regs));
-+ OF_prop_int_new(OF_env, unin, "#address-cells", 1);
-+ OF_prop_int_new(OF_env, unin, "#size-cells", 1);
-+ OF_prop_int_new(OF_env, unin, "device-rev", 3);
-+ OF_node_put(OF_env, unin);
-+ }
-
- #if 1 /* This is mandatory for claim to work
- * but I don't know where it should really be (in cpu ?)
-@@ -1693,7 +1747,9 @@
-
- /* "/options/boot-args" node */
- {
-- const unsigned char *args = "-v rootdev cdrom";
-+ // const unsigned char *args = "-v rootdev cdrom";
-+ //const unsigned char *args = "-v io=0xffffffff";
-+ const unsigned char *args = "-v";
- /* Ask MacOS X to print debug messages */
- // OF_prop_string_new(OF_env, chs, "machargs", args);
- // OF_prop_string_new(OF_env, opt, "boot-command", args);
-@@ -2013,17 +2069,17 @@
- OF_prop_int_new(OF_env, node, "min-grant", min_grant);
- OF_prop_int_new(OF_env, node, "max-latency", max_latency);
- if (dev->type != NULL)
-- OF_prop_string_new(OF_env, node, "device_type", dev->type);
-+ OF_prop_string_new1(OF_env, node, "device_type", dev->type);
- if (dev->compat != NULL)
-- OF_prop_string_new(OF_env, node, "compatible", dev->compat);
-+ OF_prop_string_new1(OF_env, node, "compatible", dev->compat);
- if (dev->model != NULL)
-- OF_prop_string_new(OF_env, node, "model", dev->model);
-+ OF_prop_string_new1(OF_env, node, "model", dev->model);
- if (dev->acells != 0)
- OF_prop_int_new(OF_env, node, "#address-cells", dev->acells);
- if (dev->scells != 0)
-- OF_prop_int_new(OF_env, node, "#interrupt-cells", dev->acells);
-+ OF_prop_int_new(OF_env, node, "#size-cells", dev->scells);
- if (dev->icells != 0)
-- OF_prop_int_new(OF_env, node, "#size-cells", dev->acells);
-+ OF_prop_int_new(OF_env, node, "#interrupt-cells", dev->icells);
- dprintf("Done %p %p\n", parent, node);
-
- return node;
-@@ -2040,8 +2096,9 @@
- OF_env_t *OF_env;
- pci_range_t ranges[3];
- OF_regprop_t regs[1];
-- OF_node_t *pci_host;
-+ OF_node_t *pci_host, *als;
- int nranges;
-+ unsigned char buffer[OF_NAMELEN_MAX];
-
- OF_env = OF_env_main;
- dprintf("register PCI host '%s' '%s' '%s' '%s'\n",
-@@ -2052,6 +2109,17 @@
- ERROR("Cannot create pci host\n");
- return NULL;
- }
-+
-+ als = OF_node_get(OF_env, "aliases");
-+ if (als == NULL) {
-+ ERROR("Cannot get 'aliases'\n");
-+ return NULL;
-+ }
-+ sprintf(buffer, "/%s", dev->name);
-+ OF_prop_string_set(OF_env, als, "pci", buffer);
-+ OF_node_put(OF_env, als);
-+
-+
- regs[0].address = cfg_base;
- regs[0].size = cfg_len;
- OF_property_new(OF_env, pci_host, "reg", regs, sizeof(OF_regprop_t));
-@@ -2136,6 +2204,11 @@
- return pci_dev;
- }
-
-+/* XXX: suppress that, used for interrupt map init */
-+OF_node_t *pci_host_node;
-+uint32_t pci_host_interrupt_map[7 * 32];
-+int pci_host_interrupt_map_len = 0;
-+
- void OF_finalize_pci_host (void *dev, int first_bus, int nb_busses)
- {
- OF_env_t *OF_env;
-@@ -2145,10 +2218,12 @@
- regs[0].address = first_bus;
- regs[0].size = nb_busses;
- OF_property_new(OF_env, dev, "bus-range", regs, sizeof(OF_regprop_t));
-+ pci_host_node = dev;
- }
-
- void OF_finalize_pci_device (void *dev, uint8_t bus, uint8_t devfn,
-- uint32_t *regions, uint32_t *sizes)
-+ uint32_t *regions, uint32_t *sizes,
-+ int irq_line)
- {
- OF_env_t *OF_env;
- pci_reg_prop_t pregs[6], rregs[6];
-@@ -2156,6 +2231,7 @@
- int i, j, k;
-
- OF_env = OF_env_main;
-+ /* XXX: only useful for VGA card in fact */
- if (regions[0] != 0x00000000)
- OF_prop_int_set(OF_env, dev, "address", regions[0] & ~0x0000000F);
- for (i = 0, j = 0, k = 0; i < 6; i++) {
-@@ -2222,7 +2298,22 @@
- } else {
- OF_property_new(OF_env, dev, "assigned-addresses", NULL, 0);
- }
--#if 0
-+ if (irq_line >= 0) {
-+ int i;
-+ OF_prop_int_new(OF_env, dev, "interrupts", 1);
-+ i = pci_host_interrupt_map_len;
-+ pci_host_interrupt_map[i++] = (devfn << 8) & 0xf800;
-+ pci_host_interrupt_map[i++] = 0;
-+ pci_host_interrupt_map[i++] = 0;
-+ pci_host_interrupt_map[i++] = 0;
-+ pci_host_interrupt_map[i++] = 0; /* pic handle will be patched later */
-+ pci_host_interrupt_map[i++] = irq_line;
-+ if (arch != ARCH_HEATHROW) {
-+ pci_host_interrupt_map[i++] = 1;
-+ }
-+ pci_host_interrupt_map_len = i;
-+ }
-+#if 1
- {
- OF_prop_t *prop_name = ((OF_node_t *)dev)->prop_name;
-
-@@ -2390,6 +2481,54 @@
- return 0;
- }
-
-+static void keylargo_ata(OF_node_t *mio, uint32_t base_address,
-+ uint32_t base, int irq1, int irq2,
-+ uint16_t pic_phandle)
-+{
-+ OF_env_t *OF_env = OF_env_main;
-+ OF_node_t *ata;
-+ OF_regprop_t regs[2];
-+
-+ ata = OF_node_new(OF_env, mio, "ata-4", base);
-+ if (ata == NULL) {
-+ ERROR("Cannot create 'ata-4'\n");
-+ return;
-+ }
-+ OF_prop_string_new(OF_env, ata, "device_type", "ata");
-+#if 1
-+ OF_prop_string_new(OF_env, ata, "compatible", "key2largo-ata");
-+ OF_prop_string_new(OF_env, ata, "model", "ata-4");
-+ OF_prop_string_new(OF_env, ata, "cable-type", "80-conductor");
-+#else
-+ OF_prop_string_new(OF_env, ata, "compatible", "cmd646-ata");
-+ OF_prop_string_new(OF_env, ata, "model", "ata-4");
-+#endif
-+ OF_prop_int_new(OF_env, ata, "#address-cells", 1);
-+ OF_prop_int_new(OF_env, ata, "#size-cells", 0);
-+ regs[0].address = base;
-+ regs[0].size = 0x00001000;
-+#if 0 // HACK: Don't set up DMA registers
-+ regs[1].address = 0x00008A00;
-+ regs[1].size = 0x00001000;
-+ OF_property_new(OF_env, ata, "reg",
-+ regs, 2 * sizeof(OF_regprop_t));
-+#else
-+ OF_property_new(OF_env, ata, "reg",
-+ regs, sizeof(OF_regprop_t));
-+#endif
-+ OF_prop_int_new(OF_env, ata, "interrupt-parent", pic_phandle);
-+ regs[0].address = irq1;
-+ regs[0].size = 0x00000001;
-+ regs[1].address = irq2;
-+ regs[1].size = 0x00000000;
-+ OF_property_new(OF_env, ata, "interrupts",
-+ regs, 2 * sizeof(OF_regprop_t));
-+ if (base == 0x1f000)
-+ ide_pci_pmac_register(base_address + base, 0x00000000, ata);
-+ else
-+ ide_pci_pmac_register(0x00000000, base_address + base, ata);
-+}
-+
- void OF_finalize_pci_macio (void *dev, uint32_t base_address, uint32_t size,
- void *private_data)
- {
-@@ -2398,6 +2537,8 @@
- pci_reg_prop_t pregs[2];
- OF_node_t *mio, *chs, *als;
- uint16_t pic_phandle;
-+ int rec_len;
-+ OF_prop_t *mio_reg;
-
- OF_DPRINTF("mac-io: %p\n", dev);
- OF_env = OF_env_main;
-@@ -2416,10 +2557,14 @@
- mio = dev;
- mio->private_data = private_data;
- pregs[0].addr.hi = 0x00000000;
-- pregs[0].addr.mid = 0x82013810;
-+ pregs[0].addr.mid = 0x00000000;
- pregs[0].addr.lo = 0x00000000;
- pregs[0].size_hi = base_address;
- pregs[0].size_lo = size;
-+ mio_reg = OF_property_get(OF_env, mio, "reg");
-+ if (mio_reg && mio_reg->vlen >= 5 * 4) {
-+ pregs[0].addr.mid = ((pci_reg_prop_t *)mio_reg->value)->addr.hi;
-+ }
- OF_property_new(OF_env, mio, "ranges",
- &pregs, sizeof(pci_reg_prop_t));
- #if 0
-@@ -2431,8 +2576,32 @@
- OF_property_new(OF_env, mio, "assigned-addresses",
- &pregs, sizeof(pci_reg_prop_t));
- #endif
-+
-+ if (arch == ARCH_HEATHROW) {
-+ /* Heathrow PIC */
-+ OF_regprop_t regs;
-+ OF_node_t *mpic;
-+ const char compat_str[] = "heathrow\0mac-risc";
-+
-+ mpic = OF_node_new(OF_env, mio, "interrupt-controller", 0x10);
-+ if (mpic == NULL) {
-+ ERROR("Cannot create 'mpic'\n");
-+ goto out;
-+ }
-+ OF_prop_string_new(OF_env, mpic, "device_type", "interrupt-controller");
-+ OF_property_new(OF_env, mpic, "compatible", compat_str, sizeof(compat_str));
-+ OF_prop_int_new(OF_env, mpic, "#interrupt-cells", 1);
-+ regs.address = 0x10;
-+ regs.size = 0x20;
-+ OF_property_new(OF_env, mpic, "reg",
-+ &regs, sizeof(regs));
-+ OF_property_new(OF_env, mpic, "interrupt-controller", NULL, 0);
-+ pic_phandle = OF_pack_handle(OF_env, mpic);
-+ OF_prop_int_new(OF_env, chs, "interrupt-controller", pic_phandle);
-+ OF_node_put(OF_env, mpic);
-+ rec_len = 6;
-+ } else {
- /* OpenPIC */
-- {
- OF_regprop_t regs[4];
- OF_node_t *mpic;
- mpic = OF_node_new(OF_env, mio, "interrupt-controller", 0x40000);
-@@ -2455,8 +2624,37 @@
- pic_phandle = OF_pack_handle(OF_env, mpic);
- OF_prop_int_new(OF_env, chs, "interrupt-controller", pic_phandle);
- OF_node_put(OF_env, mpic);
-+ rec_len = 7;
- }
--#if 1
-+
-+ /* patch pci host table */
-+ /* XXX: do it after the PCI init */
-+ {
-+ int i;
-+ uint32_t tab[4];
-+
-+ for(i = 0; i < pci_host_interrupt_map_len; i += rec_len)
-+ pci_host_interrupt_map[i + 4] = pic_phandle;
-+#if 0
-+ dprintf("interrupt-map:\n");
-+ for(i = 0; i < pci_host_interrupt_map_len; i++) {
-+ dprintf(" %08x", pci_host_interrupt_map[i]);
-+ if ((i % rec_len) == (rec_len - 1))
-+ dprintf("\n");
-+ }
-+ dprintf("\n");
-+#endif
-+ OF_property_new(OF_env, pci_host_node, "interrupt-map",
-+ pci_host_interrupt_map,
-+ pci_host_interrupt_map_len * sizeof(uint32_t));
-+ tab[0] = 0xf800;
-+ tab[1] = 0;
-+ tab[2] = 0;
-+ tab[3] = 0;
-+ OF_property_new(OF_env, pci_host_node, "interrupt-map-mask",
-+ tab, 4 * sizeof(uint32_t));
-+ }
-+#if 0
- /* escc is useful to get MacOS X debug messages */
- {
- OF_regprop_t regs[8];
-@@ -2645,85 +2843,12 @@
- OF_node_put(OF_env, scc);
- }
- #endif
-- /* IDE controller */
-- {
-- OF_node_t *ata;
-- OF_regprop_t regs[2];
-- ata = OF_node_new(OF_env, mio, "ata-4", 0x1f000);
-- if (ata == NULL) {
-- ERROR("Cannot create 'ata-4'\n");
-- goto out;
-- }
-- OF_prop_string_new(OF_env, ata, "device_type", "ata");
--#if 1
-- OF_prop_string_new(OF_env, ata, "compatible", "keylargo-ata");
-- OF_prop_string_new(OF_env, ata, "model", "ata-4");
--#else
-- OF_prop_string_new(OF_env, ata, "compatible", "cmd646-ata");
-- OF_prop_string_new(OF_env, ata, "model", "ata-4");
--#endif
-- OF_prop_int_new(OF_env, ata, "#address-cells", 1);
-- OF_prop_int_new(OF_env, ata, "#size-cells", 0);
-- regs[0].address = 0x0001F000;
-- regs[0].size = 0x00001000;
--#if 0 // HACK: Don't set up DMA registers
-- regs[1].address = 0x00008A00;
-- regs[1].size = 0x00001000;
-- OF_property_new(OF_env, ata, "reg",
-- regs, 2 * sizeof(OF_regprop_t));
--#else
-- OF_property_new(OF_env, ata, "reg",
-- regs, sizeof(OF_regprop_t));
--#endif
-- OF_prop_int_new(OF_env, ata, "interrupt-parent", pic_phandle);
-- regs[0].address = 0x00000013;
-- regs[0].size = 0x00000001;
-- regs[1].address = 0x0000000B;
-- regs[1].size = 0x00000000;
-- OF_property_new(OF_env, ata, "interrupts",
-- regs, 2 * sizeof(OF_regprop_t));
-- ide_pci_pmac_register(base_address + 0x1f000, 0x00000000, ata);
--
-- }
-- {
-- OF_node_t *ata;
-- OF_regprop_t regs[2];
-- ata = OF_node_new(OF_env, mio, "ata-4", 0x20000);
-- if (ata == NULL) {
-- ERROR("Cannot create 'ata-4'\n");
-- goto out;
-- }
-- OF_prop_string_new(OF_env, ata, "device_type", "ata");
--#if 1
-- OF_prop_string_new(OF_env, ata, "compatible", "keylargo-ata");
-- OF_prop_string_new(OF_env, ata, "model", "ata-4");
--#else
-- OF_prop_string_new(OF_env, ata, "compatible", "cmd646-ata");
-- OF_prop_string_new(OF_env, ata, "model", "ata-4");
--#endif
-- OF_prop_int_new(OF_env, ata, "#address-cells", 1);
-- OF_prop_int_new(OF_env, ata, "#size-cells", 0);
-- regs[0].address = 0x00020000;
-- regs[0].size = 0x00001000;
--#if 0 // HACK: Don't set up DMA registers
-- regs[1].address = 0x00008A00;
-- regs[1].size = 0x00001000;
-- OF_property_new(OF_env, ata, "reg",
-- regs, 2 * sizeof(OF_regprop_t));
--#else
-- OF_property_new(OF_env, ata, "reg",
-- regs, sizeof(OF_regprop_t));
--#endif
-- OF_prop_int_new(OF_env, ata, "interrupt-parent", pic_phandle);
-- regs[0].address = 0x00000014;
-- regs[0].size = 0x00000001;
-- regs[1].address = 0x0000000B;
-- regs[1].size = 0x00000000;
-- OF_property_new(OF_env, ata, "interrupts",
-- regs, 2 * sizeof(OF_regprop_t));
-- ide_pci_pmac_register(0x00000000, base_address + 0x20000, ata);
--
-+ /* Keylargo IDE controller: need some work (DMA problem ?) */
-+ if (arch == ARCH_MAC99) {
-+ keylargo_ata(mio, base_address, 0x1f000, 0x13, 0xb, pic_phandle);
-+ keylargo_ata(mio, base_address, 0x20000, 0x14, 0xb, pic_phandle);
- }
-+#if 0
- /* Timer */
- {
- OF_node_t *tmr;
-@@ -2746,10 +2871,11 @@
- regs, sizeof(OF_regprop_t));
- OF_node_put(OF_env, tmr);
- }
-+#endif
- /* VIA-PMU */
- {
- /* Controls adb, RTC and power-mgt (forget it !) */
-- OF_node_t *via, *adb, *rtc;
-+ OF_node_t *via, *adb;
- OF_regprop_t regs[1];
- #if 0 // THIS IS A HACK AND IS COMPLETELY ABSURD !
- // (but needed has Qemu doesn't emulate via-pmu).
-@@ -2773,14 +2899,21 @@
- regs[0].size = 0x00002000;
- OF_property_new(OF_env, via, "reg", regs, sizeof(OF_regprop_t));
- OF_prop_int_new(OF_env, via, "interrupt-parent", pic_phandle);
-+ if (arch == ARCH_HEATHROW) {
-+ OF_prop_int_new(OF_env, via, "interrupts", 0x12);
-+ } else {
- regs[0].address = 0x00000019;
- regs[0].size = 0x00000001;
- OF_property_new(OF_env, via, "interrupts",
- regs, sizeof(OF_regprop_t));
-+ }
-+ /* force usage of OF bus speeds */
-+ OF_prop_int_new(OF_env, via, "BusSpeedCorrect", 1);
- #if 0
- OF_prop_int_new(OF_env, via, "pmu-version", 0x00D0740C);
- #endif
--#if 1
-+ {
-+ OF_node_t *kbd, *mouse;
- /* ADB pseudo-device */
- adb = OF_node_new(OF_env, via, "adb", OF_ADDRESS_NONE);
- if (adb == NULL) {
-@@ -2797,9 +2930,26 @@
- OF_prop_int_new(OF_env, adb, "#size-cells", 0);
- OF_pack_get_path(OF_env, tmp, 512, adb);
- OF_prop_string_new(OF_env, als, "adb", tmp);
-- /* XXX: add "keyboard@2" and "mouse@3" */
-- OF_node_put(OF_env, adb);
--#endif
-+
-+ kbd = OF_node_new(OF_env, adb, "keyboard", 2);
-+ if (kbd == NULL) {
-+ ERROR("Cannot create 'kbd'\n");
-+ goto out;
-+ }
-+ OF_prop_string_new(OF_env, kbd, "device_type", "keyboard");
-+ OF_prop_int_new(OF_env, kbd, "reg", 2);
-+
-+ mouse = OF_node_new(OF_env, adb, "mouse", 3);
-+ if (mouse == NULL) {
-+ ERROR("Cannot create 'mouse'\n");
-+ goto out;
-+ }
-+ OF_prop_string_new(OF_env, mouse, "device_type", "mouse");
-+ OF_prop_int_new(OF_env, mouse, "reg", 3);
-+ OF_prop_int_new(OF_env, mouse, "#buttons", 3);
-+ }
-+ {
-+ OF_node_t *rtc;
-
- rtc = OF_node_new(OF_env, via, "rtc", OF_ADDRESS_NONE);
- if (rtc == NULL) {
-@@ -2813,14 +2963,68 @@
- OF_prop_string_new(OF_env, rtc, "compatible", "rtc");
- #endif
- OF_node_put(OF_env, rtc);
-- OF_node_put(OF_env, via);
- }
-+ // OF_node_put(OF_env, via);
-+ }
-+ {
-+ OF_node_t *pmgt;
-+ pmgt = OF_node_new(OF_env, mio, "power-mgt", OF_ADDRESS_NONE);
-+ OF_prop_string_new(OF_env, pmgt, "device_type", "power-mgt");
-+ OF_prop_string_new(OF_env, pmgt, "compatible", "cuda");
-+ OF_prop_string_new(OF_env, pmgt, "mgt-kind", "min-consumption-pwm-led");
-+ OF_node_put(OF_env, pmgt);
-+ }
-+
-+ if (arch == ARCH_HEATHROW) {
-+ /* NVRAM */
-+ OF_node_t *nvr;
-+ OF_regprop_t regs;
-+ nvr = OF_node_new(OF_env, mio, "nvram", 0x60000);
-+ OF_prop_string_new(OF_env, nvr, "device_type", "nvram");
-+ regs.address = 0x60000;
-+ regs.size = 0x00020000;
-+ OF_property_new(OF_env, nvr, "reg", &regs, sizeof(regs));
-+ OF_prop_int_new(OF_env, nvr, "#bytes", 0x2000);
-+ OF_node_put(OF_env, nvr);
-+ }
-+
- out:
- // OF_node_put(OF_env, mio);
- OF_node_put(OF_env, chs);
- OF_node_put(OF_env, als);
- }
-
-+void OF_finalize_pci_ide (void *dev,
-+ uint32_t io_base0, uint32_t io_base1,
-+ uint32_t io_base2, uint32_t io_base3)
-+{
-+ OF_env_t *OF_env = OF_env_main;
-+ OF_node_t *pci_ata = dev;
-+ OF_node_t *ata, *atas[2];
-+ int i;
-+
-+ OF_prop_int_new(OF_env, pci_ata, "#address-cells", 1);
-+ OF_prop_int_new(OF_env, pci_ata, "#size-cells", 0);
-+
-+ /* XXX: Darwin handles only one device */
-+ for(i = 0; i < 1; i++) {
-+ ata = OF_node_new(OF_env, pci_ata, "ata-4", i);
-+ if (ata == NULL) {
-+ ERROR("Cannot create 'ata-4'\n");
-+ return;
-+ }
-+ OF_prop_string_new(OF_env, ata, "device_type", "ata");
-+ OF_prop_string_new(OF_env, ata, "compatible", "cmd646-ata");
-+ OF_prop_string_new(OF_env, ata, "model", "ata-4");
-+ OF_prop_int_new(OF_env, ata, "#address-cells", 1);
-+ OF_prop_int_new(OF_env, ata, "#size-cells", 0);
-+ OF_prop_int_new(OF_env, ata, "reg", i);
-+ atas[i] = ata;
-+ }
-+ ide_pci_pc_register(io_base0, io_base1, io_base2, io_base3,
-+ atas[0], atas[1]);
-+}
-+
- /*****************************************************************************/
- /* Fake package */
- static void OF_method_fake (OF_env_t *OF_env)
-@@ -2862,11 +3066,11 @@
- /* As we get a 1:1 mapping, do nothing */
- ihandle = popd(OF_env);
- args = (void *)popd(OF_env);
-- address = popd(OF_env);
-- virt = popd(OF_env);
-- size = popd(OF_env);
- popd(OF_env);
-- OF_DPRINTF("Translate address %0x %0x %0x %0x\n", ihandle, address,
-+ size = popd(OF_env);
-+ virt = popd(OF_env);
-+ address = popd(OF_env);
-+ OF_DPRINTF("Map %0x %0x %0x %0x\n", ihandle, address,
- virt, size);
- pushd(OF_env, 0);
- }
-@@ -3270,7 +3474,7 @@
- OF_prop_string_new(OF_env, dsk, "device_type", "block");
- OF_prop_string_new(OF_env, dsk, "category", type);
- OF_prop_int_new(OF_env, dsk, "device_id", devnum);
-- OF_prop_int_new(OF_env, dsk, "reg", 0);
-+ OF_prop_int_new(OF_env, dsk, "reg", devnum);
- OF_method_new(OF_env, dsk, "open", &OF_blockdev_open);
- OF_method_new(OF_env, dsk, "seek", &OF_blockdev_seek);
- OF_method_new(OF_env, dsk, "read", &OF_blockdev_read);
-@@ -3432,7 +3636,8 @@
- }
-
- void OF_vga_register (const unsigned char *name, unused uint32_t address,
-- int width, int height, int depth)
-+ int width, int height, int depth,
-+ unsigned long vga_bios_addr, unsigned long vga_bios_size)
- {
- OF_env_t *OF_env;
- unsigned char tmp[OF_NAMELEN_MAX];
-@@ -3504,6 +3709,18 @@
- OF_prop_string_new(OF_env, als, "display", tmp);
- OF_node_put(OF_env, als);
- /* XXX: may also need read-rectangle */
-+
-+ if (vga_bios_size >= 8) {
-+ const uint8_t *p;
-+ int size;
-+ /* check the QEMU VGA BIOS header */
-+ p = (const uint8_t *)vga_bios_addr;
-+ if (p[0] == 'N' && p[1] == 'D' && p[2] == 'R' && p[3] == 'V') {
-+ size = *(uint32_t *)(p + 4);
-+ OF_property_new(OF_env, disp, "driver,AAPL,MacOS,PowerPC",
-+ p + 8, size);
-+ }
-+ }
- out:
- OF_node_put(OF_env, disp);
- }
-@@ -4451,7 +4668,10 @@
- break;
- case 0x233441d3: /* MacOS X 10.2 and OpenDarwin 1.41 */
- /* Create "memory-map" pseudo device */
-- popd(OF_env);
-+ {
-+ OF_node_t *map;
-+ uint32_t phandle;
-+
- /* Find "/packages" */
- chs = OF_pack_find_by_name(OF_env, OF_node_root, "/chosen");
- if (chs == NULL) {
-@@ -4459,10 +4679,6 @@
- ERROR("Cannot get '/chosen'\n");
- break;
- }
-- {
--#if 1
-- OF_node_t *map;
-- uint32_t phandle;
- map = OF_node_new(OF_env, chs, "memory-map", OF_ADDRESS_NONE);
- if (map == NULL) {
- pushd(OF_env, -1);
-@@ -4473,11 +4689,8 @@
- OF_node_put(OF_env, map);
- OF_node_put(OF_env, chs);
- pushd(OF_env, phandle);
-- }
--#else
-- pushd(OF_env, 0);
--#endif
- pushd(OF_env, 0);
-+ }
- break;
- case 0x32a2d18e: /* MacOS X 10.2 and OpenDarwin 6.02 */
- /* Return screen ihandle */
-@@ -4540,9 +4753,10 @@
- case 0x4ad41f2d:
- /* Yaboot: wait 10 ms: sure ! */
- break;
-+
- default:
- /* ERROR */
-- printf("Script:\n%s\n", FString);
-+ printf("Script: len=%d\n%s\n", (int)strlen(FString), FString);
- printf("Call %0x NOT IMPLEMENTED !\n", crc);
- bug();
- break;
-@@ -4581,6 +4795,7 @@
- {
- OF_CHECK_NBARGS(OF_env, 0);
- /* Should free all OF resources */
-+ bd_reset_all();
- #if defined (DEBUG_BIOS)
- {
- uint16_t loglevel = 0x02 | 0x10 | 0x80;
-diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/pci.c OpenHackWare-release-0.4/src/pci.c
---- OpenHackWare-release-0.4.org/src/pci.c 2005-03-31 09:23:33.000000000 +0200
-+++ OpenHackWare-release-0.4/src/pci.c 2005-07-07 23:27:37.000000000 +0200
-@@ -99,8 +99,8 @@
- uint16_t min_grant;
- uint16_t max_latency;
- uint8_t irq_line;
-- uint32_t regions[6];
-- uint32_t sizes[6];
-+ uint32_t regions[7]; /* the region 6 is the PCI ROM */
-+ uint32_t sizes[7];
- pci_device_t *next;
- };
-
-@@ -158,6 +158,7 @@
-
- /* IRQ numbers assigned to PCI IRQs */
- static uint8_t prep_pci_irqs[4] = { 9, 11, 9, 11 };
-+static uint8_t heathrow_pci_irqs[4] = { 0x15, 0x16, 0x17, 0x18 };
- static uint8_t pmac_pci_irqs[4] = { 8, 9, 10, 11 };
-
- /* PREP PCI host */
-@@ -399,6 +400,79 @@
- &uninorth_config_readl, &uninorth_config_writel,
- };
-
-+/* Grackle PCI host */
-+
-+static uint32_t grackle_cfg_address (pci_bridge_t *bridge,
-+ uint8_t bus, uint8_t devfn,
-+ uint8_t offset)
-+{
-+ uint32_t addr;
-+ addr = 0x80000000 | (bus << 16) | (devfn << 8) | (offset & 0xfc);
-+ stswap32((uint32_t *)bridge->cfg_addr, addr);
-+ return bridge->cfg_data + (offset & 3);
-+}
-+
-+static uint8_t grackle_config_readb (pci_bridge_t *bridge,
-+ uint8_t bus, uint8_t devfn,
-+ uint8_t offset)
-+{
-+ uint32_t addr;
-+ addr = grackle_cfg_address(bridge, bus, devfn, offset);
-+ return *((uint8_t *)addr);
-+}
-+
-+static void grackle_config_writeb (pci_bridge_t *bridge,
-+ uint8_t bus, uint8_t devfn,
-+ uint8_t offset, uint8_t val)
-+{
-+ uint32_t addr;
-+ addr = grackle_cfg_address(bridge, bus, devfn, offset);
-+ *((uint8_t *)addr) = val;
-+}
-+
-+static uint16_t grackle_config_readw (pci_bridge_t *bridge,
-+ uint8_t bus, uint8_t devfn,
-+ uint8_t offset)
-+{
-+ uint32_t addr;
-+ addr = grackle_cfg_address(bridge, bus, devfn, offset);
-+ return ldswap16((uint16_t *)addr);
-+}
-+
-+static void grackle_config_writew (pci_bridge_t *bridge,
-+ uint8_t bus, uint8_t devfn,
-+ uint8_t offset, uint16_t val)
-+{
-+ uint32_t addr;
-+ addr = grackle_cfg_address(bridge, bus, devfn, offset);
-+ stswap16((uint16_t *)addr, val);
-+}
-+
-+static uint32_t grackle_config_readl (pci_bridge_t *bridge,
-+ uint8_t bus, uint8_t devfn,
-+ uint8_t offset)
-+{
-+ uint32_t addr;
-+ addr = grackle_cfg_address(bridge, bus, devfn, offset);
-+ return ldswap32((uint32_t *)addr);
-+}
-+
-+static void grackle_config_writel (pci_bridge_t *bridge,
-+ uint8_t bus, uint8_t devfn,
-+ uint8_t offset, uint32_t val)
-+{
-+ uint32_t addr;
-+
-+ addr = grackle_cfg_address(bridge, bus, devfn, offset);
-+ stswap32((uint32_t *)addr, val);
-+}
-+
-+static pci_ops_t grackle_pci_ops = {
-+ &grackle_config_readb, &grackle_config_writeb,
-+ &grackle_config_readw, &grackle_config_writew,
-+ &grackle_config_readl, &grackle_config_writel,
-+};
-+
- static inline uint8_t pci_config_readb (pci_bridge_t *bridge,
- uint8_t bus, uint8_t devfn,
- uint8_t offset)
-@@ -466,12 +540,22 @@
- },
- };
-
-+static int ide_config_cb2 (pci_device_t *device)
-+{
-+ OF_finalize_pci_ide(device->common.OF_private,
-+ device->regions[0] & ~0x0000000F,
-+ device->regions[1] & ~0x0000000F,
-+ device->regions[2] & ~0x0000000F,
-+ device->regions[3] & ~0x0000000F);
-+ return 0;
-+}
-+
- static pci_dev_t ide_devices[] = {
- {
-- 0x8086, 0x0100,
-- NULL, "Qemu IDE", "Qemu IDE", "ide",
-+ 0x1095, 0x0646, /* CMD646 IDE controller */
-+ "pci-ide", "pci-ata", NULL, NULL,
- 0, 0, 0,
-- NULL, NULL,
-+ ide_config_cb2, NULL,
- },
- {
- 0xFFFF, 0xFFFF,
-@@ -481,7 +565,9 @@
- },
- };
-
--static int ide_config_cb (pci_device_t *device)
-+#if 0
-+/* should base it on PCI ID, not on arch */
-+static int ide_config_cb (unused pci_device_t *device)
- {
- printf("Register IDE controller\n");
- switch (arch) {
-@@ -491,14 +577,8 @@
- device->common.OF_private);
- break;
- default:
-- ide_pci_pc_register(device->regions[0] & ~0x0000000F,
-- device->regions[1] & ~0x0000000F,
-- device->regions[2] & ~0x0000000F,
-- device->regions[3] & ~0x0000000F,
-- device->common.OF_private);
- break;
- }
--
- return 0;
- }
-
-@@ -512,16 +592,12 @@
- device->common.OF_private);
- break;
- default:
-- ide_pci_pc_register(device->regions[0] & ~0x0000000F,
-- device->regions[1] & ~0x0000000F,
-- device->regions[2] & ~0x0000000F,
-- device->regions[3] & ~0x0000000F,
-- device->common.OF_private);
- break;
- }
-
- return 0;
- }
-+#endif
-
- static pci_subclass_t mass_subclass[] = {
- {
-@@ -530,7 +606,7 @@
- },
- {
- 0x01, "IDE controller", "ide", ide_devices, NULL,
-- &ide_config_cb, NULL,
-+ NULL, NULL,
- },
- {
- 0x02, "Floppy disk controller", NULL, NULL, NULL,
-@@ -546,7 +622,7 @@
- },
- {
- 0x05, "ATA controller", "ata", NULL, NULL,
-- &ata_config_cb, NULL,
-+ NULL, NULL,
- },
- {
- 0x80, "misc mass-storage controller", NULL, NULL, NULL,
-@@ -646,7 +722,9 @@
- /* VGA 640x480x16 */
- OF_vga_register(device->common.device->name,
- device->regions[0] & ~0x0000000F,
-- vga_width, vga_height, vga_depth);
-+ vga_width, vga_height, vga_depth,
-+ device->regions[6] & ~0x0000000F,
-+ device->sizes[6]);
- }
- vga_console_register();
-
-@@ -750,6 +828,13 @@
- NULL, &PREP_pci_ops,
- };
-
-+pci_dev_t grackle_fake_bridge = {
-+ 0xFFFF, 0xFFFF,
-+ "pci", "pci-bridge", "DEC,21154", "DEC,21154.pci-bridge",
-+ -1, -1, -1,
-+ NULL, &grackle_pci_ops,
-+};
-+
- static pci_dev_t hbrg_devices[] = {
- {
- 0x106B, 0x0020, NULL,
-@@ -758,8 +843,8 @@
- NULL, &uninorth_agp_fake_bridge,
- },
- {
-- 0x106B, 0x001F,
-- NULL, "pci", "AAPL,UniNorth", "uni-north",
-+ 0x106B, 0x001F, NULL,
-+ "pci", "AAPL,UniNorth", "uni-north",
- 3, 2, 1,
- NULL, &uninorth_fake_bridge,
- },
-@@ -770,10 +855,10 @@
- NULL, &uninorth_fake_bridge,
- },
- {
-- 0x1011, 0x0026, NULL,
-- "pci-bridge", NULL, NULL,
-+ 0x1057, 0x0002, "pci",
-+ "pci", "MOT,MPC106", "grackle",
- 3, 2, 1,
-- NULL, &PREP_pci_ops,
-+ NULL, &grackle_fake_bridge,
- },
- {
- 0x1057, 0x4801, NULL,
-@@ -1443,7 +1528,14 @@
- }
-
- static const pci_dev_t misc_pci[] = {
-- /* Apple Mac-io controller */
-+ /* Paddington Mac I/O */
-+ {
-+ 0x106B, 0x0017,
-+ "mac-io", "mac-io", "AAPL,343S1211", "paddington\1heathrow",
-+ 1, 1, 1,
-+ &macio_config_cb, NULL,
-+ },
-+ /* KeyLargo Mac I/O */
- {
- 0x106B, 0x0022,
- "mac-io", "mac-io", "AAPL,Keylargo", "Keylargo",
-@@ -1599,7 +1691,7 @@
- uint8_t min_grant, uint8_t max_latency,
- int irq_line)
- {
-- uint32_t cmd;
-+ uint32_t cmd, addr;
- int i;
-
- device->min_grant = min_grant;
-@@ -1611,22 +1703,28 @@
- printf("MAP PCI device %d:%d to IRQ %d\n",
- device->bus, device->devfn, irq_line);
- }
-- for (i = 0; i < 6; i++) {
-+ for (i = 0; i < 7; i++) {
- if ((device->regions[i] & ~0xF) != 0x00000000 &&
- (device->regions[i] & ~0xF) != 0xFFFFFFF0) {
- printf("Map PCI device %d:%d %d to %0x %0x (%s)\n",
- device->bus, device->devfn, i,
- device->regions[i], device->sizes[i],
-- device->regions[i] & 0x00000001 ? "I/O" : "memory");
-+ (device->regions[i] & 0x00000001) && i != 6 ? "I/O" :
-+ "memory");
-+ if (i != 6) {
- cmd = pci_config_readl(bridge, device->bus, device->devfn, 0x04);
- if (device->regions[i] & 0x00000001)
- cmd |= 0x00000001;
- else
- cmd |= 0x00000002;
- pci_config_writel(bridge, device->bus, device->devfn, 0x04, cmd);
-+ }
-+ if (i == 6)
-+ addr = 0x30; /* PCI ROM */
-+ else
-+ addr = 0x10 + (i * sizeof(uint32_t));
- pci_config_writel(bridge, device->bus, device->devfn,
-- 0x10 + (i * sizeof(uint32_t)),
-- device->regions[i]);
-+ addr, device->regions[i]);
- }
- }
- }
-@@ -1900,7 +1998,7 @@
- goto out;
- }
- ret = (pci_u_t *)newd;
-- max_areas = 6;
-+ max_areas = 7;
- /* register PCI device in OF tree */
- if (bridge->dev.common.type == PCI_FAKE_BRIDGE) {
- newd->common.OF_private =
-@@ -1927,6 +2025,9 @@
- /* Handle 64 bits memory mapping */
- continue;
- }
-+ if (i == 6)
-+ addr = 0x30; /* PCI ROM */
-+ else
- addr = 0x10 + (i * sizeof(uint32_t));
- /* Get region size
- * Note: we assume it's always a power of 2
-@@ -1935,7 +2036,7 @@
- smask = pci_config_readl(bridge, bus, devfn, addr);
- if (smask == 0x00000000 || smask == 0xFFFFFFFF)
- continue;
-- if (smask & 0x00000001) {
-+ if ((smask & 0x00000001) != 0 && i != 6) {
- /* I/O space */
- base = io_base;
- /* Align to a minimum of 256 bytes (arbitrary) */
-@@ -1947,6 +2048,8 @@
- /* Align to a minimum of 64 kB (arbitrary) */
- min_align = 1 << 16;
- amask = 0x0000000F;
-+ if (i == 6)
-+ smask |= 1; /* PCI ROM enable */
- }
- omask = smask & amask;
- smask &= ~amask;
-@@ -1980,7 +2083,10 @@
- if (irq_pin > 0) {
- /* assign the IRQ */
- irq_pin = ((devfn >> 3) + irq_pin - 1) & 3;
-- if (arch == ARCH_PREP) {
-+ /* XXX: should base it on the PCI bridge type, not the arch */
-+ switch(arch) {
-+ case ARCH_PREP:
-+ {
- int elcr_port, val;
- irq_line = prep_pci_irqs[irq_pin];
- /* set the IRQ to level-sensitive */
-@@ -1988,14 +2094,22 @@
- val = inb(elcr_port);
- val |= 1 << (irq_line & 7);
- outb(elcr_port, val);
-- } else {
-+ }
-+ break;
-+ case ARCH_MAC99:
- irq_line = pmac_pci_irqs[irq_pin];
-+ break;
-+ case ARCH_HEATHROW:
-+ irq_line = heathrow_pci_irqs[irq_pin];
-+ break;
-+ default:
-+ break;
- }
- }
- update_device:
- pci_update_device(bridge, newd, min_grant, max_latency, irq_line);
- OF_finalize_pci_device(newd->common.OF_private, bus, devfn,
-- newd->regions, newd->sizes);
-+ newd->regions, newd->sizes, irq_line);
- /* Call special inits if needed */
- if (dev->config_cb != NULL)
- (*dev->config_cb)(newd);
-@@ -2049,6 +2163,32 @@
- case ARCH_CHRP:
- /* TODO */
- break;
-+ case ARCH_HEATHROW:
-+ dev = pci_find_device(0x06, 0x00, 0xFF, checkv, checkp);
-+ if (dev == NULL)
-+ return -1;
-+ fake_host = pci_add_host(hostp, dev,
-+ (0x06 << 24) | (0x00 << 16) | (0xFF << 8));
-+ if (fake_host == NULL)
-+ return -1;
-+ fake_host->dev.common.type = PCI_FAKE_HOST;
-+ dev = &grackle_fake_bridge;
-+ if (dev == NULL)
-+ goto free_fake_host;
-+ fake_bridge = pci_add_bridge(fake_host, 0, 0, dev,
-+ (0x06 << 24) | (0x04 << 16) | (0xFF << 8),
-+ cfg_base, cfg_len,
-+ cfg_base + 0x7ec00000,
-+ cfg_base + 0x7ee00000,
-+ mem_base, mem_len,
-+ io_base, io_len,
-+ rbase, rlen,
-+ 0,
-+ &grackle_pci_ops);
-+ if (fake_bridge == NULL)
-+ goto free_fake_host;
-+ fake_bridge->dev.common.type = PCI_FAKE_BRIDGE;
-+ break;
- case ARCH_MAC99:
- dev = pci_find_device(0x06, 0x00, 0xFF, checkv, checkp);
- if (dev == NULL)
-@@ -2167,6 +2307,30 @@
- case ARCH_CHRP:
- /* TODO */
- break;
-+ case ARCH_HEATHROW:
-+ cfg_base = 0x80000000;
-+ cfg_len = 0x7f000000;
-+ mem_base = 0x80000000;
-+ mem_len = 0x01000000;
-+ io_base = 0xfe000000;
-+ io_len = 0x00800000;
-+#if 1
-+ rbase = 0xfd000000;
-+ rlen = 0x01000000;
-+#else
-+ rbase = 0x00000000;
-+ rlen = 0x01000000;
-+#endif
-+ if (pci_check_host(&pci_main, cfg_base, cfg_len,
-+ mem_base, mem_len, io_base, io_len, rbase, rlen,
-+ 0x1057, 0x0002) == 0) {
-+ isa_io_base = io_base;
-+ busnum++;
-+ }
-+ for (curh = pci_main; curh->next != NULL; curh = curh->next)
-+ continue;
-+ pci_check_devices(curh);
-+ break;
- case ARCH_MAC99:
- /* We are supposed to have 3 host bridges:
- * - the uninorth AGP bridge at 0xF0000000
diff --git a/pc-bios/ppc_rom.bin b/pc-bios/ppc_rom.bin
index 0ad0282499..d378d9a95e 100644
--- a/pc-bios/ppc_rom.bin
+++ b/pc-bios/ppc_rom.bin
Binary files differ
diff --git a/qdev-monitor.c b/qdev-monitor.c
index 6673e3cb61..9268c8759f 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -522,7 +522,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
return NULL;
}
- /* create device, set properties */
+ /* create device */
dev = DEVICE(object_new(driver));
if (bus) {
@@ -533,11 +533,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
if (id) {
dev->id = id;
}
- if (qemu_opt_foreach(opts, set_property, dev, 1) != 0) {
- object_unparent(OBJECT(dev));
- object_unref(OBJECT(dev));
- return NULL;
- }
+
if (dev->id) {
object_property_add_child(qdev_get_peripheral(), dev->id,
OBJECT(dev), NULL);
@@ -549,6 +545,13 @@ DeviceState *qdev_device_add(QemuOpts *opts)
g_free(name);
}
+ /* set properties */
+ if (qemu_opt_foreach(opts, set_property, dev, 1) != 0) {
+ object_unparent(OBJECT(dev));
+ object_unref(OBJECT(dev));
+ return NULL;
+ }
+
dev->opts = opts;
object_property_set_bool(OBJECT(dev), true, "realized", &err);
if (err != NULL) {
diff --git a/qmp.c b/qmp.c
index f556a04d19..87a28f797d 100644
--- a/qmp.c
+++ b/qmp.c
@@ -114,8 +114,11 @@ void qmp_cpu(int64_t index, Error **errp)
void qmp_cpu_add(int64_t id, Error **errp)
{
- if (current_machine->hot_add_cpu) {
- current_machine->hot_add_cpu(id, errp);
+ MachineClass *mc;
+
+ mc = MACHINE_GET_CLASS(current_machine);
+ if (mc->qemu_machine->hot_add_cpu) {
+ mc->qemu_machine->hot_add_cpu(id, errp);
} else {
error_setg(errp, "Not supported");
}
diff --git a/qom/object.c b/qom/object.c
index 660859c0e7..c88909c6b6 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1293,6 +1293,7 @@ void object_property_add_str(Object *obj, const char *name,
void (*set)(Object *, const char *, Error **),
Error **errp)
{
+ Error *local_err = NULL;
StringProperty *prop = g_malloc0(sizeof(*prop));
prop->get = get;
@@ -1302,7 +1303,11 @@ void object_property_add_str(Object *obj, const char *name,
get ? property_get_str : NULL,
set ? property_set_str : NULL,
property_release_str,
- prop, errp);
+ prop, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ g_free(prop);
+ }
}
typedef struct BoolProperty
@@ -1349,6 +1354,7 @@ void object_property_add_bool(Object *obj, const char *name,
void (*set)(Object *, bool, Error **),
Error **errp)
{
+ Error *local_err = NULL;
BoolProperty *prop = g_malloc0(sizeof(*prop));
prop->get = get;
@@ -1358,7 +1364,11 @@ void object_property_add_bool(Object *obj, const char *name,
get ? property_get_bool : NULL,
set ? property_set_bool : NULL,
property_release_bool,
- prop, errp);
+ prop, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ g_free(prop);
+ }
}
static char *qdev_get_type(Object *obj, Error **errp)
diff --git a/roms/openhackware b/roms/openhackware
new file mode 160000
+Subproject e9829b5584169ad14df2ca8776b87f4985aa9f0
diff --git a/tests/Makefile b/tests/Makefile
index e146f81d44..7bc3999ecc 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -69,9 +69,24 @@ gcov-files-ipack-y += hw/ipack/ipack.c
check-qtest-ipack-y += tests/ipoctal232-test$(EXESUF)
gcov-files-ipack-y += hw/char/ipoctal232.c
+check-qtest-virtioserial-y += tests/virtio-console-test$(EXESUF)
+gcov-files-virtioserial-y += hw/char/virtio-console.c
+
gcov-files-virtio-y += i386-softmmu/hw/virtio/virtio.c
check-qtest-virtio-y += tests/virtio-net-test$(EXESUF)
gcov-files-virtio-y += i386-softmmu/hw/net/virtio-net.c
+check-qtest-virtio-y += tests/virtio-balloon-test$(EXESUF)
+gcov-files-virtio-y += i386-softmmu/hw/virtio/virtio-balloon.c
+check-qtest-virtio-y += tests/virtio-blk-test$(EXESUF)
+gcov-files-virtio-y += i386-softmmu/hw/block/virtio-blk.c
+check-qtest-virtio-y += tests/virtio-rng-test$(EXESUF)
+gcov-files-virtio-y += hw/virtio/virtio-rng.c
+check-qtest-virtio-y += tests/virtio-scsi-test$(EXESUF)
+gcov-files-virtio-y += i386-softmmu/hw/scsi/virtio-scsi.c
+check-qtest-virtio-y += tests/virtio-serial-test$(EXESUF)
+gcov-files-virtio-y += i386-softmmu/hw/char/virtio-serial-bus.c
+check-qtest-virtio-y += $(check-qtest-virtioserial-y)
+gcov-files-virtio-y += $(gcov-files-virtioserial-y)
check-qtest-pci-y += tests/e1000-test$(EXESUF)
gcov-files-pci-y += hw/net/e1000.c
@@ -87,9 +102,9 @@ gcov-files-pci-y += hw/net/ne2000.c
check-qtest-pci-y += $(check-qtest-virtio-y)
gcov-files-pci-y += $(gcov-files-virtio-y) hw/virtio/virtio-pci.c
check-qtest-pci-y += tests/tpci200-test$(EXESUF)
-gcov-files-pci-y += hw/char/tpci200.c
+gcov-files-pci-y += hw/ipack/tpci200.c
check-qtest-pci-y += $(check-qtest-ipack-y)
-gcov-files-pci-y += $(gcov-files-ipack-y) hw/ipack/tpci200.c
+gcov-files-pci-y += $(gcov-files-ipack-y)
check-qtest-i386-y = tests/endianness-test$(EXESUF)
check-qtest-i386-y += tests/fdc-test$(EXESUF)
@@ -129,6 +144,8 @@ check-qtest-arm-y = tests/tmp105-test$(EXESUF)
gcov-files-arm-y += hw/misc/tmp105.c
check-qtest-ppc-y += tests/boot-order-test$(EXESUF)
check-qtest-ppc64-y += tests/boot-order-test$(EXESUF)
+check-qtest-ppc64-y += tests/spapr-phb-test$(EXESUF)
+gcov-files-ppc64-y += ppc64-softmmu/hw/ppc/spapr_pci.c
check-qtest-microblazeel-y = $(check-qtest-microblaze-y)
check-qtest-xtensaeb-y = $(check-qtest-xtensa-y)
@@ -225,6 +242,7 @@ libqos-omap-obj-y = $(libqos-obj-y) tests/libqos/i2c-omap.o
tests/rtc-test$(EXESUF): tests/rtc-test.o
tests/m48t59-test$(EXESUF): tests/m48t59-test.o
tests/endianness-test$(EXESUF): tests/endianness-test.o
+tests/spapr-phb-test$(EXESUF): tests/spapr-phb-test.o $(libqos-obj-y)
tests/fdc-test$(EXESUF): tests/fdc-test.o
tests/ide-test$(EXESUF): tests/ide-test.o $(libqos-pc-obj-y)
tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o
@@ -239,7 +257,13 @@ tests/pcnet-test$(EXESUF): tests/pcnet-test.o
tests/eepro100-test$(EXESUF): tests/eepro100-test.o
tests/vmxnet3-test$(EXESUF): tests/vmxnet3-test.o
tests/ne2000-test$(EXESUF): tests/ne2000-test.o
+tests/virtio-balloon-test$(EXESUF): tests/virtio-balloon-test.o
+tests/virtio-blk-test$(EXESUF): tests/virtio-blk-test.o
tests/virtio-net-test$(EXESUF): tests/virtio-net-test.o
+tests/virtio-rng-test$(EXESUF): tests/virtio-rng-test.o
+tests/virtio-scsi-test$(EXESUF): tests/virtio-scsi-test.o
+tests/virtio-serial-test$(EXESUF): tests/virtio-serial-test.o
+tests/virtio-console-test$(EXESUF): tests/virtio-console-test.o
tests/tpci200-test$(EXESUF): tests/tpci200-test.o
tests/ipoctal232-test$(EXESUF): tests/ipoctal232-test.o
tests/qom-test$(EXESUF): tests/qom-test.o
diff --git a/tests/libqtest.c b/tests/libqtest.c
index f587d36176..2b90e4a76e 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -34,6 +34,7 @@
#include "qapi/qmp/json-parser.h"
#define MAX_IRQ 256
+#define SOCKET_TIMEOUT 5
QTestState *global_qtest;
@@ -78,12 +79,16 @@ static int socket_accept(int sock)
struct sockaddr_un addr;
socklen_t addrlen;
int ret;
+ struct timeval timeout = { .tv_sec = SOCKET_TIMEOUT,
+ .tv_usec = 0 };
+
+ setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (void *)&timeout,
+ sizeof(timeout));
addrlen = sizeof(addr);
do {
ret = accept(sock, (struct sockaddr *)&addr, &addrlen);
} while (ret == -1 && errno == EINTR);
- g_assert_no_errno(ret);
close(sock);
return ret;
@@ -147,12 +152,16 @@ QTestState *qtest_init(const char *extra_args)
}
s->fd = socket_accept(sock);
- s->qmp_fd = socket_accept(qmpsock);
+ if (s->fd >= 0) {
+ s->qmp_fd = socket_accept(qmpsock);
+ }
unlink(socket_path);
unlink(qmp_socket_path);
g_free(socket_path);
g_free(qmp_socket_path);
+ g_assert(s->fd >= 0 && s->qmp_fd >= 0);
+
s->rx = g_string_new("");
for (i = 0; i < MAX_IRQ; i++) {
s->irq_level[i] = false;
@@ -581,3 +590,23 @@ void qtest_memwrite(QTestState *s, uint64_t addr, const void *data, size_t size)
qtest_sendf(s, "\n");
qtest_rsp(s, 0);
}
+
+QDict *qmp(const char *fmt, ...)
+{
+ va_list ap;
+ QDict *response;
+
+ va_start(ap, fmt);
+ response = qtest_qmpv(global_qtest, fmt, ap);
+ va_end(ap);
+ return response;
+}
+
+void qmp_discard_response(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ qtest_qmpv_discard_response(global_qtest, fmt, ap);
+ va_end(ap);
+}
diff --git a/tests/libqtest.h b/tests/libqtest.h
index 9deebdcdfa..8268c098bf 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -356,16 +356,7 @@ static inline void qtest_end(void)
*
* Sends a QMP message to QEMU and returns the response.
*/
-static inline QDict *qmp(const char *fmt, ...)
-{
- va_list ap;
- QDict *response;
-
- va_start(ap, fmt);
- response = qtest_qmpv(global_qtest, fmt, ap);
- va_end(ap);
- return response;
-}
+QDict *qmp(const char *fmt, ...);
/**
* qmp_discard_response:
@@ -373,14 +364,7 @@ static inline QDict *qmp(const char *fmt, ...)
*
* Sends a QMP message to QEMU and consumes the response.
*/
-static inline void qmp_discard_response(const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- qtest_qmpv_discard_response(global_qtest, fmt, ap);
- va_end(ap);
-}
+void qmp_discard_response(const char *fmt, ...);
/**
* get_irq:
diff --git a/tests/qdev-monitor-test.c b/tests/qdev-monitor-test.c
index ba7f9cc238..e20ffd67a7 100644
--- a/tests/qdev-monitor-test.c
+++ b/tests/qdev-monitor-test.c
@@ -32,8 +32,7 @@ static void test_device_add(void)
"}}");
g_assert(response);
error = qdict_get_qdict(response, "error");
- g_assert(!strcmp(qdict_get_try_str(error, "desc") ?: "",
- "Device needs media, but drive is empty"));
+ g_assert_cmpstr(qdict_get_try_str(error, "class"), ==, "GenericError");
QDECREF(response);
/* Delete the drive */
@@ -42,7 +41,7 @@ static void test_device_add(void)
" \"command-line\": \"drive_del drive0\""
"}}");
g_assert(response);
- g_assert(!strcmp(qdict_get_try_str(response, "return") ?: "(null)", ""));
+ g_assert_cmpstr(qdict_get_try_str(response, "return"), ==, "");
QDECREF(response);
/* Try to re-add the drive. This fails with duplicate IDs if a leaked
@@ -53,8 +52,7 @@ static void test_device_add(void)
" \"command-line\": \"drive_add pci-addr=auto if=none,id=drive0\""
"}}");
g_assert(response);
- g_assert(!strcmp(qdict_get_try_str(response, "return") ?: "",
- "OK\r\n"));
+ g_assert_cmpstr(qdict_get_try_str(response, "return"), ==, "OK\r\n");
QDECREF(response);
qtest_end();
diff --git a/tests/qom-test.c b/tests/qom-test.c
index b6671fbec3..6d9a00b448 100644
--- a/tests/qom-test.c
+++ b/tests/qom-test.c
@@ -10,6 +10,7 @@
#include <glib.h>
#include <string.h>
+#include "qemu-common.h"
#include "libqtest.h"
#include "qemu/osdep.h"
#include "qapi/qmp/types.h"
@@ -43,6 +44,40 @@ static bool is_blacklisted(const char *arch, const char *mach)
return false;
}
+static void test_properties(const char *path)
+{
+ char *child_path;
+ QDict *response, *tuple;
+ QList *list;
+ QListEntry *entry;
+
+ g_test_message("Obtaining properties of %s", path);
+ response = qmp("{ 'execute': 'qom-list',"
+ " 'arguments': { 'path': '%s' } }", path);
+ g_assert(response);
+
+ g_assert(qdict_haskey(response, "return"));
+ list = qobject_to_qlist(qdict_get(response, "return"));
+ QLIST_FOREACH_ENTRY(list, entry) {
+ tuple = qobject_to_qdict(qlist_entry_obj(entry));
+ if (strstart(qdict_get_str(tuple, "type"), "child<", NULL)) {
+ child_path = g_strdup_printf("%s/%s",
+ path, qdict_get_str(tuple, "name"));
+ test_properties(child_path);
+ g_free(child_path);
+ } else {
+ const char *prop = qdict_get_str(tuple, "name");
+ g_test_message("Testing property %s.%s", path, prop);
+ response = qmp("{ 'execute': 'qom-get',"
+ " 'arguments': { 'path': '%s',"
+ " 'property': '%s' } }",
+ path, prop);
+ /* qom-get may fail but should not, e.g., segfault. */
+ g_assert(response);
+ }
+ }
+}
+
static void test_machine(gconstpointer data)
{
const char *machine = data;
@@ -51,8 +86,12 @@ static void test_machine(gconstpointer data)
args = g_strdup_printf("-machine %s", machine);
qtest_start(args);
+
+ test_properties("/machine");
+
response = qmp("{ 'execute': 'quit' }");
g_assert(qdict_haskey(response, "return"));
+
qtest_end();
g_free(args);
}
diff --git a/tests/spapr-phb-test.c b/tests/spapr-phb-test.c
new file mode 100644
index 0000000000..b629de475a
--- /dev/null
+++ b/tests/spapr-phb-test.c
@@ -0,0 +1,35 @@
+/*
+ * QTest testcase for SPAPR PHB
+ *
+ * Authors:
+ * Alexey Kardashevskiy <aik@ozlabs.ru>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include <glib.h>
+
+#include "libqtest.h"
+
+#define TYPE_SPAPR_PCI_HOST_BRIDGE "spapr-pci-host-bridge"
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void test_phb_device(void)
+{
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+
+ g_test_init(&argc, &argv, NULL);
+ qtest_add_func("/spapr-phb/device", test_phb_device);
+
+ qtest_start("-device " TYPE_SPAPR_PCI_HOST_BRIDGE ",index=100");
+
+ ret = g_test_run();
+
+ qtest_end();
+
+ return ret;
+}
diff --git a/tests/virtio-balloon-test.c b/tests/virtio-balloon-test.c
new file mode 100644
index 0000000000..becebb51a7
--- /dev/null
+++ b/tests/virtio-balloon-test.c
@@ -0,0 +1,33 @@
+/*
+ * QTest testcase for VirtIO Balloon
+ *
+ * Copyright (c) 2014 SUSE LINUX Products GmbH
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void pci_nop(void)
+{
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+
+ g_test_init(&argc, &argv, NULL);
+ qtest_add_func("/virtio/balloon/pci/nop", pci_nop);
+
+ qtest_start("-device virtio-balloon-pci");
+ ret = g_test_run();
+
+ qtest_end();
+
+ return ret;
+}
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
new file mode 100644
index 0000000000..d53f875b89
--- /dev/null
+++ b/tests/virtio-blk-test.c
@@ -0,0 +1,34 @@
+/*
+ * QTest testcase for VirtIO Block Device
+ *
+ * Copyright (c) 2014 SUSE LINUX Products GmbH
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void pci_nop(void)
+{
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+
+ g_test_init(&argc, &argv, NULL);
+ qtest_add_func("/virtio/blk/pci/nop", pci_nop);
+
+ qtest_start("-drive id=drv0,if=none,file=/dev/null "
+ "-device virtio-blk-pci,drive=drv0");
+ ret = g_test_run();
+
+ qtest_end();
+
+ return ret;
+}
diff --git a/tests/virtio-console-test.c b/tests/virtio-console-test.c
new file mode 100644
index 0000000000..f98f5af252
--- /dev/null
+++ b/tests/virtio-console-test.c
@@ -0,0 +1,34 @@
+/*
+ * QTest testcase for VirtIO Console
+ *
+ * Copyright (c) 2014 SUSE LINUX Products GmbH
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void pci_nop(void)
+{
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+
+ g_test_init(&argc, &argv, NULL);
+ qtest_add_func("/virtio/console/pci/nop", pci_nop);
+
+ qtest_start("-device virtio-serial-pci,id=vser0 "
+ "-device virtconsole,bus=vser0.0");
+ ret = g_test_run();
+
+ qtest_end();
+
+ return ret;
+}
diff --git a/tests/virtio-rng-test.c b/tests/virtio-rng-test.c
new file mode 100644
index 0000000000..402c2060da
--- /dev/null
+++ b/tests/virtio-rng-test.c
@@ -0,0 +1,33 @@
+/*
+ * QTest testcase for VirtIO RNG
+ *
+ * Copyright (c) 2014 SUSE LINUX Products GmbH
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void pci_nop(void)
+{
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+
+ g_test_init(&argc, &argv, NULL);
+ qtest_add_func("/virtio/rng/pci/nop", pci_nop);
+
+ qtest_start("-device virtio-rng-pci");
+ ret = g_test_run();
+
+ qtest_end();
+
+ return ret;
+}
diff --git a/tests/virtio-scsi-test.c b/tests/virtio-scsi-test.c
new file mode 100644
index 0000000000..3230908b98
--- /dev/null
+++ b/tests/virtio-scsi-test.c
@@ -0,0 +1,35 @@
+/*
+ * QTest testcase for VirtIO SCSI
+ *
+ * Copyright (c) 2014 SUSE LINUX Products GmbH
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void pci_nop(void)
+{
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+
+ g_test_init(&argc, &argv, NULL);
+ qtest_add_func("/virtio/scsi/pci/nop", pci_nop);
+
+ qtest_start("-drive id=drv0,if=none,file=/dev/null "
+ "-device virtio-scsi-pci,id=vscsi0 "
+ "-device scsi-hd,bus=vscsi0.0,drive=drv0");
+ ret = g_test_run();
+
+ qtest_end();
+
+ return ret;
+}
diff --git a/tests/virtio-serial-test.c b/tests/virtio-serial-test.c
new file mode 100644
index 0000000000..e7438751ea
--- /dev/null
+++ b/tests/virtio-serial-test.c
@@ -0,0 +1,33 @@
+/*
+ * QTest testcase for VirtIO Serial
+ *
+ * Copyright (c) 2014 SUSE LINUX Products GmbH
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void pci_nop(void)
+{
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+
+ g_test_init(&argc, &argv, NULL);
+ qtest_add_func("/virtio/serial/pci/nop", pci_nop);
+
+ qtest_start("-device virtio-serial-pci");
+ ret = g_test_run();
+
+ qtest_end();
+
+ return ret;
+}
diff --git a/trace/control-internal.h b/trace/control-internal.h
index cce2da47c4..b3f587ed93 100644
--- a/trace/control-internal.h
+++ b/trace/control-internal.h
@@ -16,15 +16,15 @@
extern TraceEvent trace_events[];
-static inline TraceEvent *trace_event_id(TraceEventID id)
+static inline TraceEventID trace_event_count(void)
{
- assert(id < trace_event_count());
- return &trace_events[id];
+ return TRACE_EVENT_COUNT;
}
-static inline TraceEventID trace_event_count(void)
+static inline TraceEvent *trace_event_id(TraceEventID id)
{
- return TRACE_EVENT_COUNT;
+ assert(id < trace_event_count());
+ return &trace_events[id];
}
static inline bool trace_event_is_pattern(const char *str)
diff --git a/vl.c b/vl.c
index bca5c95908..862cf20f3c 100644
--- a/vl.c
+++ b/vl.c
@@ -1571,54 +1571,82 @@ void pcmcia_info(Monitor *mon, const QDict *qdict)
/***********************************************************/
/* machine registration */
-static QEMUMachine *first_machine = NULL;
-QEMUMachine *current_machine = NULL;
+MachineState *current_machine;
+
+static void machine_class_init(ObjectClass *oc, void *data)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
+ mc->qemu_machine = data;
+}
int qemu_register_machine(QEMUMachine *m)
{
- QEMUMachine **pm;
- pm = &first_machine;
- while (*pm != NULL)
- pm = &(*pm)->next;
- m->next = NULL;
- *pm = m;
+ TypeInfo ti = {
+ .name = g_strconcat(m->name, TYPE_MACHINE_SUFFIX, NULL),
+ .parent = TYPE_MACHINE,
+ .class_init = machine_class_init,
+ .class_data = (void *)m,
+ };
+
+ type_register(&ti);
+
return 0;
}
-static QEMUMachine *find_machine(const char *name)
+static MachineClass *find_machine(const char *name)
{
- QEMUMachine *m;
+ GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false);
+ MachineClass *mc = NULL;
+
+ for (el = machines; el; el = el->next) {
+ MachineClass *temp = el->data;
- for(m = first_machine; m != NULL; m = m->next) {
- if (!strcmp(m->name, name))
- return m;
- if (m->alias && !strcmp(m->alias, name))
- return m;
+ if (!strcmp(temp->qemu_machine->name, name)) {
+ mc = temp;
+ break;
+ }
+ if (temp->qemu_machine->alias &&
+ !strcmp(temp->qemu_machine->alias, name)) {
+ mc = temp;
+ break;
+ }
}
- return NULL;
+
+ g_slist_free(machines);
+ return mc;
}
-QEMUMachine *find_default_machine(void)
+MachineClass *find_default_machine(void)
{
- QEMUMachine *m;
+ GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false);
+ MachineClass *mc = NULL;
- for(m = first_machine; m != NULL; m = m->next) {
- if (m->is_default) {
- return m;
+ for (el = machines; el; el = el->next) {
+ MachineClass *temp = el->data;
+
+ if (temp->qemu_machine->is_default) {
+ mc = temp;
+ break;
}
}
- return NULL;
+
+ g_slist_free(machines);
+ return mc;
}
MachineInfoList *qmp_query_machines(Error **errp)
{
+ GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false);
MachineInfoList *mach_list = NULL;
QEMUMachine *m;
- for (m = first_machine; m; m = m->next) {
+ for (el = machines; el; el = el->next) {
+ MachineClass *mc = el->data;
MachineInfoList *entry;
MachineInfo *info;
+ m = mc->qemu_machine;
info = g_malloc0(sizeof(*info));
if (m->is_default) {
info->has_is_default = true;
@@ -1639,6 +1667,7 @@ MachineInfoList *qmp_query_machines(Error **errp)
mach_list = entry;
}
+ g_slist_free(machines);
return mach_list;
}
@@ -1832,8 +1861,12 @@ void qemu_devices_reset(void)
void qemu_system_reset(bool report)
{
- if (current_machine && current_machine->reset) {
- current_machine->reset();
+ MachineClass *mc;
+
+ mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL;
+
+ if (mc && mc->qemu_machine->reset) {
+ mc->qemu_machine->reset();
} else {
qemu_devices_reset();
}
@@ -2605,24 +2638,29 @@ static int debugcon_parse(const char *devname)
return 0;
}
-static QEMUMachine *machine_parse(const char *name)
+static MachineClass *machine_parse(const char *name)
{
- QEMUMachine *m, *machine = NULL;
+ MachineClass *mc = NULL;
+ GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false);
if (name) {
- machine = find_machine(name);
+ mc = find_machine(name);
}
- if (machine) {
- return machine;
+ if (mc) {
+ return mc;
}
printf("Supported machines are:\n");
- for (m = first_machine; m != NULL; m = m->next) {
+ for (el = machines; el; el = el->next) {
+ MachineClass *mc = el->data;
+ QEMUMachine *m = mc->qemu_machine;
if (m->alias) {
printf("%-20s %s (alias of %s)\n", m->alias, m->desc, m->name);
}
printf("%-20s %s%s\n", m->name, m->desc,
m->is_default ? " (default)" : "");
}
+
+ g_slist_free(machines);
exit(!name || !is_help_option(name));
}
@@ -2871,6 +2909,7 @@ int main(int argc, char **argv, char **envp)
int optind;
const char *optarg;
const char *loadvm = NULL;
+ MachineClass *machine_class;
QEMUMachine *machine;
const char *cpu_model;
const char *vga_model = "none";
@@ -2945,7 +2984,7 @@ int main(int argc, char **argv, char **envp)
os_setup_early_signal_handling();
module_call_init(MODULE_INIT_MACHINE);
- machine = find_default_machine();
+ machine_class = find_default_machine();
cpu_model = NULL;
ram_size = 0;
snapshot = 0;
@@ -3011,7 +3050,7 @@ int main(int argc, char **argv, char **envp)
}
switch(popt->index) {
case QEMU_OPTION_M:
- machine = machine_parse(optarg);
+ machine_class = machine_parse(optarg);
break;
case QEMU_OPTION_no_kvm_irqchip: {
olist = qemu_find_opts("machine");
@@ -3567,7 +3606,7 @@ int main(int argc, char **argv, char **envp)
}
optarg = qemu_opt_get(opts, "type");
if (optarg) {
- machine = machine_parse(optarg);
+ machine_class = machine_parse(optarg);
}
break;
case QEMU_OPTION_no_kvm:
@@ -3873,11 +3912,17 @@ int main(int argc, char **argv, char **envp)
}
#endif
- if (machine == NULL) {
+ if (machine_class == NULL) {
fprintf(stderr, "No machine found.\n");
exit(1);
}
+ current_machine = MACHINE(object_new(object_class_get_name(
+ OBJECT_CLASS(machine_class))));
+ object_property_add_child(object_get_root(), "machine",
+ OBJECT(current_machine), &error_abort);
+
+ machine = machine_class->qemu_machine;
if (machine->hw_version) {
qemu_set_version(machine->hw_version);
}
@@ -4306,7 +4351,9 @@ int main(int argc, char **argv, char **envp)
.kernel_cmdline = kernel_cmdline,
.initrd_filename = initrd_filename,
.cpu_model = cpu_model };
- machine->init(&args);
+
+ current_machine->init_args = args;
+ machine->init(&current_machine->init_args);
audio_init();
@@ -4314,8 +4361,6 @@ int main(int argc, char **argv, char **envp)
set_numa_modes();
- current_machine = machine;
-
/* init USB devices */
if (usb_enabled(false)) {
if (foreach_device_config(DEV_USB, usb_parse) < 0)