Revision e87231d4 hw/sun4u.c
b/hw/sun4u.c | ||
---|---|---|
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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 |
}; |
Also available in: Unified diff