[Qemu-devel] Building qemu on OpenSolaris/SPARC fails: tcg_unsigned_cond undefined symbol

2009-12-26 Thread Palle Lyckegaard

Hi,

Building on OpenSolaris/SPARC fails with:

...
  LINK  mips64-softmmu/qemu-system-mips64
Undefined   first referenced
 symbol in file
tcg_unsigned_cond   libqemu.a(tcg.o)
ld: fatal: symbol referencing errors. No output written to 
qemu-system-mips64

collect2: ld returned 1 exit status
gmake[1]: *** [qemu-system-mips64] Error 1
make: *** [subdir-mips64-softmmu] Error 2
...


Host info (uname -a):

SunOS opensolaris 5.11 snv_111b sun4u sparc SUNW,Ultra-5_10 Solaris


It apperars as if 
http://git.savannah.gnu.org/cgit/qemu.git/commit/?id=56f4927e34c63fc02b2fb8f7b09b1900075b6f26 
has introduced a reference to tcg_unsigned_cond().


Regards
Palle




Re: [Qemu-devel] [RFC,PATCH 00/11] Half-convert info qtree to QMP.

2009-12-26 Thread Nathan Baum
Oops. Sorry for the spam.

Your client isn't broken. Due to mail server misconfiguration on my
part, I've managed to send this patch series twice.

I thought it hadn't been sent the first time around. Guess it was hidden
in a queue somewhere.






[Qemu-devel] [RFC, PATCH 07/11] qdev: Add sysbus_dev_info to system_bus_info

2009-12-26 Thread Nathan Baum
Signed-off-by: Nathan Baum 
---
 hw/sysbus.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/hw/sysbus.c b/hw/sysbus.c
index 2092d9f..5d2bbb4 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -23,11 +23,13 @@
 #include "qjson.h"
 
 static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent);
+static QObject *sysbus_dev_info(Monitor *mon, DeviceState *dev);
 
 struct BusInfo system_bus_info = {
 .name   = "System",
 .size   = sizeof(BusState),
 .print_dev  = sysbus_dev_print,
+.info_dev  = sysbus_dev_info,
 };
 
 void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq)
-- 
1.6.3.3





[Qemu-devel] [RFC, PATCH 01/11] Add info_dev function pointer for BusInfo.

2009-12-26 Thread Nathan Baum
This function will be called to produce bus-specific data for QMP's
query-qtree command.

Signed-off-by: Nathan Baum 
---
 hw/qdev.h |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.h b/hw/qdev.h
index bbcdba1..93467a5 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -43,10 +43,12 @@ struct DeviceState {
 };
 
 typedef void (*bus_dev_printfn)(Monitor *mon, DeviceState *dev, int indent);
+typedef QObject *(*bus_dev_infofn)(Monitor *mon, DeviceState *dev);
 struct BusInfo {
 const char *name;
 size_t size;
 bus_dev_printfn print_dev;
+bus_dev_infofn info_dev;
 Property *props;
 };
 
-- 
1.6.3.3





[Qemu-devel] [RFC,PATCH 06/11] qdev: sysbus_dev_info

2009-12-26 Thread Nathan Baum
Returns information about the system bus as a QObject.

Signed-off-by: Nathan Baum 
---
 hw/sysbus.c |   18 ++
 1 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/hw/sysbus.c b/hw/sysbus.c
index 1f7f138..2092d9f 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -20,6 +20,7 @@
 #include "sysbus.h"
 #include "sysemu.h"
 #include "monitor.h"
+#include "qjson.h"
 
 static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent);
 
@@ -170,3 +171,20 @@ static void sysbus_dev_print(Monitor *mon, DeviceState 
*dev, int indent)
indent, "", s->mmio[i].addr, s->mmio[i].size);
 }
 }
+
+static QObject *sysbus_dev_info(Monitor *mon, DeviceState *dev)
+{
+SysBusDevice *s = sysbus_from_qdev(dev);
+QDict *dict = qdict_new();
+QList *list = qlist_new();
+int i;
+
+for (i = 0; i < s->num_mmio; i++) {
+qlist_append_obj(list, qobject_from_jsonf("{ 'addr': " TARGET_FMT_plx 
", 'size': " TARGET_FMT_plx " }",
+  s->mmio[i].addr, 
s->mmio[i].size));
+}
+
+qdict_put(dict, "mmio", list);
+return (QObject *) dict;
+
+}
-- 
1.6.3.3





[Qemu-devel] [RFC, PATCH 09/11] qdev: Add usb_bus_dev_info to usb_bus_info.

2009-12-26 Thread Nathan Baum
Signed-off-by: Nathan Baum 
---
 hw/usb-bus.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index 6d02807..582924d 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -6,11 +6,13 @@
 #include "qjson.h"
 
 static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent);
+static QObject *usb_bus_dev_info(Monitor *mon, DeviceState *qdev);
 
 static struct BusInfo usb_bus_info = {
 .name  = "USB",
 .size  = sizeof(USBBus),
 .print_dev = usb_bus_dev_print,
+.info_dev = usb_bus_dev_info,
 };
 static int next_usb_bus = 0;
 static QTAILQ_HEAD(, USBBus) busses = QTAILQ_HEAD_INITIALIZER(busses);
-- 
1.6.3.3





[Qemu-devel] [RFC, PATCH 03/11] qdev: Add isabuf_dev_info to ISA's BusInfo struct.

2009-12-26 Thread Nathan Baum
Signed-off-by: Nathan Baum 
---
 hw/isa-bus.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index b3d599f..ed965d8 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -32,11 +32,13 @@ struct ISABus {
 static ISABus *isabus;
 
 static void isabus_dev_print(Monitor *mon, DeviceState *dev, int indent);
+static QObject *isabus_dev_info(Monitor *mon, DeviceState *dev);
 
 static struct BusInfo isa_bus_info = {
 .name  = "ISA",
 .size  = sizeof(ISABus),
 .print_dev = isabus_dev_print,
+.info_dev = isabus_dev_info,
 };
 
 ISABus *isa_bus_new(DeviceState *dev)
-- 
1.6.3.3





[Qemu-devel] [RFC, PATCH 11/11] Change the monitor to use the new do_info_qtree.

2009-12-26 Thread Nathan Baum
Signed-off-by: Nathan Baum 
---
 hw/qdev.c |9 -
 hw/qdev.h |3 ++-
 monitor.c |3 ++-
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index f5d68c6..d9d3778 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -727,6 +727,12 @@ static void do_info_qbus(Monitor *mon, BusState *bus, 
QObject **ret_data)
 *ret_data = (QObject *) qdict;
 }
 
+void do_info_qtree(Monitor *mon, QObject **ret_data)
+{
+if (main_system_bus)
+do_info_qbus(mon, main_system_bus, ret_data);
+}
+
 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## 
__VA_ARGS__)
 static void qbus_print(Monitor *mon, BusState *bus, int indent);
 
@@ -780,8 +786,9 @@ static void qbus_print(Monitor *mon, BusState *bus, int 
indent)
 }
 #undef qdev_printf
 
-void do_info_qtree(Monitor *mon)
+void do_info_qtree_print(Monitor *mon, const QObject *data)
 {
+// TODO: Display qtree from the data!
 if (main_system_bus)
 qbus_print(mon, main_system_bus, 0);
 }
diff --git a/hw/qdev.h b/hw/qdev.h
index 93467a5..aad4f75 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -168,7 +168,8 @@ void qbus_free(BusState *bus);
 
 /*** monitor commands ***/
 
-void do_info_qtree(Monitor *mon);
+void do_info_qtree(Monitor *mon, QObject **ret_data);
+void do_info_qtree_print(Monitor *mon, const QObject *data);
 void do_info_qdm(Monitor *mon);
 void do_device_add(Monitor *mon, const QDict *qdict);
 void do_device_del(Monitor *mon, const QDict *qdict);
diff --git a/monitor.c b/monitor.c
index e6b5424..8d5b650 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2607,7 +2607,8 @@ static const mon_cmd_t info_cmds[] = {
 .args_type  = "",
 .params = "",
 .help   = "show device tree",
-.mhandler.info = do_info_qtree,
+.user_print = do_info_qtree_print,
+.mhandler.info_new = do_info_qtree,
 },
 {
 .name   = "qdm",
-- 
1.6.3.3





[Qemu-devel] [RFC,PATCH 08/11] qdev: Add usb_bus_dev_info

2009-12-26 Thread Nathan Baum
Returns a QObject with information about a USB device.

Signed-off-by: Nathan Baum 
---
 hw/usb-bus.c |   13 +
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index 54027df..6d02807 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -3,6 +3,7 @@
 #include "qdev.h"
 #include "sysemu.h"
 #include "monitor.h"
+#include "qjson.h"
 
 static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent);
 
@@ -232,6 +233,18 @@ static void usb_bus_dev_print(Monitor *mon, DeviceState 
*qdev, int indent)
dev->attached ? ", attached" : "");
 }
 
+static QObject *usb_bus_dev_info(Monitor *mon, DeviceState *qdev)
+{
+USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev);
+USBBus *bus = usb_bus_from_device(dev);
+return qobject_from_jsonf("{'busnr': %d, 'addr':%d, 'speed': %s, 'desc': 
%s, 'attached': %i}",
+  bus->busnr,
+  dev->addr,
+  usb_speed(dev->speed),
+  dev->product_desc,
+  dev->attached);
+}
+
 void usb_info(Monitor *mon)
 {
 USBBus *bus;
-- 
1.6.3.3





[Qemu-devel] [RFC,PATCH 10/11] qdev: Add do_info_qbus and friends.

2009-12-26 Thread Nathan Baum
Places information about a bus and the devices on into a QObject.

Signed-off-by: Nathan Baum 
---
 hw/qdev.c |   73 +
 1 files changed, 73 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index b6bd4ae..f5d68c6 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -30,6 +30,8 @@
 #include "sysemu.h"
 #include "monitor.h"
 #include "qerror.h"
+#include "qint.h"
+#include "qbool.h"
 
 static int qdev_hotplug = 0;
 
@@ -654,6 +656,77 @@ void qbus_free(BusState *bus)
 }
 }
 
+static void do_info_qbus(Monitor *mon, BusState *bus, QObject **ret_data);
+
+static void do_info_qdev_props(Monitor *mon, DeviceState *dev, Property 
*props, const char *prefix,
+   QDict *qdict)
+{
+char name[64];
+char value[64];
+
+if (!props)
+return;
+while (props->name) {
+if (props->info->print) {
+props->info->print(dev, props, value, sizeof(value));
+snprintf(name, sizeof(name), "%s-%s", prefix, props->name);
+qdict_put(qdict, name, qstring_from_str(value));
+}
+props++;
+}
+}
+
+static void do_info_qdev(Monitor *mon, DeviceState *dev, QObject **ret_data)
+{
+BusState *child;
+QDict *qdict;
+QList *children;
+
+qdict = qdict_new();
+qdict_put(qdict, "name", qstring_from_str(dev->info->name));
+if (dev->id)
+qdict_put(qdict, "id", qstring_from_str(dev->id));
+qdict_put(qdict, "gpio-in", qint_from_int(dev->num_gpio_in));
+qdict_put(qdict, "gpio-out", qint_from_int(dev->num_gpio_out));
+do_info_qdev_props(mon, dev, dev->info->props, "dev", qdict);
+do_info_qdev_props(mon, dev, dev->parent_bus->info->props, "bus", qdict);
+children = qlist_new();
+QLIST_FOREACH(child, &dev->child_bus, sibling) {
+QObject *data = NULL;
+do_info_qbus(mon, child, &data);
+if (data)
+qlist_append_obj(children, data);
+}
+if (!qlist_empty(children))
+qdict_put(qdict, "children", children);
+if (dev->parent_bus->info->info_dev) {
+qdict_put_obj(qdict, "info", dev->parent_bus->info->info_dev(mon, 
dev));
+}
+*ret_data = (QObject *) qdict;
+}
+
+static void do_info_qbus(Monitor *mon, BusState *bus, QObject **ret_data)
+{
+struct DeviceState *dev;
+QDict *qdict;
+QList *children;
+
+qdict = qdict_new();
+qdict_put(qdict, "bus", qstring_from_str(bus->name));
+qdict_put(qdict, "type", qstring_from_str(bus->info->name));
+qdict_put(qdict, "allow_hotplug", qbool_from_int(bus->allow_hotplug));
+children = qlist_new();
+qdict_put(qdict, "children", children);
+QLIST_FOREACH(dev, &bus->children, sibling) {
+QObject *data = NULL;
+do_info_qdev(mon, dev, &data);
+if (data)
+qlist_append_obj(children, data);
+}
+
+*ret_data = (QObject *) qdict;
+}
+
 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## 
__VA_ARGS__)
 static void qbus_print(Monitor *mon, BusState *bus, int indent);
 
-- 
1.6.3.3





[Qemu-devel] [PATCH 09/11] qdev: Add usb_bus_dev_info to usb_bus_info.

2009-12-26 Thread Nathan Baum
Signed-off-by: Nathan Baum 
---
 hw/usb-bus.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index 6d02807..582924d 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -6,11 +6,13 @@
 #include "qjson.h"
 
 static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent);
+static QObject *usb_bus_dev_info(Monitor *mon, DeviceState *qdev);
 
 static struct BusInfo usb_bus_info = {
 .name  = "USB",
 .size  = sizeof(USBBus),
 .print_dev = usb_bus_dev_print,
+.info_dev = usb_bus_dev_info,
 };
 static int next_usb_bus = 0;
 static QTAILQ_HEAD(, USBBus) busses = QTAILQ_HEAD_INITIALIZER(busses);
-- 
1.6.3.3





[Qemu-devel] [RFC,PATCH 04/11] qdev: pcibus_dev_info

2009-12-26 Thread Nathan Baum
This returns a QObject detailing the PCI-specific data about the device.

Signed-off-by: Nathan Baum 
---
 hw/pci.c |   48 
 1 files changed, 48 insertions(+), 0 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 9722fce..8688d8a 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -27,6 +27,8 @@
 #include "net.h"
 #include "sysemu.h"
 #include "loader.h"
+#include "qjson.h"
+#include "qint.h"
 
 //#define DEBUG_PCI
 #ifdef DEBUG_PCI
@@ -1585,6 +1587,52 @@ static void pcibus_dev_print(Monitor *mon, DeviceState 
*dev, int indent)
 }
 }
 
+static QObject *pcibus_dev_info(Monitor *mon, DeviceState *dev)
+{
+PCIDevice *d = (PCIDevice *)dev;
+const pci_class_desc *desc;
+PCIIORegion *r;
+int i, class;
+QObject *retval;
+QList *regions;
+
+retval = qobject_from_jsonf("{ 'addr': { 'bus' : %d, 'slot' : %d, 'func': 
%d }, "
+"  'device': { 'vendor': %d, 'id': %d }, "
+"  'subsystem': { 'vendor': %d, 'id': %d } "
+"}",
+d->config[PCI_SECONDARY_BUS],
+PCI_SLOT(d->devfn),
+PCI_FUNC(d->devfn),
+pci_get_word(d->config + PCI_VENDOR_ID),
+pci_get_word(d->config + PCI_DEVICE_ID),
+pci_get_word(d->config + 
PCI_SUBSYSTEM_VENDOR_ID),
+pci_get_word(d->config + PCI_SUBSYSTEM_ID));
+class = pci_get_word(d->config + PCI_CLASS_DEVICE);
+desc = pci_class_descriptions;
+while (desc->desc && class != desc->class)
+desc++;
+if (desc->desc) {
+qdict_put(qobject_to_qdict(retval), "class", 
qstring_from_str(desc->desc));
+} else {
+qdict_put(qobject_to_qdict(retval), "class", qint_from_int(class));
+}
+
+regions = qlist_new();
+qdict_put(qobject_to_qdict(retval), "regions", regions);
+
+for (i = 0; i < PCI_NUM_REGIONS; i++) {
+r = &d->io_regions[i];
+if (!r->size)
+continue;
+qlist_append_obj(regions,
+ qobject_from_jsonf("{'type':%s,'addr':%d,'size':%d}",
+r->type & 
PCI_BASE_ADDRESS_SPACE_IO ? "i/o" : "mem",
+(int) r->addr,
+(int) r->size));
+}
+return retval;
+}
+
 static PCIDeviceInfo bridge_info = {
 .qdev.name= "pci-bridge",
 .qdev.size= sizeof(PCIBridge),
-- 
1.6.3.3





[Qemu-devel] [PATCH 11/11] Change the monitor to use the new do_info_qtree.

2009-12-26 Thread Nathan Baum
Signed-off-by: Nathan Baum 
---
 hw/qdev.c |9 -
 hw/qdev.h |3 ++-
 monitor.c |3 ++-
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index f5d68c6..d9d3778 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -727,6 +727,12 @@ static void do_info_qbus(Monitor *mon, BusState *bus, 
QObject **ret_data)
 *ret_data = (QObject *) qdict;
 }
 
+void do_info_qtree(Monitor *mon, QObject **ret_data)
+{
+if (main_system_bus)
+do_info_qbus(mon, main_system_bus, ret_data);
+}
+
 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## 
__VA_ARGS__)
 static void qbus_print(Monitor *mon, BusState *bus, int indent);
 
@@ -780,8 +786,9 @@ static void qbus_print(Monitor *mon, BusState *bus, int 
indent)
 }
 #undef qdev_printf
 
-void do_info_qtree(Monitor *mon)
+void do_info_qtree_print(Monitor *mon, const QObject *data)
 {
+// TODO: Display qtree from the data!
 if (main_system_bus)
 qbus_print(mon, main_system_bus, 0);
 }
diff --git a/hw/qdev.h b/hw/qdev.h
index 93467a5..aad4f75 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -168,7 +168,8 @@ void qbus_free(BusState *bus);
 
 /*** monitor commands ***/
 
-void do_info_qtree(Monitor *mon);
+void do_info_qtree(Monitor *mon, QObject **ret_data);
+void do_info_qtree_print(Monitor *mon, const QObject *data);
 void do_info_qdm(Monitor *mon);
 void do_device_add(Monitor *mon, const QDict *qdict);
 void do_device_del(Monitor *mon, const QDict *qdict);
diff --git a/monitor.c b/monitor.c
index e6b5424..8d5b650 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2607,7 +2607,8 @@ static const mon_cmd_t info_cmds[] = {
 .args_type  = "",
 .params = "",
 .help   = "show device tree",
-.mhandler.info = do_info_qtree,
+.user_print = do_info_qtree_print,
+.mhandler.info_new = do_info_qtree,
 },
 {
 .name   = "qdm",
-- 
1.6.3.3





[Qemu-devel] [PATCH 10/11] qdev: Add do_info_qbus and friends.

2009-12-26 Thread Nathan Baum
Places information about a bus and the devices on into a QObject.

Signed-off-by: Nathan Baum 
---
 hw/qdev.c |   73 +
 1 files changed, 73 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index b6bd4ae..f5d68c6 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -30,6 +30,8 @@
 #include "sysemu.h"
 #include "monitor.h"
 #include "qerror.h"
+#include "qint.h"
+#include "qbool.h"
 
 static int qdev_hotplug = 0;
 
@@ -654,6 +656,77 @@ void qbus_free(BusState *bus)
 }
 }
 
+static void do_info_qbus(Monitor *mon, BusState *bus, QObject **ret_data);
+
+static void do_info_qdev_props(Monitor *mon, DeviceState *dev, Property 
*props, const char *prefix,
+   QDict *qdict)
+{
+char name[64];
+char value[64];
+
+if (!props)
+return;
+while (props->name) {
+if (props->info->print) {
+props->info->print(dev, props, value, sizeof(value));
+snprintf(name, sizeof(name), "%s-%s", prefix, props->name);
+qdict_put(qdict, name, qstring_from_str(value));
+}
+props++;
+}
+}
+
+static void do_info_qdev(Monitor *mon, DeviceState *dev, QObject **ret_data)
+{
+BusState *child;
+QDict *qdict;
+QList *children;
+
+qdict = qdict_new();
+qdict_put(qdict, "name", qstring_from_str(dev->info->name));
+if (dev->id)
+qdict_put(qdict, "id", qstring_from_str(dev->id));
+qdict_put(qdict, "gpio-in", qint_from_int(dev->num_gpio_in));
+qdict_put(qdict, "gpio-out", qint_from_int(dev->num_gpio_out));
+do_info_qdev_props(mon, dev, dev->info->props, "dev", qdict);
+do_info_qdev_props(mon, dev, dev->parent_bus->info->props, "bus", qdict);
+children = qlist_new();
+QLIST_FOREACH(child, &dev->child_bus, sibling) {
+QObject *data = NULL;
+do_info_qbus(mon, child, &data);
+if (data)
+qlist_append_obj(children, data);
+}
+if (!qlist_empty(children))
+qdict_put(qdict, "children", children);
+if (dev->parent_bus->info->info_dev) {
+qdict_put_obj(qdict, "info", dev->parent_bus->info->info_dev(mon, 
dev));
+}
+*ret_data = (QObject *) qdict;
+}
+
+static void do_info_qbus(Monitor *mon, BusState *bus, QObject **ret_data)
+{
+struct DeviceState *dev;
+QDict *qdict;
+QList *children;
+
+qdict = qdict_new();
+qdict_put(qdict, "bus", qstring_from_str(bus->name));
+qdict_put(qdict, "type", qstring_from_str(bus->info->name));
+qdict_put(qdict, "allow_hotplug", qbool_from_int(bus->allow_hotplug));
+children = qlist_new();
+qdict_put(qdict, "children", children);
+QLIST_FOREACH(dev, &bus->children, sibling) {
+QObject *data = NULL;
+do_info_qdev(mon, dev, &data);
+if (data)
+qlist_append_obj(children, data);
+}
+
+*ret_data = (QObject *) qdict;
+}
+
 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## 
__VA_ARGS__)
 static void qbus_print(Monitor *mon, BusState *bus, int indent);
 
-- 
1.6.3.3





[Qemu-devel] [RFC, PATCH 05/11] qdev: Add pcibus_dev_info to pci_bus_info

2009-12-26 Thread Nathan Baum
Signed-off-by: Nathan Baum 
---
 hw/pci.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 8688d8a..36605e7 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -59,11 +59,13 @@ struct PCIBus {
 };
 
 static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent);
+static QObject *pcibus_dev_info(Monitor *mon, DeviceState *dev);
 
 static struct BusInfo pci_bus_info = {
 .name   = "PCI",
 .size   = sizeof(PCIBus),
 .print_dev  = pcibus_dev_print,
+.info_dev   = pcibus_dev_info,
 .props  = (Property[]) {
 DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
 DEFINE_PROP_STRING("romfile", PCIDevice, romfile),
-- 
1.6.3.3





[Qemu-devel] [PATCH 08/11] qdev: Add usb_bus_dev_info

2009-12-26 Thread Nathan Baum
Returns a QObject with information about a USB device.

Signed-off-by: Nathan Baum 
---
 hw/usb-bus.c |   13 +
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index 54027df..6d02807 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -3,6 +3,7 @@
 #include "qdev.h"
 #include "sysemu.h"
 #include "monitor.h"
+#include "qjson.h"
 
 static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent);
 
@@ -232,6 +233,18 @@ static void usb_bus_dev_print(Monitor *mon, DeviceState 
*qdev, int indent)
dev->attached ? ", attached" : "");
 }
 
+static QObject *usb_bus_dev_info(Monitor *mon, DeviceState *qdev)
+{
+USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev);
+USBBus *bus = usb_bus_from_device(dev);
+return qobject_from_jsonf("{'busnr': %d, 'addr':%d, 'speed': %s, 'desc': 
%s, 'attached': %i}",
+  bus->busnr,
+  dev->addr,
+  usb_speed(dev->speed),
+  dev->product_desc,
+  dev->attached);
+}
+
 void usb_info(Monitor *mon)
 {
 USBBus *bus;
-- 
1.6.3.3





[Qemu-devel] [RFC,PATCH 00/11] Half-convert info qtree to QMP.

2009-12-26 Thread Nathan Baum
Hullo.

This series of patches partially converts info qtree to QMP.

I've gone halfway: one can use query-qtree in QMP.

I haven't converted the old monitor function other than to rename it;
do_info_qtree_print just ignores the QObject it is passed and prints
the qtree the old-fashioned way.

 hw/isa-bus.c |   19 +
 hw/pci.c |   50 +++
 hw/qdev.c|   82 +-
 hw/qdev.h|5 +++-
 hw/sysbus.c  |   20 ++
 hw/usb-bus.c |   15 ++
 monitor.c|3 +-
 7 files changed, 191 insertions(+), 3 deletions(-)





[Qemu-devel] [PATCH 04/11] qdev: pcibus_dev_info

2009-12-26 Thread Nathan Baum
This returns a QObject detailing the PCI-specific data about the device.

Signed-off-by: Nathan Baum 
---
 hw/pci.c |   48 
 1 files changed, 48 insertions(+), 0 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 9722fce..8688d8a 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -27,6 +27,8 @@
 #include "net.h"
 #include "sysemu.h"
 #include "loader.h"
+#include "qjson.h"
+#include "qint.h"
 
 //#define DEBUG_PCI
 #ifdef DEBUG_PCI
@@ -1585,6 +1587,52 @@ static void pcibus_dev_print(Monitor *mon, DeviceState 
*dev, int indent)
 }
 }
 
+static QObject *pcibus_dev_info(Monitor *mon, DeviceState *dev)
+{
+PCIDevice *d = (PCIDevice *)dev;
+const pci_class_desc *desc;
+PCIIORegion *r;
+int i, class;
+QObject *retval;
+QList *regions;
+
+retval = qobject_from_jsonf("{ 'addr': { 'bus' : %d, 'slot' : %d, 'func': 
%d }, "
+"  'device': { 'vendor': %d, 'id': %d }, "
+"  'subsystem': { 'vendor': %d, 'id': %d } "
+"}",
+d->config[PCI_SECONDARY_BUS],
+PCI_SLOT(d->devfn),
+PCI_FUNC(d->devfn),
+pci_get_word(d->config + PCI_VENDOR_ID),
+pci_get_word(d->config + PCI_DEVICE_ID),
+pci_get_word(d->config + 
PCI_SUBSYSTEM_VENDOR_ID),
+pci_get_word(d->config + PCI_SUBSYSTEM_ID));
+class = pci_get_word(d->config + PCI_CLASS_DEVICE);
+desc = pci_class_descriptions;
+while (desc->desc && class != desc->class)
+desc++;
+if (desc->desc) {
+qdict_put(qobject_to_qdict(retval), "class", 
qstring_from_str(desc->desc));
+} else {
+qdict_put(qobject_to_qdict(retval), "class", qint_from_int(class));
+}
+
+regions = qlist_new();
+qdict_put(qobject_to_qdict(retval), "regions", regions);
+
+for (i = 0; i < PCI_NUM_REGIONS; i++) {
+r = &d->io_regions[i];
+if (!r->size)
+continue;
+qlist_append_obj(regions,
+ qobject_from_jsonf("{'type':%s,'addr':%d,'size':%d}",
+r->type & 
PCI_BASE_ADDRESS_SPACE_IO ? "i/o" : "mem",
+(int) r->addr,
+(int) r->size));
+}
+return retval;
+}
+
 static PCIDeviceInfo bridge_info = {
 .qdev.name= "pci-bridge",
 .qdev.size= sizeof(PCIBridge),
-- 
1.6.3.3





[Qemu-devel] [PATCH 07/11] qdev: Add sysbus_dev_info to system_bus_info

2009-12-26 Thread Nathan Baum
Signed-off-by: Nathan Baum 
---
 hw/sysbus.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/hw/sysbus.c b/hw/sysbus.c
index 2092d9f..5d2bbb4 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -23,11 +23,13 @@
 #include "qjson.h"
 
 static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent);
+static QObject *sysbus_dev_info(Monitor *mon, DeviceState *dev);
 
 struct BusInfo system_bus_info = {
 .name   = "System",
 .size   = sizeof(BusState),
 .print_dev  = sysbus_dev_print,
+.info_dev  = sysbus_dev_info,
 };
 
 void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq)
-- 
1.6.3.3





[Qemu-devel] [RFC, PATCH 02/11] qdev: isabus_dev_info returns a QObject detailing the IRQ lines used by the device.

2009-12-26 Thread Nathan Baum
Signed-off-by: Nathan Baum 
---
 hw/isa-bus.c |   17 +
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index 4d489d2..b3d599f 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -21,6 +21,8 @@
 #include "monitor.h"
 #include "sysbus.h"
 #include "isa.h"
+#include "qjson.h"
+#include "qint.h"
 
 struct ISABus {
 BusState qbus;
@@ -143,6 +145,21 @@ static void isabus_dev_print(Monitor *mon, DeviceState 
*dev, int indent)
 }
 }
 
+static QObject *isabus_dev_info(Monitor *mon, DeviceState *dev)
+{
+ISADevice *d = DO_UPCAST(ISADevice, qdev, dev);
+
+if (d->isairq[1] != -1) {
+return qobject_from_jsonf("{'irq':[%d,%d]}",
+  d->isairq[0], d->isairq[1]);
+} else if (d->isairq[0] != -1) {
+return qobject_from_jsonf("{'irq':[%d]}",
+  d->isairq[0]);
+} else {
+return qobject_from_jsonf("{'irq':[]}");
+}
+}
+
 static int isabus_bridge_init(SysBusDevice *dev)
 {
 /* nothing */
-- 
1.6.3.3





[Qemu-devel] [PATCH 03/11] qdev: Add isabuf_dev_info to ISA's BusInfo struct.

2009-12-26 Thread Nathan Baum
Signed-off-by: Nathan Baum 
---
 hw/isa-bus.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index b3d599f..ed965d8 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -32,11 +32,13 @@ struct ISABus {
 static ISABus *isabus;
 
 static void isabus_dev_print(Monitor *mon, DeviceState *dev, int indent);
+static QObject *isabus_dev_info(Monitor *mon, DeviceState *dev);
 
 static struct BusInfo isa_bus_info = {
 .name  = "ISA",
 .size  = sizeof(ISABus),
 .print_dev = isabus_dev_print,
+.info_dev = isabus_dev_info,
 };
 
 ISABus *isa_bus_new(DeviceState *dev)
-- 
1.6.3.3





[Qemu-devel] [PATCH 06/11] qdev: sysbus_dev_info

2009-12-26 Thread Nathan Baum
Returns information about the system bus as a QObject.

Signed-off-by: Nathan Baum 
---
 hw/sysbus.c |   18 ++
 1 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/hw/sysbus.c b/hw/sysbus.c
index 1f7f138..2092d9f 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -20,6 +20,7 @@
 #include "sysbus.h"
 #include "sysemu.h"
 #include "monitor.h"
+#include "qjson.h"
 
 static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent);
 
@@ -170,3 +171,20 @@ static void sysbus_dev_print(Monitor *mon, DeviceState 
*dev, int indent)
indent, "", s->mmio[i].addr, s->mmio[i].size);
 }
 }
+
+static QObject *sysbus_dev_info(Monitor *mon, DeviceState *dev)
+{
+SysBusDevice *s = sysbus_from_qdev(dev);
+QDict *dict = qdict_new();
+QList *list = qlist_new();
+int i;
+
+for (i = 0; i < s->num_mmio; i++) {
+qlist_append_obj(list, qobject_from_jsonf("{ 'addr': " TARGET_FMT_plx 
", 'size': " TARGET_FMT_plx " }",
+  s->mmio[i].addr, 
s->mmio[i].size));
+}
+
+qdict_put(dict, "mmio", list);
+return (QObject *) dict;
+
+}
-- 
1.6.3.3





[Qemu-devel] [PATCH 05/11] qdev: Add pcibus_dev_info to pci_bus_info

2009-12-26 Thread Nathan Baum
Signed-off-by: Nathan Baum 
---
 hw/pci.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 8688d8a..36605e7 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -59,11 +59,13 @@ struct PCIBus {
 };
 
 static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent);
+static QObject *pcibus_dev_info(Monitor *mon, DeviceState *dev);
 
 static struct BusInfo pci_bus_info = {
 .name   = "PCI",
 .size   = sizeof(PCIBus),
 .print_dev  = pcibus_dev_print,
+.info_dev   = pcibus_dev_info,
 .props  = (Property[]) {
 DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
 DEFINE_PROP_STRING("romfile", PCIDevice, romfile),
-- 
1.6.3.3





[Qemu-devel] [PATCH 01/11] Add info_dev function pointer for BusInfo.

2009-12-26 Thread Nathan Baum
This function will be called to produce bus-specific data for QMP's
query-qtree command.

Signed-off-by: Nathan Baum 
---
 hw/qdev.h |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.h b/hw/qdev.h
index bbcdba1..93467a5 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -43,10 +43,12 @@ struct DeviceState {
 };
 
 typedef void (*bus_dev_printfn)(Monitor *mon, DeviceState *dev, int indent);
+typedef QObject *(*bus_dev_infofn)(Monitor *mon, DeviceState *dev);
 struct BusInfo {
 const char *name;
 size_t size;
 bus_dev_printfn print_dev;
+bus_dev_infofn info_dev;
 Property *props;
 };
 
-- 
1.6.3.3





[Qemu-devel] [RFC,PATCH 00/11] Half-convert info qtree to QMP.

2009-12-26 Thread Nathan Baum
Hullo.

This series of patches partially converts info qtree to QMP.

I've gone halfway: one can use query-qtree in QMP.

I haven't converted the old monitor function other than to rename it;
do_info_qtree_print just ignores the QObject it is passed and prints
the qtree the old-fashioned way.

 hw/isa-bus.c |   19 +
 hw/pci.c |   50 +++
 hw/qdev.c|   82 +-
 hw/qdev.h|5 +++-
 hw/sysbus.c  |   20 ++
 hw/usb-bus.c |   15 ++
 monitor.c|3 +-
 7 files changed, 191 insertions(+), 3 deletions(-)





[Qemu-devel] [PATCH 02/11] qdev: isabus_dev_info returns a QObject detailing the IRQ lines used by the device.

2009-12-26 Thread Nathan Baum
Signed-off-by: Nathan Baum 
---
 hw/isa-bus.c |   17 +
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index 4d489d2..b3d599f 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -21,6 +21,8 @@
 #include "monitor.h"
 #include "sysbus.h"
 #include "isa.h"
+#include "qjson.h"
+#include "qint.h"
 
 struct ISABus {
 BusState qbus;
@@ -143,6 +145,21 @@ static void isabus_dev_print(Monitor *mon, DeviceState 
*dev, int indent)
 }
 }
 
+static QObject *isabus_dev_info(Monitor *mon, DeviceState *dev)
+{
+ISADevice *d = DO_UPCAST(ISADevice, qdev, dev);
+
+if (d->isairq[1] != -1) {
+return qobject_from_jsonf("{'irq':[%d,%d]}",
+  d->isairq[0], d->isairq[1]);
+} else if (d->isairq[0] != -1) {
+return qobject_from_jsonf("{'irq':[%d]}",
+  d->isairq[0]);
+} else {
+return qobject_from_jsonf("{'irq':[]}");
+}
+}
+
 static int isabus_bridge_init(SysBusDevice *dev)
 {
 /* nothing */
-- 
1.6.3.3





[Qemu-devel] [PATCH 2/2] multiboot: Separate multiboot loading into separate file

2009-12-26 Thread Adam Lackorzynski
Move multiboot loading code into separate files as suggested by Alex Graf.

Signed-off-by: Adam Lackorzynski 
---
 Makefile.target |2 +-
 hw/multiboot.c  |  331 +++
 hw/multiboot.h  |   12 ++
 hw/pc.c |  305 +--
 4 files changed, 347 insertions(+), 303 deletions(-)
 create mode 100644 hw/multiboot.c
 create mode 100644 hw/multiboot.h

diff --git a/Makefile.target b/Makefile.target
index 7c1f30c..7f3e497 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -194,7 +194,7 @@ obj-i386-y += fdc.o mc146818rtc.o serial.o i8259.o i8254.o 
pcspk.o pc.o
 obj-i386-y += cirrus_vga.o apic.o ioapic.o parallel.o acpi.o piix_pci.o
 obj-i386-y += usb-uhci.o vmmouse.o vmport.o vmware_vga.o hpet.o
 obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o
-obj-i386-y += ne2000-isa.o
+obj-i386-y += ne2000-isa.o multiboot.o
 
 # shared objects
 obj-ppc-y = ppc.o ide/core.o ide/qdev.o ide/isa.o ide/pci.o ide/macio.o
diff --git a/hw/multiboot.c b/hw/multiboot.c
new file mode 100644
index 000..a25fbf6
--- /dev/null
+++ b/hw/multiboot.c
@@ -0,0 +1,331 @@
+/*
+ * QEMU PC System Emulator
+ *
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "hw.h"
+#include "fw_cfg.h"
+#include "multiboot.h"
+#include "loader.h"
+#include "elf.h"
+#include "sysemu.h"
+
+/* Show multiboot debug output */
+//#define DEBUG_MULTIBOOT
+
+#ifdef DEBUG_MULTIBOOT
+#define mb_debug(a...) fprintf(stderr, ## a)
+#else
+#define mb_debug(a...)
+#endif
+
+#define MULTIBOOT_STRUCT_ADDR 0x9000
+
+#if MULTIBOOT_STRUCT_ADDR > 0xf
+#error multiboot struct needs to fit in 16 bit real mode
+#endif
+
+enum {
+/* Multiboot info */
+MBI_FLAGS   = 0,
+MBI_MEM_LOWER   = 4,
+MBI_MEM_UPPER   = 8,
+MBI_BOOT_DEVICE = 12,
+MBI_CMDLINE = 16,
+MBI_MODS_COUNT  = 20,
+MBI_MODS_ADDR   = 24,
+MBI_MMAP_ADDR   = 48,
+
+MBI_SIZE= 88,
+
+/* Multiboot modules */
+MB_MOD_START= 0,
+MB_MOD_END  = 4,
+MB_MOD_CMDLINE  = 8,
+
+MB_MOD_SIZE = 16,
+
+/* Region offsets */
+ADDR_E820_MAP = MULTIBOOT_STRUCT_ADDR + 0,
+ADDR_MBI  = ADDR_E820_MAP + 0x500,
+
+/* Multiboot flags */
+MULTIBOOT_FLAGS_MEMORY  = 1 << 0,
+MULTIBOOT_FLAGS_BOOT_DEVICE = 1 << 1,
+MULTIBOOT_FLAGS_CMDLINE = 1 << 2,
+MULTIBOOT_FLAGS_MODULES = 1 << 3,
+MULTIBOOT_FLAGS_MMAP= 1 << 6,
+};
+
+typedef struct {
+/* buffer holding kernel, cmdlines and mb_infos */
+void *mb_buf;
+/* address in target */
+target_phys_addr_t mb_buf_phys;
+/* size of mb_buf in bytes */
+unsigned mb_buf_size;
+/* offset of mb-info's in bytes */
+target_phys_addr_t offset_mbinfo;
+/* offset in buffer for cmdlines in bytes */
+target_phys_addr_t offset_cmdlines;
+/* offset of modules in bytes */
+target_phys_addr_t offset_mods;
+/* available slots for mb modules infos */
+int mb_mods_avail;
+/* currently used slots of mb modules */
+int mb_mods_count;
+} MultibootState;
+
+static uint32_t mb_add_cmdline(MultibootState *s, const char *cmdline)
+{
+int len = strlen(cmdline) + 1;
+target_phys_addr_t p = s->offset_cmdlines;
+
+pstrcpy((char *)s->mb_buf + p, len, cmdline);
+s->offset_cmdlines += len;
+return s->mb_buf_phys + p;
+}
+
+static void mb_add_mod(MultibootState *s,
+   target_phys_addr_t start, target_phys_addr_t end,
+   target_phys_addr_t cmdline_phys)
+{
+char *p;
+assert(s->mb_mods_count < s->mb_mods_avail);
+
+p = (char *)s->mb_buf + s->offset_mbinfo + MB_MOD_SIZE * s->mb_mods_count;
+
+stl_p(p + MB_MOD_START,   start);
+stl_p(p + MB_MOD_END, end);
+stl_p(p + MB_MOD_CMDLINE, cmdline_phys);
+
+mb_debug("mod%02d: %08x - %08x\n", s->mb_mods_count, s

[Qemu-devel] [PATCH 1/2] multiboot: Support arbitrary number of modules.

2009-12-26 Thread Adam Lackorzynski
Signed-off-by: Adam Lackorzynski 
---
 hw/pc.c |  268 +++
 1 files changed, 167 insertions(+), 101 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index 83f8dd0..2dca777 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -51,6 +51,12 @@
 /* Show multiboot debug output */
 //#define DEBUG_MULTIBOOT
 
+#ifdef DEBUG_MULTIBOOT
+#define mb_debug(a...) fprintf(stderr, ## a)
+#else
+#define mb_debug(a...)
+#endif
+
 #define BIOS_FILENAME "bios.bin"
 
 #define PC_MAX_BIOS_SIZE (4 * 1024 * 1024)
@@ -512,6 +518,85 @@ static long get_file_size(FILE *f)
 #error multiboot struct needs to fit in 16 bit real mode
 #endif
 
+enum {
+/* Multiboot info */
+MBI_FLAGS   = 0,
+MBI_MEM_LOWER   = 4,
+MBI_MEM_UPPER   = 8,
+MBI_BOOT_DEVICE = 12,
+MBI_CMDLINE = 16,
+MBI_MODS_COUNT  = 20,
+MBI_MODS_ADDR   = 24,
+MBI_MMAP_ADDR   = 48,
+
+MBI_SIZE= 88,
+
+/* Multiboot modules */
+MB_MOD_START= 0,
+MB_MOD_END  = 4,
+MB_MOD_CMDLINE  = 8,
+
+MB_MOD_SIZE = 16,
+
+/* Region offsets */
+ADDR_E820_MAP = MULTIBOOT_STRUCT_ADDR + 0,
+ADDR_MBI  = ADDR_E820_MAP + 0x500,
+
+/* Multiboot flags */
+MULTIBOOT_FLAGS_MEMORY  = 1 << 0,
+MULTIBOOT_FLAGS_BOOT_DEVICE = 1 << 1,
+MULTIBOOT_FLAGS_CMDLINE = 1 << 2,
+MULTIBOOT_FLAGS_MODULES = 1 << 3,
+MULTIBOOT_FLAGS_MMAP= 1 << 6,
+};
+
+typedef struct {
+/* buffer holding kernel, cmdlines and mb_infos */
+void *mb_buf;
+/* address in target */
+target_phys_addr_t mb_buf_phys;
+/* size of mb_buf in bytes */
+unsigned mb_buf_size;
+/* offset of mb-info's in bytes */
+target_phys_addr_t offset_mbinfo;
+/* offset in buffer for cmdlines in bytes */
+target_phys_addr_t offset_cmdlines;
+/* offset of modules in bytes */
+target_phys_addr_t offset_mods;
+/* available slots for mb modules infos */
+int mb_mods_avail;
+/* currently used slots of mb modules */
+int mb_mods_count;
+} MultibootState;
+
+static uint32_t mb_add_cmdline(MultibootState *s, const char *cmdline)
+{
+int len = strlen(cmdline) + 1;
+target_phys_addr_t p = s->offset_cmdlines;
+
+pstrcpy((char *)s->mb_buf + p, len, cmdline);
+s->offset_cmdlines += len;
+return s->mb_buf_phys + p;
+}
+
+static void mb_add_mod(MultibootState *s,
+   target_phys_addr_t start, target_phys_addr_t end,
+   target_phys_addr_t cmdline_phys)
+{
+char *p;
+assert(s->mb_mods_count < s->mb_mods_avail);
+
+p = (char *)s->mb_buf + s->offset_mbinfo + MB_MOD_SIZE * s->mb_mods_count;
+
+stl_p(p + MB_MOD_START,   start);
+stl_p(p + MB_MOD_END, end);
+stl_p(p + MB_MOD_CMDLINE, cmdline_phys);
+
+mb_debug("mod%02d: %08x - %08x\n", s->mb_mods_count, start, end);
+
+s->mb_mods_count++;
+}
+
 static int load_multiboot(void *fw_cfg,
   FILE *f,
   const char *kernel_filename,
@@ -524,12 +609,8 @@ static int load_multiboot(void *fw_cfg,
 uint32_t mh_entry_addr;
 uint32_t mh_load_addr;
 uint32_t mb_kernel_size;
-uint32_t mmap_addr = MULTIBOOT_STRUCT_ADDR;
-uint32_t mb_bootinfo = MULTIBOOT_STRUCT_ADDR + 0x500;
-uint32_t mb_mod_end;
-uint8_t bootinfo[0x500];
-uint32_t cmdline = 0x200;
-uint8_t *mb_kernel_data;
+MultibootState mbs;
+uint8_t bootinfo[MBI_SIZE];
 uint8_t *mb_bootinfo_data;
 
 /* Ok, let's see if it is a multiboot image.
@@ -550,10 +631,9 @@ static int load_multiboot(void *fw_cfg,
 if (!is_multiboot)
 return 0; /* no multiboot */
 
-#ifdef DEBUG_MULTIBOOT
-fprintf(stderr, "qemu: I believe we found a multiboot image!\n");
-#endif
+mb_debug("qemu: I believe we found a multiboot image!\n");
 memset(bootinfo, 0, sizeof(bootinfo));
+memset(&mbs, 0, sizeof(mbs));
 
 if (flags & 0x0004) { /* MULTIBOOT_HEADER_HAS_VBE */
 fprintf(stderr, "qemu: multiboot knows VBE. we don't.\n");
@@ -573,24 +653,18 @@ static int load_multiboot(void *fw_cfg,
 mb_kernel_size = elf_high - elf_low;
 mh_entry_addr = elf_entry;
 
-mb_kernel_data = qemu_malloc(mb_kernel_size);
-if (rom_copy(mb_kernel_data, mh_load_addr, mb_kernel_size) != 
mb_kernel_size) {
+mbs.mb_buf = qemu_malloc(mb_kernel_size);
+if (rom_copy(mbs.mb_buf, mh_load_addr, mb_kernel_size) != 
mb_kernel_size) {
 fprintf(stderr, "Error while fetching elf kernel from rom\n");
 exit(1);
 }
 
-#ifdef DEBUG_MULTIBOOT
-fprintf(stderr, "qemu: loading multiboot-elf kernel (%#x bytes) with 
entry %#zx\n",
-mb_kernel_size, (size_t)mh_entry_addr);
-#endif
+mb_debug("qemu: loading multiboot-elf kernel (%#x bytes) with entry 
%#zx\n",
+  mb_kernel_size, (size_t)mh_entry_addr);
 } else {
 /* Valid if mh_flags sets MULTIBOOT_HEADER_HAS_ADDR