From 8e24af7bda0b6c013c4afd6bc294ecceb1edc928 Mon Sep 17 00:00:00 2001
From: Matt Borgerson <contact@mborgerson.com>
Date: Tue, 26 Jun 2018 14:45:02 -0700
Subject: [PATCH] Fix basic Xbox machine init

---
 hw/xbox/xbox.c     | 604 ++++++++++++++++++++++++++++++---------------
 hw/xbox/xbox.h     |  36 ++-
 hw/xbox/xbox_pci.c | 184 +++++---------
 hw/xbox/xbox_pci.h |   7 +-
 4 files changed, 497 insertions(+), 334 deletions(-)

diff --git a/hw/xbox/xbox.c b/hw/xbox/xbox.c
index 8efc9f82a9..b3e75751b8 100644
--- a/hw/xbox/xbox.c
+++ b/hw/xbox/xbox.c
@@ -2,8 +2,9 @@
  * QEMU Xbox System Emulator
  *
  * Copyright (c) 2012 espes
+ * Copyright (c) 2018 Matt Borgerson
  *
- * Based on pc.c
+ * Based on pc.c and pc_piix.c
  * Copyright (c) 2003-2004 Fabrice Bellard
  *
  * This program is free software; you can redistribute it and/or
@@ -20,64 +21,112 @@
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "qemu/osdep.h"
 #include "hw/hw.h"
-#include "sysemu/arch_init.h"
+#include "hw/loader.h"
 #include "hw/i386/pc.h"
+#include "hw/i386/apic.h"
+#include "hw/smbios/smbios.h"
 #include "hw/pci/pci.h"
+#include "hw/pci/pci_ids.h"
+#include "hw/usb.h"
+#include "net/net.h"
 #include "hw/boards.h"
 #include "hw/ide.h"
-#include "hw/timer/mc146818rtc.h"
-#include "hw/timer/i8254.h"
-#include "hw/audio/pcspk.h"
+#include "sysemu/kvm.h"
+#include "hw/kvm/clock.h"
 #include "sysemu/sysemu.h"
-#include "hw/cpu/icc_bus.h"
 #include "hw/sysbus.h"
+#include "sysemu/arch_init.h"
 #include "hw/i2c/smbus.h"
-#include "sysemu/blockdev.h"
-#include "hw/loader.h"
+#include "hw/xen/xen.h"
+#include "exec/memory.h"
 #include "exec/address-spaces.h"
+#include "hw/acpi/acpi.h"
+#include "cpu.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#ifdef CONFIG_XEN
+#include <xen/hvm/hvm_info_table.h>
+#include "hw/xen/xen_pt.h"
+#endif
+#include "migration/global_state.h"
+#include "migration/misc.h"
+#include "kvm_i386.h"
+#include "sysemu/numa.h"
 
-#include "hw/xbox/xbox_pci.h"
-#include "hw/xbox/nv2a.h"
+#include "hw/timer/mc146818rtc.h"
+#include "xbox_pci.h"
+#include "smbus.h"
 
-#include "hw/xbox/xbox.h"
+#include "qemu/option.h"
+#include "xbox.h"
 
-#include "net/net.h"
+#define MAX_IDE_BUS 2
 
-/* mostly from pc_memory_init */
-static void xbox_memory_init(MemoryRegion *system_memory,
-                             ram_addr_t mem_size,
-                             MemoryRegion *rom_memory,
-                             MemoryRegion **ram_memory)
+static char *machine_get_bootrom(Object *obj, Error **errp);
+static void machine_set_bootrom(Object *obj, const char *value,
+                                        Error **errp);
+static void machine_set_short_animation(Object *obj, bool value,
+                                        Error **errp);
+static bool machine_get_short_animation(Object *obj, Error **errp);
+
+// XBOX_TODO: Should be passed in through configuration
+/* bunnie's eeprom */
+const uint8_t default_eeprom[] = {
+    0xe3, 0x1c, 0x5c, 0x23, 0x6a, 0x58, 0x68, 0x37,
+    0xb7, 0x12, 0x26, 0x6c, 0x99, 0x11, 0x30, 0xd1,
+    0xe2, 0x3e, 0x4d, 0x56, 0xf7, 0x73, 0x2b, 0x73,
+    0x85, 0xfe, 0x7f, 0x0a, 0x08, 0xef, 0x15, 0x3c,
+    0x77, 0xee, 0x6d, 0x4e, 0x93, 0x2f, 0x28, 0xee,
+    0xf8, 0x61, 0xf7, 0x94, 0x17, 0x1f, 0xfc, 0x11,
+    0x0b, 0x84, 0x44, 0xed, 0x31, 0x30, 0x35, 0x35,
+    0x38, 0x31, 0x31, 0x31, 0x34, 0x30, 0x30, 0x33,
+    0x00, 0x50, 0xf2, 0x4f, 0x65, 0x52, 0x00, 0x00,
+    0x0a, 0x1e, 0x35, 0x33, 0x71, 0x85, 0x31, 0x4d,
+    0x59, 0x12, 0x38, 0x48, 0x1c, 0x91, 0x53, 0x60,
+    0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x75, 0x61, 0x57, 0xfb, 0x2c, 0x01, 0x00, 0x00,
+    0x45, 0x53, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x0a, 0x05, 0x00, 0x02, 0x04, 0x01, 0x00, 0x02,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0xc4, 0xff, 0xff, 0xff,
+    0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static void xbox_flash_init(MemoryRegion *rom_memory)
 {
-    MemoryRegion *ram;
-
-    int ret;
     char *filename;
     int bios_size;
+    int bootrom_size;
+
     MemoryRegion *bios;
-
     MemoryRegion *map_bios;
+
     uint32_t map_loc;
+    int rc, fd = -1;
 
-    /* Allocate RAM.  We allocate it as a single memory region and use
-     * aliases to address portions of it, mostly for backwards compatibility
-     * with older qemus that used qemu_ram_alloc().
-     */
-    ram = g_malloc(sizeof(*ram));
-    memory_region_init_ram(ram, NULL, "xbox.ram", mem_size);
-    vmstate_register_ram_global(ram);
-    *ram_memory = ram;
-    memory_region_add_subregion(system_memory, 0, ram);
+    char *bios_data;
 
-
-    /* Load the bios. (mostly from pc_sysfw)
-     * Can't use it verbatim, since we need the bios repeated
-     * over top 1MB of memory.
-     */
+    /* Locate BIOS ROM image */
     if (bios_name == NULL) {
         bios_name = "bios.bin";
     }
+
     filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
     if (filename) {
         bios_size = get_image_size(filename);
@@ -88,122 +137,266 @@ static void xbox_memory_init(MemoryRegion *system_memory,
         (bios_size % 65536) != 0) {
         goto bios_error;
     }
-    bios = g_malloc(sizeof(*bios));
-    memory_region_init_ram(bios, NULL, "xbox.bios", bios_size);
-    vmstate_register_ram_global(bios);
-    memory_region_set_readonly(bios, true);
-    ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
-    if (ret != 0) {
-bios_error:
-        fprintf(stderr, "qemu: could not load xbox BIOS '%s'\n", bios_name);
-        exit(1);
-    }
-    if (filename) {
+
+    /* Read BIOS ROM into memory */
+    bios_data = g_malloc(bios_size);
+    assert(bios_data != NULL);
+    fd = open(filename, O_RDONLY | O_BINARY);
+    assert(fd >= 0);
+    rc = read(fd, bios_data, bios_size);
+    assert(rc == bios_size);
+    close(fd);
+    g_free(filename);
+
+    /* XBOX_FIXME: What follows is a big hack to overlay the MCPX ROM on the
+     * top 512 bytes of the ROM region. This differs from original XQEMU
+     * sources which copied it in at lpc init; new QEMU seems to be different
+     * now in that the BIOS images supplied to rom_add_file_fixed will be
+     * loaded *after* lpc init is called, so the MCPX ROM would get
+     * overwritten. Instead, let's just map it in right here while we map in
+     * BIOS.
+     *
+     * Anyway it behaves the same as before--that is, wrongly. Really, we
+     * should let the CPU execute from MMIO emulating the TSOP access with
+     * bootrom overlay being controlled by the magic bit..but this is "good
+     * enough" for now ;).
+     */
+
+    /* Locate and overlay MCPX ROM image into new copy of BIOS if provided */
+    const char *bootrom_file = object_property_get_str(qdev_get_machine(),
+                                                       "bootrom", NULL);
+
+    if ((bootrom_file != NULL) && *bootrom_file) {
+        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bootrom_file);
+        assert(filename);
+
+        bootrom_size = get_image_size(filename);
+        if (bootrom_size != 512) {
+            fprintf(stderr, "MCPX bootrom should be 512 bytes, got %d\n",
+                    bootrom_size);
+            exit(1);
+            return;
+        }
+
+        /* Read in MCPX ROM over last 512 bytes of BIOS data */
+        fd = open(filename, O_RDONLY | O_BINARY);
+        assert(fd >= 0);
+        rc = read(fd, &bios_data[bios_size - bootrom_size], bootrom_size);
+        assert(rc == bootrom_size);
+        close(fd);
         g_free(filename);
     }
 
+    /* Create BIOS region */
+    bios = g_malloc(sizeof(*bios));
+    assert(bios != NULL);
+    memory_region_init_ram(bios, NULL, "xbox.bios", bios_size, &error_fatal);
+    memory_region_set_readonly(bios, true);
+    rom_add_blob_fixed("xbox.bios", bios_data, bios_size,
+                       (uint32_t)(-2 * bios_size));
 
-    /* map the bios repeated at the top of memory */
-    for (map_loc=(uint32_t)(-bios_size); map_loc >= 0xff000000; map_loc-=bios_size) {
+    /* Assuming bios_data will be needed for duration of execution
+     * so no free(bios) here.
+     */
+
+    /* Mirror ROM from 0xff000000 - 0xffffffff */
+    for (map_loc = (uint32_t)(-bios_size);
+         map_loc >= 0xff000000;
+         map_loc -= bios_size) {
         map_bios = g_malloc(sizeof(*map_bios));
-        memory_region_init_alias(map_bios, NULL, NULL, bios, 0, bios_size);
-
+        memory_region_init_alias(map_bios, NULL, "pci-bios", bios, 0, bios_size);
         memory_region_add_subregion(rom_memory, map_loc, map_bios);
         memory_region_set_readonly(map_bios, true);
     }
 
-    /*memory_region_add_subregion(rom_memory,
-                                (uint32_t)(-bios_size),
-                                bios);
-    */
+    return;
 
+bios_error:
+    fprintf(stderr, "qemu: could not load xbox BIOS '%s'\n", bios_name);
+    exit(1);
 }
 
-/* mostly from pc_init1 */
-void xbox_init_common(QEMUMachineInitArgs *args,
-                      const uint8_t *default_eeprom,
-                      ISABus **out_isa_bus)
+static void xbox_memory_init(PCMachineState *pcms,
+                             MemoryRegion *system_memory,
+                             MemoryRegion *rom_memory,
+                             MemoryRegion **ram_memory)
 {
-    int i;
-    ram_addr_t ram_size = args->ram_size;
-    const char *cpu_model = args->cpu_model;
+    // int linux_boot, i;
+    MemoryRegion *ram;//, *option_rom_mr;
+    // FWCfgState *fw_cfg;
+    MachineState *machine = MACHINE(pcms);
+    // PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
 
-    PCIBus *host_bus;
+    // linux_boot = (machine->kernel_filename != NULL);
+
+    /* Allocate RAM.  We allocate it as a single memory region and use
+     * aliases to address portions of it, mostly for backwards compatibility
+     * with older qemus that used qemu_ram_alloc().
+     */
+    ram = g_malloc(sizeof(*ram));
+    memory_region_init_ram(ram, NULL, "xbox.ram",
+                           machine->ram_size, &error_fatal);
+
+    *ram_memory = ram;
+    memory_region_add_subregion(system_memory, 0, ram);
+
+    xbox_flash_init(rom_memory);
+}
+
+
+/* FIXME: Move to header file */
+void nv2a_init(PCIBus *bus, int devfn, MemoryRegion *ram);
+
+#include "hw/timer/i8254.h"
+#include "hw/audio/pcspk.h"
+
+/* PC hardware initialisation */
+static void xbox_init(MachineState *machine)
+{
+    xbox_init_common(machine, default_eeprom, NULL, NULL);
+}
+
+void xbox_init_common(MachineState *machine,
+                      const uint8_t *eeprom,
+                      PCIBus **pci_bus_out,
+                      ISABus **isa_bus_out)
+{
+    PCMachineState *pcms = PC_MACHINE(machine);
+    PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
+
+    MemoryRegion *system_memory = get_system_memory();
+    // MemoryRegion *system_io = get_system_io();
+
+    int i;
+
+    PCIBus *pci_bus;
     ISABus *isa_bus;
 
+    qemu_irq *i8259;
+    // qemu_irq smi_irq; // XBOX_TODO: SMM support?
+
+    GSIState *gsi_state;
+
+    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
+    BusState *idebus[MAX_IDE_BUS];
+    ISADevice *rtc_state;
+    // ISADevice *pit;
+
     MemoryRegion *ram_memory;
     MemoryRegion *pci_memory;
+    MemoryRegion *rom_memory;
 
-    qemu_irq *cpu_irq;
-    qemu_irq *gsi;
-    qemu_irq *i8259;
-    GSIState *gsi_state;
-
-    PCIDevice *ide_dev;
-    BusState *idebus[MAX_IDE_BUS];
-
-    ISADevice *rtc_state;
-    ISADevice *pit;
-    i2c_bus *smbus;
+    I2CBus *smbus;
     PCIBus *agp_bus;
 
+    pc_cpus_init(pcms);
 
-    DeviceState *icc_bridge;
-    icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE);
-    object_property_add_child(qdev_get_machine(), "icc-bridge",
-                              OBJECT(icc_bridge), NULL);
-
-    pc_cpus_init(cpu_model, icc_bridge);
+    if (kvm_enabled() && pcmc->kvmclock_enabled) {
+        kvmclock_create();
+    }
 
     pci_memory = g_new(MemoryRegion, 1);
-    memory_region_init(pci_memory, NULL, "pci", INT64_MAX);
+    memory_region_init(pci_memory, NULL, "pci", UINT64_MAX);
+    rom_memory = pci_memory;
+
+    pc_guest_info_init(pcms);
 
     /* allocate ram and load rom/bios */
-    xbox_memory_init(get_system_memory(), ram_size,
-                     pci_memory, &ram_memory);
-
+    xbox_memory_init(pcms, system_memory, rom_memory, &ram_memory);
 
     gsi_state = g_malloc0(sizeof(*gsi_state));
-    gsi = qemu_allocate_irqs(gsi_handler, gsi_state, GSI_NUM_PINS);
+    pcms->gsi = qemu_allocate_irqs(gsi_handler, gsi_state, GSI_NUM_PINS);
 
-
-    /* init buses */
-    xbox_pci_init(gsi,
+    xbox_pci_init(pcms->gsi,
                   get_system_memory(), get_system_io(),
                   pci_memory, ram_memory,
-                  &host_bus,
+                  &pci_bus,
                   &isa_bus,
                   &smbus,
                   &agp_bus);
 
+    pcms->bus = pci_bus;
 
-    /* irq shit */
-    isa_bus_irqs(isa_bus, gsi);
-    cpu_irq = pc_allocate_cpu_irq();
-    i8259 = i8259_init(isa_bus, cpu_irq[0]);
+    isa_bus_irqs(isa_bus, pcms->gsi);
+
+    // if (kvm_pic_in_kernel()) {
+    //     i8259 = kvm_i8259_init(isa_bus);
+    // } else if (xen_enabled()) {
+    //     i8259 = xen_interrupt_controller_init();
+    // } else {
+        i8259 = i8259_init(isa_bus, pc_allocate_cpu_irq());
+    // }
 
     for (i = 0; i < ISA_NUM_IRQS; i++) {
         gsi_state->i8259_irq[i] = i8259[i];
     }
+    g_free(i8259);
 
+    // if (pcmc->pci_enabled) {
+    //     ioapic_init_gsi(gsi_state, "i440fx");
+    // }
 
-    /* basic device init */
-    rtc_state = rtc_init(isa_bus, 2000, NULL);
-    pit = pit_init(isa_bus, 0x40, 0, NULL);
+    pc_register_ferr_irq(pcms->gsi[13]);
 
-    /* does apparently have a pc speaker, though not used? */
+    // pc_vga_init(isa_bus, pcmc->pci_enabled ? pci_bus : NULL);
+
+    assert(pcms->vmport != ON_OFF_AUTO__MAX);
+    if (pcms->vmport == ON_OFF_AUTO_AUTO) {
+        pcms->vmport = xen_enabled() ? ON_OFF_AUTO_OFF : ON_OFF_AUTO_ON;
+    }
+
+    /* init basic PC hardware */
+    pcms->pit = 1; // XBOX_FIXME: What's the right way to do this?
+    // pc_basic_device_init(isa_bus, pcms->gsi, &rtc_state, true,
+    //                      (pcms->vmport != ON_OFF_AUTO_ON), pcms->pit, 0x4);
+    rtc_state = mc146818_rtc_init(isa_bus, 2000, NULL);
+
+    // qemu_register_boot_set(pc_boot_set, rtc_state);
+    ISADevice *pit = NULL;
+
+    if (kvm_pit_in_kernel()) {
+        pit = kvm_pit_init(isa_bus, 0x40);
+    } else {
+        pit = i8254_pit_init(isa_bus, 0x40, 0, NULL);
+    }
+    // if (hpet) {
+    //     /* connect PIT to output control line of the HPET */
+    //     qdev_connect_gpio_out(hpet, 0, qdev_get_gpio_in(DEVICE(pit), 0));
+    // }
     pcspk_init(isa_bus, pit);
 
-    /* IDE shit
-     * piix3's ide be right for now, maybe
-     */
-    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
-    ide_drive_get(hd, MAX_IDE_BUS);
-    ide_dev = pci_piix3_ide_init(host_bus, hd, PCI_DEVFN(9, 0));
+    // i8257_dma_init(isa_bus, 0);
+
+    // pc_nic_init(pcmc, isa_bus, pci_bus);
+
+    ide_drive_get(hd, ARRAY_SIZE(hd));
+    // if (pcmc->pci_enabled) {
+        PCIDevice *dev;
+        // if (xen_enabled()) {
+            // dev = pci_piix3_xen_ide_init(pci_bus, hd, piix3_devfn + 1);
+        // } else {
+            dev = pci_piix3_ide_init(pci_bus, hd, PCI_DEVFN(9, 0));
+        // }
+        idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0");
+        idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1");
+    // } else {
+    //     for(i = 0; i < MAX_IDE_BUS; i++) {
+    //         ISADevice *dev;
+    //         char busname[] = "ide.0";
+    //         dev = isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i],
+    //                            ide_irq[i],
+    //                            hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]);
+    //         /*
+    //          * The ide bus name is ide.0 for the first bus and ide.1 for the
+    //          * second one.
+    //          */
+    //         busname[4] = '0' + i;
+    //         idebus[i] = qdev_get_child_bus(DEVICE(dev), busname);
+    //     }
+    // }
+
+    pc_cmos_init(pcms, idebus[0], idebus[1], rtc_state);
 
-    idebus[0] = qdev_get_child_bus(&ide_dev->qdev, "ide.0");
-    idebus[1] = qdev_get_child_bus(&ide_dev->qdev, "ide.1");
-    
     // xbox bios wants this bit pattern set to mark the data as valid
     uint8_t bits = 0x55;
     for (i = 0x10; i < 0x70; i++) {
@@ -218,25 +411,24 @@ void xbox_init_common(QEMUMachineInitArgs *args,
 
     /* smbus devices */
     uint8_t *eeprom_buf = g_malloc0(256);
-    memcpy(eeprom_buf, default_eeprom, 256);
+    memcpy(eeprom_buf, eeprom, 256);
     smbus_eeprom_init_single(smbus, 0x54, eeprom_buf);
-    
+
     smbus_xbox_smc_init(smbus, 0x10);
     smbus_cx25871_init(smbus, 0x45);
     smbus_adm1032_init(smbus, 0x4c);
 
-
     /* USB */
-    PCIDevice *usb1 = pci_create(host_bus, PCI_DEVFN(3, 0), "pci-ohci");
+    PCIDevice *usb1 = pci_create(pci_bus, PCI_DEVFN(3, 0), "pci-ohci");
     qdev_prop_set_uint32(&usb1->qdev, "num-ports", 4);
     qdev_init_nofail(&usb1->qdev);
 
-    PCIDevice *usb0 = pci_create(host_bus, PCI_DEVFN(2, 0), "pci-ohci");
+    PCIDevice *usb0 = pci_create(pci_bus, PCI_DEVFN(2, 0), "pci-ohci");
     qdev_prop_set_uint32(&usb0->qdev, "num-ports", 4);
     qdev_init_nofail(&usb0->qdev);
 
     /* Ethernet! */
-    PCIDevice *nvnet = pci_create(host_bus, PCI_DEVFN(4, 0), "nvnet");
+    PCIDevice *nvnet = pci_create(pci_bus, PCI_DEVFN(4, 0), "nvnet");
 
     for (i = 0; i < nb_nics; i++) {
         NICInfo *nd = &nd_table[i];
@@ -246,113 +438,115 @@ void xbox_init_common(QEMUMachineInitArgs *args,
     }
 
     /* APU! */
-    PCIDevice *apu = pci_create_simple(host_bus, PCI_DEVFN(5, 0), "mcpx-apu");
+    pci_create_simple(pci_bus, PCI_DEVFN(5, 0), "mcpx-apu");
 
     /* ACI! */
-    PCIDevice *aci = pci_create_simple(host_bus, PCI_DEVFN(6, 0), "mcpx-aci");
+    pci_create_simple(pci_bus, PCI_DEVFN(6, 0), "mcpx-aci");
 
     /* GPU! */
     nv2a_init(agp_bus, PCI_DEVFN(0, 0), ram_memory);
 
-    *out_isa_bus = isa_bus;
+    if (pci_bus_out) {
+        *pci_bus_out = pci_bus;
+    }
+    if (isa_bus_out) {
+        *isa_bus_out = isa_bus;
+    }
 }
 
-static void xbox_init(QEMUMachineInitArgs *args)
+static void xbox_machine_options(MachineClass *m)
 {
-#if 0
-    /* Placeholder blank eeprom for xbox 1.0:
-     *   Serial number 000000000000
-     *   Mac address 00:00:00:00:00:00
-     *   ...etc.
-     */
-    const uint8_t eeprom[] = {
-        0x25, 0x42, 0x88, 0x24, 0xA3, 0x1A, 0x7D, 0xF4,
-        0xEE, 0x53, 0x3F, 0x39, 0x5D, 0x27, 0x98, 0x0E,
-        0x58, 0xB3, 0x26, 0xC3, 0x70, 0x82, 0xE5, 0xC6,
-        0xF7, 0xC5, 0x54, 0x38, 0xA0, 0x58, 0xB9, 0x5D,
-        0xB7, 0x27, 0xC7, 0xB1, 0x67, 0xCF, 0x99, 0x3E,
-        0xC8, 0x6E, 0xC8, 0x53, 0xEF, 0x7C, 0x01, 0x37,
-        0x6F, 0x6E, 0x2F, 0x6F, 0x30, 0x30, 0x30, 0x30,
-        0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-    };
-#endif
-    /* bunnie's eeprom */
-    const uint8_t eeprom[] = {
-        0xe3, 0x1c, 0x5c, 0x23, 0x6a, 0x58, 0x68, 0x37,
-        0xb7, 0x12, 0x26, 0x6c, 0x99, 0x11, 0x30, 0xd1,
-        0xe2, 0x3e, 0x4d, 0x56, 0xf7, 0x73, 0x2b, 0x73,
-        0x85, 0xfe, 0x7f, 0x0a, 0x08, 0xef, 0x15, 0x3c,
-        0x77, 0xee, 0x6d, 0x4e, 0x93, 0x2f, 0x28, 0xee,
-        0xf8, 0x61, 0xf7, 0x94, 0x17, 0x1f, 0xfc, 0x11,
-        0x0b, 0x84, 0x44, 0xed, 0x31, 0x30, 0x35, 0x35,
-        0x38, 0x31, 0x31, 0x31, 0x34, 0x30, 0x30, 0x33,
-        0x00, 0x50, 0xf2, 0x4f, 0x65, 0x52, 0x00, 0x00,
-        0x0a, 0x1e, 0x35, 0x33, 0x71, 0x85, 0x31, 0x4d,
-        0x59, 0x12, 0x38, 0x48, 0x1c, 0x91, 0x53, 0x60,
-        0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x75, 0x61, 0x57, 0xfb, 0x2c, 0x01, 0x00, 0x00,
-        0x45, 0x53, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x0a, 0x05, 0x00, 0x02, 0x04, 0x01, 0x00, 0x02,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0xc4, 0xff, 0xff, 0xff,
-        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-    };
+    PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+    m->desc              = "Microsoft Xbox";
+    m->max_cpus          = 1;
+    m->option_rom_has_mr = true;
+    m->rom_file_has_mr   = false;
+    m->no_floppy         = 1,
+    m->no_cdrom          = 1,
+    m->no_sdcard         = 1,
+    m->default_cpu_type  = X86_CPU_TYPE_NAME("486");
 
-    ISABus *isa_bus;
-    xbox_init_common(args, eeprom, &isa_bus);
+    pcmc->pci_enabled         = true;
+    pcmc->has_acpi_build      = false;
+    pcmc->smbios_defaults     = false;
+    pcmc->gigabyte_align      = false;
+    pcmc->smbios_legacy_mode  = true;
+    pcmc->has_reserved_memory = false;
+    pcmc->default_nic_model   = "nvnet";
 }
 
-static QEMUMachine xbox_machine = {
-    .name = "xbox",
-    .desc = "Microsoft Xbox",
-    .init = xbox_init,
-    .max_cpus = 1,
-    .no_floppy = 1,
-    .no_cdrom = 1,
-    .no_sdcard = 1,
-    PC_DEFAULT_MACHINE_OPTIONS
+static char *machine_get_bootrom(Object *obj, Error **errp)
+{
+    XboxMachineState *ms = XBOX_MACHINE(obj);
+
+    return g_strdup(ms->bootrom);
+}
+
+static void machine_set_bootrom(Object *obj, const char *value,
+                                        Error **errp)
+{
+    XboxMachineState *ms = XBOX_MACHINE(obj);
+
+    g_free(ms->bootrom);
+    ms->bootrom = g_strdup(value);
+}
+
+static void machine_set_short_animation(Object *obj, bool value,
+                                        Error **errp)
+{
+    XboxMachineState *ms = XBOX_MACHINE(obj);
+
+    ms->short_animation = value;
+}
+
+static bool machine_get_short_animation(Object *obj, Error **errp)
+{
+    XboxMachineState *ms = XBOX_MACHINE(obj);
+    return ms->short_animation;
+}
+
+static inline void xbox_machine_initfn(Object *obj)
+{
+    object_property_add_str(obj, "bootrom", machine_get_bootrom,
+                            machine_set_bootrom, NULL);
+    object_property_set_description(obj, "bootrom",
+                                    "Xbox bootrom file", NULL);
+
+    object_property_add_bool(obj, "short-animation",
+                             machine_get_short_animation,
+                             machine_set_short_animation, NULL);
+    object_property_set_description(obj, "short-animation",
+                                    "Skip Xbox boot animation",
+                                    NULL);
+    object_property_set_bool(obj, false, "short-animation", NULL);
+
+}
+
+static void xbox_machine_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    xbox_machine_options(mc);
+    mc->init = xbox_init;
+}
+
+static const TypeInfo pc_machine_type_xbox = {
+    .name = TYPE_XBOX_MACHINE,
+    .parent = TYPE_PC_MACHINE,
+    .abstract = false,
+    .instance_size = sizeof(XboxMachineState),
+    .instance_init = xbox_machine_initfn,
+    .class_size = sizeof(XboxMachineClass),
+    .class_init = xbox_machine_class_init,
+    .interfaces = (InterfaceInfo[]) {
+         // { TYPE_HOTPLUG_HANDLER },
+         // { TYPE_NMI },
+         { }
+    },
 };
 
-static void xbox_machine_init(void) {
-    qemu_register_machine(&xbox_machine);
+static void pc_machine_init_xbox(void)
+{
+    type_register(&pc_machine_type_xbox);
 }
 
-machine_init(xbox_machine_init);
\ No newline at end of file
+type_init(pc_machine_init_xbox)
diff --git a/hw/xbox/xbox.h b/hw/xbox/xbox.h
index 9c0c6b1346..167f4d4dd6 100644
--- a/hw/xbox/xbox.h
+++ b/hw/xbox/xbox.h
@@ -2,6 +2,7 @@
  * QEMU Xbox System Emulator
  *
  * Copyright (c) 2013 espes
+ * Copyright (c) 2018 Matt Borgerson
  *
  * Based on pc.c
  * Copyright (c) 2003-2004 Fabrice Bellard
@@ -23,10 +24,37 @@
 #ifndef HW_XBOX_H
 #define HW_XBOX_H
 
+#include "hw/boards.h"
+
 #define MAX_IDE_BUS 2
 
-void xbox_init_common(QEMUMachineInitArgs *args,
-                      const uint8_t *default_eeprom,
-                      ISABus **out_isa_bus);
+void xbox_init_common(MachineState *machine,
+                      const uint8_t *eeprom,
+                      PCIBus **pci_bus_out,
+                      ISABus **isa_bus_out);
 
-#endif
\ No newline at end of file
+#define TYPE_XBOX_MACHINE MACHINE_TYPE_NAME("xbox")
+
+#define XBOX_MACHINE(obj) \
+    OBJECT_CHECK(XboxMachineState, (obj), TYPE_XBOX_MACHINE)
+
+#define XBOX_MACHINE_CLASS(klass) \
+    OBJECT_CLASS_CHECK(XboxMachineClass, (klass), TYPE_XBOX_MACHINE)
+
+typedef struct XboxMachineState {
+    /*< private >*/
+    PCMachineState parent_obj;
+
+    /*< public >*/
+    char *bootrom;
+    bool short_animation;
+} XboxMachineState;
+
+typedef struct XboxMachineClass {
+    /*< private >*/
+    PCMachineClass parent_class;
+
+    /*< public >*/
+} XboxMachineClass;
+
+#endif
diff --git a/hw/xbox/xbox_pci.c b/hw/xbox/xbox_pci.c
index 8e119536aa..ea166f0116 100644
--- a/hw/xbox/xbox_pci.c
+++ b/hw/xbox/xbox_pci.c
@@ -2,6 +2,7 @@
  * QEMU Xbox PCI buses implementation
  *
  * Copyright (c) 2012 espes
+ * Copyright (c) 2018 Matt Borgerson
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -16,28 +17,36 @@
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
+
+#include "qemu/osdep.h"
 #include "hw/hw.h"
-#include "qemu/range.h"
-#include "hw/isa/isa.h"
-#include "hw/sysbus.h"
-#include "hw/loader.h"
-#include "qemu/config-file.h"
 #include "hw/i386/pc.h"
 #include "hw/pci/pci.h"
+#include "hw/pci/pci_host.h"
+#include "hw/isa/isa.h"
+#include "hw/sysbus.h"
+#include "qapi/error.h"
+#include "qemu/range.h"
+#include "hw/xen/xen.h"
+#include "hw/pci-host/pam.h"
+#include "sysemu/sysemu.h"
+#include "hw/i386/ioapic.h"
+#include "qapi/visitor.h"
+#include "qemu/error-report.h"
+#include "hw/loader.h"
+#include "qemu/config-file.h"
 #include "hw/pci/pci_bus.h"
 #include "hw/pci/pci_bridge.h"
 #include "exec/address-spaces.h"
 #include "qemu-common.h"
-
+#include "qemu/option.h"
 #include "hw/xbox/acpi_xbox.h"
 #include "hw/xbox/amd_smbus.h"
-
 #include "hw/xbox/xbox_pci.h"
 
-
  /*
   * xbox chipset based on nForce 420, which was based on AMD-760
-  * 
+  *
   * http://support.amd.com/us/ChipsetMotherboard_TechDocs/24494.pdf
   * http://support.amd.com/us/ChipsetMotherboard_TechDocs/24416.pdf
   * http://support.amd.com/us/ChipsetMotherboard_TechDocs/24467.pdf
@@ -57,8 +66,6 @@
 # define XBOXPCI_DPRINTF(format, ...)     do { } while (0)
 #endif
 
-
-
 #define XBOX_NUM_INT_IRQS 8
 #define XBOX_NUM_PIRQS    4
 
@@ -80,7 +87,7 @@ static void xbox_lpc_set_irq(void *opaque, int pirq, int level)
     if (pirq < XBOX_NUM_INT_IRQS) {
         /* devices on the internal bus */
         uint32_t routing = pci_get_long(lpc->dev.config + XBOX_LPC_INT_IRQ_ROUT);
-        pic_irq = (routing >> (pirq*4)) & 0xF;
+        pic_irq = (routing >> (pirq * 4)) & 0xF;
 
         if (pic_irq == 0) {
             return;
@@ -124,7 +131,7 @@ static void xbox_lpc_set_acpi_irq(void *opaque, int irq_num, int level)
     assert(irq_num == 0 || irq_num == 1);
 
     uint32_t routing = pci_get_long(lpc->dev.config + XBOX_LPC_ACPI_IRQ_ROUT);
-    int irq = (routing >> (irq_num*8)) & 0xff;
+    int irq = (routing >> (irq_num * 8)) & 0xff;
 
     if (irq == 0 || irq >= XBOX_NUM_PIC_IRQS) {
         return;
@@ -132,8 +139,6 @@ static void xbox_lpc_set_acpi_irq(void *opaque, int irq_num, int level)
     qemu_set_irq(lpc->pic[irq], level);
 }
 
-
-
 void xbox_pci_init(qemu_irq *pic,
                    MemoryRegion *address_space_mem,
                    MemoryRegion *address_space_io,
@@ -141,7 +146,7 @@ void xbox_pci_init(qemu_irq *pic,
                    MemoryRegion *ram_memory,
                    PCIBus **out_host_bus,
                    ISABus **out_isa_bus,
-                   i2c_bus **out_smbus,
+                   I2CBus **out_smbus,
                    PCIBus **out_agp_bus)
 {
     DeviceState *host;
@@ -154,7 +159,7 @@ void xbox_pci_init(qemu_irq *pic,
     host = qdev_create(NULL, "xbox-pcihost");
     host_state = PCI_HOST_BRIDGE(host);
 
-    host_bus = pci_bus_new(host, NULL,
+    host_bus = pci_root_bus_new(host, NULL,
                            pci_memory, address_space_io, 0, TYPE_PCI_BUS);
     host_state->bus = host_bus;
     qdev_init_nofail(host);
@@ -172,7 +177,7 @@ void xbox_pci_init(qemu_irq *pic,
                              "pci-hole",
                              bridge_state->pci_address_space,
                              ram_size,
-                             0x100000000ULL - ram_size);    
+                             0x100000000ULL - ram_size);
     memory_region_add_subregion(bridge_state->system_memory, ram_size,
                                 &bridge_state->pci_hole);
 
@@ -191,9 +196,9 @@ void xbox_pci_init(qemu_irq *pic,
     xbox_pm_init(lpc, &lpc_state->pm, acpi_irq[0]);
     //xbox_lpc_reset(&s->dev.qdev);
 
-
     /* smbus */
-    PCIDevice *smbus = pci_create_simple_multifunction(host_bus, PCI_DEVFN(1, 1),
+    PCIDevice *smbus = pci_create_simple_multifunction(host_bus,
+                                                       PCI_DEVFN(1, 1),
                                                        true, "xbox-smbus");
 
     XBOX_SMBState *smbus_state = XBOX_SMBUS_DEVICE(smbus);
@@ -206,15 +211,12 @@ void xbox_pci_init(qemu_irq *pic,
     //qdev_init_nofail(qdev);
     PCIBus *agp_bus = pci_bridge_get_sec_bus(PCI_BRIDGE(agp));
 
-
-
     *out_host_bus = host_bus;
     *out_isa_bus = lpc_state->isa_bus;
     *out_smbus = smbus_state->smb.smbus;
     *out_agp_bus = agp_bus;
 }
 
-
 #define XBOX_SMBUS_BASE_BAR 1
 
 static void xbox_smb_ioport_writeb(void *opaque, hwaddr addr,
@@ -245,7 +247,7 @@ static const MemoryRegionOps xbox_smbus_ops = {
     },
 };
 
-static int xbox_smbus_initfn(PCIDevice *dev)
+static void xbox_smbus_realize(PCIDevice *dev, Error **errp)
 {
     XBOX_SMBState *s = XBOX_SMBUS_DEVICE(dev);
 
@@ -253,24 +255,21 @@ static int xbox_smbus_initfn(PCIDevice *dev)
                           s, "xbox-smbus-bar", 32);
     pci_register_bar(dev, XBOX_SMBUS_BASE_BAR, PCI_BASE_ADDRESS_SPACE_IO,
                      &s->smb_bar);
-
-    return 0;
 }
 
-
 static void xbox_smbus_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
-    k->init         = xbox_smbus_initfn;
+    k->realize      = xbox_smbus_realize;
     k->vendor_id    = PCI_VENDOR_ID_NVIDIA;
     k->device_id    = PCI_DEVICE_ID_NVIDIA_NFORCE_SMBUS;
     k->revision     = 161;
     k->class_id     = PCI_CLASS_SERIAL_SMBUS;
 
     dc->desc        = "nForce PCI System Management";
-    dc->no_user     = 1;
+    dc->user_creatable = false;
 }
 
 static const TypeInfo xbox_smbus_info = {
@@ -278,84 +277,31 @@ static const TypeInfo xbox_smbus_info = {
     .parent = TYPE_PCI_DEVICE,
     .instance_size = sizeof(XBOX_SMBState),
     .class_init = xbox_smbus_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
+        { },
+    },
 };
 
-
-
-static int xbox_lpc_initfn(PCIDevice *d)
+static void xbox_lpc_realize(PCIDevice *dev, Error **errp)
 {
-    XBOX_LPCState *s = XBOX_LPC_DEVICE(d);
+    XBOX_LPCState *d = XBOX_LPC_DEVICE(dev);
     ISABus *isa_bus;
 
-    isa_bus = isa_bus_new(&d->qdev, get_system_io());
-    s->isa_bus = isa_bus;
-
-
-    /* southbridge chip contains and controls bootrom image.
-     * can't load it through loader.c because it overlaps with the bios...
-     * We really should just commandeer the entire top 16Mb.
-     */
-    QemuOpts *machine_opts = qemu_opts_find(qemu_find_opts("machine"), NULL);
-    if (machine_opts) {
-        const char *bootrom_file = qemu_opt_get(machine_opts, "bootrom");
-
-        int rc, fd = -1;
-        if (bootrom_file) {
-            char *filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bootrom_file);
-            assert(filename);
-
-            s->bootrom_size = get_image_size(filename);
-            if (s->bootrom_size != 512) {
-                fprintf(stderr, "MCPX bootrom should be 512 bytes, got %d\n",
-                        s->bootrom_size);
-                return -1;
-            }
-
-            fd = open(filename, O_RDONLY | O_BINARY);
-            assert(fd >= 0);
-            rc = read(fd, s->bootrom_data, s->bootrom_size);
-            assert(rc == s->bootrom_size);
-
-            close(fd);
-        }
+    isa_bus = isa_bus_new(DEVICE(d), get_system_memory(),
+                          pci_address_space_io(dev), errp);
+    if (isa_bus == NULL) {
+        return;
     }
-
-
-    return 0;
+    d->isa_bus = isa_bus;
 }
 
-
-
 static void xbox_lpc_reset(DeviceState *dev)
 {
-    PCIDevice *d = PCI_DEVICE(dev);
-    XBOX_LPCState *s = XBOX_LPC_DEVICE(d);
-
-
-    if (s->bootrom_size) {
-        /* qemu's memory region shit is actually kinda broken -
-         * Trying to execute off a non-page-aligned memory region
-         * is fucked, so we can't just map in the bootrom.
-         *
-         * We need to be able to disable it at runtime, and
-         * it shouldn't be visible ontop of the bios mirrors. It'll have to
-         * be a hack.
-         *
-         * Be lazy for now and just write it ontop of the bios.
-         *
-         * (We do this here since loader.c loads roms into memory in a reset
-         * handler, and here we /should/ be handled after it.)
-         */
-
-        hwaddr bootrom_addr = (uint32_t)(-s->bootrom_size);
-        cpu_physical_memory_write_rom(bootrom_addr,
-                                      s->bootrom_data,
-                                      s->bootrom_size);
-     }
-
+    // PCIDevice *d = PCI_DEVICE(dev);
+    // XBOX_LPCState *s = XBOX_LPC_DEVICE(d);
 }
 
-
 #if 0
 /* Xbox 1.1 uses a config register instead of a bar to set the pm base address */
 #define XBOX_LPC_PMBASE 0x84
@@ -409,8 +355,8 @@ static void xbox_lpc_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
-    k->no_hotplug   = 1;
-    k->init         = xbox_lpc_initfn;
+    dc->hotpluggable = false;
+    k->realize      = xbox_lpc_realize;
     //k->config_write = xbox_lpc_config_write;
     k->vendor_id    = PCI_VENDOR_ID_NVIDIA;
     k->device_id    = PCI_DEVICE_ID_NVIDIA_NFORCE_LPC;
@@ -418,7 +364,7 @@ static void xbox_lpc_class_init(ObjectClass *klass, void *data)
     k->class_id     = PCI_CLASS_BRIDGE_ISA;
 
     dc->desc        = "nForce LPC Bridge";
-    dc->no_user     = 1;
+    dc->user_creatable = false;
     dc->reset       = xbox_lpc_reset;
     //dc->vmsd        = &vmstate_xbox_lpc;
 }
@@ -428,16 +374,17 @@ static const TypeInfo xbox_lpc_info = {
     .parent = TYPE_PCI_DEVICE,
     .instance_size = sizeof(XBOX_LPCState),
     .class_init = xbox_lpc_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
+        { },
+    },
 };
 
-
-
-
-static int xbox_agp_initfn(PCIDevice *d)
+static void xbox_agp_realize(PCIDevice *d, Error **errp)
 {
     pci_set_word(d->config + PCI_PREF_MEMORY_BASE, PCI_PREF_RANGE_TYPE_32);
     pci_set_word(d->config + PCI_PREF_MEMORY_LIMIT, PCI_PREF_RANGE_TYPE_32);
-    return pci_bridge_initfn(d, TYPE_PCI_BUS);
+    pci_bridge_initfn(d, TYPE_PCI_BUS);
 }
 
 static void xbox_agp_class_init(ObjectClass *klass, void *data)
@@ -445,7 +392,7 @@ static void xbox_agp_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
-    k->init         = xbox_agp_initfn;
+    k->realize      = xbox_agp_realize;
     k->exit         = pci_bridge_exitfn;
     k->config_write = pci_bridge_write_config;
     k->is_bridge    = 1;
@@ -462,18 +409,15 @@ static const TypeInfo xbox_agp_info = {
     .parent        = TYPE_PCI_BRIDGE,
     .instance_size = sizeof(PCIBridge),
     .class_init    = xbox_agp_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
+        { },
+    },
 };
 
-
-
-
-
-
-static int xbox_pci_initfn(PCIDevice *d)
+static void xbox_pci_realize(PCIDevice *d, Error **errp)
 {
     //XBOX_PCIState *s = DO_UPCAST(XBOX_PCIState, dev, dev);
-
-    return 0;
 }
 
 static void xbox_pci_class_init(ObjectClass *klass, void *data)
@@ -481,8 +425,8 @@ static void xbox_pci_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
-    k->no_hotplug = 1;
-    k->init = xbox_pci_initfn;
+    dc->hotpluggable = false;
+    k->realize = xbox_pci_realize;
     //k->config_write = xbox_pci_write_config;
     k->vendor_id = PCI_VENDOR_ID_NVIDIA;
     k->device_id = PCI_DEVICE_ID_NVIDIA_XBOX_PCHB;
@@ -490,7 +434,7 @@ static void xbox_pci_class_init(ObjectClass *klass, void *data)
     k->class_id = PCI_CLASS_BRIDGE_HOST;
 
     dc->desc = "Xbox PCI Host";
-    dc->no_user = 1;
+    dc->user_creatable = false;
 }
 
 static const TypeInfo xbox_pci_info = {
@@ -498,10 +442,12 @@ static const TypeInfo xbox_pci_info = {
     .parent        = TYPE_PCI_DEVICE,
     .instance_size = sizeof(XBOX_PCIState),
     .class_init    = xbox_pci_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
+        { },
+    },
 };
 
-
-
 #define CONFIG_ADDR 0xcf8
 #define CONFIG_DATA 0xcfc
 
@@ -524,14 +470,13 @@ static int xbox_pcihost_initfn(SysBusDevice *dev)
     return 0;
 }
 
-
 static void xbox_pcihost_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = xbox_pcihost_initfn;
-    dc->no_user = 1;
+    dc->user_creatable = false;
 }
 
 static const TypeInfo xbox_pcihost_info = {
@@ -541,7 +486,6 @@ static const TypeInfo xbox_pcihost_info = {
     .class_init    = xbox_pcihost_class_init,
 };
 
-
 static void xboxpci_register_types(void)
 {
     type_register(&xbox_pcihost_info);
diff --git a/hw/xbox/xbox_pci.h b/hw/xbox/xbox_pci.h
index 8cd24670c6..e9c9cdff19 100644
--- a/hw/xbox/xbox_pci.h
+++ b/hw/xbox/xbox_pci.h
@@ -31,7 +31,6 @@
 #include "hw/acpi/acpi.h"
 #include "hw/xbox/acpi_xbox.h"
 
-
 typedef struct XBOX_PCIState {
     PCIDevice dev;
 
@@ -68,8 +67,6 @@ typedef struct XBOX_LPCState {
 #define XBOX_LPC_DEVICE(obj) \
     OBJECT_CHECK(XBOX_LPCState, (obj), "xbox-lpc")
 
-
-
 void xbox_pci_init(qemu_irq *pic,
                    MemoryRegion *address_space_mem,
                    MemoryRegion *address_space_io,
@@ -77,7 +74,7 @@ void xbox_pci_init(qemu_irq *pic,
                    MemoryRegion *ram_memory,
                    PCIBus **out_host_bus,
                    ISABus **out_isa_bus,
-                   i2c_bus **out_smbus,
+                   I2CBus **out_smbus,
                    PCIBus **out_agp_bus);
 
-#endif
\ No newline at end of file
+#endif