Add PowerPC power-management state check callback.
[qemu] / hw / integratorcp.c
index bce9b59..83c6208 100644 (file)
@@ -1,7 +1,7 @@
-/* 
+/*
  * ARM Integrator CP System emulation.
  *
- * Copyright (c) 2005-2006 CodeSourcery.
+ * Copyright (c) 2005-2007 CodeSourcery.
  * Written by Paul Brook
  *
  * This code is licenced under the GPL
 #include "vl.h"
 #include "arm_pic.h"
 
-#define KERNEL_ARGS_ADDR 0x100
-#define KERNEL_LOAD_ADDR 0x00010000
-#define INITRD_LOAD_ADDR 0x00800000
-
 void DMA_run (void)
 {
 }
@@ -261,7 +257,7 @@ static void integratorcm_init(int memsz, uint32_t flash_offset)
 
     iomemtype = cpu_register_io_memory(0, integratorcm_readfn,
                                        integratorcm_writefn, s);
-    cpu_register_physical_memory(0x10000000, 0x007fffff, iomemtype);
+    cpu_register_physical_memory(0x10000000, 0x00800000, iomemtype);
     integratorcm_do_remap(s, 1);
     /* ??? Save/restore.  */
 }
@@ -271,28 +267,22 @@ static void integratorcm_init(int memsz, uint32_t flash_offset)
 
 typedef struct icp_pic_state
 {
-  arm_pic_handler handler;
   uint32_t base;
   uint32_t level;
   uint32_t irq_enabled;
   uint32_t fiq_enabled;
-  void *parent;
-  int parent_irq;
-  int parent_fiq;
+  qemu_irq parent_irq;
+  qemu_irq parent_fiq;
 } icp_pic_state;
 
 static void icp_pic_update(icp_pic_state *s)
 {
     uint32_t flags;
 
-    if (s->parent_irq != -1) {
-        flags = (s->level & s->irq_enabled);
-        pic_set_irq_new(s->parent, s->parent_irq, flags != 0);
-    }
-    if (s->parent_fiq != -1) {
-        flags = (s->level & s->fiq_enabled);
-        pic_set_irq_new(s->parent, s->parent_fiq, flags != 0);
-    }
+    flags = (s->level & s->irq_enabled);
+    qemu_set_irq(s->parent_irq, flags != 0);
+    flags = (s->level & s->fiq_enabled);
+    qemu_set_irq(s->parent_fiq, flags != 0);
 }
 
 static void icp_pic_set_irq(void *opaque, int irq, int level)
@@ -329,7 +319,7 @@ static uint32_t icp_pic_read(void *opaque, target_phys_addr_t offset)
     case 5: /* INT_SOFTCLR */
     case 11: /* FRQ_ENABLECLR */
     default:
-        printf ("icp_pic_read: Bad register offset 0x%x\n", offset);
+        printf ("icp_pic_read: Bad register offset 0x%x\n", (int)offset);
         return 0;
     }
 }
@@ -349,11 +339,11 @@ static void icp_pic_write(void *opaque, target_phys_addr_t offset,
         break;
     case 4: /* INT_SOFTSET */
         if (value & 1)
-            pic_set_irq_new(s, 0, 1);
+            icp_pic_set_irq(s, 0, 1);
         break;
     case 5: /* INT_SOFTCLR */
         if (value & 1)
-            pic_set_irq_new(s, 0, 0);
+            icp_pic_set_irq(s, 0, 0);
         break;
     case 10: /* FRQ_ENABLESET */
         s->fiq_enabled |= value;
@@ -366,7 +356,7 @@ static void icp_pic_write(void *opaque, target_phys_addr_t offset,
     case 8: /* FRQ_STATUS */
     case 9: /* FRQ_RAWSTAT */
     default:
-        printf ("icp_pic_write: Bad register offset 0x%x\n", offset);
+        printf ("icp_pic_write: Bad register offset 0x%x\n", (int)offset);
         return;
     }
     icp_pic_update(s);
@@ -384,25 +374,25 @@ static CPUWriteMemoryFunc *icp_pic_writefn[] = {
    icp_pic_write
 };
 
-static icp_pic_state *icp_pic_init(uint32_t base, void *parent,
-                                   int parent_irq, int parent_fiq)
+static qemu_irq *icp_pic_init(uint32_t base,
+                              qemu_irq parent_irq, qemu_irq parent_fiq)
 {
     icp_pic_state *s;
     int iomemtype;
+    qemu_irq *qi;
 
     s = (icp_pic_state *)qemu_mallocz(sizeof(icp_pic_state));
     if (!s)
         return NULL;
-    s->handler = icp_pic_set_irq;
+    qi = qemu_allocate_irqs(icp_pic_set_irq, s, 32);
     s->base = base;
-    s->parent = parent;
     s->parent_irq = parent_irq;
     s->parent_fiq = parent_fiq;
     iomemtype = cpu_register_io_memory(0, icp_pic_readfn,
                                        icp_pic_writefn, s);
-    cpu_register_physical_memory(base, 0x007fffff, iomemtype);
+    cpu_register_physical_memory(base, 0x00800000, iomemtype);
     /* ??? Save/restore.  */
-    return s;
+    return qi;
 }
 
 /* CP control registers.  */
@@ -464,80 +454,28 @@ static void icp_control_init(uint32_t base)
     s = (icp_control_state *)qemu_mallocz(sizeof(icp_control_state));
     iomemtype = cpu_register_io_memory(0, icp_control_readfn,
                                        icp_control_writefn, s);
-    cpu_register_physical_memory(base, 0x007fffff, iomemtype);
+    cpu_register_physical_memory(base, 0x00800000, iomemtype);
     s->base = base;
     /* ??? Save/restore.  */
 }
 
 
-/* The worlds second smallest bootloader.  Set r0-r2, then jump to kernel.  */
-static uint32_t bootloader[] = {
-  0xe3a00000, /* mov     r0, #0 */
-  0xe3a01013, /* mov     r1, #0x13 */
-  0xe3811c01, /* orr     r1, r1, #0x100 */
-  0xe59f2000, /* ldr     r2, [pc, #0] */
-  0xe59ff000, /* ldr     pc, [pc, #0] */
-  0, /* Address of kernel args.  Set by integratorcp_init.  */
-  0  /* Kernel entry point.  Set by integratorcp_init.  */
-};
-
-static void set_kernel_args(uint32_t ram_size, int initrd_size,
-                            const char *kernel_cmdline)
-{
-    uint32_t *p;
-
-    p = (uint32_t *)(phys_ram_base + KERNEL_ARGS_ADDR);
-    /* ATAG_CORE */
-    stl_raw(p++, 5);
-    stl_raw(p++, 0x54410001);
-    stl_raw(p++, 1);
-    stl_raw(p++, 0x1000);
-    stl_raw(p++, 0);
-    /* ATAG_MEM */
-    stl_raw(p++, 4);
-    stl_raw(p++, 0x54410002);
-    stl_raw(p++, ram_size);
-    stl_raw(p++, 0);
-    if (initrd_size) {
-        /* ATAG_INITRD2 */
-        stl_raw(p++, 4);
-        stl_raw(p++, 0x54420005);
-        stl_raw(p++, INITRD_LOAD_ADDR);
-        stl_raw(p++, initrd_size);
-    }
-    if (kernel_cmdline && *kernel_cmdline) {
-        /* ATAG_CMDLINE */
-        int cmdline_size;
-
-        cmdline_size = strlen(kernel_cmdline);
-        memcpy (p + 2, kernel_cmdline, cmdline_size + 1);
-        cmdline_size = (cmdline_size >> 2) + 1;
-        stl_raw(p++, cmdline_size + 2);
-        stl_raw(p++, 0x54410009);
-        p += cmdline_size;
-    }
-    /* ATAG_END */
-    stl_raw(p++, 0);
-    stl_raw(p++, 0);
-}
-
 /* Board init.  */
 
 static void integratorcp_init(int ram_size, int vga_ram_size, int boot_device,
                      DisplayState *ds, const char **fd_filename, int snapshot,
                      const char *kernel_filename, const char *kernel_cmdline,
-                     const char *initrd_filename, uint32_t cpuid)
+                     const char *initrd_filename, const char *cpu_model)
 {
     CPUState *env;
     uint32_t bios_offset;
-    icp_pic_state *pic;
-    void *cpu_pic;
-    int kernel_size;
-    int initrd_size;
-    int n;
+    qemu_irq *pic;
+    qemu_irq *cpu_pic;
 
     env = cpu_init();
-    cpu_arm_set_model(env, cpuid);
+    if (!cpu_model)
+        cpu_model = "arm926";
+    cpu_arm_set_model(env, cpu_model);
     bios_offset = ram_size + vga_ram_size;
     /* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash.  */
     /* ??? RAM shoud repeat to fill physical memory space.  */
@@ -548,82 +486,37 @@ static void integratorcp_init(int ram_size, int vga_ram_size, int boot_device,
 
     integratorcm_init(ram_size >> 20, bios_offset);
     cpu_pic = arm_pic_init_cpu(env);
-    pic = icp_pic_init(0x14000000, cpu_pic, ARM_PIC_CPU_IRQ, ARM_PIC_CPU_FIQ);
-    icp_pic_init(0xca000000, pic, 26, -1);
+    pic = icp_pic_init(0x14000000, cpu_pic[ARM_PIC_CPU_IRQ],
+                       cpu_pic[ARM_PIC_CPU_FIQ]);
+    icp_pic_init(0xca000000, pic[26], NULL);
     icp_pit_init(0x13000000, pic, 5);
-    pl011_init(0x16000000, pic, 1, serial_hds[0]);
-    pl011_init(0x17000000, pic, 2, serial_hds[1]);
+    pl031_init(0x15000000, pic[8]);
+    pl011_init(0x16000000, pic[1], serial_hds[0]);
+    pl011_init(0x17000000, pic[2], serial_hds[1]);
     icp_control_init(0xcb000000);
-    pl050_init(0x18000000, pic, 3, 0);
-    pl050_init(0x19000000, pic, 4, 1);
+    pl050_init(0x18000000, pic[3], 0);
+    pl050_init(0x19000000, pic[4], 1);
+    pl181_init(0x1c000000, sd_bdrv, pic[23], pic[24]);
     if (nd_table[0].vlan) {
         if (nd_table[0].model == NULL
             || strcmp(nd_table[0].model, "smc91c111") == 0) {
-            smc91c111_init(&nd_table[0], 0xc8000000, pic, 27);
+            smc91c111_init(&nd_table[0], 0xc8000000, pic[27]);
+        } else if (strcmp(nd_table[0].model, "?") == 0) {
+            fprintf(stderr, "qemu: Supported NICs: smc91c111\n");
+            exit (1);
         } else {
             fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
             exit (1);
         }
     }
-    pl110_init(ds, 0xc0000000, pic, 22, 0);
-
-    /* Load the kernel.  */
-    if (!kernel_filename) {
-        fprintf(stderr, "Kernel image must be specified\n");
-        exit(1);
-    }
-    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", kernel_filename);
-        exit(1);
-    }
-    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 initrd '%s'\n",
-                    initrd_filename);
-            exit(1);
-        }
-    } else {
-        initrd_size = 0;
-    }
-    bootloader[5] = KERNEL_ARGS_ADDR;
-    bootloader[6] = KERNEL_LOAD_ADDR;
-    for (n = 0; n < sizeof(bootloader) / 4; n++)
-        stl_raw(phys_ram_base + (n * 4), bootloader[n]);
-    set_kernel_args(ram_size, initrd_size, kernel_cmdline);
-}
+    pl110_init(ds, 0xc0000000, pic[22], 0);
 
-static void integratorcp926_init(int ram_size, int vga_ram_size,
-    int boot_device, DisplayState *ds, const char **fd_filename, int snapshot,
-    const char *kernel_filename, const char *kernel_cmdline,
-    const char *initrd_filename)
-{
-    integratorcp_init(ram_size, vga_ram_size, boot_device, ds, fd_filename,
-                      snapshot, kernel_filename, kernel_cmdline,
-                      initrd_filename, ARM_CPUID_ARM926);
-}
-
-static void integratorcp1026_init(int ram_size, int vga_ram_size,
-    int boot_device, DisplayState *ds, const char **fd_filename, int snapshot,
-    const char *kernel_filename, const char *kernel_cmdline,
-    const char *initrd_filename)
-{
-    integratorcp_init(ram_size, vga_ram_size, boot_device, ds, fd_filename,
-                      snapshot, kernel_filename, kernel_cmdline,
-                      initrd_filename, ARM_CPUID_ARM1026);
+    arm_load_kernel(env, ram_size, kernel_filename, kernel_cmdline,
+                    initrd_filename, 0x113, 0x0);
 }
 
-QEMUMachine integratorcp926_machine = {
-    "integratorcp926",
+QEMUMachine integratorcp_machine = {
+    "integratorcp",
     "ARM Integrator/CP (ARM926EJ-S)",
-    integratorcp926_init,
-};
-
-QEMUMachine integratorcp1026_machine = {
-    "integratorcp1026",
-    "ARM Integrator/CP (ARM1026EJ-S)",
-    integratorcp1026_init,
+    integratorcp_init,
 };