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