180bb2ff7SRichard Henderson /* 280bb2ff7SRichard Henderson * QEMU Alpha DP264/CLIPPER hardware system emulator. 380bb2ff7SRichard Henderson * 480bb2ff7SRichard Henderson * Choose CLIPPER IRQ mappings over, say, DP264, MONET, or WEBBRICK 566a0a2cbSDong Xu Wang * variants because CLIPPER doesn't have an SMC669 SuperIO controller 680bb2ff7SRichard Henderson * that we need to emulate as well. 780bb2ff7SRichard Henderson */ 880bb2ff7SRichard Henderson 9e2e5e114SPeter Maydell #include "qemu/osdep.h" 104771d756SPaolo Bonzini #include "qemu-common.h" 114771d756SPaolo Bonzini #include "cpu.h" 1280bb2ff7SRichard Henderson #include "elf.h" 1383c9f4caSPaolo Bonzini #include "hw/loader.h" 1447b43a1fSPaolo Bonzini #include "alpha_sys.h" 15c525436eSMarkus Armbruster #include "qemu/error-report.h" 16bcdb9064SPhilippe Mathieu-Daudé #include "hw/rtc/mc146818rtc.h" 1725297910SMark Cave-Ayland #include "hw/ide/pci.h" 180d09e41aSPaolo Bonzini #include "hw/timer/i8254.h" 19a4cb7739SPhilippe Mathieu-Daudé #include "hw/isa/superio.h" 20f4564fc0SPhilippe Mathieu-Daudé #include "hw/dma/i8257.h" 21852c27e2SPaolo Bonzini #include "net/net.h" 22f348b6d1SVeronia Bahaa #include "qemu/cutils.h" 232c65db5eSPaolo Bonzini #include "qemu/datadir.h" 24b58337ffSPhilippe Mathieu-Daudé #include "net/net.h" 2580bb2ff7SRichard Henderson 2680bb2ff7SRichard Henderson #define MAX_IDE_BUS 2 2780bb2ff7SRichard Henderson 2880bb2ff7SRichard Henderson static uint64_t cpu_alpha_superpage_to_phys(void *opaque, uint64_t addr) 2980bb2ff7SRichard Henderson { 3080bb2ff7SRichard Henderson if (((addr >> 41) & 3) == 2) { 3180bb2ff7SRichard Henderson addr &= 0xffffffffffull; 3280bb2ff7SRichard Henderson } 3380bb2ff7SRichard Henderson return addr; 3480bb2ff7SRichard Henderson } 3580bb2ff7SRichard Henderson 3680bb2ff7SRichard Henderson /* Note that there are at least 3 viewpoints of IRQ numbers on Alpha systems. 3780bb2ff7SRichard Henderson (0) The dev_irq_n lines into the cpu, which we totally ignore, 3880bb2ff7SRichard Henderson (1) The DRIR lines in the typhoon chipset, 3980bb2ff7SRichard Henderson (2) The "vector" aka mangled interrupt number reported by SRM PALcode, 4080bb2ff7SRichard Henderson (3) The interrupt number assigned by the kernel. 4180bb2ff7SRichard Henderson The following function is concerned with (1) only. */ 4280bb2ff7SRichard Henderson 4380bb2ff7SRichard Henderson static int clipper_pci_map_irq(PCIDevice *d, int irq_num) 4480bb2ff7SRichard Henderson { 4580bb2ff7SRichard Henderson int slot = d->devfn >> 3; 4680bb2ff7SRichard Henderson 4780bb2ff7SRichard Henderson assert(irq_num >= 0 && irq_num <= 3); 4880bb2ff7SRichard Henderson 4980bb2ff7SRichard Henderson return (slot + 1) * 4 + irq_num; 5080bb2ff7SRichard Henderson } 5180bb2ff7SRichard Henderson 523ef96221SMarcel Apfelbaum static void clipper_init(MachineState *machine) 5380bb2ff7SRichard Henderson { 543ef96221SMarcel Apfelbaum ram_addr_t ram_size = machine->ram_size; 553ef96221SMarcel Apfelbaum const char *kernel_filename = machine->kernel_filename; 563ef96221SMarcel Apfelbaum const char *kernel_cmdline = machine->kernel_cmdline; 573ef96221SMarcel Apfelbaum const char *initrd_filename = machine->initrd_filename; 58ad601177SAndreas Färber AlphaCPU *cpus[4]; 5980bb2ff7SRichard Henderson PCIBus *pci_bus; 60be1765f3SBALATON Zoltan PCIDevice *pci_dev; 6148a18b3cSHervé Poussineau ISABus *isa_bus; 6280bb2ff7SRichard Henderson qemu_irq rtc_irq; 6380bb2ff7SRichard Henderson long size, i; 64c18f8556SShannon Zhao char *palcode_filename; 65617160c9SBALATON Zoltan uint64_t palcode_entry; 66617160c9SBALATON Zoltan uint64_t kernel_entry, kernel_low; 6733decbd2SLike Xu unsigned int smp_cpus = machine->smp.cpus; 6880bb2ff7SRichard Henderson 6980bb2ff7SRichard Henderson /* Create up to 4 cpus. */ 7080bb2ff7SRichard Henderson memset(cpus, 0, sizeof(cpus)); 7180bb2ff7SRichard Henderson for (i = 0; i < smp_cpus; ++i) { 72fb92da84SIgor Mammedov cpus[i] = ALPHA_CPU(cpu_create(machine->cpu_type)); 7380bb2ff7SRichard Henderson } 7480bb2ff7SRichard Henderson 75ad601177SAndreas Färber cpus[0]->env.trap_arg0 = ram_size; 76ad601177SAndreas Färber cpus[0]->env.trap_arg1 = 0; 77ad601177SAndreas Färber cpus[0]->env.trap_arg2 = smp_cpus; 7880bb2ff7SRichard Henderson 79*3a8233dcSJason Thorpe /* 80*3a8233dcSJason Thorpe * Init the chipset. Because we're using CLIPPER IRQ mappings, 81*3a8233dcSJason Thorpe * the minimum PCI device IdSel is 1. 82*3a8233dcSJason Thorpe */ 83b844d822SIgor Mammedov pci_bus = typhoon_init(machine->ram, &isa_bus, &rtc_irq, cpus, 84*3a8233dcSJason Thorpe clipper_pci_map_irq, PCI_DEVFN(1, 0)); 8580bb2ff7SRichard Henderson 86e605e969SRichard Henderson /* Since we have an SRM-compatible PALcode, use the SRM epoch. */ 876c646a11SPhilippe Mathieu-Daudé mc146818_rtc_init(isa_bus, 1900, rtc_irq); 88e605e969SRichard Henderson 89acf695ecSPhilippe Mathieu-Daudé i8254_pit_init(isa_bus, 0x40, 0, NULL); 9080bb2ff7SRichard Henderson 9180bb2ff7SRichard Henderson /* VGA setup. Don't bother loading the bios. */ 92606f90ccSAurelien Jarno pci_vga_init(pci_bus); 9380bb2ff7SRichard Henderson 9480bb2ff7SRichard Henderson /* Network setup. e1000 is good enough, failing Tulip support. */ 9580bb2ff7SRichard Henderson for (i = 0; i < nb_nics; i++) { 9629b358f9SDavid Gibson pci_nic_init_nofail(&nd_table[i], pci_bus, "e1000", NULL); 9780bb2ff7SRichard Henderson } 9880bb2ff7SRichard Henderson 99f4564fc0SPhilippe Mathieu-Daudé /* 2 82C37 (dma) */ 100f4564fc0SPhilippe Mathieu-Daudé isa_create_simple(isa_bus, "i82374"); 101f4564fc0SPhilippe Mathieu-Daudé 102a4cb7739SPhilippe Mathieu-Daudé /* Super I/O */ 103a4cb7739SPhilippe Mathieu-Daudé isa_create_simple(isa_bus, TYPE_SMC37C669_SUPERIO); 104a4cb7739SPhilippe Mathieu-Daudé 10580bb2ff7SRichard Henderson /* IDE disk setup. */ 10625297910SMark Cave-Ayland pci_dev = pci_create_simple(pci_bus, -1, "cmd646-ide"); 107be1765f3SBALATON Zoltan pci_ide_create_devs(pci_dev); 10880bb2ff7SRichard Henderson 10980bb2ff7SRichard Henderson /* Load PALcode. Given that this is not "real" cpu palcode, 11080bb2ff7SRichard Henderson but one explicitly written for the emulation, we might as 11180bb2ff7SRichard Henderson well load it directly from and ELF image. */ 112c18f8556SShannon Zhao palcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, 1132c4a83ebSPaolo Bonzini machine->firmware ?: "palcode-clipper"); 11480bb2ff7SRichard Henderson if (palcode_filename == NULL) { 115c525436eSMarkus Armbruster error_report("no palcode provided"); 11680bb2ff7SRichard Henderson exit(1); 11780bb2ff7SRichard Henderson } 1184366e1dbSLiam Merwick size = load_elf(palcode_filename, NULL, cpu_alpha_superpage_to_phys, 119617160c9SBALATON Zoltan NULL, &palcode_entry, NULL, NULL, NULL, 1207ef295eaSPeter Crosthwaite 0, EM_ALPHA, 0, 0); 12180bb2ff7SRichard Henderson if (size < 0) { 122c525436eSMarkus Armbruster error_report("could not load palcode '%s'", palcode_filename); 12380bb2ff7SRichard Henderson exit(1); 12480bb2ff7SRichard Henderson } 125c18f8556SShannon Zhao g_free(palcode_filename); 12680bb2ff7SRichard Henderson 12780bb2ff7SRichard Henderson /* Start all cpus at the PALcode RESET entry point. */ 12880bb2ff7SRichard Henderson for (i = 0; i < smp_cpus; ++i) { 129ad601177SAndreas Färber cpus[i]->env.pc = palcode_entry; 130ad601177SAndreas Färber cpus[i]->env.palbr = palcode_entry; 13180bb2ff7SRichard Henderson } 13280bb2ff7SRichard Henderson 13380bb2ff7SRichard Henderson /* Load a kernel. */ 13480bb2ff7SRichard Henderson if (kernel_filename) { 13580bb2ff7SRichard Henderson uint64_t param_offset; 13680bb2ff7SRichard Henderson 1374366e1dbSLiam Merwick size = load_elf(kernel_filename, NULL, cpu_alpha_superpage_to_phys, 138617160c9SBALATON Zoltan NULL, &kernel_entry, &kernel_low, NULL, NULL, 1397ef295eaSPeter Crosthwaite 0, EM_ALPHA, 0, 0); 14080bb2ff7SRichard Henderson if (size < 0) { 141c525436eSMarkus Armbruster error_report("could not load kernel '%s'", kernel_filename); 14280bb2ff7SRichard Henderson exit(1); 14380bb2ff7SRichard Henderson } 14480bb2ff7SRichard Henderson 145ad601177SAndreas Färber cpus[0]->env.trap_arg1 = kernel_entry; 14680bb2ff7SRichard Henderson 14780bb2ff7SRichard Henderson param_offset = kernel_low - 0x6000; 14880bb2ff7SRichard Henderson 14980bb2ff7SRichard Henderson if (kernel_cmdline) { 15080bb2ff7SRichard Henderson pstrcpy_targphys("cmdline", param_offset, 0x100, kernel_cmdline); 15180bb2ff7SRichard Henderson } 15280bb2ff7SRichard Henderson 15380bb2ff7SRichard Henderson if (initrd_filename) { 154f3839fdaSLi Zhijian long initrd_base; 155f3839fdaSLi Zhijian int64_t initrd_size; 15680bb2ff7SRichard Henderson 15780bb2ff7SRichard Henderson initrd_size = get_image_size(initrd_filename); 15880bb2ff7SRichard Henderson if (initrd_size < 0) { 159c525436eSMarkus Armbruster error_report("could not load initial ram disk '%s'", 16080bb2ff7SRichard Henderson initrd_filename); 16180bb2ff7SRichard Henderson exit(1); 16280bb2ff7SRichard Henderson } 16380bb2ff7SRichard Henderson 16480bb2ff7SRichard Henderson /* Put the initrd image as high in memory as possible. */ 16580bb2ff7SRichard Henderson initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK; 16680bb2ff7SRichard Henderson load_image_targphys(initrd_filename, initrd_base, 16780bb2ff7SRichard Henderson ram_size - initrd_base); 16880bb2ff7SRichard Henderson 16942874d3aSPeter Maydell address_space_stq(&address_space_memory, param_offset + 0x100, 17042874d3aSPeter Maydell initrd_base + 0xfffffc0000000000ULL, 17142874d3aSPeter Maydell MEMTXATTRS_UNSPECIFIED, 17242874d3aSPeter Maydell NULL); 17342874d3aSPeter Maydell address_space_stq(&address_space_memory, param_offset + 0x108, 17442874d3aSPeter Maydell initrd_size, MEMTXATTRS_UNSPECIFIED, NULL); 17580bb2ff7SRichard Henderson } 17680bb2ff7SRichard Henderson } 17780bb2ff7SRichard Henderson } 17880bb2ff7SRichard Henderson 179e264d29dSEduardo Habkost static void clipper_machine_init(MachineClass *mc) 18080bb2ff7SRichard Henderson { 181e264d29dSEduardo Habkost mc->desc = "Alpha DP264/CLIPPER"; 182e264d29dSEduardo Habkost mc->init = clipper_init; 1832059839bSMarkus Armbruster mc->block_default_type = IF_IDE; 184e264d29dSEduardo Habkost mc->max_cpus = 4; 185ea0ac7f6SPhilippe Mathieu-Daudé mc->is_default = true; 186fb92da84SIgor Mammedov mc->default_cpu_type = ALPHA_CPU_TYPE_NAME("ev67"); 187b844d822SIgor Mammedov mc->default_ram_id = "ram"; 18880bb2ff7SRichard Henderson } 18980bb2ff7SRichard Henderson 190e264d29dSEduardo Habkost DEFINE_MACHINE("clipper", clipper_machine_init) 191