📄 sun4m.c.svn-base
字号:
} register_savevm("cpu", i, 3, cpu_save, cpu_load, env); cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS); env->prom_addr = hwdef->slavio_base; } for (i = smp_cpus; i < MAX_CPUS; i++) cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS); /* allocate RAM */ if ((uint64_t)RAM_size > hwdef->max_mem) { fprintf(stderr, "qemu: Too much memory for this machine: %d, maximum %d\n", (unsigned int)RAM_size / (1024 * 1024), (unsigned int)(hwdef->max_mem / (1024 * 1024))); exit(1); } cpu_register_physical_memory(0, RAM_size, 0); /* load boot prom */ prom_offset = RAM_size + hwdef->vram_size; cpu_register_physical_memory(hwdef->slavio_base, (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK, prom_offset | IO_MEM_ROM); if (bios_name == NULL) bios_name = PROM_FILENAME; snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); ret = load_elf(buf, hwdef->slavio_base - PROM_VADDR, NULL, NULL, NULL); if (ret < 0 || ret > PROM_SIZE_MAX) ret = load_image(buf, phys_ram_base + prom_offset); if (ret < 0 || ret > PROM_SIZE_MAX) { fprintf(stderr, "qemu: could not load prom '%s'\n", buf); exit(1); } prom_offset += (ret + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK; /* set up devices */ slavio_intctl = slavio_intctl_init(hwdef->intctl_base, hwdef->intctl_base + 0x10000ULL, &hwdef->intbit_to_level[0], &slavio_irq, &slavio_cpu_irq, cpu_irqs, hwdef->clock_irq); if (hwdef->idreg_base != (target_phys_addr_t)-1) { stl_raw(phys_ram_base + prom_offset, 0xfe810103); cpu_register_physical_memory(hwdef->idreg_base, sizeof(uint32_t), prom_offset | IO_MEM_ROM); } iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version, slavio_irq[hwdef->me_irq]); espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq], iommu, &espdma_irq, &esp_reset); ledma = sparc32_dma_init(hwdef->dma_base + 16ULL, slavio_irq[hwdef->le_irq], iommu, &ledma_irq, &le_reset); if (graphic_depth != 8 && graphic_depth != 24) { fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth); exit (1); } tcx_init(ds, hwdef->tcx_base, phys_ram_base + RAM_size, RAM_size, hwdef->vram_size, graphic_width, graphic_height, graphic_depth); if (nd_table[0].model == NULL || strcmp(nd_table[0].model, "lance") == 0) { lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset); } else if (strcmp(nd_table[0].model, "?") == 0) { fprintf(stderr, "qemu: Supported NICs: lance\n"); exit (1); } else { fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model); exit (1); } nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0, hwdef->nvram_size, 8); slavio_timer_init_all(hwdef->counter_base, slavio_irq[hwdef->clock1_irq], slavio_cpu_irq, smp_cpus); slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq], nographic); // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq], serial_hds[1], serial_hds[0]); if (hwdef->fd_base != (target_phys_addr_t)-1) { /* there is zero or one floppy drive */ fd[1] = fd[0] = NULL; index = drive_get_index(IF_FLOPPY, 0, 0); if (index != -1) fd[0] = drives_table[index].bdrv; sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd); } if (drive_get_max_bus(IF_SCSI) > 0) { fprintf(stderr, "qemu: too many SCSI bus\n"); exit(1); } main_esp = esp_init(hwdef->esp_base, espdma, *espdma_irq, esp_reset); for (i = 0; i < ESP_MAX_DEVS; i++) { index = drive_get_index(IF_SCSI, 0, i); if (index == -1) continue; esp_scsi_attach(main_esp, drives_table[index].bdrv, i); } slavio_misc = slavio_misc_init(hwdef->slavio_base, hwdef->power_base, slavio_irq[hwdef->me_irq]); if (hwdef->cs_base != (target_phys_addr_t)-1) cs_init(hwdef->cs_base, hwdef->cs_irq, slavio_intctl); kernel_size = sun4m_load_kernel(kernel_filename, kernel_cmdline, initrd_filename); nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline, boot_device, RAM_size, kernel_size, graphic_width, graphic_height, graphic_depth, hwdef->machine_id, "Sun4m"); if (hwdef->ecc_base != (target_phys_addr_t)-1) ecc_init(hwdef->ecc_base, hwdef->ecc_version);}static void sun4c_hw_init(const struct hwdef *hwdef, int RAM_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model){ CPUState *env; unsigned int i; void *iommu, *espdma, *ledma, *main_esp, *nvram; qemu_irq *cpu_irqs, *slavio_irq, *espdma_irq, *ledma_irq; qemu_irq *esp_reset, *le_reset; unsigned long prom_offset, kernel_size; int ret; char buf[1024]; BlockDriverState *fd[MAX_FD]; int index; /* init CPU */ if (!cpu_model) cpu_model = hwdef->default_cpu_model; env = cpu_init(cpu_model); if (!env) { fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n"); exit(1); } cpu_sparc_set_id(env, 0); qemu_register_reset(main_cpu_reset, env); register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); cpu_irqs = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS); env->prom_addr = hwdef->slavio_base; /* allocate RAM */ if ((uint64_t)RAM_size > hwdef->max_mem) { fprintf(stderr, "qemu: Too much memory for this machine: %d, maximum %d\n", (unsigned int)RAM_size / (1024 * 1024), (unsigned int)hwdef->max_mem / (1024 * 1024)); exit(1); } cpu_register_physical_memory(0, RAM_size, 0); /* load boot prom */ prom_offset = RAM_size + hwdef->vram_size; cpu_register_physical_memory(hwdef->slavio_base, (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK, prom_offset | IO_MEM_ROM); if (bios_name == NULL) bios_name = PROM_FILENAME; snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); ret = load_elf(buf, hwdef->slavio_base - PROM_VADDR, NULL, NULL, NULL); if (ret < 0 || ret > PROM_SIZE_MAX) ret = load_image(buf, phys_ram_base + prom_offset); if (ret < 0 || ret > PROM_SIZE_MAX) { fprintf(stderr, "qemu: could not load prom '%s'\n", buf); exit(1); } prom_offset += (ret + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK; /* set up devices */ slavio_intctl = sun4c_intctl_init(hwdef->sun4c_intctl_base, &slavio_irq, cpu_irqs); iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version, slavio_irq[hwdef->me_irq]); espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq], iommu, &espdma_irq, &esp_reset); ledma = sparc32_dma_init(hwdef->dma_base + 16ULL, slavio_irq[hwdef->le_irq], iommu, &ledma_irq, &le_reset); if (graphic_depth != 8 && graphic_depth != 24) { fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth); exit (1); } tcx_init(ds, hwdef->tcx_base, phys_ram_base + RAM_size, RAM_size, hwdef->vram_size, graphic_width, graphic_height, graphic_depth); if (nd_table[0].model == NULL || strcmp(nd_table[0].model, "lance") == 0) { lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset); } else if (strcmp(nd_table[0].model, "?") == 0) { fprintf(stderr, "qemu: Supported NICs: lance\n"); exit (1); } else { fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model); exit (1); } nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0, hwdef->nvram_size, 2); slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq], nographic); // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq], serial_hds[1], serial_hds[0]); if (hwdef->fd_base != (target_phys_addr_t)-1) { /* there is zero or one floppy drive */ fd[1] = fd[0] = NULL; index = drive_get_index(IF_FLOPPY, 0, 0); if (index != -1) fd[0] = drives_table[index].bdrv; sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd); } if (drive_get_max_bus(IF_SCSI) > 0) { fprintf(stderr, "qemu: too many SCSI bus\n"); exit(1); } main_esp = esp_init(hwdef->esp_base, espdma, *espdma_irq, esp_reset); for (i = 0; i < ESP_MAX_DEVS; i++) { index = drive_get_index(IF_SCSI, 0, i); if (index == -1) continue; esp_scsi_attach(main_esp, drives_table[index].bdrv, i); } kernel_size = sun4m_load_kernel(kernel_filename, kernel_cmdline, initrd_filename); nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline, boot_device, RAM_size, kernel_size, graphic_width, graphic_height, graphic_depth, hwdef->machine_id, "Sun4c");}static const struct hwdef hwdefs[] = { /* SS-5 */ { .iommu_base = 0x10000000, .tcx_base = 0x50000000, .cs_base = 0x6c000000, .slavio_base = 0x70000000, .ms_kb_base = 0x71000000, .serial_base = 0x71100000, .nvram_base = 0x71200000, .fd_base = 0x71400000, .counter_base = 0x71d00000, .intctl_base = 0x71e00000, .idreg_base = 0x78000000, .dma_base = 0x78400000, .esp_base = 0x78800000, .le_base = 0x78c00000, .power_base = 0x7a000000, .ecc_base = -1, .sun4c_intctl_base = -1, .sun4c_counter_base = -1, .vram_size = 0x00100000, .nvram_size = 0x2000, .esp_irq = 18, .le_irq = 16, .clock_irq = 7, .clock1_irq = 19, .ms_kb_irq = 14, .ser_irq = 15, .fd_irq = 22, .me_irq = 30, .cs_irq = 5, .machine_id = 0x80, .iommu_version = 0x05000000, .intbit_to_level = { 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12, 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0, }, .max_mem = 0x10000000, .default_cpu_model = "Fujitsu MB86904", }, /* SS-10 */ { .iommu_base = 0xfe0000000ULL, .tcx_base = 0xe20000000ULL, .cs_base = -1, .slavio_base = 0xff0000000ULL, .ms_kb_base = 0xff1000000ULL, .serial_base = 0xff1100000ULL, .nvram_base = 0xff1200000ULL, .fd_base = 0xff1700000ULL, .counter_base = 0xff1300000ULL, .intctl_base = 0xff1400000ULL, .idreg_base = 0xef0000000ULL, .dma_base = 0xef0400000ULL, .esp_base = 0xef0800000ULL, .le_base = 0xef0c00000ULL, .power_base = 0xefa000000ULL, .ecc_base = 0xf00000000ULL, .ecc_version = 0x10000000, // version 0, implementation 1 .sun4c_intctl_base = -1, .sun4c_counter_base = -1, .vram_size = 0x00100000, .nvram_size = 0x2000, .esp_irq = 18, .le_irq = 16, .clock_irq = 7, .clock1_irq = 19, .ms_kb_irq = 14, .ser_irq = 15, .fd_irq = 22, .me_irq = 30, .cs_irq = -1, .machine_id = 0x72, .iommu_version = 0x03000000, .intbit_to_level = { 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12, 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0, }, .max_mem = 0xffffffff, // XXX actually first 62GB ok .default_cpu_model = "TI SuperSparc II", }, /* SS-600MP */ { .iommu_base = 0xfe0000000ULL, .tcx_base = 0xe20000000ULL, .cs_base = -1, .slavio_base = 0xff0000000ULL, .ms_kb_base = 0xff1000000ULL, .serial_base = 0xff1100000ULL, .nvram_base = 0xff1200000ULL, .fd_base = -1, .counter_base = 0xff1300000ULL, .intctl_base = 0xff1400000ULL, .idreg_base = -1, .dma_base = 0xef0081000ULL, .esp_base = 0xef0080000ULL, .le_base = 0xef0060000ULL, .power_base = 0xefa000000ULL, .ecc_base = 0xf00000000ULL, .ecc_version = 0x00000000, // version 0, implementation 0 .sun4c_intctl_base = -1, .sun4c_counter_base = -1, .vram_size = 0x00100000, .nvram_size = 0x2000, .esp_irq = 18, .le_irq = 16, .clock_irq = 7, .clock1_irq = 19, .ms_kb_irq = 14, .ser_irq = 15, .fd_irq = 22, .me_irq = 30, .cs_irq = -1, .machine_id = 0x71, .iommu_version = 0x01000000, .intbit_to_level = { 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12, 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0, }, .max_mem = 0xffffffff, // XXX actually first 62GB ok .default_cpu_model = "TI SuperSparc II", },
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -