Use relative path for bios
[qemu] / hw / sun4u.c
index 59aee1b..7d02018 100644 (file)
 //#define DEBUG_IRQ
 
 #ifdef DEBUG_IRQ
-#define DPRINTF(fmt, args...)                           \
-    do { printf("CPUIRQ: " fmt , ##args); } while (0)
+#define DPRINTF(fmt, ...)                                       \
+    do { printf("CPUIRQ: " fmt , ## __VA_ARGS__); } while (0)
 #else
-#define DPRINTF(fmt, args...)
+#define DPRINTF(fmt, ...)
 #endif
 
 #define KERNEL_LOAD_ADDR     0x00404000
@@ -89,24 +89,9 @@ void DMA_register_channel (int nchan,
 {
 }
 
-static int nvram_boot_set(void *opaque, const char *boot_device)
+static int fw_cfg_boot_set(void *opaque, const char *boot_device)
 {
-    unsigned int i;
-    uint8_t image[sizeof(ohwcfg_v3_t)];
-    ohwcfg_v3_t *header = (ohwcfg_v3_t *)ℑ
-    m48t59_t *nvram = (m48t59_t *)opaque;
-
-    for (i = 0; i < sizeof(image); i++)
-        image[i] = m48t59_read(nvram, i) & 0xff;
-
-    pstrcpy((char *)header->boot_devices, sizeof(header->boot_devices),
-            boot_device);
-    header->nboot_devices = strlen(boot_device) & 0xff;
-    header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8));
-
-    for (i = 0; i < sizeof(image); i++)
-        m48t59_write(nvram, i, image[i]);
-
+    fw_cfg_add_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]);
     return 0;
 }
 
@@ -124,51 +109,11 @@ static int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
     unsigned int i;
     uint32_t start, end;
     uint8_t image[0x1ff0];
-    ohwcfg_v3_t *header = (ohwcfg_v3_t *)&image;
-    struct sparc_arch_cfg *sparc_header;
     struct OpenBIOS_nvpart_v1 *part_header;
 
     memset(image, '\0', sizeof(image));
 
-    // Try to match PPC NVRAM
-    pstrcpy((char *)header->struct_ident, sizeof(header->struct_ident),
-            "QEMU_BIOS");
-    header->struct_version = cpu_to_be32(3); /* structure v3 */
-
-    header->nvram_size = cpu_to_be16(NVRAM_size);
-    header->nvram_arch_ptr = cpu_to_be16(sizeof(ohwcfg_v3_t));
-    header->nvram_arch_size = cpu_to_be16(sizeof(struct sparc_arch_cfg));
-    pstrcpy((char *)header->arch, sizeof(header->arch), arch);
-    header->nb_cpus = smp_cpus & 0xff;
-    header->RAM0_base = 0;
-    header->RAM0_size = cpu_to_be64((uint64_t)RAM_size);
-    pstrcpy((char *)header->boot_devices, sizeof(header->boot_devices),
-            boot_devices);
-    header->nboot_devices = strlen(boot_devices) & 0xff;
-    header->kernel_image = cpu_to_be64((uint64_t)kernel_image);
-    header->kernel_size = cpu_to_be64((uint64_t)kernel_size);
-    if (cmdline) {
-        pstrcpy_targphys(CMDLINE_ADDR, TARGET_PAGE_SIZE, cmdline);
-        header->cmdline = cpu_to_be64((uint64_t)CMDLINE_ADDR);
-        header->cmdline_size = cpu_to_be64((uint64_t)strlen(cmdline));
-    }
-    header->initrd_image = cpu_to_be64((uint64_t)initrd_image);
-    header->initrd_size = cpu_to_be64((uint64_t)initrd_size);
-    header->NVRAM_image = cpu_to_be64((uint64_t)NVRAM_image);
-
-    header->width = cpu_to_be16(width);
-    header->height = cpu_to_be16(height);
-    header->depth = cpu_to_be16(depth);
-    if (nographic)
-        header->graphic_flags = cpu_to_be16(OHW_GF_NOGRAPHICS);
-
-    header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8));
-
-    // Architecture specific header
-    start = sizeof(ohwcfg_v3_t);
-    sparc_header = (struct sparc_arch_cfg *)&image[start];
-    sparc_header->valid = 0;
-    start += sizeof(struct sparc_arch_cfg);
+    start = 0;
 
     // OpenBIOS nvram variables
     // Variable partition
@@ -200,16 +145,14 @@ static int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
     for (i = 0; i < sizeof(image); i++)
         m48t59_write(nvram, i, image[i]);
 
-    qemu_register_boot_set(nvram_boot_set, nvram);
-
     return 0;
 }
 
-void pic_info(void)
+void pic_info(Monitor *mon)
 {
 }
 
-void irq_info(void)
+void irq_info(Monitor *mon)
 {
 }
 
@@ -274,13 +217,13 @@ static void main_cpu_reset(void *opaque)
     cpu_reset(env);
     env->tick_cmpr = TICK_INT_DIS | 0;
     ptimer_set_limit(env->tick, TICK_MAX, 1);
-    ptimer_run(env->tick, 0);
+    ptimer_run(env->tick, 1);
     env->stick_cmpr = TICK_INT_DIS | 0;
     ptimer_set_limit(env->stick, TICK_MAX, 1);
-    ptimer_run(env->stick, 0);
+    ptimer_run(env->stick, 1);
     env->hstick_cmpr = TICK_INT_DIS | 0;
     ptimer_set_limit(env->hstick, TICK_MAX, 1);
-    ptimer_run(env->hstick, 0);
+    ptimer_run(env->hstick, 1);
     env->gregs[1] = 0; // Memory start
     env->gregs[2] = ram_size; // Memory size
     env->gregs[3] = 0; // Machine description XXX
@@ -365,20 +308,17 @@ pci_ebus_init(PCIBus *bus, int devfn)
     PCIDevice *s;
 
     s = pci_register_device(bus, "EBUS", sizeof(*s), devfn, NULL, NULL);
-    s->config[0x00] = 0x8e; // vendor_id : Sun
-    s->config[0x01] = 0x10;
-    s->config[0x02] = 0x00; // device_id
-    s->config[0x03] = 0x10;
+    pci_config_set_vendor_id(s->config, PCI_VENDOR_ID_SUN);
+    pci_config_set_device_id(s->config, PCI_DEVICE_ID_SUN_EBUS);
     s->config[0x04] = 0x06; // command = bus master, pci mem
     s->config[0x05] = 0x00;
     s->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
     s->config[0x07] = 0x03; // status = medium devsel
     s->config[0x08] = 0x01; // revision
     s->config[0x09] = 0x00; // programming i/f
-    s->config[0x0A] = 0x80; // class_sub = misc bridge
-    s->config[0x0B] = 0x06; // class_base = PCI_bridge
+    pci_config_set_class(s->config, PCI_CLASS_BRIDGE_OTHER);
     s->config[0x0D] = 0x0a; // latency_timer
-    s->config[0x0E] = 0x00; // header_type
+    s->config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
 
     pci_register_io_region(s, 0, 0x1000000, PCI_ADDRESS_SPACE_MEM,
                            ebus_mmio_mapfunc);
@@ -386,18 +326,18 @@ pci_ebus_init(PCIBus *bus, int devfn)
                            ebus_mmio_mapfunc);
 }
 
-static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size,
+static void sun4uv_init(ram_addr_t RAM_size,
                         const char *boot_devices,
                         const char *kernel_filename, const char *kernel_cmdline,
                         const char *initrd_filename, const char *cpu_model,
                         const struct hwdef *hwdef)
 {
     CPUState *env;
-    char buf[1024];
+    char *filename;
     m48t59_t *nvram;
     int ret, linux_boot;
     unsigned int i;
-    ram_addr_t ram_offset, prom_offset, vga_ram_offset;
+    ram_addr_t ram_offset, prom_offset;
     long initrd_size, kernel_size;
     PCIBus *pci_bus, *pci_bus2, *pci_bus3;
     QEMUBH *bh;
@@ -434,7 +374,7 @@ static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size,
     reset_info = qemu_mallocz(sizeof(ResetData));
     reset_info->env = env;
     reset_info->reset_addr = hwdef->prom_addr + 0x40ULL;
-    qemu_register_reset(main_cpu_reset, reset_info);
+    qemu_register_reset(main_cpu_reset, 0, reset_info);
     main_cpu_reset(reset_info);
     // Override warm reset address with cold start address
     env->pc = hwdef->prom_addr + 0x20ULL;
@@ -452,17 +392,23 @@ static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size,
 
     if (bios_name == NULL)
         bios_name = PROM_FILENAME;
-    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
-    ret = load_elf(buf, hwdef->prom_addr - PROM_VADDR, NULL, NULL, NULL);
-    if (ret < 0) {
-        ret = load_image_targphys(buf, hwdef->prom_addr,
-                                  (PROM_SIZE_MAX + TARGET_PAGE_SIZE) &
-                                  TARGET_PAGE_MASK);
+    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+    if (filename) {
+        ret = load_elf(filename, hwdef->prom_addr - PROM_VADDR,
+                       NULL, NULL, NULL);
         if (ret < 0) {
-            fprintf(stderr, "qemu: could not load prom '%s'\n",
-                    buf);
-            exit(1);
+            ret = load_image_targphys(filename, hwdef->prom_addr,
+                                      (PROM_SIZE_MAX + TARGET_PAGE_SIZE) &
+                                  TARGET_PAGE_MASK);
         }
+        qemu_free(filename);
+    } else {
+        ret = -1;
+    }
+    if (ret < 0) {
+        fprintf(stderr, "qemu: could not load prom '%s'\n",
+                bios_name);
+        exit(1);
     }
 
     kernel_size = 0;
@@ -507,10 +453,7 @@ static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size,
     pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, NULL, &pci_bus2,
                            &pci_bus3);
     isa_mem_base = VGA_BASE;
-    vga_ram_offset = qemu_ram_alloc(vga_ram_size);
-    pci_vga_init(pci_bus, phys_ram_base + vga_ram_offset,
-                 vga_ram_offset, vga_ram_size,
-                 0, 0);
+    pci_vga_init(pci_bus, 0, 0);
 
     // XXX Should be pci_bus3
     pci_ebus_init(pci_bus, -1);
@@ -578,6 +521,18 @@ static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size,
     fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
     fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
     fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
+    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, KERNEL_LOAD_ADDR);
+    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
+    if (kernel_cmdline) {
+        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);
+        pstrcpy_targphys(CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);
+    } else {
+        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
+    }
+    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, INITRD_LOAD_ADDR);
+    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
+    fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, boot_devices[0]);
+    qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
 }
 
 enum {
@@ -611,58 +566,62 @@ static const struct hwdef hwdefs[] = {
 };
 
 /* Sun4u hardware initialisation */
-static void sun4u_init(ram_addr_t RAM_size, int vga_ram_size,
+static void sun4u_init(ram_addr_t RAM_size,
                        const char *boot_devices,
                        const char *kernel_filename, const char *kernel_cmdline,
                        const char *initrd_filename, const char *cpu_model)
 {
-    sun4uv_init(RAM_size, vga_ram_size, boot_devices, kernel_filename,
+    sun4uv_init(RAM_size, boot_devices, kernel_filename,
                 kernel_cmdline, initrd_filename, cpu_model, &hwdefs[0]);
 }
 
 /* Sun4v hardware initialisation */
-static void sun4v_init(ram_addr_t RAM_size, int vga_ram_size,
+static void sun4v_init(ram_addr_t RAM_size,
                        const char *boot_devices,
                        const char *kernel_filename, const char *kernel_cmdline,
                        const char *initrd_filename, const char *cpu_model)
 {
-    sun4uv_init(RAM_size, vga_ram_size, boot_devices, kernel_filename,
+    sun4uv_init(RAM_size, boot_devices, kernel_filename,
                 kernel_cmdline, initrd_filename, cpu_model, &hwdefs[1]);
 }
 
 /* Niagara hardware initialisation */
-static void niagara_init(ram_addr_t RAM_size, int vga_ram_size,
+static void niagara_init(ram_addr_t RAM_size,
                          const char *boot_devices,
                          const char *kernel_filename, const char *kernel_cmdline,
                          const char *initrd_filename, const char *cpu_model)
 {
-    sun4uv_init(RAM_size, vga_ram_size, boot_devices, kernel_filename,
+    sun4uv_init(RAM_size, boot_devices, kernel_filename,
                 kernel_cmdline, initrd_filename, cpu_model, &hwdefs[2]);
 }
 
-QEMUMachine sun4u_machine = {
+static QEMUMachine sun4u_machine = {
     .name = "sun4u",
     .desc = "Sun4u platform",
     .init = sun4u_init,
-    .ram_require = PROM_SIZE_MAX + VGA_RAM_SIZE,
-    .nodisk_ok = 1,
     .max_cpus = 1, // XXX for now
+    .is_default = 1,
 };
 
-QEMUMachine sun4v_machine = {
+static QEMUMachine sun4v_machine = {
     .name = "sun4v",
     .desc = "Sun4v platform",
     .init = sun4v_init,
-    .ram_require = PROM_SIZE_MAX + VGA_RAM_SIZE,
-    .nodisk_ok = 1,
     .max_cpus = 1, // XXX for now
 };
 
-QEMUMachine niagara_machine = {
+static QEMUMachine niagara_machine = {
     .name = "Niagara",
     .desc = "Sun4v platform, Niagara",
     .init = niagara_init,
-    .ram_require = PROM_SIZE_MAX + VGA_RAM_SIZE,
-    .nodisk_ok = 1,
     .max_cpus = 1, // XXX for now
 };
+
+static void sun4u_machine_init(void)
+{
+    qemu_register_machine(&sun4u_machine);
+    qemu_register_machine(&sun4v_machine);
+    qemu_register_machine(&niagara_machine);
+}
+
+machine_init(sun4u_machine_init);