xref: /qemu/hw/hppa/machine.c (revision 2ed4faa03fa92e3ab9160c09f3eb866fbdd60ecc)
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