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,7 +346,7 @@ endif
346 endif 346 endif
347 ifeq ($(TARGET_BASE_ARCH), arm) 347 ifeq ($(TARGET_BASE_ARCH), arm)
348 VL_OBJS+= integratorcp.o versatilepb.o ps2.o smc91c111.o arm_pic.o arm_timer.o 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 endif 350 endif
351 ifeq ($(TARGET_BASE_ARCH), sh4) 351 ifeq ($(TARGET_BASE_ARCH), sh4)
352 VL_OBJS+= shix.o sh7750.o sh7750_regnames.o tc58128.o 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 +10,6 @@
10 #include "vl.h" 10 #include "vl.h"
11 #include "arm_pic.h" 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 void DMA_run (void) 13 void DMA_run (void)
18 { 14 {
19 } 15 }
@@ -470,57 +466,6 @@ static void icp_control_init(uint32_t base) @@ -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 /* Board init. */ 469 /* Board init. */
525 470
526 static void integratorcp_init(int ram_size, int vga_ram_size, int boot_device, 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,9 +477,6 @@ static void integratorcp_init(int ram_size, int vga_ram_size, int boot_device,
532 uint32_t bios_offset; 477 uint32_t bios_offset;
533 icp_pic_state *pic; 478 icp_pic_state *pic;
534 void *cpu_pic; 479 void *cpu_pic;
535 - int kernel_size;  
536 - int initrd_size;  
537 - int n;  
538 480
539 env = cpu_init(); 481 env = cpu_init();
540 cpu_arm_set_model(env, cpuid); 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,33 +509,8 @@ static void integratorcp_init(int ram_size, int vga_ram_size, int boot_device,
567 } 509 }
568 pl110_init(ds, 0xc0000000, pic, 22, 0); 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 static void integratorcp926_init(int ram_size, int vga_ram_size, 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 * Copyright (c) 2005-2006 CodeSourcery. 4 * Copyright (c) 2005-2006 CodeSourcery.
5 * Written by Paul Brook 5 * Written by Paul Brook
@@ -10,10 +10,6 @@ @@ -10,10 +10,6 @@
10 #include "vl.h" 10 #include "vl.h"
11 #include "arm_pic.h" 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 /* Primary interrupt controller. */ 13 /* Primary interrupt controller. */
18 14
19 typedef struct vpb_sic_state 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,66 +147,16 @@ static vpb_sic_state *vpb_sic_init(uint32_t base, void *parent, int irq)
151 147
152 /* Board init. */ 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 DisplayState *ds, const char **fd_filename, int snapshot, 155 DisplayState *ds, const char **fd_filename, int snapshot,
207 const char *kernel_filename, const char *kernel_cmdline, 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 CPUState *env; 159 CPUState *env;
211 - int kernel_size;  
212 - int initrd_size;  
213 - int n;  
214 void *pic; 160 void *pic;
215 void *sic; 161 void *sic;
216 162
@@ -250,6 +196,7 @@ static void vpb_init(int ram_size, int vga_ram_size, int boot_device, @@ -250,6 +196,7 @@ static void vpb_init(int ram_size, int vga_ram_size, int boot_device,
250 that includes hardware cursor support from the PL111. */ 196 that includes hardware cursor support from the PL111. */
251 pl110_init(ds, 0x10120000, pic, 16, 1); 197 pl110_init(ds, 0x10120000, pic, 16, 1);
252 198
  199 + /* Memory map for Versatile/PB: */
253 /* 0x10000000 System registers. */ 200 /* 0x10000000 System registers. */
254 /* 0x10001000 PCI controller config registers. */ 201 /* 0x10001000 PCI controller config registers. */
255 /* 0x10002000 Serial bus interface. */ 202 /* 0x10002000 Serial bus interface. */
@@ -285,33 +232,30 @@ static void vpb_init(int ram_size, int vga_ram_size, int boot_device, @@ -285,33 +232,30 @@ static void vpb_init(int ram_size, int vga_ram_size, int boot_device,
285 /* 0x101f3000 UART2. */ 232 /* 0x101f3000 UART2. */
286 /* 0x101f4000 SSPI. */ 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 QEMUMachine versatilepb_machine = { 261 QEMUMachine versatilepb_machine = {
@@ -319,3 +263,9 @@ QEMUMachine versatilepb_machine = { @@ -319,3 +263,9 @@ QEMUMachine versatilepb_machine = {
319 "ARM Versatile/PB (ARM926EJ-S)", 263 "ARM Versatile/PB (ARM926EJ-S)",
320 vpb_init, 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,6 +4863,7 @@ void register_machines(void)
4863 qemu_register_machine(&integratorcp926_machine); 4863 qemu_register_machine(&integratorcp926_machine);
4864 qemu_register_machine(&integratorcp1026_machine); 4864 qemu_register_machine(&integratorcp1026_machine);
4865 qemu_register_machine(&versatilepb_machine); 4865 qemu_register_machine(&versatilepb_machine);
  4866 + qemu_register_machine(&versatileab_machine);
4866 #elif defined(TARGET_SH4) 4867 #elif defined(TARGET_SH4)
4867 qemu_register_machine(&shix_machine); 4868 qemu_register_machine(&shix_machine);
4868 #else 4869 #else
@@ -987,6 +987,7 @@ extern QEMUMachine integratorcp1026_machine; @@ -987,6 +987,7 @@ extern QEMUMachine integratorcp1026_machine;
987 987
988 /* versatilepb.c */ 988 /* versatilepb.c */
989 extern QEMUMachine versatilepb_machine; 989 extern QEMUMachine versatilepb_machine;
  990 +extern QEMUMachine versatileab_machine;
990 991
991 /* ps2.c */ 992 /* ps2.c */
992 void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg); 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,6 +1020,12 @@ void *pl190_init(uint32_t base, void *parent, int irq, int fiq);
1019 void sp804_init(uint32_t base, void *pic, int irq); 1020 void sp804_init(uint32_t base, void *pic, int irq);
1020 void icp_pit_init(uint32_t base, void *pic, int irq); 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 /* sh7750.c */ 1029 /* sh7750.c */
1023 struct SH7750State; 1030 struct SH7750State;
1024 1031