New '-bios' option, used to select an alternate BIOS image from bios_dir.
[qemu] / hw / sun4m.c
index 5974812..f9961c7 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * QEMU Sun4m System Emulator
- * 
+ *
  * Copyright (c) 2003-2005 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
@@ -50,7 +50,8 @@
 #define CMDLINE_ADDR         0x007ff000
 #define INITRD_LOAD_ADDR     0x00800000
 #define PROM_SIZE_MAX        (256 * 1024)
-#define PROM_ADDR           0xffd00000
+#define PROM_PADDR           0xff0000000ULL
+#define PROM_VADDR           0xffd00000
 #define PROM_FILENAME       "openbios-sparc32"
 
 #define MAX_CPUS 16
@@ -315,6 +316,7 @@ static void *sun4m_hw_init(const struct hwdef *hwdef, int RAM_size,
     const sparc_def_t *def;
     qemu_irq *cpu_irqs[MAX_CPUS], *slavio_irq, *slavio_cpu_irq,
         *espdma_irq, *ledma_irq;
+    qemu_irq *esp_reset, *le_reset;
 
     /* init CPUs */
     sparc_find_by_name(cpu_model, &def);
@@ -352,9 +354,11 @@ static void *sun4m_hw_init(const struct hwdef *hwdef, int RAM_size,
                                        hwdef->clock_irq);
 
     espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq],
-                              iommu, &espdma_irq);
+                              iommu, &espdma_irq, &esp_reset);
+
     ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
-                             slavio_irq[hwdef->le_irq], iommu, &ledma_irq);
+                             slavio_irq[hwdef->le_irq], iommu, &ledma_irq,
+                             &le_reset);
 
     if (graphic_depth != 8 && graphic_depth != 24) {
         fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
@@ -365,7 +369,7 @@ static void *sun4m_hw_init(const struct hwdef *hwdef, int RAM_size,
 
     if (nd_table[0].model == NULL
         || strcmp(nd_table[0].model, "lance") == 0) {
-        lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq);
+        lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset);
     } else if (strcmp(nd_table[0].model, "?") == 0) {
         fprintf(stderr, "qemu: Supported NICs: lance\n");
         exit (1);
@@ -389,7 +393,9 @@ static void *sun4m_hw_init(const struct hwdef *hwdef, int RAM_size,
     slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq],
                        serial_hds[1], serial_hds[0]);
     fdctrl_init(slavio_irq[hwdef->fd_irq], 0, 1, hwdef->fd_base, fd_table);
-    main_esp = esp_init(bs_table, hwdef->esp_base, espdma, *espdma_irq);
+
+    main_esp = esp_init(bs_table, hwdef->esp_base, espdma, *espdma_irq,
+                        esp_reset);
 
     for (i = 0; i < MAX_DISKS; i++) {
         if (bs_table[i]) {
@@ -420,27 +426,30 @@ static void sun4m_load_kernel(long vram_size, int RAM_size, int boot_device,
     linux_boot = (kernel_filename != NULL);
 
     prom_offset = RAM_size + vram_size;
-    cpu_register_physical_memory(PROM_ADDR, 
-                                 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK, 
+    cpu_register_physical_memory(PROM_PADDR,
+                                 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK,
                                  prom_offset | IO_MEM_ROM);
 
-    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAME);
-    ret = load_elf(buf, 0, NULL, NULL, NULL);
+    if (bios_name == NULL)
+        bios_name = PROM_FILENAME;
+    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
+    ret = load_elf(buf, PROM_PADDR - PROM_VADDR, NULL, NULL, NULL);
     if (ret < 0) {
-       fprintf(stderr, "qemu: could not load prom '%s'\n", 
+       fprintf(stderr, "qemu: could not load prom '%s'\n",
                buf);
        exit(1);
     }
 
     kernel_size = 0;
     if (linux_boot) {
-        kernel_size = load_elf(kernel_filename, -0xf0000000, NULL, NULL, NULL);
+        kernel_size = load_elf(kernel_filename, -0xf0000000ULL, NULL, NULL,
+                               NULL);
         if (kernel_size < 0)
            kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
        if (kernel_size < 0)
            kernel_size = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
         if (kernel_size < 0) {
-            fprintf(stderr, "qemu: could not load kernel '%s'\n", 
+            fprintf(stderr, "qemu: could not load kernel '%s'\n",
                     kernel_filename);
            exit(1);
         }
@@ -450,7 +459,7 @@ static void sun4m_load_kernel(long vram_size, int RAM_size, int boot_device,
         if (initrd_filename) {
             initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
             if (initrd_size < 0) {
-                fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", 
+                fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
                         initrd_filename);
                 exit(1);
             }
@@ -583,7 +592,7 @@ static void ss10_init(int RAM_size, int vga_ram_size, int boot_device,
         cpu_model = "TI SuperSparc II";
     sun4m_common_init(RAM_size, boot_device, ds, kernel_filename,
                       kernel_cmdline, initrd_filename, cpu_model,
-                      1, PROM_ADDR); // XXX prom overlap, actually first 4GB ok
+                      1, 0xffffffff); // XXX actually first 62GB ok
 }
 
 QEMUMachine ss5_machine = {