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" 25*2ed4faa0SHelge Deller #include "hw/usb.h" 26134ba73fSMark Cave-Ayland #include "hw/pci/pci.h" 277df6f751SHelge Deller #include "hw/pci/pci_device.h" 28*2ed4faa0SHelge 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 90a72bd606SHelge Deller static ISABus *hppa_isa_bus(void) 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); 99a72bd606SHelge Deller memory_region_add_subregion(get_system_memory(), IDE_HPA, 100a72bd606SHelge Deller isa_region); 101a72bd606SHelge Deller 102a72bd606SHelge Deller isa_bus = isa_bus_new(NULL, get_system_memory(), isa_region, 103a72bd606SHelge Deller &error_abort); 104a536f564SHelge Deller isa_irqs = i8259_init(isa_bus, NULL); 1057067887eSPhilippe Mathieu-Daudé isa_bus_register_input_irqs(isa_bus, isa_irqs); 106a72bd606SHelge Deller 107a72bd606SHelge Deller return isa_bus; 108a72bd606SHelge Deller } 109a72bd606SHelge Deller 110e2c41ee5SHelge Deller /* 111e2c41ee5SHelge Deller * Helper functions to emulate RTC clock and DebugOutputPort 112e2c41ee5SHelge Deller */ 113e2c41ee5SHelge Deller static time_t rtc_ref; 114e2c41ee5SHelge Deller 115e2c41ee5SHelge Deller static uint64_t io_cpu_read(void *opaque, hwaddr addr, unsigned size) 116e2c41ee5SHelge Deller { 117e2c41ee5SHelge Deller uint64_t val = 0; 118e2c41ee5SHelge Deller 119e2c41ee5SHelge Deller switch (addr) { 120e2c41ee5SHelge Deller case 0: /* RTC clock */ 121e2c41ee5SHelge Deller val = time(NULL); 122e2c41ee5SHelge Deller val += rtc_ref; 123e2c41ee5SHelge Deller break; 124e2c41ee5SHelge Deller case 8: /* DebugOutputPort */ 125e2c41ee5SHelge Deller return 0xe9; /* readback */ 126e2c41ee5SHelge Deller } 127e2c41ee5SHelge Deller return val; 128e2c41ee5SHelge Deller } 129e2c41ee5SHelge Deller 130e2c41ee5SHelge Deller static void io_cpu_write(void *opaque, hwaddr addr, 131e2c41ee5SHelge Deller uint64_t val, unsigned size) 132e2c41ee5SHelge Deller { 133e2c41ee5SHelge Deller unsigned char ch; 134e2c41ee5SHelge Deller Chardev *debugout; 135e2c41ee5SHelge Deller 136e2c41ee5SHelge Deller switch (addr) { 137e2c41ee5SHelge Deller case 0: /* RTC clock */ 138e2c41ee5SHelge Deller rtc_ref = val - time(NULL); 139e2c41ee5SHelge Deller break; 140e2c41ee5SHelge Deller case 8: /* DebugOutputPort */ 141e2c41ee5SHelge Deller ch = val; 142e2c41ee5SHelge Deller debugout = serial_hd(0); 143e2c41ee5SHelge Deller if (debugout) { 144e2c41ee5SHelge Deller qemu_chr_fe_write_all(debugout->be, &ch, 1); 145e2c41ee5SHelge Deller } else { 146e2c41ee5SHelge Deller fprintf(stderr, "%c", ch); 147e2c41ee5SHelge Deller } 148e2c41ee5SHelge Deller break; 149e2c41ee5SHelge Deller } 150e2c41ee5SHelge Deller } 151e2c41ee5SHelge Deller 152e2c41ee5SHelge Deller static const MemoryRegionOps hppa_io_helper_ops = { 153e2c41ee5SHelge Deller .read = io_cpu_read, 154e2c41ee5SHelge Deller .write = io_cpu_write, 155e2c41ee5SHelge Deller .endianness = DEVICE_BIG_ENDIAN, 156e2c41ee5SHelge Deller .valid = { 157e2c41ee5SHelge Deller .min_access_size = 1, 158e2c41ee5SHelge Deller .max_access_size = 8, 159e2c41ee5SHelge Deller }, 160e2c41ee5SHelge Deller .impl = { 161e2c41ee5SHelge Deller .min_access_size = 1, 162e2c41ee5SHelge Deller .max_access_size = 8, 163e2c41ee5SHelge Deller }, 164e2c41ee5SHelge Deller }; 165e2c41ee5SHelge Deller 166e2c41ee5SHelge Deller 167a72bd606SHelge Deller static uint64_t cpu_hppa_to_phys(void *opaque, uint64_t addr) 168a72bd606SHelge Deller { 169a72bd606SHelge Deller addr &= (0x10000000 - 1); 170a72bd606SHelge Deller return addr; 171a72bd606SHelge Deller } 172a72bd606SHelge Deller 173a72bd606SHelge Deller static HPPACPU *cpu[HPPA_MAX_CPUS]; 174a72bd606SHelge Deller static uint64_t firmware_entry; 175813dff13SHelge Deller 17632ff8bf2SHelge Deller static void fw_cfg_boot_set(void *opaque, const char *boot_device, 17732ff8bf2SHelge Deller Error **errp) 17832ff8bf2SHelge Deller { 17932ff8bf2SHelge Deller fw_cfg_modify_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]); 18032ff8bf2SHelge Deller } 18132ff8bf2SHelge Deller 182bcd4dd4cSHelge Deller static FWCfgState *create_fw_cfg(MachineState *ms, PCIBus *pci_bus) 18328b71a2eSHelge Deller { 18428b71a2eSHelge Deller FWCfgState *fw_cfg; 18528b71a2eSHelge Deller uint64_t val; 186069d2966SHelge Deller const char qemu_version[] = QEMU_VERSION; 187bcd4dd4cSHelge Deller MachineClass *mc = MACHINE_GET_CLASS(ms); 188bcd4dd4cSHelge Deller int len; 18928b71a2eSHelge Deller 19024576007SHelge Deller fw_cfg = fw_cfg_init_mem(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 4); 19128b71a2eSHelge Deller fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, ms->smp.cpus); 19228b71a2eSHelge Deller fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, HPPA_MAX_CPUS); 193bfdf22bcSPaolo Bonzini fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, ms->ram_size); 19428b71a2eSHelge Deller 19528b71a2eSHelge Deller val = cpu_to_le64(MIN_SEABIOS_HPPA_VERSION); 19628b71a2eSHelge Deller fw_cfg_add_file(fw_cfg, "/etc/firmware-min-version", 19728b71a2eSHelge Deller g_memdup(&val, sizeof(val)), sizeof(val)); 19828b71a2eSHelge Deller 1996d1ef68cSHelge Deller val = cpu_to_le64(HPPA_TLB_ENTRIES - HPPA_BTLB_ENTRIES); 200df5c6a50SHelge Deller fw_cfg_add_file(fw_cfg, "/etc/cpu/tlb_entries", 201df5c6a50SHelge Deller g_memdup(&val, sizeof(val)), sizeof(val)); 202df5c6a50SHelge Deller 203bcd4dd4cSHelge Deller val = cpu_to_le64(HPPA_BTLB_ENTRIES); 204bcd4dd4cSHelge Deller fw_cfg_add_file(fw_cfg, "/etc/cpu/btlb_entries", 205bcd4dd4cSHelge Deller g_memdup(&val, sizeof(val)), sizeof(val)); 206bcd4dd4cSHelge Deller 207bcd4dd4cSHelge Deller len = strlen(mc->name) + 1; 208bcd4dd4cSHelge Deller fw_cfg_add_file(fw_cfg, "/etc/hppa/machine", 209bcd4dd4cSHelge Deller g_memdup(mc->name, len), len); 210bcd4dd4cSHelge Deller 211b28c4a64SHelge Deller val = cpu_to_le64(HPA_POWER_BUTTON); 212bcd4dd4cSHelge Deller fw_cfg_add_file(fw_cfg, "/etc/hppa/power-button-addr", 213bcd4dd4cSHelge Deller g_memdup(&val, sizeof(val)), sizeof(val)); 214bcd4dd4cSHelge Deller 215e2c41ee5SHelge Deller val = cpu_to_le64(CPU_HPA + 16); 216e2c41ee5SHelge Deller fw_cfg_add_file(fw_cfg, "/etc/hppa/rtc-addr", 217e2c41ee5SHelge Deller g_memdup(&val, sizeof(val)), sizeof(val)); 218e2c41ee5SHelge Deller 219bcd4dd4cSHelge Deller val = cpu_to_le64(CPU_HPA + 24); 220bcd4dd4cSHelge Deller fw_cfg_add_file(fw_cfg, "/etc/hppa/DebugOutputPort", 221b28c4a64SHelge Deller g_memdup(&val, sizeof(val)), sizeof(val)); 222b28c4a64SHelge Deller 22397ec4d21SPaolo Bonzini fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ms->boot_config.order[0]); 22432ff8bf2SHelge Deller qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); 22532ff8bf2SHelge Deller 226069d2966SHelge Deller fw_cfg_add_file(fw_cfg, "/etc/qemu-version", 227069d2966SHelge Deller g_memdup(qemu_version, sizeof(qemu_version)), 228069d2966SHelge Deller sizeof(qemu_version)); 229069d2966SHelge Deller 230bcd4dd4cSHelge Deller fw_cfg_add_extra_pci_roots(pci_bus, fw_cfg); 231bcd4dd4cSHelge Deller 23228b71a2eSHelge Deller return fw_cfg; 23328b71a2eSHelge Deller } 23428b71a2eSHelge Deller 235e881e3c8SMark Cave-Ayland static LasiState *lasi_init(void) 236e881e3c8SMark Cave-Ayland { 237e881e3c8SMark Cave-Ayland DeviceState *dev; 238e881e3c8SMark Cave-Ayland 239e881e3c8SMark Cave-Ayland dev = qdev_new(TYPE_LASI_CHIP); 240e881e3c8SMark Cave-Ayland sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 241e881e3c8SMark Cave-Ayland 242e881e3c8SMark Cave-Ayland return LASI_CHIP(dev); 243e881e3c8SMark Cave-Ayland } 244e881e3c8SMark Cave-Ayland 2450d068996SMark Cave-Ayland static DinoState *dino_init(MemoryRegion *addr_space) 2460d068996SMark Cave-Ayland { 2470d068996SMark Cave-Ayland DeviceState *dev; 2480d068996SMark Cave-Ayland 2490d068996SMark Cave-Ayland dev = qdev_new(TYPE_DINO_PCI_HOST_BRIDGE); 2500d068996SMark Cave-Ayland object_property_set_link(OBJECT(dev), "memory-as", OBJECT(addr_space), 2510d068996SMark Cave-Ayland &error_fatal); 2520d068996SMark Cave-Ayland sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 2530d068996SMark Cave-Ayland 2540d068996SMark Cave-Ayland return DINO_PCI_HOST_BRIDGE(dev); 2550d068996SMark Cave-Ayland } 2560d068996SMark Cave-Ayland 2577df6f751SHelge Deller /* 2587df6f751SHelge Deller * Step 1: Create CPUs and Memory 2597df6f751SHelge Deller */ 2607df6f751SHelge Deller static void machine_HP_common_init_cpus(MachineState *machine) 261813dff13SHelge Deller { 262a72bd606SHelge Deller MemoryRegion *addr_space = get_system_memory(); 263a72bd606SHelge Deller MemoryRegion *cpu_region; 264a72bd606SHelge Deller long i; 26533decbd2SLike Xu unsigned int smp_cpus = machine->smp.cpus; 2667df6f751SHelge Deller char *name; 267a72bd606SHelge Deller 268a72bd606SHelge Deller /* Create CPUs. */ 269a72bd606SHelge Deller for (i = 0; i < smp_cpus; i++) { 2707df6f751SHelge Deller name = g_strdup_printf("cpu%ld-io-eir", i); 271a72bd606SHelge Deller cpu[i] = HPPA_CPU(cpu_create(machine->cpu_type)); 272a72bd606SHelge Deller 273a72bd606SHelge Deller cpu_region = g_new(MemoryRegion, 1); 274a72bd606SHelge Deller memory_region_init_io(cpu_region, OBJECT(cpu[i]), &hppa_io_eir_ops, 275266a880eSPaolo Bonzini cpu[i], name, 4); 276a72bd606SHelge Deller memory_region_add_subregion(addr_space, CPU_HPA + i * 0x1000, 277a72bd606SHelge Deller cpu_region); 278266a880eSPaolo Bonzini g_free(name); 279813dff13SHelge Deller } 280813dff13SHelge Deller 281e2c41ee5SHelge Deller /* RTC and DebugOutputPort on CPU #0 */ 282e2c41ee5SHelge Deller cpu_region = g_new(MemoryRegion, 1); 283e2c41ee5SHelge Deller memory_region_init_io(cpu_region, OBJECT(cpu[0]), &hppa_io_helper_ops, 284e2c41ee5SHelge Deller cpu[0], "cpu0-io-rtc", 2 * sizeof(uint64_t)); 285e2c41ee5SHelge Deller memory_region_add_subregion(addr_space, CPU_HPA + 16, cpu_region); 286e2c41ee5SHelge Deller 287a72bd606SHelge Deller /* Main memory region. */ 288b7746b11SPhilippe Mathieu-Daudé if (machine->ram_size > 3 * GiB) { 289b7746b11SPhilippe Mathieu-Daudé error_report("RAM size is currently restricted to 3GB"); 290b7746b11SPhilippe Mathieu-Daudé exit(EXIT_FAILURE); 291b7746b11SPhilippe Mathieu-Daudé } 2927c59c1e0SIgor Mammedov memory_region_add_subregion_overlap(addr_space, 0, machine->ram, -1); 2937df6f751SHelge Deller } 2947c59c1e0SIgor Mammedov 2957df6f751SHelge Deller /* 2967df6f751SHelge Deller * Last creation step: Add SCSI discs, NICs, graphics & load firmware 2977df6f751SHelge Deller */ 2987df6f751SHelge Deller static void machine_HP_common_init_tail(MachineState *machine, PCIBus *pci_bus) 2997df6f751SHelge Deller { 3007df6f751SHelge Deller const char *kernel_filename = machine->kernel_filename; 3017df6f751SHelge Deller const char *kernel_cmdline = machine->kernel_cmdline; 3027df6f751SHelge Deller const char *initrd_filename = machine->initrd_filename; 3037df6f751SHelge Deller MachineClass *mc = MACHINE_GET_CLASS(machine); 3047df6f751SHelge Deller DeviceState *dev; 305*2ed4faa0SHelge Deller PCIDevice *pci_dev; 3067df6f751SHelge Deller char *firmware_filename; 3077df6f751SHelge Deller uint64_t firmware_low, firmware_high; 3087df6f751SHelge Deller long size; 3097df6f751SHelge Deller uint64_t kernel_entry = 0, kernel_low, kernel_high; 3107df6f751SHelge Deller MemoryRegion *addr_space = get_system_memory(); 3117df6f751SHelge Deller MemoryRegion *rom_region; 3127df6f751SHelge Deller long i; 3137df6f751SHelge Deller unsigned int smp_cpus = machine->smp.cpus; 3147df6f751SHelge Deller SysBusDevice *s; 31528b71a2eSHelge Deller 316a72bd606SHelge Deller /* SCSI disk setup. */ 317877eb21dSMark Cave-Ayland dev = DEVICE(pci_create_simple(pci_bus, -1, "lsi53c895a")); 318877eb21dSMark Cave-Ayland lsi53c8xx_handle_legacy_cmdline(dev); 319a72bd606SHelge Deller 3204765384cSSven Schnelle /* Graphics setup. */ 3214765384cSSven Schnelle if (machine->enable_graphics && vga_interface_type != VGA_NONE) { 322f9bcb2d6SGautam Agrawal vga_interface_created = true; 3233e80f690SMarkus Armbruster dev = qdev_new("artist"); 3244765384cSSven Schnelle s = SYS_BUS_DEVICE(dev); 3253c6ef471SMarkus Armbruster sysbus_realize_and_unref(s, &error_fatal); 3264765384cSSven Schnelle sysbus_mmio_map(s, 0, LASI_GFX_HPA); 3274765384cSSven Schnelle sysbus_mmio_map(s, 1, ARTIST_FB_ADDR); 3284765384cSSven Schnelle } 3294765384cSSven Schnelle 3300e6de551SHelge Deller /* Network setup. */ 331c3c3fe47SMark Cave-Ayland if (enable_lasi_lan()) { 332c3c3fe47SMark Cave-Ayland lasi_82596_init(addr_space, LASI_LAN_HPA, 333c3c3fe47SMark Cave-Ayland qdev_get_gpio_in(lasi_dev, LASI_IRQ_LAN_HPA)); 334c3c3fe47SMark Cave-Ayland } 335c3c3fe47SMark Cave-Ayland 336a72bd606SHelge Deller for (i = 0; i < nb_nics; i++) { 337376b8519SHelge Deller if (!enable_lasi_lan()) { 3389f8981a9SThomas Huth pci_nic_init_nofail(&nd_table[i], pci_bus, mc->default_nic, NULL); 339a72bd606SHelge Deller } 340376b8519SHelge Deller } 341a72bd606SHelge Deller 342*2ed4faa0SHelge Deller /* BMC board: HP Powerbar SP2 Diva (with console only) */ 343*2ed4faa0SHelge Deller pci_dev = pci_new(-1, "pci-serial"); 344*2ed4faa0SHelge Deller if (!lasi_dev) { 345*2ed4faa0SHelge Deller /* bind default keyboard/serial to Diva card */ 346*2ed4faa0SHelge Deller qdev_prop_set_chr(DEVICE(pci_dev), "chardev", serial_hd(0)); 347*2ed4faa0SHelge Deller } 348*2ed4faa0SHelge Deller qdev_prop_set_uint8(DEVICE(pci_dev), "prog_if", 0); 349*2ed4faa0SHelge Deller pci_realize_and_unref(pci_dev, pci_bus, &error_fatal); 350*2ed4faa0SHelge Deller pci_config_set_vendor_id(pci_dev->config, PCI_VENDOR_ID_HP); 351*2ed4faa0SHelge Deller pci_config_set_device_id(pci_dev->config, 0x1048); 352*2ed4faa0SHelge Deller pci_set_word(&pci_dev->config[PCI_SUBSYSTEM_VENDOR_ID], PCI_VENDOR_ID_HP); 353*2ed4faa0SHelge Deller pci_set_word(&pci_dev->config[PCI_SUBSYSTEM_ID], 0x1227); /* Powerbar */ 354*2ed4faa0SHelge Deller 355*2ed4faa0SHelge Deller /* create a second serial PCI card when running Astro */ 356*2ed4faa0SHelge Deller if (!lasi_dev) { 357*2ed4faa0SHelge Deller pci_dev = pci_new(-1, "pci-serial-4x"); 358*2ed4faa0SHelge Deller qdev_prop_set_chr(DEVICE(pci_dev), "chardev1", serial_hd(1)); 359*2ed4faa0SHelge Deller qdev_prop_set_chr(DEVICE(pci_dev), "chardev2", serial_hd(2)); 360*2ed4faa0SHelge Deller qdev_prop_set_chr(DEVICE(pci_dev), "chardev3", serial_hd(3)); 361*2ed4faa0SHelge Deller qdev_prop_set_chr(DEVICE(pci_dev), "chardev4", serial_hd(4)); 362*2ed4faa0SHelge Deller pci_realize_and_unref(pci_dev, pci_bus, &error_fatal); 363*2ed4faa0SHelge Deller } 364*2ed4faa0SHelge Deller 365*2ed4faa0SHelge Deller /* create USB OHCI controller for USB keyboard & mouse on Astro machines */ 366*2ed4faa0SHelge Deller if (!lasi_dev && machine->enable_graphics) { 367*2ed4faa0SHelge Deller pci_create_simple(pci_bus, -1, "pci-ohci"); 368*2ed4faa0SHelge Deller usb_create_simple(usb_bus_find(-1), "usb-kbd"); 369*2ed4faa0SHelge Deller usb_create_simple(usb_bus_find(-1), "usb-mouse"); 370*2ed4faa0SHelge Deller } 371*2ed4faa0SHelge Deller 372b28c4a64SHelge Deller /* register power switch emulation */ 373b28c4a64SHelge Deller qemu_register_powerdown_notifier(&hppa_system_powerdown_notifier); 374b28c4a64SHelge Deller 3757df6f751SHelge Deller /* fw_cfg configuration interface */ 3767df6f751SHelge Deller create_fw_cfg(machine, pci_bus); 3777df6f751SHelge Deller 378a72bd606SHelge Deller /* Load firmware. Given that this is not "real" firmware, 379a72bd606SHelge Deller but one explicitly written for the emulation, we might as 380a72bd606SHelge Deller well load it directly from an ELF image. */ 381a72bd606SHelge Deller firmware_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, 382b57e3e97SPaolo Bonzini machine->firmware ?: "hppa-firmware.img"); 383a72bd606SHelge Deller if (firmware_filename == NULL) { 384a72bd606SHelge Deller error_report("no firmware provided"); 385a72bd606SHelge Deller exit(1); 386a72bd606SHelge Deller } 387a72bd606SHelge Deller 3884366e1dbSLiam Merwick size = load_elf(firmware_filename, NULL, NULL, NULL, 3896cdda0ffSAleksandar Markovic &firmware_entry, &firmware_low, &firmware_high, NULL, 390a72bd606SHelge Deller true, EM_PARISC, 0, 0); 391a72bd606SHelge Deller 392a72bd606SHelge Deller /* Unfortunately, load_elf sign-extends reading elf32. */ 393a72bd606SHelge Deller firmware_entry = (target_ureg)firmware_entry; 394a72bd606SHelge Deller firmware_low = (target_ureg)firmware_low; 395a72bd606SHelge Deller firmware_high = (target_ureg)firmware_high; 396a72bd606SHelge Deller 397a72bd606SHelge Deller if (size < 0) { 398a72bd606SHelge Deller error_report("could not load firmware '%s'", firmware_filename); 399a72bd606SHelge Deller exit(1); 400a72bd606SHelge Deller } 401691cbbadSRichard Henderson qemu_log_mask(CPU_LOG_PAGE, "Firmware loaded at 0x%08" PRIx64 402691cbbadSRichard Henderson "-0x%08" PRIx64 ", entry at 0x%08" PRIx64 ".\n", 403a72bd606SHelge Deller firmware_low, firmware_high, firmware_entry); 4048262863dSPhilippe Mathieu-Daudé if (firmware_low < FIRMWARE_START || firmware_high >= FIRMWARE_END) { 405a72bd606SHelge Deller error_report("Firmware overlaps with memory or IO space"); 406a72bd606SHelge Deller exit(1); 407a72bd606SHelge Deller } 408a72bd606SHelge Deller g_free(firmware_filename); 409a72bd606SHelge Deller 410a72bd606SHelge Deller rom_region = g_new(MemoryRegion, 1); 4116a3a2e82SIgor Mammedov memory_region_init_ram(rom_region, NULL, "firmware", 4126a3a2e82SIgor Mammedov (FIRMWARE_END - FIRMWARE_START), &error_fatal); 413a72bd606SHelge Deller memory_region_add_subregion(addr_space, FIRMWARE_START, rom_region); 414a72bd606SHelge Deller 415a72bd606SHelge Deller /* Load kernel */ 416a72bd606SHelge Deller if (kernel_filename) { 4174366e1dbSLiam Merwick size = load_elf(kernel_filename, NULL, &cpu_hppa_to_phys, 4186cdda0ffSAleksandar Markovic NULL, &kernel_entry, &kernel_low, &kernel_high, NULL, 419a72bd606SHelge Deller true, EM_PARISC, 0, 0); 420a72bd606SHelge Deller 421a72bd606SHelge Deller /* Unfortunately, load_elf sign-extends reading elf32. */ 422a72bd606SHelge Deller kernel_entry = (target_ureg) cpu_hppa_to_phys(NULL, kernel_entry); 423a72bd606SHelge Deller kernel_low = (target_ureg)kernel_low; 424a72bd606SHelge Deller kernel_high = (target_ureg)kernel_high; 425a72bd606SHelge Deller 426a72bd606SHelge Deller if (size < 0) { 427a72bd606SHelge Deller error_report("could not load kernel '%s'", kernel_filename); 428a72bd606SHelge Deller exit(1); 429a72bd606SHelge Deller } 430691cbbadSRichard Henderson qemu_log_mask(CPU_LOG_PAGE, "Kernel loaded at 0x%08" PRIx64 431691cbbadSRichard Henderson "-0x%08" PRIx64 ", entry at 0x%08" PRIx64 432c108cc59SPhilippe Mathieu-Daudé ", size %" PRIu64 " kB\n", 433c108cc59SPhilippe Mathieu-Daudé kernel_low, kernel_high, kernel_entry, size / KiB); 434a72bd606SHelge Deller 435a72bd606SHelge Deller if (kernel_cmdline) { 436a72bd606SHelge Deller cpu[0]->env.gr[24] = 0x4000; 437a72bd606SHelge Deller pstrcpy_targphys("cmdline", cpu[0]->env.gr[24], 438a72bd606SHelge Deller TARGET_PAGE_SIZE, kernel_cmdline); 439a72bd606SHelge Deller } 440a72bd606SHelge Deller 441a72bd606SHelge Deller if (initrd_filename) { 442a72bd606SHelge Deller ram_addr_t initrd_base; 443f3839fdaSLi Zhijian int64_t initrd_size; 444a72bd606SHelge Deller 445a72bd606SHelge Deller initrd_size = get_image_size(initrd_filename); 446a72bd606SHelge Deller if (initrd_size < 0) { 447a72bd606SHelge Deller error_report("could not load initial ram disk '%s'", 448a72bd606SHelge Deller initrd_filename); 449a72bd606SHelge Deller exit(1); 450a72bd606SHelge Deller } 451a72bd606SHelge Deller 452a72bd606SHelge Deller /* Load the initrd image high in memory. 453a72bd606SHelge Deller Mirror the algorithm used by palo: 454a72bd606SHelge Deller (1) Due to sign-extension problems and PDC, 455a72bd606SHelge Deller put the initrd no higher than 1G. 456a72bd606SHelge Deller (2) Reserve 64k for stack. */ 457bfdf22bcSPaolo Bonzini initrd_base = MIN(machine->ram_size, 1 * GiB); 458c108cc59SPhilippe Mathieu-Daudé initrd_base = initrd_base - 64 * KiB; 459a72bd606SHelge Deller initrd_base = (initrd_base - initrd_size) & TARGET_PAGE_MASK; 460a72bd606SHelge Deller 461a72bd606SHelge Deller if (initrd_base < kernel_high) { 462a72bd606SHelge Deller error_report("kernel and initial ram disk too large!"); 463a72bd606SHelge Deller exit(1); 464a72bd606SHelge Deller } 465a72bd606SHelge Deller 466a72bd606SHelge Deller load_image_targphys(initrd_filename, initrd_base, initrd_size); 467a72bd606SHelge Deller cpu[0]->env.gr[23] = initrd_base; 468a72bd606SHelge Deller cpu[0]->env.gr[22] = initrd_base + initrd_size; 469a72bd606SHelge Deller } 470a72bd606SHelge Deller } 471a72bd606SHelge Deller 472a72bd606SHelge Deller if (!kernel_entry) { 473a72bd606SHelge Deller /* When booting via firmware, tell firmware if we want interactive 474a72bd606SHelge Deller * mode (kernel_entry=1), and to boot from CD (gr[24]='d') 475a72bd606SHelge Deller * or hard disc * (gr[24]='c'). 476a72bd606SHelge Deller */ 47797ec4d21SPaolo Bonzini kernel_entry = machine->boot_config.has_menu ? machine->boot_config.menu : 0; 47897ec4d21SPaolo Bonzini cpu[0]->env.gr[24] = machine->boot_config.order[0]; 479a72bd606SHelge Deller } 480a72bd606SHelge Deller 481a72bd606SHelge Deller /* We jump to the firmware entry routine and pass the 482a72bd606SHelge Deller * various parameters in registers. After firmware initialization, 483a72bd606SHelge Deller * firmware will start the Linux kernel with ramdisk and cmdline. 484a72bd606SHelge Deller */ 485bfdf22bcSPaolo Bonzini cpu[0]->env.gr[26] = machine->ram_size; 486a72bd606SHelge Deller cpu[0]->env.gr[25] = kernel_entry; 487a72bd606SHelge Deller 488a72bd606SHelge Deller /* tell firmware how many SMP CPUs to present in inventory table */ 489a72bd606SHelge Deller cpu[0]->env.gr[21] = smp_cpus; 49024576007SHelge Deller 49124576007SHelge Deller /* tell firmware fw_cfg port */ 49224576007SHelge Deller cpu[0]->env.gr[19] = FW_CFG_IO_BASE; 493a72bd606SHelge Deller } 494a72bd606SHelge Deller 4957df6f751SHelge Deller /* 4967df6f751SHelge Deller * Create HP B160L workstation 4977df6f751SHelge Deller */ 4987df6f751SHelge Deller static void machine_HP_B160L_init(MachineState *machine) 4997df6f751SHelge Deller { 5007df6f751SHelge Deller DeviceState *dev, *dino_dev; 5017df6f751SHelge Deller MemoryRegion *addr_space = get_system_memory(); 5027df6f751SHelge Deller ISABus *isa_bus; 5037df6f751SHelge Deller PCIBus *pci_bus; 5047df6f751SHelge Deller 5057df6f751SHelge Deller /* Create CPUs and RAM. */ 5067df6f751SHelge Deller machine_HP_common_init_cpus(machine); 5077df6f751SHelge Deller 5087df6f751SHelge Deller /* Init Lasi chip */ 5097df6f751SHelge Deller lasi_dev = DEVICE(lasi_init()); 5107df6f751SHelge Deller memory_region_add_subregion(addr_space, LASI_HPA, 5117df6f751SHelge Deller sysbus_mmio_get_region( 5127df6f751SHelge Deller SYS_BUS_DEVICE(lasi_dev), 0)); 5137df6f751SHelge Deller 5147df6f751SHelge Deller /* Init Dino (PCI host bus chip). */ 5157df6f751SHelge Deller dino_dev = DEVICE(dino_init(addr_space)); 5167df6f751SHelge Deller memory_region_add_subregion(addr_space, DINO_HPA, 5177df6f751SHelge Deller sysbus_mmio_get_region( 5187df6f751SHelge Deller SYS_BUS_DEVICE(dino_dev), 0)); 5197df6f751SHelge Deller pci_bus = PCI_BUS(qdev_get_child_bus(dino_dev, "pci")); 5207df6f751SHelge Deller assert(pci_bus); 5217df6f751SHelge Deller 5227df6f751SHelge Deller /* Create ISA bus, needed for PS/2 kbd/mouse port emulation */ 5237df6f751SHelge Deller isa_bus = hppa_isa_bus(); 5247df6f751SHelge Deller assert(isa_bus); 5257df6f751SHelge Deller 5267df6f751SHelge Deller /* Serial ports: Lasi and Dino use a 7.272727 MHz clock. */ 5277df6f751SHelge Deller serial_mm_init(addr_space, LASI_UART_HPA + 0x800, 0, 5287df6f751SHelge Deller qdev_get_gpio_in(lasi_dev, LASI_IRQ_UART_HPA), 7272727 / 16, 5297df6f751SHelge Deller serial_hd(0), DEVICE_BIG_ENDIAN); 5307df6f751SHelge Deller 5317df6f751SHelge Deller serial_mm_init(addr_space, DINO_UART_HPA + 0x800, 0, 5327df6f751SHelge Deller qdev_get_gpio_in(dino_dev, DINO_IRQ_RS232INT), 7272727 / 16, 5337df6f751SHelge Deller serial_hd(1), DEVICE_BIG_ENDIAN); 5347df6f751SHelge Deller 5357df6f751SHelge Deller /* Parallel port */ 5367df6f751SHelge Deller parallel_mm_init(addr_space, LASI_LPT_HPA + 0x800, 0, 5377df6f751SHelge Deller qdev_get_gpio_in(lasi_dev, LASI_IRQ_LAN_HPA), 5387df6f751SHelge Deller parallel_hds[0]); 5397df6f751SHelge Deller 5407df6f751SHelge Deller /* PS/2 Keyboard/Mouse */ 5417df6f751SHelge Deller dev = qdev_new(TYPE_LASIPS2); 5427df6f751SHelge Deller sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 5437df6f751SHelge Deller sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, 5447df6f751SHelge Deller qdev_get_gpio_in(lasi_dev, LASI_IRQ_PS2KBD_HPA)); 5457df6f751SHelge Deller memory_region_add_subregion(addr_space, LASI_PS2KBD_HPA, 5467df6f751SHelge Deller sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 5477df6f751SHelge Deller 0)); 5487df6f751SHelge Deller memory_region_add_subregion(addr_space, LASI_PS2KBD_HPA + 0x100, 5497df6f751SHelge Deller sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 5507df6f751SHelge Deller 1)); 5517df6f751SHelge Deller 5527df6f751SHelge Deller /* Add SCSI discs, NICs, graphics & load firmware */ 5537df6f751SHelge Deller machine_HP_common_init_tail(machine, pci_bus); 5547df6f751SHelge Deller } 5557df6f751SHelge Deller 556*2ed4faa0SHelge Deller static AstroState *astro_init(void) 557*2ed4faa0SHelge Deller { 558*2ed4faa0SHelge Deller DeviceState *dev; 559*2ed4faa0SHelge Deller 560*2ed4faa0SHelge Deller dev = qdev_new(TYPE_ASTRO_CHIP); 561*2ed4faa0SHelge Deller sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 562*2ed4faa0SHelge Deller 563*2ed4faa0SHelge Deller return ASTRO_CHIP(dev); 564*2ed4faa0SHelge Deller } 565*2ed4faa0SHelge Deller 566*2ed4faa0SHelge Deller /* 567*2ed4faa0SHelge Deller * Create HP C3700 workstation 568*2ed4faa0SHelge Deller */ 569*2ed4faa0SHelge Deller static void machine_HP_C3700_init(MachineState *machine) 570*2ed4faa0SHelge Deller { 571*2ed4faa0SHelge Deller PCIBus *pci_bus; 572*2ed4faa0SHelge Deller AstroState *astro; 573*2ed4faa0SHelge Deller DeviceState *astro_dev; 574*2ed4faa0SHelge Deller MemoryRegion *addr_space = get_system_memory(); 575*2ed4faa0SHelge Deller 576*2ed4faa0SHelge Deller /* Create CPUs and RAM. */ 577*2ed4faa0SHelge Deller machine_HP_common_init_cpus(machine); 578*2ed4faa0SHelge Deller 579*2ed4faa0SHelge Deller /* Init Astro and the Elroys (PCI host bus chips). */ 580*2ed4faa0SHelge Deller astro = astro_init(); 581*2ed4faa0SHelge Deller astro_dev = DEVICE(astro); 582*2ed4faa0SHelge Deller memory_region_add_subregion(addr_space, ASTRO_HPA, 583*2ed4faa0SHelge Deller sysbus_mmio_get_region( 584*2ed4faa0SHelge Deller SYS_BUS_DEVICE(astro_dev), 0)); 585*2ed4faa0SHelge Deller pci_bus = PCI_BUS(qdev_get_child_bus(DEVICE(astro->elroy[0]), "pci")); 586*2ed4faa0SHelge Deller assert(pci_bus); 587*2ed4faa0SHelge Deller 588*2ed4faa0SHelge Deller /* Add SCSI discs, NICs, graphics & load firmware */ 589*2ed4faa0SHelge Deller machine_HP_common_init_tail(machine, pci_bus); 590*2ed4faa0SHelge Deller } 591*2ed4faa0SHelge Deller 5927966d70fSJason A. Donenfeld static void hppa_machine_reset(MachineState *ms, ShutdownCause reason) 593a72bd606SHelge Deller { 59433decbd2SLike Xu unsigned int smp_cpus = ms->smp.cpus; 595a72bd606SHelge Deller int i; 596a72bd606SHelge Deller 5977966d70fSJason A. Donenfeld qemu_devices_reset(reason); 598a72bd606SHelge Deller 599a72bd606SHelge Deller /* Start all CPUs at the firmware entry point. 600a72bd606SHelge Deller * Monarch CPU will initialize firmware, secondary CPUs 60150ba97e9SHelge Deller * will enter a small idle loop and wait for rendevouz. */ 602a72bd606SHelge Deller for (i = 0; i < smp_cpus; i++) { 60350ba97e9SHelge Deller CPUState *cs = CPU(cpu[i]); 60450ba97e9SHelge Deller 60550ba97e9SHelge Deller cpu_set_pc(cs, firmware_entry); 60650ba97e9SHelge Deller cpu[i]->env.psw = PSW_Q; 607a72bd606SHelge Deller cpu[i]->env.gr[5] = CPU_HPA + i * 0x1000; 60850ba97e9SHelge Deller 60950ba97e9SHelge Deller cs->exception_index = -1; 61050ba97e9SHelge Deller cs->halted = 0; 6116d1ef68cSHelge Deller 6126d1ef68cSHelge Deller /* clear any existing TLB and BTLB entries */ 6136d1ef68cSHelge Deller memset(cpu[i]->env.tlb, 0, sizeof(cpu[i]->env.tlb)); 6146d1ef68cSHelge Deller cpu[i]->env.tlb_last = HPPA_BTLB_ENTRIES; 615a72bd606SHelge Deller } 616a72bd606SHelge Deller 617a72bd606SHelge Deller /* already initialized by machine_hppa_init()? */ 618bfdf22bcSPaolo Bonzini if (cpu[0]->env.gr[26] == ms->ram_size) { 619a72bd606SHelge Deller return; 620a72bd606SHelge Deller } 621a72bd606SHelge Deller 622bfdf22bcSPaolo Bonzini cpu[0]->env.gr[26] = ms->ram_size; 623a72bd606SHelge Deller cpu[0]->env.gr[25] = 0; /* no firmware boot menu */ 624a72bd606SHelge Deller cpu[0]->env.gr[24] = 'c'; 625a72bd606SHelge Deller /* gr22/gr23 unused, no initrd while reboot. */ 626a72bd606SHelge Deller cpu[0]->env.gr[21] = smp_cpus; 62724576007SHelge Deller /* tell firmware fw_cfg port */ 62824576007SHelge Deller cpu[0]->env.gr[19] = FW_CFG_IO_BASE; 629a72bd606SHelge Deller } 630a72bd606SHelge Deller 6314a4554c6SHelge Deller static void hppa_nmi(NMIState *n, int cpu_index, Error **errp) 6324a4554c6SHelge Deller { 6334a4554c6SHelge Deller CPUState *cs; 6344a4554c6SHelge Deller 6354a4554c6SHelge Deller CPU_FOREACH(cs) { 6364a4554c6SHelge Deller cpu_interrupt(cs, CPU_INTERRUPT_NMI); 6374a4554c6SHelge Deller } 6384a4554c6SHelge Deller } 639a72bd606SHelge Deller 6407df6f751SHelge Deller static void HP_B160L_machine_init_class_init(ObjectClass *oc, void *data) 641813dff13SHelge Deller { 64242cc2bf6SMark Cave-Ayland MachineClass *mc = MACHINE_CLASS(oc); 64342cc2bf6SMark Cave-Ayland NMIClass *nc = NMI_CLASS(oc); 64442cc2bf6SMark Cave-Ayland 6457df6f751SHelge Deller mc->desc = "HP B160L workstation"; 646a72bd606SHelge Deller mc->default_cpu_type = TYPE_HPPA_CPU; 6477df6f751SHelge Deller mc->init = machine_HP_B160L_init; 648a72bd606SHelge Deller mc->reset = hppa_machine_reset; 649813dff13SHelge Deller mc->block_default_type = IF_SCSI; 650a72bd606SHelge Deller mc->max_cpus = HPPA_MAX_CPUS; 651a72bd606SHelge Deller mc->default_cpus = 1; 652ea0ac7f6SPhilippe Mathieu-Daudé mc->is_default = true; 653d23b6caaSPhilippe Mathieu-Daudé mc->default_ram_size = 512 * MiB; 654813dff13SHelge Deller mc->default_boot_order = "cd"; 6557c59c1e0SIgor Mammedov mc->default_ram_id = "ram"; 6569f8981a9SThomas Huth mc->default_nic = "tulip"; 657813dff13SHelge Deller 6584a4554c6SHelge Deller nc->nmi_monitor_handler = hppa_nmi; 6594a4554c6SHelge Deller } 6604a4554c6SHelge Deller 6617df6f751SHelge Deller static const TypeInfo HP_B160L_machine_init_typeinfo = { 6627df6f751SHelge Deller .name = MACHINE_TYPE_NAME("B160L"), 663c165905cSMark Cave-Ayland .parent = TYPE_MACHINE, 6647df6f751SHelge Deller .class_init = HP_B160L_machine_init_class_init, 6654a4554c6SHelge Deller .interfaces = (InterfaceInfo[]) { 6664a4554c6SHelge Deller { TYPE_NMI }, 6674a4554c6SHelge Deller { } 6684a4554c6SHelge Deller }, 6694a4554c6SHelge Deller }; 6704a4554c6SHelge Deller 671*2ed4faa0SHelge Deller static void HP_C3700_machine_init_class_init(ObjectClass *oc, void *data) 672*2ed4faa0SHelge Deller { 673*2ed4faa0SHelge Deller MachineClass *mc = MACHINE_CLASS(oc); 674*2ed4faa0SHelge Deller NMIClass *nc = NMI_CLASS(oc); 675*2ed4faa0SHelge Deller 676*2ed4faa0SHelge Deller mc->desc = "HP C3700 workstation"; 677*2ed4faa0SHelge Deller mc->default_cpu_type = TYPE_HPPA_CPU; 678*2ed4faa0SHelge Deller mc->init = machine_HP_C3700_init; 679*2ed4faa0SHelge Deller mc->reset = hppa_machine_reset; 680*2ed4faa0SHelge Deller mc->block_default_type = IF_SCSI; 681*2ed4faa0SHelge Deller mc->max_cpus = HPPA_MAX_CPUS; 682*2ed4faa0SHelge Deller mc->default_cpus = 1; 683*2ed4faa0SHelge Deller mc->is_default = false; 684*2ed4faa0SHelge Deller mc->default_ram_size = 1024 * MiB; 685*2ed4faa0SHelge Deller mc->default_boot_order = "cd"; 686*2ed4faa0SHelge Deller mc->default_ram_id = "ram"; 687*2ed4faa0SHelge Deller mc->default_nic = "tulip"; 688*2ed4faa0SHelge Deller 689*2ed4faa0SHelge Deller nc->nmi_monitor_handler = hppa_nmi; 690*2ed4faa0SHelge Deller } 691*2ed4faa0SHelge Deller 692*2ed4faa0SHelge Deller static const TypeInfo HP_C3700_machine_init_typeinfo = { 693*2ed4faa0SHelge Deller .name = MACHINE_TYPE_NAME("C3700"), 694*2ed4faa0SHelge Deller .parent = TYPE_MACHINE, 695*2ed4faa0SHelge Deller .class_init = HP_C3700_machine_init_class_init, 696*2ed4faa0SHelge Deller .interfaces = (InterfaceInfo[]) { 697*2ed4faa0SHelge Deller { TYPE_NMI }, 698*2ed4faa0SHelge Deller { } 699*2ed4faa0SHelge Deller }, 700*2ed4faa0SHelge Deller }; 701*2ed4faa0SHelge Deller 702297d4103SMark Cave-Ayland static void hppa_machine_init_register_types(void) 7034a4554c6SHelge Deller { 7047df6f751SHelge Deller type_register_static(&HP_B160L_machine_init_typeinfo); 705*2ed4faa0SHelge Deller type_register_static(&HP_C3700_machine_init_typeinfo); 7064a4554c6SHelge Deller } 7074a4554c6SHelge Deller 708297d4103SMark Cave-Ayland type_init(hppa_machine_init_register_types) 709