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); |