qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [5329] Add a generic Niagara machine


From: Blue Swirl
Subject: [Qemu-devel] [5329] Add a generic Niagara machine
Date: Fri, 26 Sep 2008 19:48:59 +0000

Revision: 5329
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=5329
Author:   blueswir1
Date:     2008-09-26 19:48:58 +0000 (Fri, 26 Sep 2008)

Log Message:
-----------
Add a generic Niagara machine

Modified Paths:
--------------
    trunk/hw/boards.h
    trunk/hw/sun4u.c
    trunk/target-sparc/helper.c
    trunk/target-sparc/machine.c

Modified: trunk/hw/boards.h
===================================================================
--- trunk/hw/boards.h   2008-09-26 18:07:24 UTC (rev 5328)
+++ trunk/hw/boards.h   2008-09-26 19:48:58 UTC (rev 5329)
@@ -66,6 +66,7 @@
 /* sun4u.c */
 extern QEMUMachine sun4u_machine;
 extern QEMUMachine sun4v_machine;
+extern QEMUMachine niagara_machine;
 
 /* integratorcp.c */
 extern QEMUMachine integratorcp_machine;

Modified: trunk/hw/sun4u.c
===================================================================
--- trunk/hw/sun4u.c    2008-09-26 18:07:24 UTC (rev 5328)
+++ trunk/hw/sun4u.c    2008-09-26 19:48:58 UTC (rev 5329)
@@ -46,7 +46,6 @@
 #define CMDLINE_ADDR         0x003ff000
 #define INITRD_LOAD_ADDR     0x00300000
 #define PROM_SIZE_MAX        (4 * 1024 * 1024)
-#define PROM_ADDR            0x1fff0000000ULL
 #define PROM_VADDR           0x000ffd00000ULL
 #define APB_SPECIAL_BASE     0x1fe00000000ULL
 #define APB_MEM_BASE         0x1ff00000000ULL
@@ -61,6 +60,8 @@
 struct hwdef {
     const char * const default_cpu_model;
     uint16_t machine_id;
+    uint64_t prom_addr;
+    uint64_t console_serial_base;
 };
 
 int DMA_get_channel_mode (int nchan)
@@ -260,9 +261,15 @@
 {
 }
 
+typedef struct ResetData {
+    CPUState *env;
+    uint64_t reset_addr;
+} ResetData;
+
 static void main_cpu_reset(void *opaque)
 {
-    CPUState *env = opaque;
+    ResetData *s = (ResetData *)opaque;
+    CPUState *env = s->env;
 
     cpu_reset(env);
     ptimer_set_limit(env->tick, 0x7fffffffffffffffULL, 1);
@@ -271,6 +278,11 @@
     ptimer_run(env->stick, 0);
     ptimer_set_limit(env->hstick, 0x7fffffffffffffffULL, 1);
     ptimer_run(env->hstick, 0);
+    env->gregs[1] = 0; // Memory start
+    env->gregs[2] = ram_size; // Memory size
+    env->gregs[3] = 0; // Machine description XXX
+    env->pc = s->reset_addr;
+    env->npc = env->pc + 4;
 }
 
 static void tick_irq(void *opaque)
@@ -328,6 +340,7 @@
     BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     BlockDriverState *fd[MAX_FD];
     void *fw_cfg;
+    ResetData *reset_info;
 
     linux_boot = (kernel_filename != NULL);
 
@@ -351,14 +364,21 @@
     bh = qemu_bh_new(hstick_irq, env);
     env->hstick = ptimer_init(bh);
     ptimer_set_period(env->hstick, 1ULL);
-    qemu_register_reset(main_cpu_reset, env);
-    main_cpu_reset(env);
 
+    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);
+    main_cpu_reset(reset_info);
+    // Override warm reset address with cold start address
+    env->pc = hwdef->prom_addr + 0x20ULL;
+    env->npc = env->pc + 4;
+
     /* allocate RAM */
     cpu_register_physical_memory(0, RAM_size, 0);
 
     prom_offset = RAM_size + vga_ram_size;
-    cpu_register_physical_memory(PROM_ADDR,
+    cpu_register_physical_memory(hwdef->prom_addr,
                                  (PROM_SIZE_MAX + TARGET_PAGE_SIZE) &
                                  TARGET_PAGE_MASK,
                                  prom_offset | IO_MEM_ROM);
@@ -366,11 +386,16 @@
     if (bios_name == NULL)
         bios_name = PROM_FILENAME;
     snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
-    ret = load_elf(buf, PROM_ADDR - PROM_VADDR, NULL, NULL, NULL);
+    ret = load_elf(buf, 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(buf, hwdef->prom_addr,
+                                  (PROM_SIZE_MAX + TARGET_PAGE_SIZE) &
+                                  TARGET_PAGE_MASK);
+        if (ret < 0) {
+            fprintf(stderr, "qemu: could not load prom '%s'\n",
+                    buf);
+            exit(1);
+        }
     }
 
     kernel_size = 0;
@@ -417,7 +442,13 @@
     pci_cirrus_vga_init(pci_bus, ds, phys_ram_base + RAM_size, RAM_size,
                         vga_ram_size);
 
-    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
+    i = 0;
+    if (hwdef->console_serial_base) {
+        serial_mm_init(hwdef->console_serial_base, 0, NULL, 115200,
+                       serial_hds[i], 1);
+        i++;
+    }
+    for(; i < MAX_SERIAL_PORTS; i++) {
         if (serial_hds[i]) {
             serial_init(serial_io[i], NULL/*serial_irq[i]*/, 115200,
                         serial_hds[i]);
@@ -482,6 +513,7 @@
 enum {
     sun4u_id = 0,
     sun4v_id = 64,
+    niagara_id,
 };
 
 static const struct hwdef hwdefs[] = {
@@ -489,12 +521,23 @@
     {
         .default_cpu_model = "TI UltraSparc II",
         .machine_id = sun4u_id,
+        .prom_addr = 0x1fff0000000ULL,
+        .console_serial_base = 0,
     },
     /* Sun4v generic PC-like machine */
     {
         .default_cpu_model = "Sun UltraSparc T1",
         .machine_id = sun4v_id,
+        .prom_addr = 0x1fff0000000ULL,
+        .console_serial_base = 0,
     },
+    /* Sun4v generic Niagara machine */
+    {
+        .default_cpu_model = "Sun UltraSparc T1",
+        .machine_id = niagara_id,
+        .prom_addr = 0xfff0000000ULL,
+        .console_serial_base = 0xfff0c2c000ULL,
+    },
 };
 
 /* Sun4u hardware initialisation */
@@ -517,6 +560,16 @@
                 kernel_cmdline, initrd_filename, cpu_model, &hwdefs[1]);
 }
 
+/* Niagara hardware initialisation */
+static void niagara_init(ram_addr_t RAM_size, int vga_ram_size,
+                         const char *boot_devices, DisplayState *ds,
+                         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, ds, kernel_filename,
+                kernel_cmdline, initrd_filename, cpu_model, &hwdefs[2]);
+}
+
 QEMUMachine sun4u_machine = {
     .name = "sun4u",
     .desc = "Sun4u platform",
@@ -532,3 +585,11 @@
     .ram_require = PROM_SIZE_MAX + VGA_RAM_SIZE,
     .nodisk_ok = 1,
 };
+
+QEMUMachine niagara_machine = {
+    .name = "Niagara",
+    .desc = "Sun4v platform, Niagara",
+    .init = niagara_init,
+    .ram_require = PROM_SIZE_MAX + VGA_RAM_SIZE,
+    .nodisk_ok = 1,
+};

Modified: trunk/target-sparc/helper.c
===================================================================
--- trunk/target-sparc/helper.c 2008-09-26 18:07:24 UTC (rev 5328)
+++ trunk/target-sparc/helper.c 2008-09-26 19:48:58 UTC (rev 5329)
@@ -658,13 +658,12 @@
 #ifdef TARGET_SPARC64
     env->pstate = PS_PRIV;
     env->hpstate = HS_PRIV;
-    env->pc = 0x1fff0000020ULL; // XXX should be different for system_reset
     env->tsptr = &env->ts[env->tl & MAXTL_MASK];
 #else
-    env->pc = 0;
     env->mmuregs[0] &= ~(MMU_E | MMU_NF);
     env->mmuregs[0] |= env->def->mmu_bm;
 #endif
+    env->pc = 0;
     env->npc = env->pc + 4;
 #endif
 }

Modified: trunk/target-sparc/machine.c
===================================================================
--- trunk/target-sparc/machine.c        2008-09-26 18:07:24 UTC (rev 5328)
+++ trunk/target-sparc/machine.c        2008-09-26 19:48:58 UTC (rev 5329)
@@ -9,6 +9,7 @@
 #ifdef TARGET_SPARC64
     qemu_register_machine(&sun4u_machine);
     qemu_register_machine(&sun4v_machine);
+    qemu_register_machine(&niagara_machine);
 #else
     qemu_register_machine(&ss5_machine);
     qemu_register_machine(&ss10_machine);






reply via email to

[Prev in Thread] Current Thread [Next in Thread]