Commit e87231d4262e472628e866394f85320829fe4fc5
1 parent
c99657d3
Add a generic Niagara machine
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5329 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
74 additions
and
12 deletions
hw/boards.h
@@ -66,6 +66,7 @@ extern QEMUMachine ss1000_machine, ss2000_machine; | @@ -66,6 +66,7 @@ extern QEMUMachine ss1000_machine, ss2000_machine; | ||
66 | /* sun4u.c */ | 66 | /* sun4u.c */ |
67 | extern QEMUMachine sun4u_machine; | 67 | extern QEMUMachine sun4u_machine; |
68 | extern QEMUMachine sun4v_machine; | 68 | extern QEMUMachine sun4v_machine; |
69 | +extern QEMUMachine niagara_machine; | ||
69 | 70 | ||
70 | /* integratorcp.c */ | 71 | /* integratorcp.c */ |
71 | extern QEMUMachine integratorcp_machine; | 72 | extern QEMUMachine integratorcp_machine; |
hw/sun4u.c
@@ -46,7 +46,6 @@ | @@ -46,7 +46,6 @@ | ||
46 | #define CMDLINE_ADDR 0x003ff000 | 46 | #define CMDLINE_ADDR 0x003ff000 |
47 | #define INITRD_LOAD_ADDR 0x00300000 | 47 | #define INITRD_LOAD_ADDR 0x00300000 |
48 | #define PROM_SIZE_MAX (4 * 1024 * 1024) | 48 | #define PROM_SIZE_MAX (4 * 1024 * 1024) |
49 | -#define PROM_ADDR 0x1fff0000000ULL | ||
50 | #define PROM_VADDR 0x000ffd00000ULL | 49 | #define PROM_VADDR 0x000ffd00000ULL |
51 | #define APB_SPECIAL_BASE 0x1fe00000000ULL | 50 | #define APB_SPECIAL_BASE 0x1fe00000000ULL |
52 | #define APB_MEM_BASE 0x1ff00000000ULL | 51 | #define APB_MEM_BASE 0x1ff00000000ULL |
@@ -61,6 +60,8 @@ | @@ -61,6 +60,8 @@ | ||
61 | struct hwdef { | 60 | struct hwdef { |
62 | const char * const default_cpu_model; | 61 | const char * const default_cpu_model; |
63 | uint16_t machine_id; | 62 | uint16_t machine_id; |
63 | + uint64_t prom_addr; | ||
64 | + uint64_t console_serial_base; | ||
64 | }; | 65 | }; |
65 | 66 | ||
66 | int DMA_get_channel_mode (int nchan) | 67 | int DMA_get_channel_mode (int nchan) |
@@ -260,9 +261,15 @@ void qemu_system_powerdown(void) | @@ -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 | static void main_cpu_reset(void *opaque) | 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 | cpu_reset(env); | 274 | cpu_reset(env); |
268 | ptimer_set_limit(env->tick, 0x7fffffffffffffffULL, 1); | 275 | ptimer_set_limit(env->tick, 0x7fffffffffffffffULL, 1); |
@@ -271,6 +278,11 @@ static void main_cpu_reset(void *opaque) | @@ -271,6 +278,11 @@ static void main_cpu_reset(void *opaque) | ||
271 | ptimer_run(env->stick, 0); | 278 | ptimer_run(env->stick, 0); |
272 | ptimer_set_limit(env->hstick, 0x7fffffffffffffffULL, 1); | 279 | ptimer_set_limit(env->hstick, 0x7fffffffffffffffULL, 1); |
273 | ptimer_run(env->hstick, 0); | 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 | static void tick_irq(void *opaque) | 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,6 +340,7 @@ static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size, | ||
328 | BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; | 340 | BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; |
329 | BlockDriverState *fd[MAX_FD]; | 341 | BlockDriverState *fd[MAX_FD]; |
330 | void *fw_cfg; | 342 | void *fw_cfg; |
343 | + ResetData *reset_info; | ||
331 | 344 | ||
332 | linux_boot = (kernel_filename != NULL); | 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,14 +364,21 @@ static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size, | ||
351 | bh = qemu_bh_new(hstick_irq, env); | 364 | bh = qemu_bh_new(hstick_irq, env); |
352 | env->hstick = ptimer_init(bh); | 365 | env->hstick = ptimer_init(bh); |
353 | ptimer_set_period(env->hstick, 1ULL); | 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 | /* allocate RAM */ | 377 | /* allocate RAM */ |
358 | cpu_register_physical_memory(0, RAM_size, 0); | 378 | cpu_register_physical_memory(0, RAM_size, 0); |
359 | 379 | ||
360 | prom_offset = RAM_size + vga_ram_size; | 380 | prom_offset = RAM_size + vga_ram_size; |
361 | - cpu_register_physical_memory(PROM_ADDR, | 381 | + cpu_register_physical_memory(hwdef->prom_addr, |
362 | (PROM_SIZE_MAX + TARGET_PAGE_SIZE) & | 382 | (PROM_SIZE_MAX + TARGET_PAGE_SIZE) & |
363 | TARGET_PAGE_MASK, | 383 | TARGET_PAGE_MASK, |
364 | prom_offset | IO_MEM_ROM); | 384 | prom_offset | IO_MEM_ROM); |
@@ -366,11 +386,16 @@ static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size, | @@ -366,11 +386,16 @@ static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size, | ||
366 | if (bios_name == NULL) | 386 | if (bios_name == NULL) |
367 | bios_name = PROM_FILENAME; | 387 | bios_name = PROM_FILENAME; |
368 | snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); | 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 | if (ret < 0) { | 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 | kernel_size = 0; | 401 | kernel_size = 0; |
@@ -417,7 +442,13 @@ static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size, | @@ -417,7 +442,13 @@ static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size, | ||
417 | pci_cirrus_vga_init(pci_bus, ds, phys_ram_base + RAM_size, RAM_size, | 442 | pci_cirrus_vga_init(pci_bus, ds, phys_ram_base + RAM_size, RAM_size, |
418 | vga_ram_size); | 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 | if (serial_hds[i]) { | 452 | if (serial_hds[i]) { |
422 | serial_init(serial_io[i], NULL/*serial_irq[i]*/, 115200, | 453 | serial_init(serial_io[i], NULL/*serial_irq[i]*/, 115200, |
423 | serial_hds[i]); | 454 | serial_hds[i]); |
@@ -482,6 +513,7 @@ static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size, | @@ -482,6 +513,7 @@ static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size, | ||
482 | enum { | 513 | enum { |
483 | sun4u_id = 0, | 514 | sun4u_id = 0, |
484 | sun4v_id = 64, | 515 | sun4v_id = 64, |
516 | + niagara_id, | ||
485 | }; | 517 | }; |
486 | 518 | ||
487 | static const struct hwdef hwdefs[] = { | 519 | static const struct hwdef hwdefs[] = { |
@@ -489,11 +521,22 @@ static const struct hwdef hwdefs[] = { | @@ -489,11 +521,22 @@ static const struct hwdef hwdefs[] = { | ||
489 | { | 521 | { |
490 | .default_cpu_model = "TI UltraSparc II", | 522 | .default_cpu_model = "TI UltraSparc II", |
491 | .machine_id = sun4u_id, | 523 | .machine_id = sun4u_id, |
524 | + .prom_addr = 0x1fff0000000ULL, | ||
525 | + .console_serial_base = 0, | ||
492 | }, | 526 | }, |
493 | /* Sun4v generic PC-like machine */ | 527 | /* Sun4v generic PC-like machine */ |
494 | { | 528 | { |
495 | .default_cpu_model = "Sun UltraSparc T1", | 529 | .default_cpu_model = "Sun UltraSparc T1", |
496 | .machine_id = sun4v_id, | 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,6 +560,16 @@ static void sun4v_init(ram_addr_t RAM_size, int vga_ram_size, | ||
517 | kernel_cmdline, initrd_filename, cpu_model, &hwdefs[1]); | 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 | QEMUMachine sun4u_machine = { | 573 | QEMUMachine sun4u_machine = { |
521 | .name = "sun4u", | 574 | .name = "sun4u", |
522 | .desc = "Sun4u platform", | 575 | .desc = "Sun4u platform", |
@@ -532,3 +585,11 @@ QEMUMachine sun4v_machine = { | @@ -532,3 +585,11 @@ QEMUMachine sun4v_machine = { | ||
532 | .ram_require = PROM_SIZE_MAX + VGA_RAM_SIZE, | 585 | .ram_require = PROM_SIZE_MAX + VGA_RAM_SIZE, |
533 | .nodisk_ok = 1, | 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,13 +658,12 @@ void cpu_reset(CPUSPARCState *env) | ||
658 | #ifdef TARGET_SPARC64 | 658 | #ifdef TARGET_SPARC64 |
659 | env->pstate = PS_PRIV; | 659 | env->pstate = PS_PRIV; |
660 | env->hpstate = HS_PRIV; | 660 | env->hpstate = HS_PRIV; |
661 | - env->pc = 0x1fff0000020ULL; // XXX should be different for system_reset | ||
662 | env->tsptr = &env->ts[env->tl & MAXTL_MASK]; | 661 | env->tsptr = &env->ts[env->tl & MAXTL_MASK]; |
663 | #else | 662 | #else |
664 | - env->pc = 0; | ||
665 | env->mmuregs[0] &= ~(MMU_E | MMU_NF); | 663 | env->mmuregs[0] &= ~(MMU_E | MMU_NF); |
666 | env->mmuregs[0] |= env->def->mmu_bm; | 664 | env->mmuregs[0] |= env->def->mmu_bm; |
667 | #endif | 665 | #endif |
666 | + env->pc = 0; | ||
668 | env->npc = env->pc + 4; | 667 | env->npc = env->pc + 4; |
669 | #endif | 668 | #endif |
670 | } | 669 | } |
target-sparc/machine.c
@@ -9,6 +9,7 @@ void register_machines(void) | @@ -9,6 +9,7 @@ void register_machines(void) | ||
9 | #ifdef TARGET_SPARC64 | 9 | #ifdef TARGET_SPARC64 |
10 | qemu_register_machine(&sun4u_machine); | 10 | qemu_register_machine(&sun4u_machine); |
11 | qemu_register_machine(&sun4v_machine); | 11 | qemu_register_machine(&sun4v_machine); |
12 | + qemu_register_machine(&niagara_machine); | ||
12 | #else | 13 | #else |
13 | qemu_register_machine(&ss5_machine); | 14 | qemu_register_machine(&ss5_machine); |
14 | qemu_register_machine(&ss10_machine); | 15 | qemu_register_machine(&ss10_machine); |