|
|
1.1 ! root 1: /* ! 2: * QEMU Alpha DP264/CLIPPER hardware system emulator. ! 3: * ! 4: * Choose CLIPPER IRQ mappings over, say, DP264, MONET, or WEBBRICK ! 5: * variants because CLIPPER doesn't have an SMC669 SuperIO controler ! 6: * that we need to emulate as well. ! 7: */ ! 8: ! 9: #include "hw.h" ! 10: #include "elf.h" ! 11: #include "loader.h" ! 12: #include "boards.h" ! 13: #include "alpha_sys.h" ! 14: #include "sysemu.h" ! 15: #include "mc146818rtc.h" ! 16: #include "ide.h" ! 17: ! 18: #define MAX_IDE_BUS 2 ! 19: ! 20: static uint64_t cpu_alpha_superpage_to_phys(void *opaque, uint64_t addr) ! 21: { ! 22: if (((addr >> 41) & 3) == 2) { ! 23: addr &= 0xffffffffffull; ! 24: } ! 25: return addr; ! 26: } ! 27: ! 28: /* Note that there are at least 3 viewpoints of IRQ numbers on Alpha systems. ! 29: (0) The dev_irq_n lines into the cpu, which we totally ignore, ! 30: (1) The DRIR lines in the typhoon chipset, ! 31: (2) The "vector" aka mangled interrupt number reported by SRM PALcode, ! 32: (3) The interrupt number assigned by the kernel. ! 33: The following function is concerned with (1) only. */ ! 34: ! 35: static int clipper_pci_map_irq(PCIDevice *d, int irq_num) ! 36: { ! 37: int slot = d->devfn >> 3; ! 38: ! 39: assert(irq_num >= 0 && irq_num <= 3); ! 40: ! 41: return (slot + 1) * 4 + irq_num; ! 42: } ! 43: ! 44: static void clipper_init(ram_addr_t ram_size, ! 45: const char *boot_device, ! 46: const char *kernel_filename, ! 47: const char *kernel_cmdline, ! 48: const char *initrd_filename, ! 49: const char *cpu_model) ! 50: { ! 51: CPUState *cpus[4]; ! 52: PCIBus *pci_bus; ! 53: qemu_irq rtc_irq; ! 54: long size, i; ! 55: const char *palcode_filename; ! 56: uint64_t palcode_entry, palcode_low, palcode_high; ! 57: uint64_t kernel_entry, kernel_low, kernel_high; ! 58: ! 59: /* Create up to 4 cpus. */ ! 60: memset(cpus, 0, sizeof(cpus)); ! 61: for (i = 0; i < smp_cpus; ++i) { ! 62: cpus[i] = cpu_init(cpu_model ? cpu_model : "ev67"); ! 63: } ! 64: ! 65: cpus[0]->trap_arg0 = ram_size; ! 66: cpus[0]->trap_arg1 = 0; ! 67: cpus[0]->trap_arg2 = smp_cpus; ! 68: ! 69: /* Init the chipset. */ ! 70: pci_bus = typhoon_init(ram_size, &rtc_irq, cpus, clipper_pci_map_irq); ! 71: ! 72: rtc_init(1980, rtc_irq); ! 73: pit_init(0x40, 0); ! 74: isa_create_simple("i8042"); ! 75: ! 76: /* VGA setup. Don't bother loading the bios. */ ! 77: alpha_pci_vga_setup(pci_bus); ! 78: ! 79: /* Serial code setup. */ ! 80: for (i = 0; i < MAX_SERIAL_PORTS; ++i) { ! 81: if (serial_hds[i]) { ! 82: serial_isa_init(i, serial_hds[i]); ! 83: } ! 84: } ! 85: ! 86: /* Network setup. e1000 is good enough, failing Tulip support. */ ! 87: for (i = 0; i < nb_nics; i++) { ! 88: pci_nic_init_nofail(&nd_table[i], "e1000", NULL); ! 89: } ! 90: ! 91: /* IDE disk setup. */ ! 92: { ! 93: DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; ! 94: ide_drive_get(hd, MAX_IDE_BUS); ! 95: ! 96: pci_cmd646_ide_init(pci_bus, hd, 0); ! 97: } ! 98: ! 99: /* Load PALcode. Given that this is not "real" cpu palcode, ! 100: but one explicitly written for the emulation, we might as ! 101: well load it directly from and ELF image. */ ! 102: palcode_filename = (bios_name ? bios_name : "palcode-clipper"); ! 103: palcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, palcode_filename); ! 104: if (palcode_filename == NULL) { ! 105: hw_error("no palcode provided\n"); ! 106: exit(1); ! 107: } ! 108: size = load_elf(palcode_filename, cpu_alpha_superpage_to_phys, ! 109: NULL, &palcode_entry, &palcode_low, &palcode_high, ! 110: 0, EM_ALPHA, 0); ! 111: if (size < 0) { ! 112: hw_error("could not load palcode '%s'\n", palcode_filename); ! 113: exit(1); ! 114: } ! 115: ! 116: /* Start all cpus at the PALcode RESET entry point. */ ! 117: for (i = 0; i < smp_cpus; ++i) { ! 118: cpus[i]->pal_mode = 1; ! 119: cpus[i]->pc = palcode_entry; ! 120: cpus[i]->palbr = palcode_entry; ! 121: } ! 122: ! 123: /* Load a kernel. */ ! 124: if (kernel_filename) { ! 125: uint64_t param_offset; ! 126: ! 127: size = load_elf(kernel_filename, cpu_alpha_superpage_to_phys, ! 128: NULL, &kernel_entry, &kernel_low, &kernel_high, ! 129: 0, EM_ALPHA, 0); ! 130: if (size < 0) { ! 131: hw_error("could not load kernel '%s'\n", kernel_filename); ! 132: exit(1); ! 133: } ! 134: ! 135: cpus[0]->trap_arg1 = kernel_entry; ! 136: ! 137: param_offset = kernel_low - 0x6000; ! 138: ! 139: if (kernel_cmdline) { ! 140: pstrcpy_targphys("cmdline", param_offset, 0x100, kernel_cmdline); ! 141: } ! 142: ! 143: if (initrd_filename) { ! 144: long initrd_base, initrd_size; ! 145: ! 146: initrd_size = get_image_size(initrd_filename); ! 147: if (initrd_size < 0) { ! 148: hw_error("could not load initial ram disk '%s'\n", ! 149: initrd_filename); ! 150: exit(1); ! 151: } ! 152: ! 153: /* Put the initrd image as high in memory as possible. */ ! 154: initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK; ! 155: load_image_targphys(initrd_filename, initrd_base, ! 156: ram_size - initrd_base); ! 157: ! 158: stq_phys(param_offset + 0x100, initrd_base + 0xfffffc0000000000ULL); ! 159: stq_phys(param_offset + 0x108, initrd_size); ! 160: } ! 161: } ! 162: } ! 163: ! 164: static QEMUMachine clipper_machine = { ! 165: .name = "clipper", ! 166: .desc = "Alpha DP264/CLIPPER", ! 167: .init = clipper_init, ! 168: .max_cpus = 4, ! 169: .is_default = 1, ! 170: }; ! 171: ! 172: static void clipper_machine_init(void) ! 173: { ! 174: qemu_register_machine(&clipper_machine); ! 175: } ! 176: ! 177: machine_init(clipper_machine_init);
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.