Revision ee76f82e hw/sun4m.c

b/hw/sun4m.c
1 1
/*
2
 * QEMU Sun4m & Sun4d System Emulator
2
 * QEMU Sun4m & Sun4d & Sun4c System Emulator
3 3
 *
4 4
 * Copyright (c) 2003-2005 Fabrice Bellard
5 5
 *
......
51 51
 * SPARCcenter 2000
52 52
 * SPARCserver 1000
53 53
 *
54
 * Sun4c architecture was used in the following machines:
55
 * SPARCstation 1/1+, SPARCserver 1/1+
56
 * SPARCstation SLC
57
 * SPARCstation IPC
58
 * SPARCstation ELC
59
 * SPARCstation IPX
60
 *
54 61
 * See for example: http://www.sunhelp.org/faq/sunref1.html
55 62
 */
56 63

  
......
79 86
    target_phys_addr_t tcx_base, cs_base, power_base;
80 87
    target_phys_addr_t ecc_base;
81 88
    uint32_t ecc_version;
89
    target_phys_addr_t sun4c_intctl_base, sun4c_counter_base;
82 90
    long vram_size, nvram_size;
83 91
    // IRQ numbers are not PIL ones, but master interrupt controller register
84 92
    // bit numbers
......
521 529
        ecc_init(hwdef->ecc_base, hwdef->ecc_version);
522 530
}
523 531

  
532
static void sun4c_hw_init(const struct hwdef *hwdef, int RAM_size,
533
                          const char *boot_device,
534
                          DisplayState *ds, const char *kernel_filename,
535
                          const char *kernel_cmdline,
536
                          const char *initrd_filename, const char *cpu_model)
537
{
538
    CPUState *env;
539
    unsigned int i;
540
    void *iommu, *espdma, *ledma, *main_esp, *nvram;
541
    qemu_irq *cpu_irqs, *slavio_irq, *espdma_irq, *ledma_irq;
542
    qemu_irq *esp_reset, *le_reset;
543
    unsigned long prom_offset, kernel_size;
544
    int ret;
545
    char buf[1024];
546
    BlockDriverState *fd[MAX_FD];
547
    int index;
548

  
549
    /* init CPU */
550
    if (!cpu_model)
551
        cpu_model = hwdef->default_cpu_model;
552

  
553
    env = cpu_init(cpu_model);
554
    if (!env) {
555
        fprintf(stderr, "Unable to find Sparc CPU definition\n");
556
        exit(1);
557
    }
558

  
559
    cpu_sparc_set_id(env, 0);
560

  
561
    qemu_register_reset(main_cpu_reset, env);
562
    register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
563
    cpu_irqs = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);
564

  
565
    /* allocate RAM */
566
    if ((uint64_t)RAM_size > hwdef->max_mem) {
567
        fprintf(stderr, "qemu: Too much memory for this machine: %d, maximum %d\n",
568
                (unsigned int)RAM_size / (1024 * 1024),
569
                (unsigned int)hwdef->max_mem / (1024 * 1024));
570
        exit(1);
571
    }
572
    cpu_register_physical_memory(0, RAM_size, 0);
573

  
574
    /* load boot prom */
575
    prom_offset = RAM_size + hwdef->vram_size;
576
    cpu_register_physical_memory(hwdef->slavio_base,
577
                                 (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) &
578
                                 TARGET_PAGE_MASK,
579
                                 prom_offset | IO_MEM_ROM);
580

  
581
    if (bios_name == NULL)
582
        bios_name = PROM_FILENAME;
583
    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
584
    ret = load_elf(buf, hwdef->slavio_base - PROM_VADDR, NULL, NULL, NULL);
585
    if (ret < 0 || ret > PROM_SIZE_MAX)
586
        ret = load_image(buf, phys_ram_base + prom_offset);
587
    if (ret < 0 || ret > PROM_SIZE_MAX) {
588
        fprintf(stderr, "qemu: could not load prom '%s'\n",
589
                buf);
590
        exit(1);
591
    }
592
    prom_offset += (ret + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
593

  
594
    /* set up devices */
595
    slavio_intctl = sun4c_intctl_init(hwdef->sun4c_intctl_base,
596
                                      &slavio_irq, cpu_irqs);
597

  
598
    iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version);
599

  
600
    espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq],
601
                              iommu, &espdma_irq, &esp_reset);
602

  
603
    ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,
604
                             slavio_irq[hwdef->le_irq], iommu, &ledma_irq,
605
                             &le_reset);
606

  
607
    if (graphic_depth != 8 && graphic_depth != 24) {
608
        fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
609
        exit (1);
610
    }
611
    tcx_init(ds, hwdef->tcx_base, phys_ram_base + RAM_size, RAM_size,
612
             hwdef->vram_size, graphic_width, graphic_height, graphic_depth);
613

  
614
    if (nd_table[0].model == NULL
615
        || strcmp(nd_table[0].model, "lance") == 0) {
616
        lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset);
617
    } else if (strcmp(nd_table[0].model, "?") == 0) {
618
        fprintf(stderr, "qemu: Supported NICs: lance\n");
619
        exit (1);
620
    } else {
621
        fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
622
        exit (1);
623
    }
624

  
625
    nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0,
626
                        hwdef->nvram_size, 8);
627

  
628
    slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq],
629
                              nographic);
630
    // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
631
    // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
632
    slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq],
633
                       serial_hds[1], serial_hds[0]);
634

  
635
    if (hwdef->fd_base != (target_phys_addr_t)-1) {
636
        /* there is zero or one floppy drive */
637
        fd[1] = fd[0] = NULL;
638
        index = drive_get_index(IF_FLOPPY, 0, 0);
639
        if (index != -1)
640
            fd[0] = drives_table[index].bdrv;
641

  
642
        sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd);
643
    }
644

  
645
    if (drive_get_max_bus(IF_SCSI) > 0) {
646
        fprintf(stderr, "qemu: too many SCSI bus\n");
647
        exit(1);
648
    }
649

  
650
    main_esp = esp_init(hwdef->esp_base, espdma, *espdma_irq,
651
                        esp_reset);
652

  
653
    for (i = 0; i < ESP_MAX_DEVS; i++) {
654
        index = drive_get_index(IF_SCSI, 0, i);
655
        if (index == -1)
656
            continue;
657
        esp_scsi_attach(main_esp, drives_table[index].bdrv, i);
658
    }
659

  
660
    kernel_size = sun4m_load_kernel(kernel_filename, kernel_cmdline,
661
                                    initrd_filename);
662

  
663
    nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
664
               boot_device, RAM_size, kernel_size, graphic_width,
665
               graphic_height, graphic_depth, hwdef->machine_id, "Sun4c");
666
}
667

  
524 668
static const struct hwdef hwdefs[] = {
525 669
    /* SS-5 */
526 670
    {
......
540 684
        .le_base      = 0x78c00000,
541 685
        .power_base   = 0x7a000000,
542 686
        .ecc_base     = -1,
687
        .sun4c_intctl_base  = -1,
688
        .sun4c_counter_base = -1,
543 689
        .vram_size    = 0x00100000,
544 690
        .nvram_size   = 0x2000,
545 691
        .esp_irq = 18,
......
579 725
        .power_base   = 0xefa000000ULL,
580 726
        .ecc_base     = 0xf00000000ULL,
581 727
        .ecc_version  = 0x10000000, // version 0, implementation 1
728
        .sun4c_intctl_base  = -1,
729
        .sun4c_counter_base = -1,
582 730
        .vram_size    = 0x00100000,
583 731
        .nvram_size   = 0x2000,
584 732
        .esp_irq = 18,
......
618 766
        .power_base   = 0xefa000000ULL,
619 767
        .ecc_base     = 0xf00000000ULL,
620 768
        .ecc_version  = 0x00000000, // version 0, implementation 0
769
        .sun4c_intctl_base  = -1,
770
        .sun4c_counter_base = -1,
621 771
        .vram_size    = 0x00100000,
622 772
        .nvram_size   = 0x2000,
623 773
        .esp_irq = 18,
......
657 807
        .power_base   = 0xefa000000ULL,
658 808
        .ecc_base     = 0xf00000000ULL,
659 809
        .ecc_version  = 0x20000000, // version 0, implementation 2
810
        .sun4c_intctl_base  = -1,
811
        .sun4c_counter_base = -1,
660 812
        .vram_size    = 0x00100000,
661 813
        .nvram_size   = 0x2000,
662 814
        .esp_irq = 18,
......
677 829
        .max_mem = 0xffffffff, // XXX actually first 62GB ok
678 830
        .default_cpu_model = "TI SuperSparc II",
679 831
    },
832
    /* SS-2 */
833
    {
834
        .iommu_base   = 0xf8000000,
835
        .tcx_base     = 0xfe000000,
836
        .cs_base      = -1,
837
        .slavio_base  = 0xf6000000,
838
        .ms_kb_base   = 0xf0000000,
839
        .serial_base  = 0xf1000000,
840
        .nvram_base   = 0xf2000000,
841
        .fd_base      = 0xf7200000,
842
        .counter_base = -1,
843
        .intctl_base  = -1,
844
        .dma_base     = 0xf8400000,
845
        .esp_base     = 0xf8800000,
846
        .le_base      = 0xf8c00000,
847
        .power_base   = -1,
848
        .sun4c_intctl_base  = 0xf5000000,
849
        .sun4c_counter_base = 0xf3000000,
850
        .vram_size    = 0x00100000,
851
        .nvram_size   = 0x2000, // XXX 0x800,
852
        .esp_irq = 2,
853
        .le_irq = 3,
854
        .clock_irq = 5,
855
        .clock1_irq = 7,
856
        .ms_kb_irq = 1,
857
        .ser_irq = 1,
858
        .fd_irq = 1,
859
        .me_irq = 1,
860
        .cs_irq = -1,
861
        .machine_id = 0x55,
862
        .max_mem = 0x10000000,
863
        .default_cpu_model = "Cypress CY7C601",
864
    },
680 865
};
681 866

  
682 867
/* SPARCstation 5 hardware initialisation */
......
719 904
                  kernel_cmdline, initrd_filename, cpu_model);
720 905
}
721 906

  
907
/* SPARCstation 2 hardware initialisation */
908
static void ss2_init(int RAM_size, int vga_ram_size,
909
                     const char *boot_device, DisplayState *ds,
910
                     const char *kernel_filename, const char *kernel_cmdline,
911
                     const char *initrd_filename, const char *cpu_model)
912
{
913
    sun4c_hw_init(&hwdefs[4], RAM_size, boot_device, ds, kernel_filename,
914
                  kernel_cmdline, initrd_filename, cpu_model);
915
}
916

  
722 917
QEMUMachine ss5_machine = {
723 918
    "SS-5",
724 919
    "Sun4m platform, SPARCstation 5",
......
743 938
    ss20_init,
744 939
};
745 940

  
941
QEMUMachine ss2_machine = {
942
    "SS-2",
943
    "Sun4c platform, SPARCstation 2",
944
    ss2_init,
945
};
746 946

  
747 947
static const struct sun4d_hwdef sun4d_hwdefs[] = {
748 948
    /* SS-1000 */

Also available in: Unified diff