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