Commit 1640695026373034f9740ad1bcb69f27e584218c

Authored by pbrook
1 parent 008a8818

Add nominal ARM Versatil/AB board emulation.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1864 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
... ... @@ -346,7 +346,7 @@ endif
346 346 endif
347 347 ifeq ($(TARGET_BASE_ARCH), arm)
348 348 VL_OBJS+= integratorcp.o versatilepb.o ps2.o smc91c111.o arm_pic.o arm_timer.o
349   -VL_OBJS+= pl011.o pl050.o pl080.o pl110.o pl190.o
  349 +VL_OBJS+= arm_boot.o pl011.o pl050.o pl080.o pl110.o pl190.o
350 350 endif
351 351 ifeq ($(TARGET_BASE_ARCH), sh4)
352 352 VL_OBJS+= shix.o sh7750.o sh7750_regnames.o tc58128.o
... ...
hw/arm_boot.c 0 → 100644
  1 +/*
  2 + * ARM kernel loader.
  3 + *
  4 + * Copyright (c) 2006 CodeSourcery.
  5 + * Written by Paul Brook
  6 + *
  7 + * This code is licenced under the GPL.
  8 + */
  9 +
  10 +#include "vl.h"
  11 +
  12 +#define KERNEL_ARGS_ADDR 0x100
  13 +#define KERNEL_LOAD_ADDR 0x00010000
  14 +#define INITRD_LOAD_ADDR 0x00800000
  15 +
  16 +/* The worlds second smallest bootloader. Set r0-r2, then jump to kernel. */
  17 +static uint32_t bootloader[] = {
  18 + 0xe3a00000, /* mov r0, #0 */
  19 + 0xe3a01000, /* mov r1, #0x?? */
  20 + 0xe3811c00, /* orr r1, r1, #0x??00 */
  21 + 0xe59f2000, /* ldr r2, [pc, #0] */
  22 + 0xe59ff000, /* ldr pc, [pc, #0] */
  23 + 0, /* Address of kernel args. Set by integratorcp_init. */
  24 + 0 /* Kernel entry point. Set by integratorcp_init. */
  25 +};
  26 +
  27 +static void set_kernel_args(uint32_t ram_size, int initrd_size,
  28 + const char *kernel_cmdline)
  29 +{
  30 + uint32_t *p;
  31 +
  32 + p = (uint32_t *)(phys_ram_base + KERNEL_ARGS_ADDR);
  33 + /* ATAG_CORE */
  34 + stl_raw(p++, 5);
  35 + stl_raw(p++, 0x54410001);
  36 + stl_raw(p++, 1);
  37 + stl_raw(p++, 0x1000);
  38 + stl_raw(p++, 0);
  39 + /* ATAG_MEM */
  40 + stl_raw(p++, 4);
  41 + stl_raw(p++, 0x54410002);
  42 + stl_raw(p++, ram_size);
  43 + stl_raw(p++, 0);
  44 + if (initrd_size) {
  45 + /* ATAG_INITRD2 */
  46 + stl_raw(p++, 4);
  47 + stl_raw(p++, 0x54420005);
  48 + stl_raw(p++, INITRD_LOAD_ADDR);
  49 + stl_raw(p++, initrd_size);
  50 + }
  51 + if (kernel_cmdline && *kernel_cmdline) {
  52 + /* ATAG_CMDLINE */
  53 + int cmdline_size;
  54 +
  55 + cmdline_size = strlen(kernel_cmdline);
  56 + memcpy (p + 2, kernel_cmdline, cmdline_size + 1);
  57 + cmdline_size = (cmdline_size >> 2) + 1;
  58 + stl_raw(p++, cmdline_size + 2);
  59 + stl_raw(p++, 0x54410009);
  60 + p += cmdline_size;
  61 + }
  62 + /* ATAG_END */
  63 + stl_raw(p++, 0);
  64 + stl_raw(p++, 0);
  65 +}
  66 +
  67 +void arm_load_kernel(int ram_size, const char *kernel_filename,
  68 + const char *kernel_cmdline, const char *initrd_filename,
  69 + int board_id)
  70 +{
  71 + int kernel_size;
  72 + int initrd_size;
  73 + int n;
  74 +
  75 + /* Load the kernel. */
  76 + if (!kernel_filename) {
  77 + fprintf(stderr, "Kernel image must be specified\n");
  78 + exit(1);
  79 + }
  80 + kernel_size = load_image(kernel_filename,
  81 + phys_ram_base + KERNEL_LOAD_ADDR);
  82 + if (kernel_size < 0) {
  83 + fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
  84 + exit(1);
  85 + }
  86 + if (initrd_filename) {
  87 + initrd_size = load_image(initrd_filename,
  88 + phys_ram_base + INITRD_LOAD_ADDR);
  89 + if (initrd_size < 0) {
  90 + fprintf(stderr, "qemu: could not load initrd '%s'\n",
  91 + initrd_filename);
  92 + exit(1);
  93 + }
  94 + } else {
  95 + initrd_size = 0;
  96 + }
  97 + bootloader[1] |= board_id & 0xff;
  98 + bootloader[2] |= (board_id >> 8) & 0xff;
  99 + bootloader[5] = KERNEL_ARGS_ADDR;
  100 + bootloader[6] = KERNEL_LOAD_ADDR;
  101 + for (n = 0; n < sizeof(bootloader) / 4; n++)
  102 + stl_raw(phys_ram_base + (n * 4), bootloader[n]);
  103 + set_kernel_args(ram_size, initrd_size, kernel_cmdline);
  104 +}
  105 +
... ...
hw/integratorcp.c
... ... @@ -10,10 +10,6 @@
10 10 #include "vl.h"
11 11 #include "arm_pic.h"
12 12  
13   -#define KERNEL_ARGS_ADDR 0x100
14   -#define KERNEL_LOAD_ADDR 0x00010000
15   -#define INITRD_LOAD_ADDR 0x00800000
16   -
17 13 void DMA_run (void)
18 14 {
19 15 }
... ... @@ -470,57 +466,6 @@ static void icp_control_init(uint32_t base)
470 466 }
471 467  
472 468  
473   -/* The worlds second smallest bootloader. Set r0-r2, then jump to kernel. */
474   -static uint32_t bootloader[] = {
475   - 0xe3a00000, /* mov r0, #0 */
476   - 0xe3a01013, /* mov r1, #0x13 */
477   - 0xe3811c01, /* orr r1, r1, #0x100 */
478   - 0xe59f2000, /* ldr r2, [pc, #0] */
479   - 0xe59ff000, /* ldr pc, [pc, #0] */
480   - 0, /* Address of kernel args. Set by integratorcp_init. */
481   - 0 /* Kernel entry point. Set by integratorcp_init. */
482   -};
483   -
484   -static void set_kernel_args(uint32_t ram_size, int initrd_size,
485   - const char *kernel_cmdline)
486   -{
487   - uint32_t *p;
488   -
489   - p = (uint32_t *)(phys_ram_base + KERNEL_ARGS_ADDR);
490   - /* ATAG_CORE */
491   - stl_raw(p++, 5);
492   - stl_raw(p++, 0x54410001);
493   - stl_raw(p++, 1);
494   - stl_raw(p++, 0x1000);
495   - stl_raw(p++, 0);
496   - /* ATAG_MEM */
497   - stl_raw(p++, 4);
498   - stl_raw(p++, 0x54410002);
499   - stl_raw(p++, ram_size);
500   - stl_raw(p++, 0);
501   - if (initrd_size) {
502   - /* ATAG_INITRD2 */
503   - stl_raw(p++, 4);
504   - stl_raw(p++, 0x54420005);
505   - stl_raw(p++, INITRD_LOAD_ADDR);
506   - stl_raw(p++, initrd_size);
507   - }
508   - if (kernel_cmdline && *kernel_cmdline) {
509   - /* ATAG_CMDLINE */
510   - int cmdline_size;
511   -
512   - cmdline_size = strlen(kernel_cmdline);
513   - memcpy (p + 2, kernel_cmdline, cmdline_size + 1);
514   - cmdline_size = (cmdline_size >> 2) + 1;
515   - stl_raw(p++, cmdline_size + 2);
516   - stl_raw(p++, 0x54410009);
517   - p += cmdline_size;
518   - }
519   - /* ATAG_END */
520   - stl_raw(p++, 0);
521   - stl_raw(p++, 0);
522   -}
523   -
524 469 /* Board init. */
525 470  
526 471 static void integratorcp_init(int ram_size, int vga_ram_size, int boot_device,
... ... @@ -532,9 +477,6 @@ static void integratorcp_init(int ram_size, int vga_ram_size, int boot_device,
532 477 uint32_t bios_offset;
533 478 icp_pic_state *pic;
534 479 void *cpu_pic;
535   - int kernel_size;
536   - int initrd_size;
537   - int n;
538 480  
539 481 env = cpu_init();
540 482 cpu_arm_set_model(env, cpuid);
... ... @@ -567,33 +509,8 @@ static void integratorcp_init(int ram_size, int vga_ram_size, int boot_device,
567 509 }
568 510 pl110_init(ds, 0xc0000000, pic, 22, 0);
569 511  
570   - /* Load the kernel. */
571   - if (!kernel_filename) {
572   - fprintf(stderr, "Kernel image must be specified\n");
573   - exit(1);
574   - }
575   - kernel_size = load_image(kernel_filename,
576   - phys_ram_base + KERNEL_LOAD_ADDR);
577   - if (kernel_size < 0) {
578   - fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
579   - exit(1);
580   - }
581   - if (initrd_filename) {
582   - initrd_size = load_image(initrd_filename,
583   - phys_ram_base + INITRD_LOAD_ADDR);
584   - if (initrd_size < 0) {
585   - fprintf(stderr, "qemu: could not load initrd '%s'\n",
586   - initrd_filename);
587   - exit(1);
588   - }
589   - } else {
590   - initrd_size = 0;
591   - }
592   - bootloader[5] = KERNEL_ARGS_ADDR;
593   - bootloader[6] = KERNEL_LOAD_ADDR;
594   - for (n = 0; n < sizeof(bootloader) / 4; n++)
595   - stl_raw(phys_ram_base + (n * 4), bootloader[n]);
596   - set_kernel_args(ram_size, initrd_size, kernel_cmdline);
  512 + arm_load_kernel(ram_size, kernel_filename, kernel_cmdline,
  513 + initrd_filename, 0x113);
597 514 }
598 515  
599 516 static void integratorcp926_init(int ram_size, int vga_ram_size,
... ...
hw/versatilepb.c
1 1 /*
2   - * ARM Versatile Platform Baseboard System emulation.
  2 + * ARM Versatile Platform/Application Baseboard System emulation.
3 3 *
4 4 * Copyright (c) 2005-2006 CodeSourcery.
5 5 * Written by Paul Brook
... ... @@ -10,10 +10,6 @@
10 10 #include "vl.h"
11 11 #include "arm_pic.h"
12 12  
13   -#define KERNEL_ARGS_ADDR 0x100
14   -#define KERNEL_LOAD_ADDR 0x00010000
15   -#define INITRD_LOAD_ADDR 0x00800000
16   -
17 13 /* Primary interrupt controller. */
18 14  
19 15 typedef struct vpb_sic_state
... ... @@ -151,66 +147,16 @@ static vpb_sic_state *vpb_sic_init(uint32_t base, void *parent, int irq)
151 147  
152 148 /* Board init. */
153 149  
154   -/* The worlds second smallest bootloader. Set r0-r2, then jump to kernel. */
155   -static uint32_t bootloader[] = {
156   - 0xe3a00000, /* mov r0, #0 */
157   - 0xe3a01083, /* mov r1, #0x83 */
158   - 0xe3811c01, /* orr r1, r1, #0x100 */
159   - 0xe59f2000, /* ldr r2, [pc, #0] */
160   - 0xe59ff000, /* ldr pc, [pc, #0] */
161   - 0, /* Address of kernel args. Set by integratorcp_init. */
162   - 0 /* Kernel entry point. Set by integratorcp_init. */
163   -};
164   -
165   -static void set_kernel_args(uint32_t ram_size, int initrd_size,
166   - const char *kernel_cmdline)
167   -{
168   - uint32_t *p;
169   -
170   - p = (uint32_t *)(phys_ram_base + KERNEL_ARGS_ADDR);
171   - /* ATAG_CORE */
172   - stl_raw(p++, 5);
173   - stl_raw(p++, 0x54410001);
174   - stl_raw(p++, 1);
175   - stl_raw(p++, 0x1000);
176   - stl_raw(p++, 0);
177   - /* ATAG_MEM */
178   - stl_raw(p++, 4);
179   - stl_raw(p++, 0x54410002);
180   - stl_raw(p++, ram_size);
181   - stl_raw(p++, 0);
182   - if (initrd_size) {
183   - /* ATAG_INITRD2 */
184   - stl_raw(p++, 4);
185   - stl_raw(p++, 0x54420005);
186   - stl_raw(p++, INITRD_LOAD_ADDR);
187   - stl_raw(p++, initrd_size);
188   - }
189   - if (kernel_cmdline && *kernel_cmdline) {
190   - /* ATAG_CMDLINE */
191   - int cmdline_size;
  150 +/* The AB and PB boards both use the same core, just with different
  151 + peripherans and expansion busses. For now we emulate a subset of the
  152 + PB peripherals and just change the board ID. */
192 153  
193   - cmdline_size = strlen(kernel_cmdline);
194   - memcpy (p + 2, kernel_cmdline, cmdline_size + 1);
195   - cmdline_size = (cmdline_size >> 2) + 1;
196   - stl_raw(p++, cmdline_size + 2);
197   - stl_raw(p++, 0x54410009);
198   - p += cmdline_size;
199   - }
200   - /* ATAG_END */
201   - stl_raw(p++, 0);
202   - stl_raw(p++, 0);
203   -}
204   -
205   -static void vpb_init(int ram_size, int vga_ram_size, int boot_device,
  154 +static void versatile_init(int ram_size, int vga_ram_size, int boot_device,
206 155 DisplayState *ds, const char **fd_filename, int snapshot,
207 156 const char *kernel_filename, const char *kernel_cmdline,
208   - const char *initrd_filename)
  157 + const char *initrd_filename, int board_id)
209 158 {
210 159 CPUState *env;
211   - int kernel_size;
212   - int initrd_size;
213   - int n;
214 160 void *pic;
215 161 void *sic;
216 162  
... ... @@ -250,6 +196,7 @@ static void vpb_init(int ram_size, int vga_ram_size, int boot_device,
250 196 that includes hardware cursor support from the PL111. */
251 197 pl110_init(ds, 0x10120000, pic, 16, 1);
252 198  
  199 + /* Memory map for Versatile/PB: */
253 200 /* 0x10000000 System registers. */
254 201 /* 0x10001000 PCI controller config registers. */
255 202 /* 0x10002000 Serial bus interface. */
... ... @@ -285,33 +232,30 @@ static void vpb_init(int ram_size, int vga_ram_size, int boot_device,
285 232 /* 0x101f3000 UART2. */
286 233 /* 0x101f4000 SSPI. */
287 234  
288   - /* Load the kernel. */
289   - if (!kernel_filename) {
290   - fprintf(stderr, "Kernel image must be specified\n");
291   - exit(1);
292   - }
293   - kernel_size = load_image(kernel_filename,
294   - phys_ram_base + KERNEL_LOAD_ADDR);
295   - if (kernel_size < 0) {
296   - fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
297   - exit(1);
298   - }
299   - if (initrd_filename) {
300   - initrd_size = load_image(initrd_filename,
301   - phys_ram_base + INITRD_LOAD_ADDR);
302   - if (initrd_size < 0) {
303   - fprintf(stderr, "qemu: could not load initrd '%s'\n",
304   - initrd_filename);
305   - exit(1);
306   - }
307   - } else {
308   - initrd_size = 0;
309   - }
310   - bootloader[5] = KERNEL_ARGS_ADDR;
311   - bootloader[6] = KERNEL_LOAD_ADDR;
312   - for (n = 0; n < sizeof(bootloader) / 4; n++)
313   - stl_raw(phys_ram_base + (n * 4), bootloader[n]);
314   - set_kernel_args(ram_size, initrd_size, kernel_cmdline);
  235 + arm_load_kernel(ram_size, kernel_filename, kernel_cmdline,
  236 + initrd_filename, board_id);
  237 +}
  238 +
  239 +static void vpb_init(int ram_size, int vga_ram_size, int boot_device,
  240 + DisplayState *ds, const char **fd_filename, int snapshot,
  241 + const char *kernel_filename, const char *kernel_cmdline,
  242 + const char *initrd_filename)
  243 +{
  244 + versatile_init(ram_size, vga_ram_size, boot_device,
  245 + ds, fd_filename, snapshot,
  246 + kernel_filename, kernel_cmdline,
  247 + initrd_filename, 0x183);
  248 +}
  249 +
  250 +static void vab_init(int ram_size, int vga_ram_size, int boot_device,
  251 + DisplayState *ds, const char **fd_filename, int snapshot,
  252 + const char *kernel_filename, const char *kernel_cmdline,
  253 + const char *initrd_filename)
  254 +{
  255 + versatile_init(ram_size, vga_ram_size, boot_device,
  256 + ds, fd_filename, snapshot,
  257 + kernel_filename, kernel_cmdline,
  258 + initrd_filename, 0x25e);
315 259 }
316 260  
317 261 QEMUMachine versatilepb_machine = {
... ... @@ -319,3 +263,9 @@ QEMUMachine versatilepb_machine = {
319 263 "ARM Versatile/PB (ARM926EJ-S)",
320 264 vpb_init,
321 265 };
  266 +
  267 +QEMUMachine versatileab_machine = {
  268 + "versatileab",
  269 + "ARM Versatile/AB (ARM926EJ-S)",
  270 + vab_init,
  271 +};
... ...
... ... @@ -4863,6 +4863,7 @@ void register_machines(void)
4863 4863 qemu_register_machine(&integratorcp926_machine);
4864 4864 qemu_register_machine(&integratorcp1026_machine);
4865 4865 qemu_register_machine(&versatilepb_machine);
  4866 + qemu_register_machine(&versatileab_machine);
4866 4867 #elif defined(TARGET_SH4)
4867 4868 qemu_register_machine(&shix_machine);
4868 4869 #else
... ...
... ... @@ -987,6 +987,7 @@ extern QEMUMachine integratorcp1026_machine;
987 987  
988 988 /* versatilepb.c */
989 989 extern QEMUMachine versatilepb_machine;
  990 +extern QEMUMachine versatileab_machine;
990 991  
991 992 /* ps2.c */
992 993 void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg);
... ... @@ -1019,6 +1020,12 @@ void *pl190_init(uint32_t base, void *parent, int irq, int fiq);
1019 1020 void sp804_init(uint32_t base, void *pic, int irq);
1020 1021 void icp_pit_init(uint32_t base, void *pic, int irq);
1021 1022  
  1023 +/* arm_boot.c */
  1024 +
  1025 +void arm_load_kernel(int ram_size, const char *kernel_filename,
  1026 + const char *kernel_cmdline, const char *initrd_filename,
  1027 + int board_id);
  1028 +
1022 1029 /* sh7750.c */
1023 1030 struct SH7750State;
1024 1031  
... ...