]> Git Repo - qemu.git/blobdiff - hw/mips_malta.c
savevm: Factorize ram globals reset in its own function
[qemu.git] / hw / mips_malta.c
index 0110daa1a359199857d289737011ba7b8a018497..632b466e32454e8ede1597ebe0e67d6f8427e445 100644 (file)
@@ -33,8 +33,6 @@
 #include "mips.h"
 #include "mips_cpudevs.h"
 #include "pci.h"
-#include "usb-uhci.h"
-#include "vmware_vga.h"
 #include "qemu-char.h"
 #include "sysemu.h"
 #include "arch_init.h"
 #include "loader.h"
 #include "elf.h"
 #include "mc146818rtc.h"
+#include "i8254.h"
 #include "blockdev.h"
 #include "exec-memory.h"
+#include "sysbus.h"             /* SysBusDevice */
 
 //#define DEBUG_BOARD_INIT
 
 #define ENVP_NB_ENTRIES                16
 #define ENVP_ENTRY_SIZE                256
 
+/* Hardware addresses */
+#define FLASH_ADDRESS 0x1e000000ULL
+#define FPGA_ADDRESS  0x1f000000ULL
+#define RESET_ADDRESS 0x1fc00000ULL
+
+#define FLASH_SIZE    0x400000
+
 #define MAX_IDE_BUS 2
 
 typedef struct {
@@ -72,6 +79,11 @@ typedef struct {
     SerialState *uart;
 } MaltaFPGAState;
 
+typedef struct {
+    SysBusDevice busdev;
+    qemu_irq *i8259;
+} MaltaState;
+
 static ISADevice *pit;
 
 static struct _loaderparams {
@@ -325,9 +337,9 @@ static void malta_fpga_write(void *opaque, target_phys_addr_t addr,
         break;
 
     /* LEDBAR Register */
-    /* XXX: implement a 8-LED array */
     case 0x00408:
         s->leds = val & 0xff;
+        malta_fpga_update_display(s);
         break;
 
     /* ASCIIWORD Register */
@@ -446,11 +458,8 @@ static MaltaFPGAState *malta_fpga_init(MemoryRegion *address_space,
 
     s->display = qemu_chr_new("fpga", "vc:320x200", malta_fpga_led_init);
 
-#ifdef TARGET_WORDS_BIGENDIAN
-    s->uart = serial_mm_init(base + 0x900, 3, uart_irq, 230400, uart_chr, 1, 1);
-#else
-    s->uart = serial_mm_init(base + 0x900, 3, uart_irq, 230400, uart_chr, 1, 0);
-#endif
+    s->uart = serial_mm_init(address_space, base + 0x900, 3, uart_irq,
+                             230400, uart_chr, DEVICE_NATIVE_ENDIAN);
 
     malta_fpga_reset(s);
     qemu_register_reset(malta_fpga_reset, s);
@@ -497,7 +506,7 @@ static void network_init(void)
      a3 - RAM size in bytes
 */
 
-static void write_bootloader (CPUState *env, uint8_t *base,
+static void write_bootloader (CPUMIPSState *env, uint8_t *base,
                               int64_t kernel_entry)
 {
     uint32_t *p;
@@ -733,7 +742,7 @@ static int64_t load_kernel (void)
     return kernel_entry;
 }
 
-static void malta_mips_config(CPUState *env)
+static void malta_mips_config(CPUMIPSState *env)
 {
     env->mvp->CP0_MVPConf0 |= ((smp_cpus - 1) << CP0MVPC0_PVPE) |
                          ((smp_cpus * env->nr_threads - 1) << CP0MVPC0_PTC);
@@ -741,8 +750,10 @@ static void malta_mips_config(CPUState *env)
 
 static void main_cpu_reset(void *opaque)
 {
-    CPUState *env = opaque;
-    cpu_reset(env);
+    MIPSCPU *cpu = opaque;
+    CPUMIPSState *env = &cpu->env;
+
+    cpu_reset(CPU(cpu));
 
     /* The bootloader does not need to be rewritten as it is located in a
        read only location. The kernel location and the arguments table
@@ -756,7 +767,7 @@ static void main_cpu_reset(void *opaque)
 
 static void cpu_request_exit(void *opaque, int irq, int level)
 {
-    CPUState *env = cpu_single_env;
+    CPUMIPSState *env = cpu_single_env;
 
     if (env && level) {
         cpu_exit(env);
@@ -774,11 +785,13 @@ void mips_malta_init (ram_addr_t ram_size,
     MemoryRegion *system_memory = get_system_memory();
     MemoryRegion *ram = g_new(MemoryRegion, 1);
     MemoryRegion *bios, *bios_alias = g_new(MemoryRegion, 1);
-    target_long bios_size;
+    target_long bios_size = FLASH_SIZE;
     int64_t kernel_entry;
     PCIBus *pci_bus;
-    CPUState *env;
-    qemu_irq *i8259;
+    ISABus *isa_bus;
+    MIPSCPU *cpu;
+    CPUMIPSState *env;
+    qemu_irq *isa_irq;
     qemu_irq *cpu_exit_irq;
     int piix4_devfn;
     i2c_bus *smbus;
@@ -787,9 +800,14 @@ void mips_malta_init (ram_addr_t ram_size,
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     DriveInfo *fd[MAX_FD];
     int fl_idx = 0;
-    int fl_sectors = 0;
+    int fl_sectors = bios_size >> 16;
     int be;
 
+    DeviceState *dev = qdev_create(NULL, "mips-malta");
+    MaltaState *s = DO_UPCAST(MaltaState, busdev.qdev, dev);
+
+    qdev_init_nofail(dev);
+
     /* Make sure the first 3 serial ports are associated with a device. */
     for(i = 0; i < 3; i++) {
         if (!serial_hds[i]) {
@@ -809,15 +827,17 @@ void mips_malta_init (ram_addr_t ram_size,
     }
 
     for (i = 0; i < smp_cpus; i++) {
-        env = cpu_init(cpu_model);
-        if (!env) {
+        cpu = cpu_mips_init(cpu_model);
+        if (cpu == NULL) {
             fprintf(stderr, "Unable to find CPU definition\n");
             exit(1);
         }
+        env = &cpu->env;
+
         /* Init internal devices */
         cpu_mips_irq_init_cpu(env);
         cpu_mips_clock_init(env);
-        qemu_register_reset(main_cpu_reset, env);
+        qemu_register_reset(main_cpu_reset, cpu);
     }
     env = first_cpu;
 
@@ -828,7 +848,8 @@ void mips_malta_init (ram_addr_t ram_size,
                 ((unsigned int)ram_size / (1 << 20)));
         exit(1);
     }
-    memory_region_init_ram(ram, NULL, "mips_malta.ram", ram_size);
+    memory_region_init_ram(ram, "mips_malta.ram", ram_size);
+    vmstate_register_ram_global(ram);
     memory_region_add_subregion(system_memory, 0, ram);
 
 #ifdef TARGET_WORDS_BIGENDIAN
@@ -837,18 +858,26 @@ void mips_malta_init (ram_addr_t ram_size,
     be = 0;
 #endif
     /* FPGA */
-    malta_fpga_init(system_memory, 0x1f000000LL, env->irq[2], serial_hds[2]);
+    malta_fpga_init(system_memory, FPGA_ADDRESS, env->irq[2], serial_hds[2]);
 
-    /* Load firmware in flash / BIOS unless we boot directly into a kernel. */
+    /* Load firmware in flash / BIOS. */
+    dinfo = drive_get(IF_PFLASH, 0, fl_idx);
+#ifdef DEBUG_BOARD_INIT
+    if (dinfo) {
+        printf("Register parallel flash %d size " TARGET_FMT_lx " at "
+               "addr %08llx '%s' %x\n",
+               fl_idx, bios_size, FLASH_ADDRESS,
+               bdrv_get_device_name(dinfo->bdrv), fl_sectors);
+    }
+#endif
+    fl = pflash_cfi01_register(FLASH_ADDRESS, NULL, "mips_malta.bios",
+                               BIOS_SIZE, dinfo ? dinfo->bdrv : NULL,
+                               65536, fl_sectors,
+                               4, 0x0000, 0x0000, 0x0000, 0x0000, be);
+    bios = pflash_cfi01_get_memory(fl);
+    fl_idx++;
     if (kernel_filename) {
         /* Write a small bootloader to the flash location. */
-        bios = g_new(MemoryRegion, 1);
-        memory_region_init_ram(bios, NULL, "mips_malta.bios", BIOS_SIZE);
-        memory_region_set_readonly(bios, true);
-        memory_region_init_alias(bios_alias, "bios.1fc", bios, 0, BIOS_SIZE);
-        /* Map the bios at two physical locations, as on the real board. */
-        memory_region_add_subregion(system_memory, 0x1e000000LL, bios);
-        memory_region_add_subregion(system_memory, 0x1fc00000LL, bios_alias);
         loaderparams.ram_size = ram_size;
         loaderparams.kernel_filename = kernel_filename;
         loaderparams.kernel_cmdline = kernel_cmdline;
@@ -856,44 +885,15 @@ void mips_malta_init (ram_addr_t ram_size,
         kernel_entry = load_kernel();
         write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry);
     } else {
-        dinfo = drive_get(IF_PFLASH, 0, fl_idx);
-        if (dinfo) {
-            /* Load firmware from flash. */
-            bios_size = 0x400000;
-            fl_sectors = bios_size >> 16;
-#ifdef DEBUG_BOARD_INIT
-            printf("Register parallel flash %d size " TARGET_FMT_lx " at "
-                   "addr %08llx '%s' %x\n",
-                   fl_idx, bios_size, 0x1e000000LL,
-                   bdrv_get_device_name(dinfo->bdrv), fl_sectors);
-#endif
-            fl = pflash_cfi01_register(0x1e000000LL,
-                                       NULL, "mips_malta.bios", BIOS_SIZE,
-                                       dinfo->bdrv, 65536, fl_sectors,
-                                       4, 0x0000, 0x0000, 0x0000, 0x0000, be);
-            bios = pflash_cfi01_get_memory(fl);
-            /* Map the bios at two physical locations, as on the real board. */
-            memory_region_init_alias(bios_alias, "bios.1fc",
-                                     bios, 0, BIOS_SIZE);
-            memory_region_add_subregion(system_memory, 0x1fc00000LL,
-                                        bios_alias);
-           fl_idx++;
-        } else {
-            bios = g_new(MemoryRegion, 1);
-            memory_region_init_ram(bios, NULL, "mips_malta.bios", BIOS_SIZE);
-            memory_region_set_readonly(bios, true);
-            memory_region_init_alias(bios_alias, "bios.1fc",
-                                     bios, 0, BIOS_SIZE);
-            /* Map the bios at two physical locations, as on the real board. */
-            memory_region_add_subregion(system_memory, 0x1e000000LL, bios);
-            memory_region_add_subregion(system_memory, 0x1fc00000LL,
-                                        bios_alias);
+        /* Load firmware from flash. */
+        if (!dinfo) {
             /* Load a BIOS image. */
-            if (bios_name == NULL)
+            if (bios_name == NULL) {
                 bios_name = BIOS_FILENAME;
+            }
             filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
             if (filename) {
-                bios_size = load_image_targphys(filename, 0x1fc00000LL,
+                bios_size = load_image_targphys(filename, FLASH_ADDRESS,
                                                 BIOS_SIZE);
                 g_free(filename);
             } else {
@@ -914,11 +914,16 @@ void mips_malta_init (ram_addr_t ram_size,
             uint32_t *end = addr + bios_size;
             while (addr < end) {
                 bswap32s(addr);
+                addr++;
             }
         }
 #endif
     }
 
+    /* Map the BIOS at a 2nd physical location, as on the real board. */
+    memory_region_init_alias(bios_alias, "bios.1fc", bios, 0, BIOS_SIZE);
+    memory_region_add_subregion(system_memory, RESET_ADDRESS, bios_alias);
+
     /* Board ID = 0x420 (Malta Board with CoreLV)
        XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
        map to the board ID. */
@@ -928,61 +933,80 @@ void mips_malta_init (ram_addr_t ram_size,
     cpu_mips_irq_init_cpu(env);
     cpu_mips_clock_init(env);
 
-    /* Interrupt controller */
-    /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
-    i8259 = i8259_init(env->irq[2]);
+    /*
+     * We have a circular dependency problem: pci_bus depends on isa_irq,
+     * isa_irq is provided by i8259, i8259 depends on ISA, ISA depends
+     * on piix4, and piix4 depends on pci_bus.  To stop the cycle we have
+     * qemu_irq_proxy() adds an extra bit of indirection, allowing us
+     * to resolve the isa_irq -> i8259 dependency after i8259 is initialized.
+     */
+    isa_irq = qemu_irq_proxy(&s->i8259, 16);
 
     /* Northbridge */
-    pci_bus = gt64120_register(i8259);
+    pci_bus = gt64120_register(isa_irq);
 
     /* Southbridge */
     ide_drive_get(hd, MAX_IDE_BUS);
 
-    piix4_devfn = piix4_init(pci_bus, 80);
-    isa_bus_irqs(i8259);
+    piix4_devfn = piix4_init(pci_bus, &isa_bus, 80);
+
+    /* Interrupt controller */
+    /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
+    s->i8259 = i8259_init(isa_bus, env->irq[2]);
+
+    isa_bus_irqs(isa_bus, s->i8259);
     pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);
-    usb_uhci_piix4_init(pci_bus, piix4_devfn + 2);
-    smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100, isa_get_irq(9),
-                          NULL, NULL, 0);
+    pci_create_simple(pci_bus, piix4_devfn + 2, "piix4-usb-uhci");
+    smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100,
+                          isa_get_irq(NULL, 9), NULL, 0, NULL);
     /* TODO: Populate SPD eeprom data.  */
     smbus_eeprom_init(smbus, 8, NULL, 0);
-    pit = pit_init(0x40, 0);
+    pit = pit_init(isa_bus, 0x40, 0, NULL);
     cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
     DMA_init(0, cpu_exit_irq);
 
     /* Super I/O */
-    isa_create_simple("i8042");
+    isa_create_simple(isa_bus, "i8042");
 
-    rtc_init(2000, NULL);
-    serial_isa_init(0, serial_hds[0]);
-    serial_isa_init(1, serial_hds[1]);
+    rtc_init(isa_bus, 2000, NULL);
+    serial_isa_init(isa_bus, 0, serial_hds[0]);
+    serial_isa_init(isa_bus, 1, serial_hds[1]);
     if (parallel_hds[0])
-        parallel_init(0, parallel_hds[0]);
+        parallel_init(isa_bus, 0, parallel_hds[0]);
     for(i = 0; i < MAX_FD; i++) {
         fd[i] = drive_get(IF_FLOPPY, 0, i);
     }
-    fdctrl_init_isa(fd);
+    fdctrl_init_isa(isa_bus, fd);
 
     /* Sound card */
-    audio_init(NULL, pci_bus);
+    audio_init(isa_bus, pci_bus);
 
     /* Network card */
     network_init();
 
     /* Optional PCI video card */
-    if (cirrus_vga_enabled) {
-        pci_cirrus_vga_init(pci_bus);
-    } else if (vmsvga_enabled) {
-        if (!pci_vmsvga_init(pci_bus)) {
-            fprintf(stderr, "Warning: vmware_vga not available,"
-                    " using standard VGA instead\n");
-            pci_vga_init(pci_bus);
-        }
-    } else if (std_vga_enabled) {
-        pci_vga_init(pci_bus);
-    }
+    pci_vga_init(pci_bus);
 }
 
+static int mips_malta_sysbus_device_init(SysBusDevice *sysbusdev)
+{
+    return 0;
+}
+
+static void mips_malta_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = mips_malta_sysbus_device_init;
+}
+
+static TypeInfo mips_malta_device = {
+    .name          = "mips-malta",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(MaltaState),
+    .class_init    = mips_malta_class_init,
+};
+
 static QEMUMachine mips_malta_machine = {
     .name = "malta",
     .desc = "MIPS Malta Core LV",
@@ -991,9 +1015,15 @@ static QEMUMachine mips_malta_machine = {
     .is_default = 1,
 };
 
+static void mips_malta_register_types(void)
+{
+    type_register_static(&mips_malta_device);
+}
+
 static void mips_malta_machine_init(void)
 {
     qemu_register_machine(&mips_malta_machine);
 }
 
+type_init(mips_malta_register_types)
 machine_init(mips_malta_machine_init);
This page took 0.032633 seconds and 4 git commands to generate.