1813dff13SHelge Deller /* 2813dff13SHelge Deller * QEMU HPPA hardware system emulator. 3a536f564SHelge Deller * (C) Copyright 2018-2023 Helge Deller <deller@gmx.de> 4a536f564SHelge Deller * 5a536f564SHelge Deller * This work is licensed under the GNU GPL license version 2 or later. 6813dff13SHelge Deller */ 7813dff13SHelge Deller 8813dff13SHelge Deller #include "qemu/osdep.h" 92c65db5eSPaolo Bonzini #include "qemu/datadir.h" 10813dff13SHelge Deller #include "cpu.h" 11813dff13SHelge Deller #include "elf.h" 12813dff13SHelge Deller #include "hw/loader.h" 13813dff13SHelge Deller #include "qemu/error-report.h" 1471e8a915SMarkus Armbruster #include "sysemu/reset.h" 15813dff13SHelge Deller #include "sysemu/sysemu.h" 16b28c4a64SHelge Deller #include "sysemu/runstate.h" 17bcdb9064SPhilippe Mathieu-Daudé #include "hw/rtc/mc146818rtc.h" 18813dff13SHelge Deller #include "hw/timer/i8254.h" 19813dff13SHelge Deller #include "hw/char/serial.h" 209701e569SMark Cave-Ayland #include "hw/char/parallel.h" 21134ba73fSMark Cave-Ayland #include "hw/intc/i8259.h" 22d26c575cSMark Cave-Ayland #include "hw/input/lasips2.h" 23376b8519SHelge Deller #include "hw/net/lasi_82596.h" 244a4554c6SHelge Deller #include "hw/nmi.h" 25134ba73fSMark Cave-Ayland #include "hw/pci/pci.h" 260db9350eSMark Cave-Ayland #include "hw/pci-host/dino.h" 2745f569a1SMark Cave-Ayland #include "hw/misc/lasi.h" 28148da670SMark Cave-Ayland #include "hppa_hardware.h" 29c108cc59SPhilippe Mathieu-Daudé #include "qemu/units.h" 30813dff13SHelge Deller #include "qapi/error.h" 31852c27e2SPaolo Bonzini #include "net/net.h" 32691cbbadSRichard Henderson #include "qemu/log.h" 33813dff13SHelge Deller 34a536f564SHelge Deller #define MIN_SEABIOS_HPPA_VERSION 10 /* require at least this fw version */ 3528b71a2eSHelge Deller 36b28c4a64SHelge Deller #define HPA_POWER_BUTTON (FIRMWARE_END - 0x10) 37b28c4a64SHelge Deller 38932befaaSMark Cave-Ayland #define enable_lasi_lan() 0 39932befaaSMark Cave-Ayland 40932befaaSMark Cave-Ayland 41b28c4a64SHelge Deller static void hppa_powerdown_req(Notifier *n, void *opaque) 42b28c4a64SHelge Deller { 43b28c4a64SHelge Deller hwaddr soft_power_reg = HPA_POWER_BUTTON; 44b28c4a64SHelge Deller uint32_t val; 45b28c4a64SHelge Deller 46b28c4a64SHelge Deller val = ldl_be_phys(&address_space_memory, soft_power_reg); 47b28c4a64SHelge Deller if ((val >> 8) == 0) { 48b28c4a64SHelge Deller /* immediately shut down when under hardware control */ 49b28c4a64SHelge Deller qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); 50b28c4a64SHelge Deller return; 51b28c4a64SHelge Deller } 52b28c4a64SHelge Deller 53b28c4a64SHelge Deller /* clear bit 31 to indicate that the power switch was pressed. */ 54b28c4a64SHelge Deller val &= ~1; 55b28c4a64SHelge Deller stl_be_phys(&address_space_memory, soft_power_reg, val); 56b28c4a64SHelge Deller } 57b28c4a64SHelge Deller 58b28c4a64SHelge Deller static Notifier hppa_system_powerdown_notifier = { 59b28c4a64SHelge Deller .notify = hppa_powerdown_req 60b28c4a64SHelge Deller }; 61b28c4a64SHelge Deller 6228f5332aSMark Cave-Ayland /* Fallback for unassigned PCI I/O operations. Avoids MCHK. */ 6328f5332aSMark Cave-Ayland static uint64_t ignore_read(void *opaque, hwaddr addr, unsigned size) 6428f5332aSMark Cave-Ayland { 6528f5332aSMark Cave-Ayland return 0; 6628f5332aSMark Cave-Ayland } 6728f5332aSMark Cave-Ayland 6828f5332aSMark Cave-Ayland static void ignore_write(void *opaque, hwaddr addr, uint64_t v, unsigned size) 6928f5332aSMark Cave-Ayland { 7028f5332aSMark Cave-Ayland } 7128f5332aSMark Cave-Ayland 7228f5332aSMark Cave-Ayland static const MemoryRegionOps hppa_pci_ignore_ops = { 7328f5332aSMark Cave-Ayland .read = ignore_read, 7428f5332aSMark Cave-Ayland .write = ignore_write, 7528f5332aSMark Cave-Ayland .endianness = DEVICE_BIG_ENDIAN, 7628f5332aSMark Cave-Ayland .valid = { 7728f5332aSMark Cave-Ayland .min_access_size = 1, 7828f5332aSMark Cave-Ayland .max_access_size = 8, 7928f5332aSMark Cave-Ayland }, 8028f5332aSMark Cave-Ayland .impl = { 8128f5332aSMark Cave-Ayland .min_access_size = 1, 8228f5332aSMark Cave-Ayland .max_access_size = 8, 8328f5332aSMark Cave-Ayland }, 8428f5332aSMark Cave-Ayland }; 85b28c4a64SHelge Deller 86a72bd606SHelge Deller static ISABus *hppa_isa_bus(void) 87a72bd606SHelge Deller { 88a72bd606SHelge Deller ISABus *isa_bus; 89a72bd606SHelge Deller qemu_irq *isa_irqs; 90a72bd606SHelge Deller MemoryRegion *isa_region; 91a72bd606SHelge Deller 92a72bd606SHelge Deller isa_region = g_new(MemoryRegion, 1); 93a72bd606SHelge Deller memory_region_init_io(isa_region, NULL, &hppa_pci_ignore_ops, 94a72bd606SHelge Deller NULL, "isa-io", 0x800); 95a72bd606SHelge Deller memory_region_add_subregion(get_system_memory(), IDE_HPA, 96a72bd606SHelge Deller isa_region); 97a72bd606SHelge Deller 98a72bd606SHelge Deller isa_bus = isa_bus_new(NULL, get_system_memory(), isa_region, 99a72bd606SHelge Deller &error_abort); 100a536f564SHelge Deller isa_irqs = i8259_init(isa_bus, NULL); 1017067887eSPhilippe Mathieu-Daudé isa_bus_register_input_irqs(isa_bus, isa_irqs); 102a72bd606SHelge Deller 103a72bd606SHelge Deller return isa_bus; 104a72bd606SHelge Deller } 105a72bd606SHelge Deller 106a72bd606SHelge Deller static uint64_t cpu_hppa_to_phys(void *opaque, uint64_t addr) 107a72bd606SHelge Deller { 108a72bd606SHelge Deller addr &= (0x10000000 - 1); 109a72bd606SHelge Deller return addr; 110a72bd606SHelge Deller } 111a72bd606SHelge Deller 112a72bd606SHelge Deller static HPPACPU *cpu[HPPA_MAX_CPUS]; 113a72bd606SHelge Deller static uint64_t firmware_entry; 114813dff13SHelge Deller 11532ff8bf2SHelge Deller static void fw_cfg_boot_set(void *opaque, const char *boot_device, 11632ff8bf2SHelge Deller Error **errp) 11732ff8bf2SHelge Deller { 11832ff8bf2SHelge Deller fw_cfg_modify_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]); 11932ff8bf2SHelge Deller } 12032ff8bf2SHelge Deller 121*bcd4dd4cSHelge Deller static FWCfgState *create_fw_cfg(MachineState *ms, PCIBus *pci_bus) 12228b71a2eSHelge Deller { 12328b71a2eSHelge Deller FWCfgState *fw_cfg; 12428b71a2eSHelge Deller uint64_t val; 125069d2966SHelge Deller const char qemu_version[] = QEMU_VERSION; 126*bcd4dd4cSHelge Deller MachineClass *mc = MACHINE_GET_CLASS(ms); 127*bcd4dd4cSHelge Deller int len; 12828b71a2eSHelge Deller 12924576007SHelge Deller fw_cfg = fw_cfg_init_mem(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 4); 13028b71a2eSHelge Deller fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, ms->smp.cpus); 13128b71a2eSHelge Deller fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, HPPA_MAX_CPUS); 132bfdf22bcSPaolo Bonzini fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, ms->ram_size); 13328b71a2eSHelge Deller 13428b71a2eSHelge Deller val = cpu_to_le64(MIN_SEABIOS_HPPA_VERSION); 13528b71a2eSHelge Deller fw_cfg_add_file(fw_cfg, "/etc/firmware-min-version", 13628b71a2eSHelge Deller g_memdup(&val, sizeof(val)), sizeof(val)); 13728b71a2eSHelge Deller 1386d1ef68cSHelge Deller val = cpu_to_le64(HPPA_TLB_ENTRIES - HPPA_BTLB_ENTRIES); 139df5c6a50SHelge Deller fw_cfg_add_file(fw_cfg, "/etc/cpu/tlb_entries", 140df5c6a50SHelge Deller g_memdup(&val, sizeof(val)), sizeof(val)); 141df5c6a50SHelge Deller 142*bcd4dd4cSHelge Deller val = cpu_to_le64(HPPA_BTLB_ENTRIES); 143*bcd4dd4cSHelge Deller fw_cfg_add_file(fw_cfg, "/etc/cpu/btlb_entries", 144*bcd4dd4cSHelge Deller g_memdup(&val, sizeof(val)), sizeof(val)); 145*bcd4dd4cSHelge Deller 146*bcd4dd4cSHelge Deller len = strlen(mc->name) + 1; 147*bcd4dd4cSHelge Deller fw_cfg_add_file(fw_cfg, "/etc/hppa/machine", 148*bcd4dd4cSHelge Deller g_memdup(mc->name, len), len); 149*bcd4dd4cSHelge Deller 150b28c4a64SHelge Deller val = cpu_to_le64(HPA_POWER_BUTTON); 151*bcd4dd4cSHelge Deller fw_cfg_add_file(fw_cfg, "/etc/hppa/power-button-addr", 152*bcd4dd4cSHelge Deller g_memdup(&val, sizeof(val)), sizeof(val)); 153*bcd4dd4cSHelge Deller 154*bcd4dd4cSHelge Deller val = cpu_to_le64(CPU_HPA + 24); 155*bcd4dd4cSHelge Deller fw_cfg_add_file(fw_cfg, "/etc/hppa/DebugOutputPort", 156b28c4a64SHelge Deller g_memdup(&val, sizeof(val)), sizeof(val)); 157b28c4a64SHelge Deller 15897ec4d21SPaolo Bonzini fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ms->boot_config.order[0]); 15932ff8bf2SHelge Deller qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); 16032ff8bf2SHelge Deller 161069d2966SHelge Deller fw_cfg_add_file(fw_cfg, "/etc/qemu-version", 162069d2966SHelge Deller g_memdup(qemu_version, sizeof(qemu_version)), 163069d2966SHelge Deller sizeof(qemu_version)); 164069d2966SHelge Deller 165*bcd4dd4cSHelge Deller fw_cfg_add_extra_pci_roots(pci_bus, fw_cfg); 166*bcd4dd4cSHelge Deller 16728b71a2eSHelge Deller return fw_cfg; 16828b71a2eSHelge Deller } 16928b71a2eSHelge Deller 170e881e3c8SMark Cave-Ayland static LasiState *lasi_init(void) 171e881e3c8SMark Cave-Ayland { 172e881e3c8SMark Cave-Ayland DeviceState *dev; 173e881e3c8SMark Cave-Ayland 174e881e3c8SMark Cave-Ayland dev = qdev_new(TYPE_LASI_CHIP); 175e881e3c8SMark Cave-Ayland sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 176e881e3c8SMark Cave-Ayland 177e881e3c8SMark Cave-Ayland return LASI_CHIP(dev); 178e881e3c8SMark Cave-Ayland } 179e881e3c8SMark Cave-Ayland 1800d068996SMark Cave-Ayland static DinoState *dino_init(MemoryRegion *addr_space) 1810d068996SMark Cave-Ayland { 1820d068996SMark Cave-Ayland DeviceState *dev; 1830d068996SMark Cave-Ayland 1840d068996SMark Cave-Ayland dev = qdev_new(TYPE_DINO_PCI_HOST_BRIDGE); 1850d068996SMark Cave-Ayland object_property_set_link(OBJECT(dev), "memory-as", OBJECT(addr_space), 1860d068996SMark Cave-Ayland &error_fatal); 1870d068996SMark Cave-Ayland sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 1880d068996SMark Cave-Ayland 1890d068996SMark Cave-Ayland return DINO_PCI_HOST_BRIDGE(dev); 1900d068996SMark Cave-Ayland } 1910d068996SMark Cave-Ayland 192813dff13SHelge Deller static void machine_hppa_init(MachineState *machine) 193813dff13SHelge Deller { 194a72bd606SHelge Deller const char *kernel_filename = machine->kernel_filename; 195a72bd606SHelge Deller const char *kernel_cmdline = machine->kernel_cmdline; 196a72bd606SHelge Deller const char *initrd_filename = machine->initrd_filename; 1979f8981a9SThomas Huth MachineClass *mc = MACHINE_GET_CLASS(machine); 1982683758cSMark Cave-Ayland DeviceState *dev, *dino_dev, *lasi_dev; 199a72bd606SHelge Deller PCIBus *pci_bus; 200a72bd606SHelge Deller ISABus *isa_bus; 201a72bd606SHelge Deller char *firmware_filename; 202a72bd606SHelge Deller uint64_t firmware_low, firmware_high; 203a72bd606SHelge Deller long size; 204a72bd606SHelge Deller uint64_t kernel_entry = 0, kernel_low, kernel_high; 205a72bd606SHelge Deller MemoryRegion *addr_space = get_system_memory(); 206a72bd606SHelge Deller MemoryRegion *rom_region; 207a72bd606SHelge Deller MemoryRegion *cpu_region; 208a72bd606SHelge Deller long i; 20933decbd2SLike Xu unsigned int smp_cpus = machine->smp.cpus; 2104765384cSSven Schnelle SysBusDevice *s; 211a72bd606SHelge Deller 212a72bd606SHelge Deller /* Create CPUs. */ 213a72bd606SHelge Deller for (i = 0; i < smp_cpus; i++) { 214266a880eSPaolo Bonzini char *name = g_strdup_printf("cpu%ld-io-eir", i); 215a72bd606SHelge Deller cpu[i] = HPPA_CPU(cpu_create(machine->cpu_type)); 216a72bd606SHelge Deller 217a72bd606SHelge Deller cpu_region = g_new(MemoryRegion, 1); 218a72bd606SHelge Deller memory_region_init_io(cpu_region, OBJECT(cpu[i]), &hppa_io_eir_ops, 219266a880eSPaolo Bonzini cpu[i], name, 4); 220a72bd606SHelge Deller memory_region_add_subregion(addr_space, CPU_HPA + i * 0x1000, 221a72bd606SHelge Deller cpu_region); 222266a880eSPaolo Bonzini g_free(name); 223813dff13SHelge Deller } 224813dff13SHelge Deller 225a72bd606SHelge Deller /* Main memory region. */ 226b7746b11SPhilippe Mathieu-Daudé if (machine->ram_size > 3 * GiB) { 227b7746b11SPhilippe Mathieu-Daudé error_report("RAM size is currently restricted to 3GB"); 228b7746b11SPhilippe Mathieu-Daudé exit(EXIT_FAILURE); 229b7746b11SPhilippe Mathieu-Daudé } 2307c59c1e0SIgor Mammedov memory_region_add_subregion_overlap(addr_space, 0, machine->ram, -1); 2317c59c1e0SIgor Mammedov 232a72bd606SHelge Deller 233376b8519SHelge Deller /* Init Lasi chip */ 234e881e3c8SMark Cave-Ayland lasi_dev = DEVICE(lasi_init()); 2352683758cSMark Cave-Ayland memory_region_add_subregion(addr_space, LASI_HPA, 2362683758cSMark Cave-Ayland sysbus_mmio_get_region( 2372683758cSMark Cave-Ayland SYS_BUS_DEVICE(lasi_dev), 0)); 238376b8519SHelge Deller 239a72bd606SHelge Deller /* Init Dino (PCI host bus chip). */ 24036f9bbdbSMark Cave-Ayland dino_dev = DEVICE(dino_init(addr_space)); 241efdb3ce2SMark Cave-Ayland memory_region_add_subregion(addr_space, DINO_HPA, 242efdb3ce2SMark Cave-Ayland sysbus_mmio_get_region( 243efdb3ce2SMark Cave-Ayland SYS_BUS_DEVICE(dino_dev), 0)); 24405245dafSMark Cave-Ayland pci_bus = PCI_BUS(qdev_get_child_bus(dino_dev, "pci")); 245a72bd606SHelge Deller assert(pci_bus); 246a72bd606SHelge Deller 247a72bd606SHelge Deller /* Create ISA bus. */ 248a72bd606SHelge Deller isa_bus = hppa_isa_bus(); 249a72bd606SHelge Deller assert(isa_bus); 250a72bd606SHelge Deller 251a72bd606SHelge Deller /* Realtime clock, used by firmware for PDC_TOD call. */ 25236f9bbdbSMark Cave-Ayland mc146818_rtc_init(isa_bus, 2000, NULL); 253a72bd606SHelge Deller 2545079892dSHelge Deller /* Serial ports: Lasi and Dino use a 7.272727 MHz clock. */ 2552da547b8SMark Cave-Ayland serial_mm_init(addr_space, LASI_UART_HPA + 0x800, 0, 2565079892dSHelge Deller qdev_get_gpio_in(lasi_dev, LASI_IRQ_UART_HPA), 7272727 / 16, 2575079892dSHelge Deller serial_hd(0), DEVICE_BIG_ENDIAN); 2585079892dSHelge Deller 2595079892dSHelge Deller serial_mm_init(addr_space, DINO_UART_HPA + 0x800, 0, 2605079892dSHelge Deller qdev_get_gpio_in(dino_dev, DINO_IRQ_RS232INT), 7272727 / 16, 2612da547b8SMark Cave-Ayland serial_hd(1), DEVICE_BIG_ENDIAN); 2622da547b8SMark Cave-Ayland 2639701e569SMark Cave-Ayland /* Parallel port */ 2649701e569SMark Cave-Ayland parallel_mm_init(addr_space, LASI_LPT_HPA + 0x800, 0, 2659701e569SMark Cave-Ayland qdev_get_gpio_in(lasi_dev, LASI_IRQ_LAN_HPA), 2669701e569SMark Cave-Ayland parallel_hds[0]); 2679701e569SMark Cave-Ayland 26828b71a2eSHelge Deller /* fw_cfg configuration interface */ 269*bcd4dd4cSHelge Deller create_fw_cfg(machine, pci_bus); 27028b71a2eSHelge Deller 271a72bd606SHelge Deller /* SCSI disk setup. */ 272877eb21dSMark Cave-Ayland dev = DEVICE(pci_create_simple(pci_bus, -1, "lsi53c895a")); 273877eb21dSMark Cave-Ayland lsi53c8xx_handle_legacy_cmdline(dev); 274a72bd606SHelge Deller 2754765384cSSven Schnelle /* Graphics setup. */ 2764765384cSSven Schnelle if (machine->enable_graphics && vga_interface_type != VGA_NONE) { 277f9bcb2d6SGautam Agrawal vga_interface_created = true; 2783e80f690SMarkus Armbruster dev = qdev_new("artist"); 2794765384cSSven Schnelle s = SYS_BUS_DEVICE(dev); 2803c6ef471SMarkus Armbruster sysbus_realize_and_unref(s, &error_fatal); 2814765384cSSven Schnelle sysbus_mmio_map(s, 0, LASI_GFX_HPA); 2824765384cSSven Schnelle sysbus_mmio_map(s, 1, ARTIST_FB_ADDR); 2834765384cSSven Schnelle } 2844765384cSSven Schnelle 2850e6de551SHelge Deller /* Network setup. */ 286c3c3fe47SMark Cave-Ayland if (enable_lasi_lan()) { 287c3c3fe47SMark Cave-Ayland lasi_82596_init(addr_space, LASI_LAN_HPA, 288c3c3fe47SMark Cave-Ayland qdev_get_gpio_in(lasi_dev, LASI_IRQ_LAN_HPA)); 289c3c3fe47SMark Cave-Ayland } 290c3c3fe47SMark Cave-Ayland 291a72bd606SHelge Deller for (i = 0; i < nb_nics; i++) { 292376b8519SHelge Deller if (!enable_lasi_lan()) { 2939f8981a9SThomas Huth pci_nic_init_nofail(&nd_table[i], pci_bus, mc->default_nic, NULL); 294a72bd606SHelge Deller } 295376b8519SHelge Deller } 296a72bd606SHelge Deller 297d26c575cSMark Cave-Ayland /* PS/2 Keyboard/Mouse */ 29892bd278cSMark Cave-Ayland dev = qdev_new(TYPE_LASIPS2); 29992bd278cSMark Cave-Ayland sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 30092bd278cSMark Cave-Ayland sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, 30192bd278cSMark Cave-Ayland qdev_get_gpio_in(lasi_dev, LASI_IRQ_PS2KBD_HPA)); 3026479296fSMark Cave-Ayland memory_region_add_subregion(addr_space, LASI_PS2KBD_HPA, 3036479296fSMark Cave-Ayland sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 3046479296fSMark Cave-Ayland 0)); 3056479296fSMark Cave-Ayland memory_region_add_subregion(addr_space, LASI_PS2KBD_HPA + 0x100, 3066479296fSMark Cave-Ayland sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 3076479296fSMark Cave-Ayland 1)); 308d26c575cSMark Cave-Ayland 309b28c4a64SHelge Deller /* register power switch emulation */ 310b28c4a64SHelge Deller qemu_register_powerdown_notifier(&hppa_system_powerdown_notifier); 311b28c4a64SHelge Deller 312a72bd606SHelge Deller /* Load firmware. Given that this is not "real" firmware, 313a72bd606SHelge Deller but one explicitly written for the emulation, we might as 314a72bd606SHelge Deller well load it directly from an ELF image. */ 315a72bd606SHelge Deller firmware_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, 316b57e3e97SPaolo Bonzini machine->firmware ?: "hppa-firmware.img"); 317a72bd606SHelge Deller if (firmware_filename == NULL) { 318a72bd606SHelge Deller error_report("no firmware provided"); 319a72bd606SHelge Deller exit(1); 320a72bd606SHelge Deller } 321a72bd606SHelge Deller 3224366e1dbSLiam Merwick size = load_elf(firmware_filename, NULL, NULL, NULL, 3236cdda0ffSAleksandar Markovic &firmware_entry, &firmware_low, &firmware_high, NULL, 324a72bd606SHelge Deller true, EM_PARISC, 0, 0); 325a72bd606SHelge Deller 326a72bd606SHelge Deller /* Unfortunately, load_elf sign-extends reading elf32. */ 327a72bd606SHelge Deller firmware_entry = (target_ureg)firmware_entry; 328a72bd606SHelge Deller firmware_low = (target_ureg)firmware_low; 329a72bd606SHelge Deller firmware_high = (target_ureg)firmware_high; 330a72bd606SHelge Deller 331a72bd606SHelge Deller if (size < 0) { 332a72bd606SHelge Deller error_report("could not load firmware '%s'", firmware_filename); 333a72bd606SHelge Deller exit(1); 334a72bd606SHelge Deller } 335691cbbadSRichard Henderson qemu_log_mask(CPU_LOG_PAGE, "Firmware loaded at 0x%08" PRIx64 336691cbbadSRichard Henderson "-0x%08" PRIx64 ", entry at 0x%08" PRIx64 ".\n", 337a72bd606SHelge Deller firmware_low, firmware_high, firmware_entry); 3388262863dSPhilippe Mathieu-Daudé if (firmware_low < FIRMWARE_START || firmware_high >= FIRMWARE_END) { 339a72bd606SHelge Deller error_report("Firmware overlaps with memory or IO space"); 340a72bd606SHelge Deller exit(1); 341a72bd606SHelge Deller } 342a72bd606SHelge Deller g_free(firmware_filename); 343a72bd606SHelge Deller 344a72bd606SHelge Deller rom_region = g_new(MemoryRegion, 1); 3456a3a2e82SIgor Mammedov memory_region_init_ram(rom_region, NULL, "firmware", 3466a3a2e82SIgor Mammedov (FIRMWARE_END - FIRMWARE_START), &error_fatal); 347a72bd606SHelge Deller memory_region_add_subregion(addr_space, FIRMWARE_START, rom_region); 348a72bd606SHelge Deller 349a72bd606SHelge Deller /* Load kernel */ 350a72bd606SHelge Deller if (kernel_filename) { 3514366e1dbSLiam Merwick size = load_elf(kernel_filename, NULL, &cpu_hppa_to_phys, 3526cdda0ffSAleksandar Markovic NULL, &kernel_entry, &kernel_low, &kernel_high, NULL, 353a72bd606SHelge Deller true, EM_PARISC, 0, 0); 354a72bd606SHelge Deller 355a72bd606SHelge Deller /* Unfortunately, load_elf sign-extends reading elf32. */ 356a72bd606SHelge Deller kernel_entry = (target_ureg) cpu_hppa_to_phys(NULL, kernel_entry); 357a72bd606SHelge Deller kernel_low = (target_ureg)kernel_low; 358a72bd606SHelge Deller kernel_high = (target_ureg)kernel_high; 359a72bd606SHelge Deller 360a72bd606SHelge Deller if (size < 0) { 361a72bd606SHelge Deller error_report("could not load kernel '%s'", kernel_filename); 362a72bd606SHelge Deller exit(1); 363a72bd606SHelge Deller } 364691cbbadSRichard Henderson qemu_log_mask(CPU_LOG_PAGE, "Kernel loaded at 0x%08" PRIx64 365691cbbadSRichard Henderson "-0x%08" PRIx64 ", entry at 0x%08" PRIx64 366c108cc59SPhilippe Mathieu-Daudé ", size %" PRIu64 " kB\n", 367c108cc59SPhilippe Mathieu-Daudé kernel_low, kernel_high, kernel_entry, size / KiB); 368a72bd606SHelge Deller 369a72bd606SHelge Deller if (kernel_cmdline) { 370a72bd606SHelge Deller cpu[0]->env.gr[24] = 0x4000; 371a72bd606SHelge Deller pstrcpy_targphys("cmdline", cpu[0]->env.gr[24], 372a72bd606SHelge Deller TARGET_PAGE_SIZE, kernel_cmdline); 373a72bd606SHelge Deller } 374a72bd606SHelge Deller 375a72bd606SHelge Deller if (initrd_filename) { 376a72bd606SHelge Deller ram_addr_t initrd_base; 377f3839fdaSLi Zhijian int64_t initrd_size; 378a72bd606SHelge Deller 379a72bd606SHelge Deller initrd_size = get_image_size(initrd_filename); 380a72bd606SHelge Deller if (initrd_size < 0) { 381a72bd606SHelge Deller error_report("could not load initial ram disk '%s'", 382a72bd606SHelge Deller initrd_filename); 383a72bd606SHelge Deller exit(1); 384a72bd606SHelge Deller } 385a72bd606SHelge Deller 386a72bd606SHelge Deller /* Load the initrd image high in memory. 387a72bd606SHelge Deller Mirror the algorithm used by palo: 388a72bd606SHelge Deller (1) Due to sign-extension problems and PDC, 389a72bd606SHelge Deller put the initrd no higher than 1G. 390a72bd606SHelge Deller (2) Reserve 64k for stack. */ 391bfdf22bcSPaolo Bonzini initrd_base = MIN(machine->ram_size, 1 * GiB); 392c108cc59SPhilippe Mathieu-Daudé initrd_base = initrd_base - 64 * KiB; 393a72bd606SHelge Deller initrd_base = (initrd_base - initrd_size) & TARGET_PAGE_MASK; 394a72bd606SHelge Deller 395a72bd606SHelge Deller if (initrd_base < kernel_high) { 396a72bd606SHelge Deller error_report("kernel and initial ram disk too large!"); 397a72bd606SHelge Deller exit(1); 398a72bd606SHelge Deller } 399a72bd606SHelge Deller 400a72bd606SHelge Deller load_image_targphys(initrd_filename, initrd_base, initrd_size); 401a72bd606SHelge Deller cpu[0]->env.gr[23] = initrd_base; 402a72bd606SHelge Deller cpu[0]->env.gr[22] = initrd_base + initrd_size; 403a72bd606SHelge Deller } 404a72bd606SHelge Deller } 405a72bd606SHelge Deller 406a72bd606SHelge Deller if (!kernel_entry) { 407a72bd606SHelge Deller /* When booting via firmware, tell firmware if we want interactive 408a72bd606SHelge Deller * mode (kernel_entry=1), and to boot from CD (gr[24]='d') 409a72bd606SHelge Deller * or hard disc * (gr[24]='c'). 410a72bd606SHelge Deller */ 41197ec4d21SPaolo Bonzini kernel_entry = machine->boot_config.has_menu ? machine->boot_config.menu : 0; 41297ec4d21SPaolo Bonzini cpu[0]->env.gr[24] = machine->boot_config.order[0]; 413a72bd606SHelge Deller } 414a72bd606SHelge Deller 415a72bd606SHelge Deller /* We jump to the firmware entry routine and pass the 416a72bd606SHelge Deller * various parameters in registers. After firmware initialization, 417a72bd606SHelge Deller * firmware will start the Linux kernel with ramdisk and cmdline. 418a72bd606SHelge Deller */ 419bfdf22bcSPaolo Bonzini cpu[0]->env.gr[26] = machine->ram_size; 420a72bd606SHelge Deller cpu[0]->env.gr[25] = kernel_entry; 421a72bd606SHelge Deller 422a72bd606SHelge Deller /* tell firmware how many SMP CPUs to present in inventory table */ 423a72bd606SHelge Deller cpu[0]->env.gr[21] = smp_cpus; 42424576007SHelge Deller 42524576007SHelge Deller /* tell firmware fw_cfg port */ 42624576007SHelge Deller cpu[0]->env.gr[19] = FW_CFG_IO_BASE; 427a72bd606SHelge Deller } 428a72bd606SHelge Deller 4297966d70fSJason A. Donenfeld static void hppa_machine_reset(MachineState *ms, ShutdownCause reason) 430a72bd606SHelge Deller { 43133decbd2SLike Xu unsigned int smp_cpus = ms->smp.cpus; 432a72bd606SHelge Deller int i; 433a72bd606SHelge Deller 4347966d70fSJason A. Donenfeld qemu_devices_reset(reason); 435a72bd606SHelge Deller 436a72bd606SHelge Deller /* Start all CPUs at the firmware entry point. 437a72bd606SHelge Deller * Monarch CPU will initialize firmware, secondary CPUs 43850ba97e9SHelge Deller * will enter a small idle loop and wait for rendevouz. */ 439a72bd606SHelge Deller for (i = 0; i < smp_cpus; i++) { 44050ba97e9SHelge Deller CPUState *cs = CPU(cpu[i]); 44150ba97e9SHelge Deller 44250ba97e9SHelge Deller cpu_set_pc(cs, firmware_entry); 44350ba97e9SHelge Deller cpu[i]->env.psw = PSW_Q; 444a72bd606SHelge Deller cpu[i]->env.gr[5] = CPU_HPA + i * 0x1000; 44550ba97e9SHelge Deller 44650ba97e9SHelge Deller cs->exception_index = -1; 44750ba97e9SHelge Deller cs->halted = 0; 4486d1ef68cSHelge Deller 4496d1ef68cSHelge Deller /* clear any existing TLB and BTLB entries */ 4506d1ef68cSHelge Deller memset(cpu[i]->env.tlb, 0, sizeof(cpu[i]->env.tlb)); 4516d1ef68cSHelge Deller cpu[i]->env.tlb_last = HPPA_BTLB_ENTRIES; 452a72bd606SHelge Deller } 453a72bd606SHelge Deller 454a72bd606SHelge Deller /* already initialized by machine_hppa_init()? */ 455bfdf22bcSPaolo Bonzini if (cpu[0]->env.gr[26] == ms->ram_size) { 456a72bd606SHelge Deller return; 457a72bd606SHelge Deller } 458a72bd606SHelge Deller 459bfdf22bcSPaolo Bonzini cpu[0]->env.gr[26] = ms->ram_size; 460a72bd606SHelge Deller cpu[0]->env.gr[25] = 0; /* no firmware boot menu */ 461a72bd606SHelge Deller cpu[0]->env.gr[24] = 'c'; 462a72bd606SHelge Deller /* gr22/gr23 unused, no initrd while reboot. */ 463a72bd606SHelge Deller cpu[0]->env.gr[21] = smp_cpus; 46424576007SHelge Deller /* tell firmware fw_cfg port */ 46524576007SHelge Deller cpu[0]->env.gr[19] = FW_CFG_IO_BASE; 466a72bd606SHelge Deller } 467a72bd606SHelge Deller 4684a4554c6SHelge Deller static void hppa_nmi(NMIState *n, int cpu_index, Error **errp) 4694a4554c6SHelge Deller { 4704a4554c6SHelge Deller CPUState *cs; 4714a4554c6SHelge Deller 4724a4554c6SHelge Deller CPU_FOREACH(cs) { 4734a4554c6SHelge Deller cpu_interrupt(cs, CPU_INTERRUPT_NMI); 4744a4554c6SHelge Deller } 4754a4554c6SHelge Deller } 476a72bd606SHelge Deller 477297d4103SMark Cave-Ayland static void hppa_machine_init_class_init(ObjectClass *oc, void *data) 478813dff13SHelge Deller { 47942cc2bf6SMark Cave-Ayland MachineClass *mc = MACHINE_CLASS(oc); 48042cc2bf6SMark Cave-Ayland NMIClass *nc = NMI_CLASS(oc); 48142cc2bf6SMark Cave-Ayland 4820d98fbb5SMark Cave-Ayland mc->desc = "HPPA B160L machine"; 483a72bd606SHelge Deller mc->default_cpu_type = TYPE_HPPA_CPU; 484813dff13SHelge Deller mc->init = machine_hppa_init; 485a72bd606SHelge Deller mc->reset = hppa_machine_reset; 486813dff13SHelge Deller mc->block_default_type = IF_SCSI; 487a72bd606SHelge Deller mc->max_cpus = HPPA_MAX_CPUS; 488a72bd606SHelge Deller mc->default_cpus = 1; 489ea0ac7f6SPhilippe Mathieu-Daudé mc->is_default = true; 490d23b6caaSPhilippe Mathieu-Daudé mc->default_ram_size = 512 * MiB; 491813dff13SHelge Deller mc->default_boot_order = "cd"; 4927c59c1e0SIgor Mammedov mc->default_ram_id = "ram"; 4939f8981a9SThomas Huth mc->default_nic = "tulip"; 494813dff13SHelge Deller 4954a4554c6SHelge Deller nc->nmi_monitor_handler = hppa_nmi; 4964a4554c6SHelge Deller } 4974a4554c6SHelge Deller 498297d4103SMark Cave-Ayland static const TypeInfo hppa_machine_init_typeinfo = { 499c165905cSMark Cave-Ayland .name = MACHINE_TYPE_NAME("hppa"), 500c165905cSMark Cave-Ayland .parent = TYPE_MACHINE, 501297d4103SMark Cave-Ayland .class_init = hppa_machine_init_class_init, 5024a4554c6SHelge Deller .interfaces = (InterfaceInfo[]) { 5034a4554c6SHelge Deller { TYPE_NMI }, 5044a4554c6SHelge Deller { } 5054a4554c6SHelge Deller }, 5064a4554c6SHelge Deller }; 5074a4554c6SHelge Deller 508297d4103SMark Cave-Ayland static void hppa_machine_init_register_types(void) 5094a4554c6SHelge Deller { 510297d4103SMark Cave-Ayland type_register_static(&hppa_machine_init_typeinfo); 5114a4554c6SHelge Deller } 5124a4554c6SHelge Deller 513297d4103SMark Cave-Ayland type_init(hppa_machine_init_register_types) 514