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" 252ed4faa0SHelge Deller #include "hw/usb.h" 26134ba73fSMark Cave-Ayland #include "hw/pci/pci.h" 277df6f751SHelge Deller #include "hw/pci/pci_device.h" 282ed4faa0SHelge Deller #include "hw/pci-host/astro.h" 290db9350eSMark Cave-Ayland #include "hw/pci-host/dino.h" 3045f569a1SMark Cave-Ayland #include "hw/misc/lasi.h" 31148da670SMark Cave-Ayland #include "hppa_hardware.h" 32c108cc59SPhilippe Mathieu-Daudé #include "qemu/units.h" 33813dff13SHelge Deller #include "qapi/error.h" 34852c27e2SPaolo Bonzini #include "net/net.h" 35691cbbadSRichard Henderson #include "qemu/log.h" 36813dff13SHelge Deller 37a536f564SHelge Deller #define MIN_SEABIOS_HPPA_VERSION 10 /* require at least this fw version */ 3828b71a2eSHelge Deller 39b28c4a64SHelge Deller #define HPA_POWER_BUTTON (FIRMWARE_END - 0x10) 40b28c4a64SHelge Deller 41932befaaSMark Cave-Ayland #define enable_lasi_lan() 0 42932befaaSMark Cave-Ayland 437df6f751SHelge Deller static DeviceState *lasi_dev; 44932befaaSMark Cave-Ayland 45b28c4a64SHelge Deller static void hppa_powerdown_req(Notifier *n, void *opaque) 46b28c4a64SHelge Deller { 47b28c4a64SHelge Deller hwaddr soft_power_reg = HPA_POWER_BUTTON; 48b28c4a64SHelge Deller uint32_t val; 49b28c4a64SHelge Deller 50b28c4a64SHelge Deller val = ldl_be_phys(&address_space_memory, soft_power_reg); 51b28c4a64SHelge Deller if ((val >> 8) == 0) { 52b28c4a64SHelge Deller /* immediately shut down when under hardware control */ 53b28c4a64SHelge Deller qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); 54b28c4a64SHelge Deller return; 55b28c4a64SHelge Deller } 56b28c4a64SHelge Deller 57b28c4a64SHelge Deller /* clear bit 31 to indicate that the power switch was pressed. */ 58b28c4a64SHelge Deller val &= ~1; 59b28c4a64SHelge Deller stl_be_phys(&address_space_memory, soft_power_reg, val); 60b28c4a64SHelge Deller } 61b28c4a64SHelge Deller 62b28c4a64SHelge Deller static Notifier hppa_system_powerdown_notifier = { 63b28c4a64SHelge Deller .notify = hppa_powerdown_req 64b28c4a64SHelge Deller }; 65b28c4a64SHelge Deller 6628f5332aSMark Cave-Ayland /* Fallback for unassigned PCI I/O operations. Avoids MCHK. */ 6728f5332aSMark Cave-Ayland static uint64_t ignore_read(void *opaque, hwaddr addr, unsigned size) 6828f5332aSMark Cave-Ayland { 6928f5332aSMark Cave-Ayland return 0; 7028f5332aSMark Cave-Ayland } 7128f5332aSMark Cave-Ayland 7228f5332aSMark Cave-Ayland static void ignore_write(void *opaque, hwaddr addr, uint64_t v, unsigned size) 7328f5332aSMark Cave-Ayland { 7428f5332aSMark Cave-Ayland } 7528f5332aSMark Cave-Ayland 7628f5332aSMark Cave-Ayland static const MemoryRegionOps hppa_pci_ignore_ops = { 7728f5332aSMark Cave-Ayland .read = ignore_read, 7828f5332aSMark Cave-Ayland .write = ignore_write, 7928f5332aSMark Cave-Ayland .endianness = DEVICE_BIG_ENDIAN, 8028f5332aSMark Cave-Ayland .valid = { 8128f5332aSMark Cave-Ayland .min_access_size = 1, 8228f5332aSMark Cave-Ayland .max_access_size = 8, 8328f5332aSMark Cave-Ayland }, 8428f5332aSMark Cave-Ayland .impl = { 8528f5332aSMark Cave-Ayland .min_access_size = 1, 8628f5332aSMark Cave-Ayland .max_access_size = 8, 8728f5332aSMark Cave-Ayland }, 8828f5332aSMark Cave-Ayland }; 89b28c4a64SHelge Deller 90f386a16eSRichard Henderson static ISABus *hppa_isa_bus(hwaddr addr) 91a72bd606SHelge Deller { 92a72bd606SHelge Deller ISABus *isa_bus; 93a72bd606SHelge Deller qemu_irq *isa_irqs; 94a72bd606SHelge Deller MemoryRegion *isa_region; 95a72bd606SHelge Deller 96a72bd606SHelge Deller isa_region = g_new(MemoryRegion, 1); 97a72bd606SHelge Deller memory_region_init_io(isa_region, NULL, &hppa_pci_ignore_ops, 98a72bd606SHelge Deller NULL, "isa-io", 0x800); 99f386a16eSRichard Henderson memory_region_add_subregion(get_system_memory(), addr, isa_region); 100a72bd606SHelge Deller 101a72bd606SHelge Deller isa_bus = isa_bus_new(NULL, get_system_memory(), isa_region, 102a72bd606SHelge Deller &error_abort); 103a536f564SHelge Deller isa_irqs = i8259_init(isa_bus, NULL); 1047067887eSPhilippe Mathieu-Daudé isa_bus_register_input_irqs(isa_bus, isa_irqs); 105a72bd606SHelge Deller 106a72bd606SHelge Deller return isa_bus; 107a72bd606SHelge Deller } 108a72bd606SHelge Deller 109e2c41ee5SHelge Deller /* 110e2c41ee5SHelge Deller * Helper functions to emulate RTC clock and DebugOutputPort 111e2c41ee5SHelge Deller */ 112e2c41ee5SHelge Deller static time_t rtc_ref; 113e2c41ee5SHelge Deller 114e2c41ee5SHelge Deller static uint64_t io_cpu_read(void *opaque, hwaddr addr, unsigned size) 115e2c41ee5SHelge Deller { 116e2c41ee5SHelge Deller uint64_t val = 0; 117e2c41ee5SHelge Deller 118e2c41ee5SHelge Deller switch (addr) { 119e2c41ee5SHelge Deller case 0: /* RTC clock */ 120e2c41ee5SHelge Deller val = time(NULL); 121e2c41ee5SHelge Deller val += rtc_ref; 122e2c41ee5SHelge Deller break; 123e2c41ee5SHelge Deller case 8: /* DebugOutputPort */ 124e2c41ee5SHelge Deller return 0xe9; /* readback */ 125e2c41ee5SHelge Deller } 126e2c41ee5SHelge Deller return val; 127e2c41ee5SHelge Deller } 128e2c41ee5SHelge Deller 129e2c41ee5SHelge Deller static void io_cpu_write(void *opaque, hwaddr addr, 130e2c41ee5SHelge Deller uint64_t val, unsigned size) 131e2c41ee5SHelge Deller { 132e2c41ee5SHelge Deller unsigned char ch; 133e2c41ee5SHelge Deller Chardev *debugout; 134e2c41ee5SHelge Deller 135e2c41ee5SHelge Deller switch (addr) { 136e2c41ee5SHelge Deller case 0: /* RTC clock */ 137e2c41ee5SHelge Deller rtc_ref = val - time(NULL); 138e2c41ee5SHelge Deller break; 139e2c41ee5SHelge Deller case 8: /* DebugOutputPort */ 140e2c41ee5SHelge Deller ch = val; 141e2c41ee5SHelge Deller debugout = serial_hd(0); 142e2c41ee5SHelge Deller if (debugout) { 143e2c41ee5SHelge Deller qemu_chr_fe_write_all(debugout->be, &ch, 1); 144e2c41ee5SHelge Deller } else { 145e2c41ee5SHelge Deller fprintf(stderr, "%c", ch); 146e2c41ee5SHelge Deller } 147e2c41ee5SHelge Deller break; 148e2c41ee5SHelge Deller } 149e2c41ee5SHelge Deller } 150e2c41ee5SHelge Deller 151e2c41ee5SHelge Deller static const MemoryRegionOps hppa_io_helper_ops = { 152e2c41ee5SHelge Deller .read = io_cpu_read, 153e2c41ee5SHelge Deller .write = io_cpu_write, 154e2c41ee5SHelge Deller .endianness = DEVICE_BIG_ENDIAN, 155e2c41ee5SHelge Deller .valid = { 156e2c41ee5SHelge Deller .min_access_size = 1, 157e2c41ee5SHelge Deller .max_access_size = 8, 158e2c41ee5SHelge Deller }, 159e2c41ee5SHelge Deller .impl = { 160e2c41ee5SHelge Deller .min_access_size = 1, 161e2c41ee5SHelge Deller .max_access_size = 8, 162e2c41ee5SHelge Deller }, 163e2c41ee5SHelge Deller }; 164e2c41ee5SHelge Deller 165f386a16eSRichard Henderson typedef uint64_t TranslateFn(void *opaque, uint64_t addr); 166e2c41ee5SHelge Deller 167f386a16eSRichard Henderson static uint64_t linux_kernel_virt_to_phys(void *opaque, uint64_t addr) 168a72bd606SHelge Deller { 169a72bd606SHelge Deller addr &= (0x10000000 - 1); 170a72bd606SHelge Deller return addr; 171a72bd606SHelge Deller } 172a72bd606SHelge Deller 173f386a16eSRichard Henderson static uint64_t translate_pa10(void *dummy, uint64_t addr) 174f386a16eSRichard Henderson { 175f386a16eSRichard Henderson return (uint32_t)addr; 176f386a16eSRichard Henderson } 177f386a16eSRichard Henderson 178f386a16eSRichard Henderson static uint64_t translate_pa20(void *dummy, uint64_t addr) 179f386a16eSRichard Henderson { 180f386a16eSRichard Henderson return hppa_abs_to_phys_pa2_w0(addr); 181f386a16eSRichard Henderson } 182f386a16eSRichard Henderson 183a72bd606SHelge Deller static HPPACPU *cpu[HPPA_MAX_CPUS]; 184a72bd606SHelge Deller static uint64_t firmware_entry; 185813dff13SHelge Deller 18632ff8bf2SHelge Deller static void fw_cfg_boot_set(void *opaque, const char *boot_device, 18732ff8bf2SHelge Deller Error **errp) 18832ff8bf2SHelge Deller { 18932ff8bf2SHelge Deller fw_cfg_modify_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]); 19032ff8bf2SHelge Deller } 19132ff8bf2SHelge Deller 192f386a16eSRichard Henderson static FWCfgState *create_fw_cfg(MachineState *ms, PCIBus *pci_bus, 193f386a16eSRichard Henderson hwaddr addr) 19428b71a2eSHelge Deller { 19528b71a2eSHelge Deller FWCfgState *fw_cfg; 19628b71a2eSHelge Deller uint64_t val; 197069d2966SHelge Deller const char qemu_version[] = QEMU_VERSION; 198bcd4dd4cSHelge Deller MachineClass *mc = MACHINE_GET_CLASS(ms); 1999cf2112bSRichard Henderson int btlb_entries = HPPA_BTLB_ENTRIES(&cpu[0]->env); 200bcd4dd4cSHelge Deller int len; 20128b71a2eSHelge Deller 202f386a16eSRichard Henderson fw_cfg = fw_cfg_init_mem(addr, addr + 4); 20328b71a2eSHelge Deller fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, ms->smp.cpus); 20428b71a2eSHelge Deller fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, HPPA_MAX_CPUS); 205bfdf22bcSPaolo Bonzini fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, ms->ram_size); 20628b71a2eSHelge Deller 20728b71a2eSHelge Deller val = cpu_to_le64(MIN_SEABIOS_HPPA_VERSION); 20828b71a2eSHelge Deller fw_cfg_add_file(fw_cfg, "/etc/firmware-min-version", 20928b71a2eSHelge Deller g_memdup(&val, sizeof(val)), sizeof(val)); 21028b71a2eSHelge Deller 2119cf2112bSRichard Henderson val = cpu_to_le64(HPPA_TLB_ENTRIES - btlb_entries); 212df5c6a50SHelge Deller fw_cfg_add_file(fw_cfg, "/etc/cpu/tlb_entries", 213df5c6a50SHelge Deller g_memdup(&val, sizeof(val)), sizeof(val)); 214df5c6a50SHelge Deller 2159cf2112bSRichard Henderson val = cpu_to_le64(btlb_entries); 216bcd4dd4cSHelge Deller fw_cfg_add_file(fw_cfg, "/etc/cpu/btlb_entries", 217bcd4dd4cSHelge Deller g_memdup(&val, sizeof(val)), sizeof(val)); 218bcd4dd4cSHelge Deller 219bcd4dd4cSHelge Deller len = strlen(mc->name) + 1; 220bcd4dd4cSHelge Deller fw_cfg_add_file(fw_cfg, "/etc/hppa/machine", 221bcd4dd4cSHelge Deller g_memdup(mc->name, len), len); 222bcd4dd4cSHelge Deller 223b28c4a64SHelge Deller val = cpu_to_le64(HPA_POWER_BUTTON); 224bcd4dd4cSHelge Deller fw_cfg_add_file(fw_cfg, "/etc/hppa/power-button-addr", 225bcd4dd4cSHelge Deller g_memdup(&val, sizeof(val)), sizeof(val)); 226bcd4dd4cSHelge Deller 227e2c41ee5SHelge Deller val = cpu_to_le64(CPU_HPA + 16); 228e2c41ee5SHelge Deller fw_cfg_add_file(fw_cfg, "/etc/hppa/rtc-addr", 229e2c41ee5SHelge Deller g_memdup(&val, sizeof(val)), sizeof(val)); 230e2c41ee5SHelge Deller 231bcd4dd4cSHelge Deller val = cpu_to_le64(CPU_HPA + 24); 232bcd4dd4cSHelge Deller fw_cfg_add_file(fw_cfg, "/etc/hppa/DebugOutputPort", 233b28c4a64SHelge Deller g_memdup(&val, sizeof(val)), sizeof(val)); 234b28c4a64SHelge Deller 23597ec4d21SPaolo Bonzini fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ms->boot_config.order[0]); 23632ff8bf2SHelge Deller qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); 23732ff8bf2SHelge Deller 238069d2966SHelge Deller fw_cfg_add_file(fw_cfg, "/etc/qemu-version", 239069d2966SHelge Deller g_memdup(qemu_version, sizeof(qemu_version)), 240069d2966SHelge Deller sizeof(qemu_version)); 241069d2966SHelge Deller 242bcd4dd4cSHelge Deller fw_cfg_add_extra_pci_roots(pci_bus, fw_cfg); 243bcd4dd4cSHelge Deller 24428b71a2eSHelge Deller return fw_cfg; 24528b71a2eSHelge Deller } 24628b71a2eSHelge Deller 247e881e3c8SMark Cave-Ayland static LasiState *lasi_init(void) 248e881e3c8SMark Cave-Ayland { 249e881e3c8SMark Cave-Ayland DeviceState *dev; 250e881e3c8SMark Cave-Ayland 251e881e3c8SMark Cave-Ayland dev = qdev_new(TYPE_LASI_CHIP); 252e881e3c8SMark Cave-Ayland sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 253e881e3c8SMark Cave-Ayland 254e881e3c8SMark Cave-Ayland return LASI_CHIP(dev); 255e881e3c8SMark Cave-Ayland } 256e881e3c8SMark Cave-Ayland 2570d068996SMark Cave-Ayland static DinoState *dino_init(MemoryRegion *addr_space) 2580d068996SMark Cave-Ayland { 2590d068996SMark Cave-Ayland DeviceState *dev; 2600d068996SMark Cave-Ayland 2610d068996SMark Cave-Ayland dev = qdev_new(TYPE_DINO_PCI_HOST_BRIDGE); 2620d068996SMark Cave-Ayland object_property_set_link(OBJECT(dev), "memory-as", OBJECT(addr_space), 2630d068996SMark Cave-Ayland &error_fatal); 2640d068996SMark Cave-Ayland sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 2650d068996SMark Cave-Ayland 2660d068996SMark Cave-Ayland return DINO_PCI_HOST_BRIDGE(dev); 2670d068996SMark Cave-Ayland } 2680d068996SMark Cave-Ayland 2697df6f751SHelge Deller /* 2707df6f751SHelge Deller * Step 1: Create CPUs and Memory 2717df6f751SHelge Deller */ 272f386a16eSRichard Henderson static TranslateFn *machine_HP_common_init_cpus(MachineState *machine) 273813dff13SHelge Deller { 274a72bd606SHelge Deller MemoryRegion *addr_space = get_system_memory(); 27533decbd2SLike Xu unsigned int smp_cpus = machine->smp.cpus; 276f386a16eSRichard Henderson TranslateFn *translate; 277f386a16eSRichard Henderson MemoryRegion *cpu_region; 278a72bd606SHelge Deller 279a72bd606SHelge Deller /* Create CPUs. */ 280f386a16eSRichard Henderson for (unsigned int i = 0; i < smp_cpus; i++) { 281a72bd606SHelge Deller cpu[i] = HPPA_CPU(cpu_create(machine->cpu_type)); 282f386a16eSRichard Henderson } 283f386a16eSRichard Henderson 284f386a16eSRichard Henderson /* 285f386a16eSRichard Henderson * For now, treat address layout as if PSW_W is clear. 286f386a16eSRichard Henderson * TODO: create a proper hppa64 board model and load elf64 firmware. 287f386a16eSRichard Henderson */ 288f386a16eSRichard Henderson if (hppa_is_pa20(&cpu[0]->env)) { 289f386a16eSRichard Henderson translate = translate_pa20; 290f386a16eSRichard Henderson } else { 291f386a16eSRichard Henderson translate = translate_pa10; 292f386a16eSRichard Henderson } 293f386a16eSRichard Henderson 294f386a16eSRichard Henderson for (unsigned int i = 0; i < smp_cpus; i++) { 295f386a16eSRichard Henderson g_autofree char *name = g_strdup_printf("cpu%u-io-eir", i); 296a72bd606SHelge Deller 297a72bd606SHelge Deller cpu_region = g_new(MemoryRegion, 1); 298a72bd606SHelge Deller memory_region_init_io(cpu_region, OBJECT(cpu[i]), &hppa_io_eir_ops, 299266a880eSPaolo Bonzini cpu[i], name, 4); 300f386a16eSRichard Henderson memory_region_add_subregion(addr_space, 301f386a16eSRichard Henderson translate(NULL, CPU_HPA + i * 0x1000), 302a72bd606SHelge Deller cpu_region); 303813dff13SHelge Deller } 304813dff13SHelge Deller 305e2c41ee5SHelge Deller /* RTC and DebugOutputPort on CPU #0 */ 306e2c41ee5SHelge Deller cpu_region = g_new(MemoryRegion, 1); 307e2c41ee5SHelge Deller memory_region_init_io(cpu_region, OBJECT(cpu[0]), &hppa_io_helper_ops, 308e2c41ee5SHelge Deller cpu[0], "cpu0-io-rtc", 2 * sizeof(uint64_t)); 309f386a16eSRichard Henderson memory_region_add_subregion(addr_space, translate(NULL, CPU_HPA + 16), 310f386a16eSRichard Henderson cpu_region); 311e2c41ee5SHelge Deller 312a72bd606SHelge Deller /* Main memory region. */ 313b7746b11SPhilippe Mathieu-Daudé if (machine->ram_size > 3 * GiB) { 314b7746b11SPhilippe Mathieu-Daudé error_report("RAM size is currently restricted to 3GB"); 315b7746b11SPhilippe Mathieu-Daudé exit(EXIT_FAILURE); 316b7746b11SPhilippe Mathieu-Daudé } 3177c59c1e0SIgor Mammedov memory_region_add_subregion_overlap(addr_space, 0, machine->ram, -1); 318f386a16eSRichard Henderson 319f386a16eSRichard Henderson return translate; 3207df6f751SHelge Deller } 3217c59c1e0SIgor Mammedov 3227df6f751SHelge Deller /* 3237df6f751SHelge Deller * Last creation step: Add SCSI discs, NICs, graphics & load firmware 3247df6f751SHelge Deller */ 325f386a16eSRichard Henderson static void machine_HP_common_init_tail(MachineState *machine, PCIBus *pci_bus, 326f386a16eSRichard Henderson TranslateFn *translate) 3277df6f751SHelge Deller { 3287df6f751SHelge Deller const char *kernel_filename = machine->kernel_filename; 3297df6f751SHelge Deller const char *kernel_cmdline = machine->kernel_cmdline; 3307df6f751SHelge Deller const char *initrd_filename = machine->initrd_filename; 3317df6f751SHelge Deller MachineClass *mc = MACHINE_GET_CLASS(machine); 3327df6f751SHelge Deller DeviceState *dev; 3332ed4faa0SHelge Deller PCIDevice *pci_dev; 3347df6f751SHelge Deller char *firmware_filename; 3357df6f751SHelge Deller uint64_t firmware_low, firmware_high; 3367df6f751SHelge Deller long size; 3377df6f751SHelge Deller uint64_t kernel_entry = 0, kernel_low, kernel_high; 3387df6f751SHelge Deller MemoryRegion *addr_space = get_system_memory(); 3397df6f751SHelge Deller MemoryRegion *rom_region; 3407df6f751SHelge Deller long i; 3417df6f751SHelge Deller unsigned int smp_cpus = machine->smp.cpus; 3427df6f751SHelge Deller SysBusDevice *s; 34328b71a2eSHelge Deller 344a72bd606SHelge Deller /* SCSI disk setup. */ 345877eb21dSMark Cave-Ayland dev = DEVICE(pci_create_simple(pci_bus, -1, "lsi53c895a")); 346877eb21dSMark Cave-Ayland lsi53c8xx_handle_legacy_cmdline(dev); 347a72bd606SHelge Deller 3484765384cSSven Schnelle /* Graphics setup. */ 3494765384cSSven Schnelle if (machine->enable_graphics && vga_interface_type != VGA_NONE) { 350f9bcb2d6SGautam Agrawal vga_interface_created = true; 3513e80f690SMarkus Armbruster dev = qdev_new("artist"); 3524765384cSSven Schnelle s = SYS_BUS_DEVICE(dev); 3533c6ef471SMarkus Armbruster sysbus_realize_and_unref(s, &error_fatal); 354f386a16eSRichard Henderson sysbus_mmio_map(s, 0, translate(NULL, LASI_GFX_HPA)); 355f386a16eSRichard Henderson sysbus_mmio_map(s, 1, translate(NULL, ARTIST_FB_ADDR)); 3564765384cSSven Schnelle } 3574765384cSSven Schnelle 3580e6de551SHelge Deller /* Network setup. */ 359c3c3fe47SMark Cave-Ayland if (enable_lasi_lan()) { 360f386a16eSRichard Henderson lasi_82596_init(addr_space, translate(NULL, LASI_LAN_HPA), 361c3c3fe47SMark Cave-Ayland qdev_get_gpio_in(lasi_dev, LASI_IRQ_LAN_HPA)); 362c3c3fe47SMark Cave-Ayland } 363c3c3fe47SMark Cave-Ayland 364a72bd606SHelge Deller for (i = 0; i < nb_nics; i++) { 365376b8519SHelge Deller if (!enable_lasi_lan()) { 3669f8981a9SThomas Huth pci_nic_init_nofail(&nd_table[i], pci_bus, mc->default_nic, NULL); 367a72bd606SHelge Deller } 368376b8519SHelge Deller } 369a72bd606SHelge Deller 3702ed4faa0SHelge Deller /* BMC board: HP Powerbar SP2 Diva (with console only) */ 3712ed4faa0SHelge Deller pci_dev = pci_new(-1, "pci-serial"); 3722ed4faa0SHelge Deller if (!lasi_dev) { 3732ed4faa0SHelge Deller /* bind default keyboard/serial to Diva card */ 3742ed4faa0SHelge Deller qdev_prop_set_chr(DEVICE(pci_dev), "chardev", serial_hd(0)); 3752ed4faa0SHelge Deller } 3762ed4faa0SHelge Deller qdev_prop_set_uint8(DEVICE(pci_dev), "prog_if", 0); 3772ed4faa0SHelge Deller pci_realize_and_unref(pci_dev, pci_bus, &error_fatal); 3782ed4faa0SHelge Deller pci_config_set_vendor_id(pci_dev->config, PCI_VENDOR_ID_HP); 3792ed4faa0SHelge Deller pci_config_set_device_id(pci_dev->config, 0x1048); 3802ed4faa0SHelge Deller pci_set_word(&pci_dev->config[PCI_SUBSYSTEM_VENDOR_ID], PCI_VENDOR_ID_HP); 3812ed4faa0SHelge Deller pci_set_word(&pci_dev->config[PCI_SUBSYSTEM_ID], 0x1227); /* Powerbar */ 3822ed4faa0SHelge Deller 3832ed4faa0SHelge Deller /* create a second serial PCI card when running Astro */ 3842ed4faa0SHelge Deller if (!lasi_dev) { 3852ed4faa0SHelge Deller pci_dev = pci_new(-1, "pci-serial-4x"); 3862ed4faa0SHelge Deller qdev_prop_set_chr(DEVICE(pci_dev), "chardev1", serial_hd(1)); 3872ed4faa0SHelge Deller qdev_prop_set_chr(DEVICE(pci_dev), "chardev2", serial_hd(2)); 3882ed4faa0SHelge Deller qdev_prop_set_chr(DEVICE(pci_dev), "chardev3", serial_hd(3)); 3892ed4faa0SHelge Deller qdev_prop_set_chr(DEVICE(pci_dev), "chardev4", serial_hd(4)); 3902ed4faa0SHelge Deller pci_realize_and_unref(pci_dev, pci_bus, &error_fatal); 3912ed4faa0SHelge Deller } 3922ed4faa0SHelge Deller 3932ed4faa0SHelge Deller /* create USB OHCI controller for USB keyboard & mouse on Astro machines */ 3942ed4faa0SHelge Deller if (!lasi_dev && machine->enable_graphics) { 3952ed4faa0SHelge Deller pci_create_simple(pci_bus, -1, "pci-ohci"); 3962ed4faa0SHelge Deller usb_create_simple(usb_bus_find(-1), "usb-kbd"); 3972ed4faa0SHelge Deller usb_create_simple(usb_bus_find(-1), "usb-mouse"); 3982ed4faa0SHelge Deller } 3992ed4faa0SHelge Deller 400b28c4a64SHelge Deller /* register power switch emulation */ 401b28c4a64SHelge Deller qemu_register_powerdown_notifier(&hppa_system_powerdown_notifier); 402b28c4a64SHelge Deller 4037df6f751SHelge Deller /* fw_cfg configuration interface */ 404f386a16eSRichard Henderson create_fw_cfg(machine, pci_bus, translate(NULL, FW_CFG_IO_BASE)); 4057df6f751SHelge Deller 406a72bd606SHelge Deller /* Load firmware. Given that this is not "real" firmware, 407a72bd606SHelge Deller but one explicitly written for the emulation, we might as 408a72bd606SHelge Deller well load it directly from an ELF image. */ 409a72bd606SHelge Deller firmware_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, 410b57e3e97SPaolo Bonzini machine->firmware ?: "hppa-firmware.img"); 411a72bd606SHelge Deller if (firmware_filename == NULL) { 412a72bd606SHelge Deller error_report("no firmware provided"); 413a72bd606SHelge Deller exit(1); 414a72bd606SHelge Deller } 415a72bd606SHelge Deller 416f386a16eSRichard Henderson size = load_elf(firmware_filename, NULL, translate, NULL, 4176cdda0ffSAleksandar Markovic &firmware_entry, &firmware_low, &firmware_high, NULL, 418a72bd606SHelge Deller true, EM_PARISC, 0, 0); 419a72bd606SHelge Deller 420a72bd606SHelge Deller if (size < 0) { 421a72bd606SHelge Deller error_report("could not load firmware '%s'", firmware_filename); 422a72bd606SHelge Deller exit(1); 423a72bd606SHelge Deller } 424691cbbadSRichard Henderson qemu_log_mask(CPU_LOG_PAGE, "Firmware loaded at 0x%08" PRIx64 425691cbbadSRichard Henderson "-0x%08" PRIx64 ", entry at 0x%08" PRIx64 ".\n", 426a72bd606SHelge Deller firmware_low, firmware_high, firmware_entry); 427f386a16eSRichard Henderson if (firmware_low < translate(NULL, FIRMWARE_START) || 428f386a16eSRichard Henderson firmware_high >= translate(NULL, FIRMWARE_END)) { 429a72bd606SHelge Deller error_report("Firmware overlaps with memory or IO space"); 430a72bd606SHelge Deller exit(1); 431a72bd606SHelge Deller } 432a72bd606SHelge Deller g_free(firmware_filename); 433a72bd606SHelge Deller 434a72bd606SHelge Deller rom_region = g_new(MemoryRegion, 1); 4356a3a2e82SIgor Mammedov memory_region_init_ram(rom_region, NULL, "firmware", 4366a3a2e82SIgor Mammedov (FIRMWARE_END - FIRMWARE_START), &error_fatal); 437f386a16eSRichard Henderson memory_region_add_subregion(addr_space, 438f386a16eSRichard Henderson translate(NULL, FIRMWARE_START), rom_region); 439a72bd606SHelge Deller 440a72bd606SHelge Deller /* Load kernel */ 441a72bd606SHelge Deller if (kernel_filename) { 442f386a16eSRichard Henderson size = load_elf(kernel_filename, NULL, linux_kernel_virt_to_phys, 4436cdda0ffSAleksandar Markovic NULL, &kernel_entry, &kernel_low, &kernel_high, NULL, 444a72bd606SHelge Deller true, EM_PARISC, 0, 0); 445a72bd606SHelge Deller 446f386a16eSRichard Henderson kernel_entry = linux_kernel_virt_to_phys(NULL, kernel_entry); 447a72bd606SHelge Deller 448a72bd606SHelge Deller if (size < 0) { 449a72bd606SHelge Deller error_report("could not load kernel '%s'", kernel_filename); 450a72bd606SHelge Deller exit(1); 451a72bd606SHelge Deller } 452691cbbadSRichard Henderson qemu_log_mask(CPU_LOG_PAGE, "Kernel loaded at 0x%08" PRIx64 453691cbbadSRichard Henderson "-0x%08" PRIx64 ", entry at 0x%08" PRIx64 454c108cc59SPhilippe Mathieu-Daudé ", size %" PRIu64 " kB\n", 455c108cc59SPhilippe Mathieu-Daudé kernel_low, kernel_high, kernel_entry, size / KiB); 456a72bd606SHelge Deller 457a72bd606SHelge Deller if (kernel_cmdline) { 458a72bd606SHelge Deller cpu[0]->env.gr[24] = 0x4000; 459a72bd606SHelge Deller pstrcpy_targphys("cmdline", cpu[0]->env.gr[24], 460a72bd606SHelge Deller TARGET_PAGE_SIZE, kernel_cmdline); 461a72bd606SHelge Deller } 462a72bd606SHelge Deller 463a72bd606SHelge Deller if (initrd_filename) { 464a72bd606SHelge Deller ram_addr_t initrd_base; 465f3839fdaSLi Zhijian int64_t initrd_size; 466a72bd606SHelge Deller 467a72bd606SHelge Deller initrd_size = get_image_size(initrd_filename); 468a72bd606SHelge Deller if (initrd_size < 0) { 469a72bd606SHelge Deller error_report("could not load initial ram disk '%s'", 470a72bd606SHelge Deller initrd_filename); 471a72bd606SHelge Deller exit(1); 472a72bd606SHelge Deller } 473a72bd606SHelge Deller 474a72bd606SHelge Deller /* Load the initrd image high in memory. 475a72bd606SHelge Deller Mirror the algorithm used by palo: 476a72bd606SHelge Deller (1) Due to sign-extension problems and PDC, 477a72bd606SHelge Deller put the initrd no higher than 1G. 478a72bd606SHelge Deller (2) Reserve 64k for stack. */ 479bfdf22bcSPaolo Bonzini initrd_base = MIN(machine->ram_size, 1 * GiB); 480c108cc59SPhilippe Mathieu-Daudé initrd_base = initrd_base - 64 * KiB; 481a72bd606SHelge Deller initrd_base = (initrd_base - initrd_size) & TARGET_PAGE_MASK; 482a72bd606SHelge Deller 483a72bd606SHelge Deller if (initrd_base < kernel_high) { 484a72bd606SHelge Deller error_report("kernel and initial ram disk too large!"); 485a72bd606SHelge Deller exit(1); 486a72bd606SHelge Deller } 487a72bd606SHelge Deller 488a72bd606SHelge Deller load_image_targphys(initrd_filename, initrd_base, initrd_size); 489a72bd606SHelge Deller cpu[0]->env.gr[23] = initrd_base; 490a72bd606SHelge Deller cpu[0]->env.gr[22] = initrd_base + initrd_size; 491a72bd606SHelge Deller } 492a72bd606SHelge Deller } 493a72bd606SHelge Deller 494a72bd606SHelge Deller if (!kernel_entry) { 495a72bd606SHelge Deller /* When booting via firmware, tell firmware if we want interactive 496a72bd606SHelge Deller * mode (kernel_entry=1), and to boot from CD (gr[24]='d') 497a72bd606SHelge Deller * or hard disc * (gr[24]='c'). 498a72bd606SHelge Deller */ 49997ec4d21SPaolo Bonzini kernel_entry = machine->boot_config.has_menu ? machine->boot_config.menu : 0; 50097ec4d21SPaolo Bonzini cpu[0]->env.gr[24] = machine->boot_config.order[0]; 501a72bd606SHelge Deller } 502a72bd606SHelge Deller 503a72bd606SHelge Deller /* We jump to the firmware entry routine and pass the 504a72bd606SHelge Deller * various parameters in registers. After firmware initialization, 505a72bd606SHelge Deller * firmware will start the Linux kernel with ramdisk and cmdline. 506a72bd606SHelge Deller */ 507bfdf22bcSPaolo Bonzini cpu[0]->env.gr[26] = machine->ram_size; 508a72bd606SHelge Deller cpu[0]->env.gr[25] = kernel_entry; 509a72bd606SHelge Deller 510a72bd606SHelge Deller /* tell firmware how many SMP CPUs to present in inventory table */ 511a72bd606SHelge Deller cpu[0]->env.gr[21] = smp_cpus; 51224576007SHelge Deller 51324576007SHelge Deller /* tell firmware fw_cfg port */ 51424576007SHelge Deller cpu[0]->env.gr[19] = FW_CFG_IO_BASE; 515a72bd606SHelge Deller } 516a72bd606SHelge Deller 5177df6f751SHelge Deller /* 5187df6f751SHelge Deller * Create HP B160L workstation 5197df6f751SHelge Deller */ 5207df6f751SHelge Deller static void machine_HP_B160L_init(MachineState *machine) 5217df6f751SHelge Deller { 5227df6f751SHelge Deller DeviceState *dev, *dino_dev; 5237df6f751SHelge Deller MemoryRegion *addr_space = get_system_memory(); 524f386a16eSRichard Henderson TranslateFn *translate; 5257df6f751SHelge Deller ISABus *isa_bus; 5267df6f751SHelge Deller PCIBus *pci_bus; 5277df6f751SHelge Deller 5287df6f751SHelge Deller /* Create CPUs and RAM. */ 529f386a16eSRichard Henderson translate = machine_HP_common_init_cpus(machine); 5307df6f751SHelge Deller 531*3d1611bfSHelge Deller if (hppa_is_pa20(&cpu[0]->env)) { 532*3d1611bfSHelge Deller error_report("The HP B160L workstation requires a 32-bit " 533*3d1611bfSHelge Deller "CPU. Use '-machine C3700' instead."); 534*3d1611bfSHelge Deller exit(1); 535*3d1611bfSHelge Deller } 536*3d1611bfSHelge Deller 5377df6f751SHelge Deller /* Init Lasi chip */ 5387df6f751SHelge Deller lasi_dev = DEVICE(lasi_init()); 539f386a16eSRichard Henderson memory_region_add_subregion(addr_space, translate(NULL, LASI_HPA), 5407df6f751SHelge Deller sysbus_mmio_get_region( 5417df6f751SHelge Deller SYS_BUS_DEVICE(lasi_dev), 0)); 5427df6f751SHelge Deller 5437df6f751SHelge Deller /* Init Dino (PCI host bus chip). */ 5447df6f751SHelge Deller dino_dev = DEVICE(dino_init(addr_space)); 545f386a16eSRichard Henderson memory_region_add_subregion(addr_space, translate(NULL, DINO_HPA), 5467df6f751SHelge Deller sysbus_mmio_get_region( 5477df6f751SHelge Deller SYS_BUS_DEVICE(dino_dev), 0)); 5487df6f751SHelge Deller pci_bus = PCI_BUS(qdev_get_child_bus(dino_dev, "pci")); 5497df6f751SHelge Deller assert(pci_bus); 5507df6f751SHelge Deller 5517df6f751SHelge Deller /* Create ISA bus, needed for PS/2 kbd/mouse port emulation */ 552f386a16eSRichard Henderson isa_bus = hppa_isa_bus(translate(NULL, IDE_HPA)); 5537df6f751SHelge Deller assert(isa_bus); 5547df6f751SHelge Deller 5557df6f751SHelge Deller /* Serial ports: Lasi and Dino use a 7.272727 MHz clock. */ 556f386a16eSRichard Henderson serial_mm_init(addr_space, translate(NULL, LASI_UART_HPA + 0x800), 0, 5577df6f751SHelge Deller qdev_get_gpio_in(lasi_dev, LASI_IRQ_UART_HPA), 7272727 / 16, 5587df6f751SHelge Deller serial_hd(0), DEVICE_BIG_ENDIAN); 5597df6f751SHelge Deller 560f386a16eSRichard Henderson serial_mm_init(addr_space, translate(NULL, DINO_UART_HPA + 0x800), 0, 5617df6f751SHelge Deller qdev_get_gpio_in(dino_dev, DINO_IRQ_RS232INT), 7272727 / 16, 5627df6f751SHelge Deller serial_hd(1), DEVICE_BIG_ENDIAN); 5637df6f751SHelge Deller 5647df6f751SHelge Deller /* Parallel port */ 565f386a16eSRichard Henderson parallel_mm_init(addr_space, translate(NULL, LASI_LPT_HPA + 0x800), 0, 5667df6f751SHelge Deller qdev_get_gpio_in(lasi_dev, LASI_IRQ_LAN_HPA), 5677df6f751SHelge Deller parallel_hds[0]); 5687df6f751SHelge Deller 5697df6f751SHelge Deller /* PS/2 Keyboard/Mouse */ 5707df6f751SHelge Deller dev = qdev_new(TYPE_LASIPS2); 5717df6f751SHelge Deller sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 5727df6f751SHelge Deller sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, 5737df6f751SHelge Deller qdev_get_gpio_in(lasi_dev, LASI_IRQ_PS2KBD_HPA)); 574f386a16eSRichard Henderson memory_region_add_subregion(addr_space, 575f386a16eSRichard Henderson translate(NULL, LASI_PS2KBD_HPA), 5767df6f751SHelge Deller sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 5777df6f751SHelge Deller 0)); 578f386a16eSRichard Henderson memory_region_add_subregion(addr_space, 579f386a16eSRichard Henderson translate(NULL, LASI_PS2KBD_HPA + 0x100), 5807df6f751SHelge Deller sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 5817df6f751SHelge Deller 1)); 5827df6f751SHelge Deller 5837df6f751SHelge Deller /* Add SCSI discs, NICs, graphics & load firmware */ 584f386a16eSRichard Henderson machine_HP_common_init_tail(machine, pci_bus, translate); 5857df6f751SHelge Deller } 5867df6f751SHelge Deller 5872ed4faa0SHelge Deller static AstroState *astro_init(void) 5882ed4faa0SHelge Deller { 5892ed4faa0SHelge Deller DeviceState *dev; 5902ed4faa0SHelge Deller 5912ed4faa0SHelge Deller dev = qdev_new(TYPE_ASTRO_CHIP); 5922ed4faa0SHelge Deller sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 5932ed4faa0SHelge Deller 5942ed4faa0SHelge Deller return ASTRO_CHIP(dev); 5952ed4faa0SHelge Deller } 5962ed4faa0SHelge Deller 5972ed4faa0SHelge Deller /* 5982ed4faa0SHelge Deller * Create HP C3700 workstation 5992ed4faa0SHelge Deller */ 6002ed4faa0SHelge Deller static void machine_HP_C3700_init(MachineState *machine) 6012ed4faa0SHelge Deller { 6022ed4faa0SHelge Deller PCIBus *pci_bus; 6032ed4faa0SHelge Deller AstroState *astro; 6042ed4faa0SHelge Deller DeviceState *astro_dev; 6052ed4faa0SHelge Deller MemoryRegion *addr_space = get_system_memory(); 606f386a16eSRichard Henderson TranslateFn *translate; 6072ed4faa0SHelge Deller 6082ed4faa0SHelge Deller /* Create CPUs and RAM. */ 609f386a16eSRichard Henderson translate = machine_HP_common_init_cpus(machine); 6102ed4faa0SHelge Deller 611*3d1611bfSHelge Deller if (!hppa_is_pa20(&cpu[0]->env)) { 612*3d1611bfSHelge Deller error_report("The HP C3000 workstation requires a 64-bit CPU. " 613*3d1611bfSHelge Deller "Use '-machine B160L' instead."); 614*3d1611bfSHelge Deller exit(1); 615*3d1611bfSHelge Deller } 616*3d1611bfSHelge Deller 6172ed4faa0SHelge Deller /* Init Astro and the Elroys (PCI host bus chips). */ 6182ed4faa0SHelge Deller astro = astro_init(); 6192ed4faa0SHelge Deller astro_dev = DEVICE(astro); 620f386a16eSRichard Henderson memory_region_add_subregion(addr_space, translate(NULL, ASTRO_HPA), 6212ed4faa0SHelge Deller sysbus_mmio_get_region( 6222ed4faa0SHelge Deller SYS_BUS_DEVICE(astro_dev), 0)); 6232ed4faa0SHelge Deller pci_bus = PCI_BUS(qdev_get_child_bus(DEVICE(astro->elroy[0]), "pci")); 6242ed4faa0SHelge Deller assert(pci_bus); 6252ed4faa0SHelge Deller 6262ed4faa0SHelge Deller /* Add SCSI discs, NICs, graphics & load firmware */ 627f386a16eSRichard Henderson machine_HP_common_init_tail(machine, pci_bus, translate); 6282ed4faa0SHelge Deller } 6292ed4faa0SHelge Deller 6307966d70fSJason A. Donenfeld static void hppa_machine_reset(MachineState *ms, ShutdownCause reason) 631a72bd606SHelge Deller { 63233decbd2SLike Xu unsigned int smp_cpus = ms->smp.cpus; 633a72bd606SHelge Deller int i; 634a72bd606SHelge Deller 6357966d70fSJason A. Donenfeld qemu_devices_reset(reason); 636a72bd606SHelge Deller 637a72bd606SHelge Deller /* Start all CPUs at the firmware entry point. 638a72bd606SHelge Deller * Monarch CPU will initialize firmware, secondary CPUs 63950ba97e9SHelge Deller * will enter a small idle loop and wait for rendevouz. */ 640a72bd606SHelge Deller for (i = 0; i < smp_cpus; i++) { 64150ba97e9SHelge Deller CPUState *cs = CPU(cpu[i]); 64250ba97e9SHelge Deller 64350ba97e9SHelge Deller cpu_set_pc(cs, firmware_entry); 64450ba97e9SHelge Deller cpu[i]->env.psw = PSW_Q; 645a72bd606SHelge Deller cpu[i]->env.gr[5] = CPU_HPA + i * 0x1000; 64650ba97e9SHelge Deller 64750ba97e9SHelge Deller cs->exception_index = -1; 64850ba97e9SHelge Deller cs->halted = 0; 649a72bd606SHelge Deller } 650a72bd606SHelge Deller 651a72bd606SHelge Deller /* already initialized by machine_hppa_init()? */ 652bfdf22bcSPaolo Bonzini if (cpu[0]->env.gr[26] == ms->ram_size) { 653a72bd606SHelge Deller return; 654a72bd606SHelge Deller } 655a72bd606SHelge Deller 656bfdf22bcSPaolo Bonzini cpu[0]->env.gr[26] = ms->ram_size; 657a72bd606SHelge Deller cpu[0]->env.gr[25] = 0; /* no firmware boot menu */ 658a72bd606SHelge Deller cpu[0]->env.gr[24] = 'c'; 659a72bd606SHelge Deller /* gr22/gr23 unused, no initrd while reboot. */ 660a72bd606SHelge Deller cpu[0]->env.gr[21] = smp_cpus; 66124576007SHelge Deller /* tell firmware fw_cfg port */ 66224576007SHelge Deller cpu[0]->env.gr[19] = FW_CFG_IO_BASE; 663a72bd606SHelge Deller } 664a72bd606SHelge Deller 6654a4554c6SHelge Deller static void hppa_nmi(NMIState *n, int cpu_index, Error **errp) 6664a4554c6SHelge Deller { 6674a4554c6SHelge Deller CPUState *cs; 6684a4554c6SHelge Deller 6694a4554c6SHelge Deller CPU_FOREACH(cs) { 6704a4554c6SHelge Deller cpu_interrupt(cs, CPU_INTERRUPT_NMI); 6714a4554c6SHelge Deller } 6724a4554c6SHelge Deller } 673a72bd606SHelge Deller 674*3d1611bfSHelge Deller static const char *HP_B160L_machine_valid_cpu_types[] = { 675*3d1611bfSHelge Deller TYPE_HPPA_CPU, 676*3d1611bfSHelge Deller NULL 677*3d1611bfSHelge Deller }; 678*3d1611bfSHelge Deller 6797df6f751SHelge Deller static void HP_B160L_machine_init_class_init(ObjectClass *oc, void *data) 680813dff13SHelge Deller { 68142cc2bf6SMark Cave-Ayland MachineClass *mc = MACHINE_CLASS(oc); 68242cc2bf6SMark Cave-Ayland NMIClass *nc = NMI_CLASS(oc); 68342cc2bf6SMark Cave-Ayland 6847df6f751SHelge Deller mc->desc = "HP B160L workstation"; 685a72bd606SHelge Deller mc->default_cpu_type = TYPE_HPPA_CPU; 686*3d1611bfSHelge Deller mc->valid_cpu_types = HP_B160L_machine_valid_cpu_types; 6877df6f751SHelge Deller mc->init = machine_HP_B160L_init; 688a72bd606SHelge Deller mc->reset = hppa_machine_reset; 689813dff13SHelge Deller mc->block_default_type = IF_SCSI; 690a72bd606SHelge Deller mc->max_cpus = HPPA_MAX_CPUS; 691a72bd606SHelge Deller mc->default_cpus = 1; 692ea0ac7f6SPhilippe Mathieu-Daudé mc->is_default = true; 693d23b6caaSPhilippe Mathieu-Daudé mc->default_ram_size = 512 * MiB; 694813dff13SHelge Deller mc->default_boot_order = "cd"; 6957c59c1e0SIgor Mammedov mc->default_ram_id = "ram"; 6969f8981a9SThomas Huth mc->default_nic = "tulip"; 697813dff13SHelge Deller 6984a4554c6SHelge Deller nc->nmi_monitor_handler = hppa_nmi; 6994a4554c6SHelge Deller } 7004a4554c6SHelge Deller 7017df6f751SHelge Deller static const TypeInfo HP_B160L_machine_init_typeinfo = { 7027df6f751SHelge Deller .name = MACHINE_TYPE_NAME("B160L"), 703c165905cSMark Cave-Ayland .parent = TYPE_MACHINE, 7047df6f751SHelge Deller .class_init = HP_B160L_machine_init_class_init, 7054a4554c6SHelge Deller .interfaces = (InterfaceInfo[]) { 7064a4554c6SHelge Deller { TYPE_NMI }, 7074a4554c6SHelge Deller { } 7084a4554c6SHelge Deller }, 7094a4554c6SHelge Deller }; 7104a4554c6SHelge Deller 711*3d1611bfSHelge Deller static const char *HP_C3700_machine_valid_cpu_types[] = { 712*3d1611bfSHelge Deller TYPE_HPPA64_CPU, 713*3d1611bfSHelge Deller NULL 714*3d1611bfSHelge Deller }; 715*3d1611bfSHelge Deller 7162ed4faa0SHelge Deller static void HP_C3700_machine_init_class_init(ObjectClass *oc, void *data) 7172ed4faa0SHelge Deller { 7182ed4faa0SHelge Deller MachineClass *mc = MACHINE_CLASS(oc); 7192ed4faa0SHelge Deller NMIClass *nc = NMI_CLASS(oc); 7202ed4faa0SHelge Deller 7212ed4faa0SHelge Deller mc->desc = "HP C3700 workstation"; 722fd9b04bfSHelge Deller mc->default_cpu_type = TYPE_HPPA64_CPU; 723*3d1611bfSHelge Deller mc->valid_cpu_types = HP_C3700_machine_valid_cpu_types; 7242ed4faa0SHelge Deller mc->init = machine_HP_C3700_init; 7252ed4faa0SHelge Deller mc->reset = hppa_machine_reset; 7262ed4faa0SHelge Deller mc->block_default_type = IF_SCSI; 7272ed4faa0SHelge Deller mc->max_cpus = HPPA_MAX_CPUS; 7282ed4faa0SHelge Deller mc->default_cpus = 1; 7292ed4faa0SHelge Deller mc->is_default = false; 7302ed4faa0SHelge Deller mc->default_ram_size = 1024 * MiB; 7312ed4faa0SHelge Deller mc->default_boot_order = "cd"; 7322ed4faa0SHelge Deller mc->default_ram_id = "ram"; 7332ed4faa0SHelge Deller mc->default_nic = "tulip"; 7342ed4faa0SHelge Deller 7352ed4faa0SHelge Deller nc->nmi_monitor_handler = hppa_nmi; 7362ed4faa0SHelge Deller } 7372ed4faa0SHelge Deller 7382ed4faa0SHelge Deller static const TypeInfo HP_C3700_machine_init_typeinfo = { 7392ed4faa0SHelge Deller .name = MACHINE_TYPE_NAME("C3700"), 7402ed4faa0SHelge Deller .parent = TYPE_MACHINE, 7412ed4faa0SHelge Deller .class_init = HP_C3700_machine_init_class_init, 7422ed4faa0SHelge Deller .interfaces = (InterfaceInfo[]) { 7432ed4faa0SHelge Deller { TYPE_NMI }, 7442ed4faa0SHelge Deller { } 7452ed4faa0SHelge Deller }, 7462ed4faa0SHelge Deller }; 7472ed4faa0SHelge Deller 748297d4103SMark Cave-Ayland static void hppa_machine_init_register_types(void) 7494a4554c6SHelge Deller { 7507df6f751SHelge Deller type_register_static(&HP_B160L_machine_init_typeinfo); 7512ed4faa0SHelge Deller type_register_static(&HP_C3700_machine_init_typeinfo); 7524a4554c6SHelge Deller } 7534a4554c6SHelge Deller 754297d4103SMark Cave-Ayland type_init(hppa_machine_init_register_types) 755