-/*
+/*
* 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)
{
}
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. */
}
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)
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;
}
}
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;
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);
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. */
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. */
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,
};