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