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