xref: /openbmc/qemu/hw/hppa/machine.c (revision d0ad4118abb1434d6788d9ac5a1612103f88d360)
1 /*
2  * QEMU HPPA hardware system emulator.
3  * (C) Copyright 2018-2023 Helge Deller <deller@gmx.de>
4  *
5  * This work is licensed under the GNU GPL license version 2 or later.
6  */
7 
8 #include "qemu/osdep.h"
9 #include "qemu/datadir.h"
10 #include "cpu.h"
11 #include "elf.h"
12 #include "hw/loader.h"
13 #include "qemu/error-report.h"
14 #include "system/reset.h"
15 #include "system/system.h"
16 #include "system/qtest.h"
17 #include "system/runstate.h"
18 #include "hw/rtc/mc146818rtc.h"
19 #include "hw/timer/i8254.h"
20 #include "hw/char/serial-mm.h"
21 #include "hw/char/parallel.h"
22 #include "hw/intc/i8259.h"
23 #include "hw/input/lasips2.h"
24 #include "hw/net/lasi_82596.h"
25 #include "hw/nmi.h"
26 #include "hw/usb.h"
27 #include "hw/pci/pci.h"
28 #include "hw/pci/pci_device.h"
29 #include "hw/pci-host/astro.h"
30 #include "hw/pci-host/dino.h"
31 #include "hw/misc/lasi.h"
32 #include "hppa_hardware.h"
33 #include "qemu/units.h"
34 #include "qapi/error.h"
35 #include "net/net.h"
36 #include "qemu/log.h"
37 
38 #define MIN_SEABIOS_HPPA_VERSION 12 /* require at least this fw version */
39 
40 #define HPA_POWER_BUTTON        (FIRMWARE_END - 0x10)
41 static hwaddr soft_power_reg;
42 
43 #define enable_lasi_lan()       0
44 
45 static DeviceState *lasi_dev;
46 
47 static void hppa_powerdown_req(Notifier *n, void *opaque)
48 {
49     uint32_t val;
50 
51     val = ldl_be_phys(&address_space_memory, soft_power_reg);
52     if ((val >> 8) == 0) {
53         /* immediately shut down when under hardware control */
54         qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
55         return;
56     }
57 
58     /* clear bit 31 to indicate that the power switch was pressed. */
59     val &= ~1;
60     stl_be_phys(&address_space_memory, soft_power_reg, val);
61 }
62 
63 static Notifier hppa_system_powerdown_notifier = {
64     .notify = hppa_powerdown_req
65 };
66 
67 /* Fallback for unassigned PCI I/O operations.  Avoids MCHK.  */
68 static uint64_t ignore_read(void *opaque, hwaddr addr, unsigned size)
69 {
70     return 0;
71 }
72 
73 static void ignore_write(void *opaque, hwaddr addr, uint64_t v, unsigned size)
74 {
75 }
76 
77 static const MemoryRegionOps hppa_pci_ignore_ops = {
78     .read = ignore_read,
79     .write = ignore_write,
80     .endianness = DEVICE_BIG_ENDIAN,
81     .valid = {
82         .min_access_size = 1,
83         .max_access_size = 8,
84     },
85     .impl = {
86         .min_access_size = 1,
87         .max_access_size = 8,
88     },
89 };
90 
91 static ISABus *hppa_isa_bus(hwaddr addr)
92 {
93     ISABus *isa_bus;
94     qemu_irq *isa_irqs;
95     MemoryRegion *isa_region;
96 
97     isa_region = g_new(MemoryRegion, 1);
98     memory_region_init_io(isa_region, NULL, &hppa_pci_ignore_ops,
99                           NULL, "isa-io", 0x800);
100     memory_region_add_subregion(get_system_memory(), addr, isa_region);
101 
102     isa_bus = isa_bus_new(NULL, get_system_memory(), isa_region,
103                           &error_abort);
104     isa_irqs = i8259_init(isa_bus, NULL);
105     isa_bus_register_input_irqs(isa_bus, isa_irqs);
106 
107     return isa_bus;
108 }
109 
110 /*
111  * Helper functions to emulate RTC clock and DebugOutputPort
112  */
113 static time_t rtc_ref;
114 
115 static uint64_t io_cpu_read(void *opaque, hwaddr addr, unsigned size)
116 {
117     uint64_t val = 0;
118 
119     switch (addr) {
120     case 0:             /* RTC clock */
121         val = time(NULL);
122         val += rtc_ref;
123         break;
124     case 8:             /* DebugOutputPort */
125         return 0xe9;    /* readback */
126     }
127     return val;
128 }
129 
130 static void io_cpu_write(void *opaque, hwaddr addr,
131                          uint64_t val, unsigned size)
132 {
133     unsigned char ch;
134     Chardev *debugout;
135 
136     switch (addr) {
137     case 0:             /* RTC clock */
138         rtc_ref = val - time(NULL);
139         break;
140     case 8:             /* DebugOutputPort */
141         ch = val;
142         debugout = serial_hd(0);
143         if (debugout) {
144             qemu_chr_fe_write_all(debugout->be, &ch, 1);
145         } else {
146             fprintf(stderr, "%c", ch);
147         }
148         break;
149     }
150 }
151 
152 static const MemoryRegionOps hppa_io_helper_ops = {
153     .read = io_cpu_read,
154     .write = io_cpu_write,
155     .endianness = DEVICE_BIG_ENDIAN,
156     .valid = {
157         .min_access_size = 1,
158         .max_access_size = 8,
159     },
160     .impl = {
161         .min_access_size = 1,
162         .max_access_size = 8,
163     },
164 };
165 
166 typedef uint64_t TranslateFn(void *opaque, uint64_t addr);
167 
168 static uint64_t linux_kernel_virt_to_phys(void *opaque, uint64_t addr)
169 {
170     addr &= (0x10000000 - 1);
171     return addr;
172 }
173 
174 static uint64_t translate_pa10(void *dummy, uint64_t addr)
175 {
176     return (uint32_t)addr;
177 }
178 
179 static uint64_t translate_pa20(void *dummy, uint64_t addr)
180 {
181     return hppa_abs_to_phys_pa2_w0(addr);
182 }
183 
184 static HPPACPU *cpu[HPPA_MAX_CPUS];
185 static uint64_t firmware_entry;
186 
187 static void fw_cfg_boot_set(void *opaque, const char *boot_device,
188                             Error **errp)
189 {
190     fw_cfg_modify_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]);
191 }
192 
193 static FWCfgState *create_fw_cfg(MachineState *ms, PCIBus *pci_bus,
194                                  hwaddr addr)
195 {
196     FWCfgState *fw_cfg;
197     uint64_t val;
198     const char qemu_version[] = QEMU_VERSION;
199     MachineClass *mc = MACHINE_GET_CLASS(ms);
200     int btlb_entries = HPPA_BTLB_ENTRIES(&cpu[0]->env);
201     int len;
202 
203     fw_cfg = fw_cfg_init_mem(addr, addr + 4);
204     fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, ms->smp.cpus);
205     fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, HPPA_MAX_CPUS);
206     fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, ms->ram_size);
207 
208     val = cpu_to_le64(MIN_SEABIOS_HPPA_VERSION);
209     fw_cfg_add_file(fw_cfg, "/etc/firmware-min-version",
210                     g_memdup2(&val, sizeof(val)), sizeof(val));
211 
212     val = cpu_to_le64(HPPA_TLB_ENTRIES - btlb_entries);
213     fw_cfg_add_file(fw_cfg, "/etc/cpu/tlb_entries",
214                     g_memdup2(&val, sizeof(val)), sizeof(val));
215 
216     val = cpu_to_le64(btlb_entries);
217     fw_cfg_add_file(fw_cfg, "/etc/cpu/btlb_entries",
218                     g_memdup2(&val, sizeof(val)), sizeof(val));
219 
220     len = strlen(mc->name) + 1;
221     fw_cfg_add_file(fw_cfg, "/etc/hppa/machine",
222                     g_memdup2(mc->name, len), len);
223 
224     val = cpu_to_le64(soft_power_reg);
225     fw_cfg_add_file(fw_cfg, "/etc/hppa/power-button-addr",
226                     g_memdup2(&val, sizeof(val)), sizeof(val));
227 
228     val = cpu_to_le64(CPU_HPA + 16);
229     fw_cfg_add_file(fw_cfg, "/etc/hppa/rtc-addr",
230                     g_memdup2(&val, sizeof(val)), sizeof(val));
231 
232     val = cpu_to_le64(CPU_HPA + 24);
233     fw_cfg_add_file(fw_cfg, "/etc/hppa/DebugOutputPort",
234                     g_memdup2(&val, sizeof(val)), sizeof(val));
235 
236     fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ms->boot_config.order[0]);
237     qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
238 
239     fw_cfg_add_file(fw_cfg, "/etc/qemu-version",
240                     g_memdup2(qemu_version, sizeof(qemu_version)),
241                     sizeof(qemu_version));
242 
243     pci_bus_add_fw_cfg_extra_pci_roots(fw_cfg, pci_bus, &error_abort);
244 
245     return fw_cfg;
246 }
247 
248 static LasiState *lasi_init(void)
249 {
250     DeviceState *dev;
251 
252     dev = qdev_new(TYPE_LASI_CHIP);
253     sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
254 
255     return LASI_CHIP(dev);
256 }
257 
258 static DinoState *dino_init(MemoryRegion *addr_space)
259 {
260     DeviceState *dev;
261 
262     dev = qdev_new(TYPE_DINO_PCI_HOST_BRIDGE);
263     object_property_set_link(OBJECT(dev), "memory-as", OBJECT(addr_space),
264                              &error_fatal);
265     sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
266 
267     return DINO_PCI_HOST_BRIDGE(dev);
268 }
269 
270 /*
271  * Step 1: Create CPUs and Memory
272  */
273 static TranslateFn *machine_HP_common_init_cpus(MachineState *machine)
274 {
275     MemoryRegion *addr_space = get_system_memory();
276     unsigned int smp_cpus = machine->smp.cpus;
277     TranslateFn *translate;
278     MemoryRegion *cpu_region;
279     uint64_t ram_max;
280 
281     /* Create CPUs.  */
282     for (unsigned int i = 0; i < smp_cpus; i++) {
283         cpu[i] = HPPA_CPU(cpu_create(machine->cpu_type));
284     }
285 
286     /* Initialize memory */
287     if (hppa_is_pa20(&cpu[0]->env)) {
288         translate = translate_pa20;
289         ram_max = 256 * GiB;       /* like HP rp8440 */
290     } else {
291         translate = translate_pa10;
292         ram_max = FIRMWARE_START;  /* 3.75 GB (32-bit CPU) */
293     }
294 
295     soft_power_reg = translate(NULL, HPA_POWER_BUTTON);
296 
297     for (unsigned int i = 0; i < smp_cpus; i++) {
298         g_autofree char *name = g_strdup_printf("cpu%u-io-eir", i);
299 
300         cpu_region = g_new(MemoryRegion, 1);
301         memory_region_init_io(cpu_region, OBJECT(cpu[i]), &hppa_io_eir_ops,
302                               cpu[i], name, 4);
303         memory_region_add_subregion(addr_space,
304                                     translate(NULL, CPU_HPA + i * 0x1000),
305                                     cpu_region);
306     }
307 
308     /* RTC and DebugOutputPort on CPU #0 */
309     cpu_region = g_new(MemoryRegion, 1);
310     memory_region_init_io(cpu_region, OBJECT(cpu[0]), &hppa_io_helper_ops,
311                           cpu[0], "cpu0-io-rtc", 2 * sizeof(uint64_t));
312     memory_region_add_subregion(addr_space, translate(NULL, CPU_HPA + 16),
313                                 cpu_region);
314 
315     /* Main memory region. */
316     if (machine->ram_size > ram_max) {
317         info_report("Max RAM size limited to %" PRIu64 " MB", ram_max / MiB);
318         machine->ram_size = ram_max;
319     }
320     if (machine->ram_size <= FIRMWARE_START) {
321         /* contiguous memory up to 3.75 GB RAM */
322         memory_region_add_subregion_overlap(addr_space, 0, machine->ram, -1);
323     } else {
324         /* non-contiguous: Memory above 3.75 GB is mapped at RAM_MAP_HIGH */
325         MemoryRegion *mem_region;
326         mem_region = g_new(MemoryRegion, 2);
327         memory_region_init_alias(&mem_region[0], &addr_space->parent_obj,
328                               "LowMem", machine->ram, 0, FIRMWARE_START);
329         memory_region_init_alias(&mem_region[1], &addr_space->parent_obj,
330                               "HighMem", machine->ram, FIRMWARE_START,
331                               machine->ram_size - FIRMWARE_START);
332         memory_region_add_subregion_overlap(addr_space, 0, &mem_region[0], -1);
333         memory_region_add_subregion_overlap(addr_space, RAM_MAP_HIGH,
334                                             &mem_region[1], -1);
335     }
336 
337     return translate;
338 }
339 
340 /*
341  * Last creation step: Add SCSI discs, NICs, graphics & load firmware
342  */
343 static void machine_HP_common_init_tail(MachineState *machine, PCIBus *pci_bus,
344                                         TranslateFn *translate)
345 {
346     const char *kernel_filename = machine->kernel_filename;
347     const char *kernel_cmdline = machine->kernel_cmdline;
348     const char *initrd_filename = machine->initrd_filename;
349     const char *firmware = machine->firmware;
350     MachineClass *mc = MACHINE_GET_CLASS(machine);
351     DeviceState *dev;
352     PCIDevice *pci_dev;
353     char *firmware_filename;
354     uint64_t firmware_low, firmware_high;
355     long size;
356     uint64_t kernel_entry = 0, kernel_low, kernel_high;
357     MemoryRegion *addr_space = get_system_memory();
358     MemoryRegion *rom_region;
359     unsigned int smp_cpus = machine->smp.cpus;
360     SysBusDevice *s;
361 
362     /* SCSI disk setup. */
363     if (drive_get_max_bus(IF_SCSI) >= 0) {
364         dev = DEVICE(pci_create_simple(pci_bus, -1, "lsi53c895a"));
365         lsi53c8xx_handle_legacy_cmdline(dev);
366     }
367 
368     /* Graphics setup. */
369     if (machine->enable_graphics && vga_interface_type != VGA_NONE) {
370         vga_interface_created = true;
371         dev = qdev_new("artist");
372         s = SYS_BUS_DEVICE(dev);
373         sysbus_realize_and_unref(s, &error_fatal);
374         sysbus_mmio_map(s, 0, translate(NULL, LASI_GFX_HPA));
375         sysbus_mmio_map(s, 1, translate(NULL, ARTIST_FB_ADDR));
376     }
377 
378     /* Network setup. */
379     if (lasi_dev) {
380         lasi_82596_init(addr_space, translate(NULL, LASI_LAN_HPA),
381                         qdev_get_gpio_in(lasi_dev, LASI_IRQ_LAN_HPA),
382                         enable_lasi_lan());
383     }
384 
385     pci_init_nic_devices(pci_bus, mc->default_nic);
386 
387     /* BMC board: HP Powerbar SP2 Diva (with console only) */
388     pci_dev = pci_new(-1, "pci-serial");
389     if (!lasi_dev) {
390         /* bind default keyboard/serial to Diva card */
391         qdev_prop_set_chr(DEVICE(pci_dev), "chardev", serial_hd(0));
392     }
393     qdev_prop_set_uint8(DEVICE(pci_dev), "prog_if", 0);
394     pci_realize_and_unref(pci_dev, pci_bus, &error_fatal);
395     pci_config_set_vendor_id(pci_dev->config, PCI_VENDOR_ID_HP);
396     pci_config_set_device_id(pci_dev->config, 0x1048);
397     pci_set_word(&pci_dev->config[PCI_SUBSYSTEM_VENDOR_ID], PCI_VENDOR_ID_HP);
398     pci_set_word(&pci_dev->config[PCI_SUBSYSTEM_ID], 0x1227); /* Powerbar */
399 
400     /* create a second serial PCI card when running Astro */
401     if (serial_hd(1) && !lasi_dev) {
402         pci_dev = pci_new(-1, "pci-serial-4x");
403         qdev_prop_set_chr(DEVICE(pci_dev), "chardev1", serial_hd(1));
404         qdev_prop_set_chr(DEVICE(pci_dev), "chardev2", serial_hd(2));
405         qdev_prop_set_chr(DEVICE(pci_dev), "chardev3", serial_hd(3));
406         qdev_prop_set_chr(DEVICE(pci_dev), "chardev4", serial_hd(4));
407         pci_realize_and_unref(pci_dev, pci_bus, &error_fatal);
408     }
409 
410     /* create USB OHCI controller for USB keyboard & mouse on Astro machines */
411     if (!lasi_dev && machine->enable_graphics && defaults_enabled()) {
412         USBBus *usb_bus;
413 
414         pci_create_simple(pci_bus, -1, "pci-ohci");
415         usb_bus = USB_BUS(object_resolve_type_unambiguous(TYPE_USB_BUS,
416                                                           &error_abort));
417         usb_create_simple(usb_bus, "usb-kbd");
418         usb_create_simple(usb_bus, "usb-mouse");
419     }
420 
421     /* register power switch emulation */
422     qemu_register_powerdown_notifier(&hppa_system_powerdown_notifier);
423 
424     /* fw_cfg configuration interface */
425     create_fw_cfg(machine, pci_bus, translate(NULL, FW_CFG_IO_BASE));
426 
427     /* Load firmware.  Given that this is not "real" firmware,
428        but one explicitly written for the emulation, we might as
429        well load it directly from an ELF image. Load the 64-bit
430        firmware on 64-bit machines by default if not specified
431        on command line. */
432     if (!qtest_enabled()) {
433         if (!firmware) {
434             firmware = lasi_dev ? "hppa-firmware.img" : "hppa-firmware64.img";
435         }
436         firmware_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, firmware);
437         if (firmware_filename == NULL) {
438             error_report("no firmware provided");
439             exit(1);
440         }
441 
442         size = load_elf(firmware_filename, NULL, translate, NULL,
443                         &firmware_entry, &firmware_low, &firmware_high, NULL,
444                         true, EM_PARISC, 0, 0);
445 
446         if (size < 0) {
447             error_report("could not load firmware '%s'", firmware_filename);
448             exit(1);
449         }
450         qemu_log_mask(CPU_LOG_PAGE, "Firmware loaded at 0x%08" PRIx64
451                       "-0x%08" PRIx64 ", entry at 0x%08" PRIx64 ".\n",
452                       firmware_low, firmware_high, firmware_entry);
453         if (firmware_low < translate(NULL, FIRMWARE_START) ||
454             firmware_high >= translate(NULL, FIRMWARE_END)) {
455             error_report("Firmware overlaps with memory or IO space");
456             exit(1);
457         }
458         g_free(firmware_filename);
459     }
460 
461     rom_region = g_new(MemoryRegion, 1);
462     memory_region_init_ram(rom_region, NULL, "firmware",
463                            (FIRMWARE_END - FIRMWARE_START), &error_fatal);
464     memory_region_add_subregion(addr_space,
465                                 translate(NULL, FIRMWARE_START), rom_region);
466 
467     /* Load kernel */
468     if (kernel_filename) {
469         size = load_elf(kernel_filename, NULL, linux_kernel_virt_to_phys,
470                         NULL, &kernel_entry, &kernel_low, &kernel_high, NULL,
471                         true, EM_PARISC, 0, 0);
472 
473         kernel_entry = linux_kernel_virt_to_phys(NULL, kernel_entry);
474 
475         if (size < 0) {
476             error_report("could not load kernel '%s'", kernel_filename);
477             exit(1);
478         }
479         qemu_log_mask(CPU_LOG_PAGE, "Kernel loaded at 0x%08" PRIx64
480                       "-0x%08" PRIx64 ", entry at 0x%08" PRIx64
481                       ", size %" PRIu64 " kB\n",
482                       kernel_low, kernel_high, kernel_entry, size / KiB);
483 
484         if (kernel_cmdline) {
485             cpu[0]->env.gr[24] = 0x4000;
486             pstrcpy_targphys("cmdline", cpu[0]->env.gr[24],
487                              TARGET_PAGE_SIZE, kernel_cmdline);
488         }
489 
490         if (initrd_filename) {
491             ram_addr_t initrd_base;
492             int64_t initrd_size;
493 
494             initrd_size = get_image_size(initrd_filename);
495             if (initrd_size < 0) {
496                 error_report("could not load initial ram disk '%s'",
497                              initrd_filename);
498                 exit(1);
499             }
500 
501             /* Load the initrd image high in memory.
502                Mirror the algorithm used by palo:
503                (1) Due to sign-extension problems and PDC,
504                put the initrd no higher than 1G.
505                (2) Reserve 64k for stack.  */
506             initrd_base = MIN(machine->ram_size, 1 * GiB);
507             initrd_base = initrd_base - 64 * KiB;
508             initrd_base = (initrd_base - initrd_size) & TARGET_PAGE_MASK;
509 
510             if (initrd_base < kernel_high) {
511                 error_report("kernel and initial ram disk too large!");
512                 exit(1);
513             }
514 
515             load_image_targphys(initrd_filename, initrd_base, initrd_size);
516             cpu[0]->env.gr[23] = initrd_base;
517             cpu[0]->env.gr[22] = initrd_base + initrd_size;
518         }
519     }
520 
521     if (!kernel_entry) {
522         /* When booting via firmware, tell firmware if we want interactive
523          * mode (kernel_entry=1), and to boot from CD (gr[24]='d')
524          * or hard disc * (gr[24]='c').
525          */
526         kernel_entry = machine->boot_config.has_menu ? machine->boot_config.menu : 0;
527         cpu[0]->env.gr[24] = machine->boot_config.order[0];
528     }
529 
530     /* We jump to the firmware entry routine and pass the
531      * various parameters in registers. After firmware initialization,
532      * firmware will start the Linux kernel with ramdisk and cmdline.
533      */
534     cpu[0]->env.gr[26] = machine->ram_size;
535     cpu[0]->env.gr[25] = kernel_entry;
536 
537     /* tell firmware how many SMP CPUs to present in inventory table */
538     cpu[0]->env.gr[21] = smp_cpus;
539 
540     /* tell firmware fw_cfg port */
541     cpu[0]->env.gr[19] = FW_CFG_IO_BASE;
542 }
543 
544 /*
545  * Create HP B160L workstation
546  */
547 static void machine_HP_B160L_init(MachineState *machine)
548 {
549     DeviceState *dev, *dino_dev;
550     MemoryRegion *addr_space = get_system_memory();
551     TranslateFn *translate;
552     ISABus *isa_bus;
553     PCIBus *pci_bus;
554 
555     /* Create CPUs and RAM.  */
556     translate = machine_HP_common_init_cpus(machine);
557 
558     if (hppa_is_pa20(&cpu[0]->env)) {
559         error_report("The HP B160L workstation requires a 32-bit "
560                      "CPU. Use '-machine C3700' instead.");
561         exit(1);
562     }
563 
564     /* Init Lasi chip */
565     lasi_dev = DEVICE(lasi_init());
566     memory_region_add_subregion(addr_space, translate(NULL, LASI_HPA),
567                                 sysbus_mmio_get_region(
568                                     SYS_BUS_DEVICE(lasi_dev), 0));
569 
570     /* Init Dino (PCI host bus chip).  */
571     dino_dev = DEVICE(dino_init(addr_space));
572     memory_region_add_subregion(addr_space, translate(NULL, DINO_HPA),
573                                 sysbus_mmio_get_region(
574                                     SYS_BUS_DEVICE(dino_dev), 0));
575     pci_bus = PCI_BUS(qdev_get_child_bus(dino_dev, "pci"));
576     assert(pci_bus);
577 
578     /* Create ISA bus, needed for PS/2 kbd/mouse port emulation */
579     isa_bus = hppa_isa_bus(translate(NULL, IDE_HPA));
580     assert(isa_bus);
581 
582     /* Serial ports: Lasi and Dino use a 7.272727 MHz clock. */
583     serial_mm_init(addr_space, translate(NULL, LASI_UART_HPA + 0x800), 0,
584         qdev_get_gpio_in(lasi_dev, LASI_IRQ_UART_HPA), 7272727 / 16,
585         serial_hd(0), DEVICE_BIG_ENDIAN);
586 
587     serial_mm_init(addr_space, translate(NULL, DINO_UART_HPA + 0x800), 0,
588         qdev_get_gpio_in(dino_dev, DINO_IRQ_RS232INT), 7272727 / 16,
589         serial_hd(1), DEVICE_BIG_ENDIAN);
590 
591     /* Parallel port */
592     parallel_mm_init(addr_space, translate(NULL, LASI_LPT_HPA + 0x800), 0,
593                      qdev_get_gpio_in(lasi_dev, LASI_IRQ_LAN_HPA),
594                      parallel_hds[0]);
595 
596     /* PS/2 Keyboard/Mouse */
597     dev = qdev_new(TYPE_LASIPS2);
598     sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
599     sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
600                        qdev_get_gpio_in(lasi_dev, LASI_IRQ_PS2KBD_HPA));
601     memory_region_add_subregion(addr_space,
602                                 translate(NULL, LASI_PS2KBD_HPA),
603                                 sysbus_mmio_get_region(SYS_BUS_DEVICE(dev),
604                                                        0));
605     memory_region_add_subregion(addr_space,
606                                 translate(NULL, LASI_PS2KBD_HPA + 0x100),
607                                 sysbus_mmio_get_region(SYS_BUS_DEVICE(dev),
608                                                        1));
609 
610     /* Add SCSI discs, NICs, graphics & load firmware */
611     machine_HP_common_init_tail(machine, pci_bus, translate);
612 }
613 
614 static AstroState *astro_init(void)
615 {
616     DeviceState *dev;
617 
618     dev = qdev_new(TYPE_ASTRO_CHIP);
619     sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
620 
621     return ASTRO_CHIP(dev);
622 }
623 
624 /*
625  * Create HP C3700 workstation
626  */
627 static void machine_HP_C3700_init(MachineState *machine)
628 {
629     PCIBus *pci_bus;
630     AstroState *astro;
631     DeviceState *astro_dev;
632     MemoryRegion *addr_space = get_system_memory();
633     TranslateFn *translate;
634 
635     /* Create CPUs and RAM.  */
636     translate = machine_HP_common_init_cpus(machine);
637 
638     if (!hppa_is_pa20(&cpu[0]->env)) {
639         error_report("The HP C3000 workstation requires a 64-bit CPU. "
640                      "Use '-machine B160L' instead.");
641         exit(1);
642     }
643 
644     /* Init Astro and the Elroys (PCI host bus chips).  */
645     astro = astro_init();
646     astro_dev = DEVICE(astro);
647     memory_region_add_subregion(addr_space, translate(NULL, ASTRO_HPA),
648                                 sysbus_mmio_get_region(
649                                     SYS_BUS_DEVICE(astro_dev), 0));
650     pci_bus = PCI_BUS(qdev_get_child_bus(DEVICE(astro->elroy[0]), "pci"));
651     assert(pci_bus);
652 
653     /* Add SCSI discs, NICs, graphics & load firmware */
654     machine_HP_common_init_tail(machine, pci_bus, translate);
655 }
656 
657 static void hppa_machine_reset(MachineState *ms, ResetType type)
658 {
659     unsigned int smp_cpus = ms->smp.cpus;
660     int i;
661 
662     qemu_devices_reset(type);
663 
664     /* Start all CPUs at the firmware entry point.
665      *  Monarch CPU will initialize firmware, secondary CPUs
666      *  will enter a small idle loop and wait for rendevouz. */
667     for (i = 0; i < smp_cpus; i++) {
668         CPUState *cs = CPU(cpu[i]);
669 
670         /* reset CPU */
671         resettable_reset(OBJECT(cs), RESET_TYPE_COLD);
672 
673         cpu_set_pc(cs, firmware_entry);
674         cpu[i]->env.psw = PSW_Q;
675         cpu[i]->env.gr[5] = CPU_HPA + i * 0x1000;
676     }
677 
678     /* already initialized by machine_hppa_init()? */
679     if (cpu[0]->env.gr[26] == ms->ram_size) {
680         return;
681     }
682 
683     cpu[0]->env.gr[26] = ms->ram_size;
684     cpu[0]->env.gr[25] = 0; /* no firmware boot menu */
685     cpu[0]->env.gr[24] = 'c';
686     /* gr22/gr23 unused, no initrd while reboot. */
687     cpu[0]->env.gr[21] = smp_cpus;
688     /* tell firmware fw_cfg port */
689     cpu[0]->env.gr[19] = FW_CFG_IO_BASE;
690 }
691 
692 static void hppa_nmi(NMIState *n, int cpu_index, Error **errp)
693 {
694     CPUState *cs;
695 
696     CPU_FOREACH(cs) {
697         cpu_interrupt(cs, CPU_INTERRUPT_NMI);
698     }
699 }
700 
701 static void HP_B160L_machine_init_class_init(ObjectClass *oc, void *data)
702 {
703     static const char * const valid_cpu_types[] = {
704         TYPE_HPPA_CPU,
705         NULL
706     };
707     MachineClass *mc = MACHINE_CLASS(oc);
708     NMIClass *nc = NMI_CLASS(oc);
709 
710     mc->desc = "HP B160L workstation";
711     mc->default_cpu_type = TYPE_HPPA_CPU;
712     mc->valid_cpu_types = valid_cpu_types;
713     mc->init = machine_HP_B160L_init;
714     mc->reset = hppa_machine_reset;
715     mc->block_default_type = IF_SCSI;
716     mc->max_cpus = HPPA_MAX_CPUS;
717     mc->default_cpus = 1;
718     mc->is_default = true;
719     mc->default_ram_size = 512 * MiB;
720     mc->default_boot_order = "cd";
721     mc->default_ram_id = "ram";
722     mc->default_nic = "tulip";
723 
724     nc->nmi_monitor_handler = hppa_nmi;
725 }
726 
727 static const TypeInfo HP_B160L_machine_init_typeinfo = {
728     .name = MACHINE_TYPE_NAME("B160L"),
729     .parent = TYPE_MACHINE,
730     .class_init = HP_B160L_machine_init_class_init,
731     .interfaces = (InterfaceInfo[]) {
732         { TYPE_NMI },
733         { }
734     },
735 };
736 
737 static void HP_C3700_machine_init_class_init(ObjectClass *oc, void *data)
738 {
739     static const char * const valid_cpu_types[] = {
740         TYPE_HPPA64_CPU,
741         NULL
742     };
743     MachineClass *mc = MACHINE_CLASS(oc);
744     NMIClass *nc = NMI_CLASS(oc);
745 
746     mc->desc = "HP C3700 workstation";
747     mc->default_cpu_type = TYPE_HPPA64_CPU;
748     mc->valid_cpu_types = valid_cpu_types;
749     mc->init = machine_HP_C3700_init;
750     mc->reset = hppa_machine_reset;
751     mc->block_default_type = IF_SCSI;
752     mc->max_cpus = HPPA_MAX_CPUS;
753     mc->default_cpus = 1;
754     mc->is_default = false;
755     mc->default_ram_size = 1024 * MiB;
756     mc->default_boot_order = "cd";
757     mc->default_ram_id = "ram";
758     mc->default_nic = "tulip";
759 
760     nc->nmi_monitor_handler = hppa_nmi;
761 }
762 
763 static const TypeInfo HP_C3700_machine_init_typeinfo = {
764     .name = MACHINE_TYPE_NAME("C3700"),
765     .parent = TYPE_MACHINE,
766     .class_init = HP_C3700_machine_init_class_init,
767     .interfaces = (InterfaceInfo[]) {
768         { TYPE_NMI },
769         { }
770     },
771 };
772 
773 static void hppa_machine_init_register_types(void)
774 {
775     type_register_static(&HP_B160L_machine_init_typeinfo);
776     type_register_static(&HP_C3700_machine_init_typeinfo);
777 }
778 
779 type_init(hppa_machine_init_register_types)
780