Commit e87231d4262e472628e866394f85320829fe4fc5

Authored by blueswir1
1 parent c99657d3

Add a generic Niagara machine

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5329 c046a42c-6fe2-441c-8c8c-71466251a162
hw/boards.h
... ... @@ -66,6 +66,7 @@ extern QEMUMachine ss1000_machine, ss2000_machine;
66 66 /* sun4u.c */
67 67 extern QEMUMachine sun4u_machine;
68 68 extern QEMUMachine sun4v_machine;
  69 +extern QEMUMachine niagara_machine;
69 70  
70 71 /* integratorcp.c */
71 72 extern QEMUMachine integratorcp_machine;
... ...
hw/sun4u.c
... ... @@ -46,7 +46,6 @@
46 46 #define CMDLINE_ADDR 0x003ff000
47 47 #define INITRD_LOAD_ADDR 0x00300000
48 48 #define PROM_SIZE_MAX (4 * 1024 * 1024)
49   -#define PROM_ADDR 0x1fff0000000ULL
50 49 #define PROM_VADDR 0x000ffd00000ULL
51 50 #define APB_SPECIAL_BASE 0x1fe00000000ULL
52 51 #define APB_MEM_BASE 0x1ff00000000ULL
... ... @@ -61,6 +60,8 @@
61 60 struct hwdef {
62 61 const char * const default_cpu_model;
63 62 uint16_t machine_id;
  63 + uint64_t prom_addr;
  64 + uint64_t console_serial_base;
64 65 };
65 66  
66 67 int DMA_get_channel_mode (int nchan)
... ... @@ -260,9 +261,15 @@ void qemu_system_powerdown(void)
260 261 {
261 262 }
262 263  
  264 +typedef struct ResetData {
  265 + CPUState *env;
  266 + uint64_t reset_addr;
  267 +} ResetData;
  268 +
263 269 static void main_cpu_reset(void *opaque)
264 270 {
265   - CPUState *env = opaque;
  271 + ResetData *s = (ResetData *)opaque;
  272 + CPUState *env = s->env;
266 273  
267 274 cpu_reset(env);
268 275 ptimer_set_limit(env->tick, 0x7fffffffffffffffULL, 1);
... ... @@ -271,6 +278,11 @@ static void main_cpu_reset(void *opaque)
271 278 ptimer_run(env->stick, 0);
272 279 ptimer_set_limit(env->hstick, 0x7fffffffffffffffULL, 1);
273 280 ptimer_run(env->hstick, 0);
  281 + env->gregs[1] = 0; // Memory start
  282 + env->gregs[2] = ram_size; // Memory size
  283 + env->gregs[3] = 0; // Machine description XXX
  284 + env->pc = s->reset_addr;
  285 + env->npc = env->pc + 4;
274 286 }
275 287  
276 288 static void tick_irq(void *opaque)
... ... @@ -328,6 +340,7 @@ static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size,
328 340 BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
329 341 BlockDriverState *fd[MAX_FD];
330 342 void *fw_cfg;
  343 + ResetData *reset_info;
331 344  
332 345 linux_boot = (kernel_filename != NULL);
333 346  
... ... @@ -351,14 +364,21 @@ static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size,
351 364 bh = qemu_bh_new(hstick_irq, env);
352 365 env->hstick = ptimer_init(bh);
353 366 ptimer_set_period(env->hstick, 1ULL);
354   - qemu_register_reset(main_cpu_reset, env);
355   - main_cpu_reset(env);
  367 +
  368 + reset_info = qemu_mallocz(sizeof(ResetData));
  369 + reset_info->env = env;
  370 + reset_info->reset_addr = hwdef->prom_addr + 0x40ULL;
  371 + qemu_register_reset(main_cpu_reset, reset_info);
  372 + main_cpu_reset(reset_info);
  373 + // Override warm reset address with cold start address
  374 + env->pc = hwdef->prom_addr + 0x20ULL;
  375 + env->npc = env->pc + 4;
356 376  
357 377 /* allocate RAM */
358 378 cpu_register_physical_memory(0, RAM_size, 0);
359 379  
360 380 prom_offset = RAM_size + vga_ram_size;
361   - cpu_register_physical_memory(PROM_ADDR,
  381 + cpu_register_physical_memory(hwdef->prom_addr,
362 382 (PROM_SIZE_MAX + TARGET_PAGE_SIZE) &
363 383 TARGET_PAGE_MASK,
364 384 prom_offset | IO_MEM_ROM);
... ... @@ -366,11 +386,16 @@ static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size,
366 386 if (bios_name == NULL)
367 387 bios_name = PROM_FILENAME;
368 388 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
369   - ret = load_elf(buf, PROM_ADDR - PROM_VADDR, NULL, NULL, NULL);
  389 + ret = load_elf(buf, hwdef->prom_addr - PROM_VADDR, NULL, NULL, NULL);
370 390 if (ret < 0) {
371   - fprintf(stderr, "qemu: could not load prom '%s'\n",
372   - buf);
373   - exit(1);
  391 + ret = load_image_targphys(buf, hwdef->prom_addr,
  392 + (PROM_SIZE_MAX + TARGET_PAGE_SIZE) &
  393 + TARGET_PAGE_MASK);
  394 + if (ret < 0) {
  395 + fprintf(stderr, "qemu: could not load prom '%s'\n",
  396 + buf);
  397 + exit(1);
  398 + }
374 399 }
375 400  
376 401 kernel_size = 0;
... ... @@ -417,7 +442,13 @@ static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size,
417 442 pci_cirrus_vga_init(pci_bus, ds, phys_ram_base + RAM_size, RAM_size,
418 443 vga_ram_size);
419 444  
420   - for(i = 0; i < MAX_SERIAL_PORTS; i++) {
  445 + i = 0;
  446 + if (hwdef->console_serial_base) {
  447 + serial_mm_init(hwdef->console_serial_base, 0, NULL, 115200,
  448 + serial_hds[i], 1);
  449 + i++;
  450 + }
  451 + for(; i < MAX_SERIAL_PORTS; i++) {
421 452 if (serial_hds[i]) {
422 453 serial_init(serial_io[i], NULL/*serial_irq[i]*/, 115200,
423 454 serial_hds[i]);
... ... @@ -482,6 +513,7 @@ static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size,
482 513 enum {
483 514 sun4u_id = 0,
484 515 sun4v_id = 64,
  516 + niagara_id,
485 517 };
486 518  
487 519 static const struct hwdef hwdefs[] = {
... ... @@ -489,11 +521,22 @@ static const struct hwdef hwdefs[] = {
489 521 {
490 522 .default_cpu_model = "TI UltraSparc II",
491 523 .machine_id = sun4u_id,
  524 + .prom_addr = 0x1fff0000000ULL,
  525 + .console_serial_base = 0,
492 526 },
493 527 /* Sun4v generic PC-like machine */
494 528 {
495 529 .default_cpu_model = "Sun UltraSparc T1",
496 530 .machine_id = sun4v_id,
  531 + .prom_addr = 0x1fff0000000ULL,
  532 + .console_serial_base = 0,
  533 + },
  534 + /* Sun4v generic Niagara machine */
  535 + {
  536 + .default_cpu_model = "Sun UltraSparc T1",
  537 + .machine_id = niagara_id,
  538 + .prom_addr = 0xfff0000000ULL,
  539 + .console_serial_base = 0xfff0c2c000ULL,
497 540 },
498 541 };
499 542  
... ... @@ -517,6 +560,16 @@ static void sun4v_init(ram_addr_t RAM_size, int vga_ram_size,
517 560 kernel_cmdline, initrd_filename, cpu_model, &hwdefs[1]);
518 561 }
519 562  
  563 +/* Niagara hardware initialisation */
  564 +static void niagara_init(ram_addr_t RAM_size, int vga_ram_size,
  565 + const char *boot_devices, DisplayState *ds,
  566 + const char *kernel_filename, const char *kernel_cmdline,
  567 + const char *initrd_filename, const char *cpu_model)
  568 +{
  569 + sun4uv_init(RAM_size, vga_ram_size, boot_devices, ds, kernel_filename,
  570 + kernel_cmdline, initrd_filename, cpu_model, &hwdefs[2]);
  571 +}
  572 +
520 573 QEMUMachine sun4u_machine = {
521 574 .name = "sun4u",
522 575 .desc = "Sun4u platform",
... ... @@ -532,3 +585,11 @@ QEMUMachine sun4v_machine = {
532 585 .ram_require = PROM_SIZE_MAX + VGA_RAM_SIZE,
533 586 .nodisk_ok = 1,
534 587 };
  588 +
  589 +QEMUMachine niagara_machine = {
  590 + .name = "Niagara",
  591 + .desc = "Sun4v platform, Niagara",
  592 + .init = niagara_init,
  593 + .ram_require = PROM_SIZE_MAX + VGA_RAM_SIZE,
  594 + .nodisk_ok = 1,
  595 +};
... ...
target-sparc/helper.c
... ... @@ -658,13 +658,12 @@ void cpu_reset(CPUSPARCState *env)
658 658 #ifdef TARGET_SPARC64
659 659 env->pstate = PS_PRIV;
660 660 env->hpstate = HS_PRIV;
661   - env->pc = 0x1fff0000020ULL; // XXX should be different for system_reset
662 661 env->tsptr = &env->ts[env->tl & MAXTL_MASK];
663 662 #else
664   - env->pc = 0;
665 663 env->mmuregs[0] &= ~(MMU_E | MMU_NF);
666 664 env->mmuregs[0] |= env->def->mmu_bm;
667 665 #endif
  666 + env->pc = 0;
668 667 env->npc = env->pc + 4;
669 668 #endif
670 669 }
... ...
target-sparc/machine.c
... ... @@ -9,6 +9,7 @@ void register_machines(void)
9 9 #ifdef TARGET_SPARC64
10 10 qemu_register_machine(&sun4u_machine);
11 11 qemu_register_machine(&sun4v_machine);
  12 + qemu_register_machine(&niagara_machine);
12 13 #else
13 14 qemu_register_machine(&ss5_machine);
14 15 qemu_register_machine(&ss10_machine);
... ...