machine.c (e2c41ee557f4389d577ad54b1c131d2e0b558558) machine.c (7df6f7511769af63c209d2fdcd6c7638f680e35a)
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 unchanged lines hidden (view full) ---

18#include "hw/timer/i8254.h"
19#include "hw/char/serial.h"
20#include "hw/char/parallel.h"
21#include "hw/intc/i8259.h"
22#include "hw/input/lasips2.h"
23#include "hw/net/lasi_82596.h"
24#include "hw/nmi.h"
25#include "hw/pci/pci.h"
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 unchanged lines hidden (view full) ---

18#include "hw/timer/i8254.h"
19#include "hw/char/serial.h"
20#include "hw/char/parallel.h"
21#include "hw/intc/i8259.h"
22#include "hw/input/lasips2.h"
23#include "hw/net/lasi_82596.h"
24#include "hw/nmi.h"
25#include "hw/pci/pci.h"
26#include "hw/pci/pci_device.h"
26#include "hw/pci-host/dino.h"
27#include "hw/misc/lasi.h"
28#include "hppa_hardware.h"
29#include "qemu/units.h"
30#include "qapi/error.h"
31#include "net/net.h"
32#include "qemu/log.h"
33
34#define MIN_SEABIOS_HPPA_VERSION 10 /* require at least this fw version */
35
36#define HPA_POWER_BUTTON (FIRMWARE_END - 0x10)
37
38#define enable_lasi_lan() 0
39
27#include "hw/pci-host/dino.h"
28#include "hw/misc/lasi.h"
29#include "hppa_hardware.h"
30#include "qemu/units.h"
31#include "qapi/error.h"
32#include "net/net.h"
33#include "qemu/log.h"
34
35#define MIN_SEABIOS_HPPA_VERSION 10 /* require at least this fw version */
36
37#define HPA_POWER_BUTTON (FIRMWARE_END - 0x10)
38
39#define enable_lasi_lan() 0
40
41static DeviceState *lasi_dev;
40
41static void hppa_powerdown_req(Notifier *n, void *opaque)
42{
43 hwaddr soft_power_reg = HPA_POWER_BUTTON;
44 uint32_t val;
45
46 val = ldl_be_phys(&address_space_memory, soft_power_reg);
47 if ((val >> 8) == 0) {

--- 197 unchanged lines hidden (view full) ---

245 dev = qdev_new(TYPE_DINO_PCI_HOST_BRIDGE);
246 object_property_set_link(OBJECT(dev), "memory-as", OBJECT(addr_space),
247 &error_fatal);
248 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
249
250 return DINO_PCI_HOST_BRIDGE(dev);
251}
252
42
43static void hppa_powerdown_req(Notifier *n, void *opaque)
44{
45 hwaddr soft_power_reg = HPA_POWER_BUTTON;
46 uint32_t val;
47
48 val = ldl_be_phys(&address_space_memory, soft_power_reg);
49 if ((val >> 8) == 0) {

--- 197 unchanged lines hidden (view full) ---

247 dev = qdev_new(TYPE_DINO_PCI_HOST_BRIDGE);
248 object_property_set_link(OBJECT(dev), "memory-as", OBJECT(addr_space),
249 &error_fatal);
250 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
251
252 return DINO_PCI_HOST_BRIDGE(dev);
253}
254
253static void machine_hppa_init(MachineState *machine)
255/*
256 * Step 1: Create CPUs and Memory
257 */
258static void machine_HP_common_init_cpus(MachineState *machine)
254{
259{
255 const char *kernel_filename = machine->kernel_filename;
256 const char *kernel_cmdline = machine->kernel_cmdline;
257 const char *initrd_filename = machine->initrd_filename;
258 MachineClass *mc = MACHINE_GET_CLASS(machine);
259 DeviceState *dev, *dino_dev, *lasi_dev;
260 PCIBus *pci_bus;
261 ISABus *isa_bus;
262 char *firmware_filename;
263 uint64_t firmware_low, firmware_high;
264 long size;
265 uint64_t kernel_entry = 0, kernel_low, kernel_high;
266 MemoryRegion *addr_space = get_system_memory();
260 MemoryRegion *addr_space = get_system_memory();
267 MemoryRegion *rom_region;
268 MemoryRegion *cpu_region;
269 long i;
270 unsigned int smp_cpus = machine->smp.cpus;
261 MemoryRegion *cpu_region;
262 long i;
263 unsigned int smp_cpus = machine->smp.cpus;
271 SysBusDevice *s;
264 char *name;
272
273 /* Create CPUs. */
274 for (i = 0; i < smp_cpus; i++) {
265
266 /* Create CPUs. */
267 for (i = 0; i < smp_cpus; i++) {
275 char *name = g_strdup_printf("cpu%ld-io-eir", i);
268 name = g_strdup_printf("cpu%ld-io-eir", i);
276 cpu[i] = HPPA_CPU(cpu_create(machine->cpu_type));
277
278 cpu_region = g_new(MemoryRegion, 1);
279 memory_region_init_io(cpu_region, OBJECT(cpu[i]), &hppa_io_eir_ops,
280 cpu[i], name, 4);
281 memory_region_add_subregion(addr_space, CPU_HPA + i * 0x1000,
282 cpu_region);
283 g_free(name);

--- 6 unchanged lines hidden (view full) ---

290 memory_region_add_subregion(addr_space, CPU_HPA + 16, cpu_region);
291
292 /* Main memory region. */
293 if (machine->ram_size > 3 * GiB) {
294 error_report("RAM size is currently restricted to 3GB");
295 exit(EXIT_FAILURE);
296 }
297 memory_region_add_subregion_overlap(addr_space, 0, machine->ram, -1);
269 cpu[i] = HPPA_CPU(cpu_create(machine->cpu_type));
270
271 cpu_region = g_new(MemoryRegion, 1);
272 memory_region_init_io(cpu_region, OBJECT(cpu[i]), &hppa_io_eir_ops,
273 cpu[i], name, 4);
274 memory_region_add_subregion(addr_space, CPU_HPA + i * 0x1000,
275 cpu_region);
276 g_free(name);

--- 6 unchanged lines hidden (view full) ---

283 memory_region_add_subregion(addr_space, CPU_HPA + 16, cpu_region);
284
285 /* Main memory region. */
286 if (machine->ram_size > 3 * GiB) {
287 error_report("RAM size is currently restricted to 3GB");
288 exit(EXIT_FAILURE);
289 }
290 memory_region_add_subregion_overlap(addr_space, 0, machine->ram, -1);
291}
298
292
293/*
294 * Last creation step: Add SCSI discs, NICs, graphics & load firmware
295 */
296static void machine_HP_common_init_tail(MachineState *machine, PCIBus *pci_bus)
297{
298 const char *kernel_filename = machine->kernel_filename;
299 const char *kernel_cmdline = machine->kernel_cmdline;
300 const char *initrd_filename = machine->initrd_filename;
301 MachineClass *mc = MACHINE_GET_CLASS(machine);
302 DeviceState *dev;
303 char *firmware_filename;
304 uint64_t firmware_low, firmware_high;
305 long size;
306 uint64_t kernel_entry = 0, kernel_low, kernel_high;
307 MemoryRegion *addr_space = get_system_memory();
308 MemoryRegion *rom_region;
309 long i;
310 unsigned int smp_cpus = machine->smp.cpus;
311 SysBusDevice *s;
299
312
300 /* Init Lasi chip */
301 lasi_dev = DEVICE(lasi_init());
302 memory_region_add_subregion(addr_space, LASI_HPA,
303 sysbus_mmio_get_region(
304 SYS_BUS_DEVICE(lasi_dev), 0));
305
306 /* Init Dino (PCI host bus chip). */
307 dino_dev = DEVICE(dino_init(addr_space));
308 memory_region_add_subregion(addr_space, DINO_HPA,
309 sysbus_mmio_get_region(
310 SYS_BUS_DEVICE(dino_dev), 0));
311 pci_bus = PCI_BUS(qdev_get_child_bus(dino_dev, "pci"));
312 assert(pci_bus);
313
314 /* Create ISA bus. */
315 isa_bus = hppa_isa_bus();
316 assert(isa_bus);
317
318 /* Realtime clock, used by firmware for PDC_TOD call. */
319 mc146818_rtc_init(isa_bus, 2000, NULL);
320
321 /* Serial ports: Lasi and Dino use a 7.272727 MHz clock. */
322 serial_mm_init(addr_space, LASI_UART_HPA + 0x800, 0,
323 qdev_get_gpio_in(lasi_dev, LASI_IRQ_UART_HPA), 7272727 / 16,
324 serial_hd(0), DEVICE_BIG_ENDIAN);
325
326 serial_mm_init(addr_space, DINO_UART_HPA + 0x800, 0,
327 qdev_get_gpio_in(dino_dev, DINO_IRQ_RS232INT), 7272727 / 16,
328 serial_hd(1), DEVICE_BIG_ENDIAN);
329
330 /* Parallel port */
331 parallel_mm_init(addr_space, LASI_LPT_HPA + 0x800, 0,
332 qdev_get_gpio_in(lasi_dev, LASI_IRQ_LAN_HPA),
333 parallel_hds[0]);
334
335 /* fw_cfg configuration interface */
336 create_fw_cfg(machine, pci_bus);
337
338 /* SCSI disk setup. */
339 dev = DEVICE(pci_create_simple(pci_bus, -1, "lsi53c895a"));
340 lsi53c8xx_handle_legacy_cmdline(dev);
341
342 /* Graphics setup. */
343 if (machine->enable_graphics && vga_interface_type != VGA_NONE) {
344 vga_interface_created = true;
345 dev = qdev_new("artist");

--- 10 unchanged lines hidden (view full) ---

356 }
357
358 for (i = 0; i < nb_nics; i++) {
359 if (!enable_lasi_lan()) {
360 pci_nic_init_nofail(&nd_table[i], pci_bus, mc->default_nic, NULL);
361 }
362 }
363
313 /* SCSI disk setup. */
314 dev = DEVICE(pci_create_simple(pci_bus, -1, "lsi53c895a"));
315 lsi53c8xx_handle_legacy_cmdline(dev);
316
317 /* Graphics setup. */
318 if (machine->enable_graphics && vga_interface_type != VGA_NONE) {
319 vga_interface_created = true;
320 dev = qdev_new("artist");

--- 10 unchanged lines hidden (view full) ---

331 }
332
333 for (i = 0; i < nb_nics; i++) {
334 if (!enable_lasi_lan()) {
335 pci_nic_init_nofail(&nd_table[i], pci_bus, mc->default_nic, NULL);
336 }
337 }
338
364 /* PS/2 Keyboard/Mouse */
365 dev = qdev_new(TYPE_LASIPS2);
366 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
367 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
368 qdev_get_gpio_in(lasi_dev, LASI_IRQ_PS2KBD_HPA));
369 memory_region_add_subregion(addr_space, LASI_PS2KBD_HPA,
370 sysbus_mmio_get_region(SYS_BUS_DEVICE(dev),
371 0));
372 memory_region_add_subregion(addr_space, LASI_PS2KBD_HPA + 0x100,
373 sysbus_mmio_get_region(SYS_BUS_DEVICE(dev),
374 1));
375
376 /* register power switch emulation */
377 qemu_register_powerdown_notifier(&hppa_system_powerdown_notifier);
378
339 /* register power switch emulation */
340 qemu_register_powerdown_notifier(&hppa_system_powerdown_notifier);
341
342 /* fw_cfg configuration interface */
343 create_fw_cfg(machine, pci_bus);
344
379 /* Load firmware. Given that this is not "real" firmware,
380 but one explicitly written for the emulation, we might as
381 well load it directly from an ELF image. */
382 firmware_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS,
383 machine->firmware ?: "hppa-firmware.img");
384 if (firmware_filename == NULL) {
385 error_report("no firmware provided");
386 exit(1);

--- 101 unchanged lines hidden (view full) ---

488
489 /* tell firmware how many SMP CPUs to present in inventory table */
490 cpu[0]->env.gr[21] = smp_cpus;
491
492 /* tell firmware fw_cfg port */
493 cpu[0]->env.gr[19] = FW_CFG_IO_BASE;
494}
495
345 /* Load firmware. Given that this is not "real" firmware,
346 but one explicitly written for the emulation, we might as
347 well load it directly from an ELF image. */
348 firmware_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS,
349 machine->firmware ?: "hppa-firmware.img");
350 if (firmware_filename == NULL) {
351 error_report("no firmware provided");
352 exit(1);

--- 101 unchanged lines hidden (view full) ---

454
455 /* tell firmware how many SMP CPUs to present in inventory table */
456 cpu[0]->env.gr[21] = smp_cpus;
457
458 /* tell firmware fw_cfg port */
459 cpu[0]->env.gr[19] = FW_CFG_IO_BASE;
460}
461
462/*
463 * Create HP B160L workstation
464 */
465static void machine_HP_B160L_init(MachineState *machine)
466{
467 DeviceState *dev, *dino_dev;
468 MemoryRegion *addr_space = get_system_memory();
469 ISABus *isa_bus;
470 PCIBus *pci_bus;
471
472 /* Create CPUs and RAM. */
473 machine_HP_common_init_cpus(machine);
474
475 /* Init Lasi chip */
476 lasi_dev = DEVICE(lasi_init());
477 memory_region_add_subregion(addr_space, LASI_HPA,
478 sysbus_mmio_get_region(
479 SYS_BUS_DEVICE(lasi_dev), 0));
480
481 /* Init Dino (PCI host bus chip). */
482 dino_dev = DEVICE(dino_init(addr_space));
483 memory_region_add_subregion(addr_space, DINO_HPA,
484 sysbus_mmio_get_region(
485 SYS_BUS_DEVICE(dino_dev), 0));
486 pci_bus = PCI_BUS(qdev_get_child_bus(dino_dev, "pci"));
487 assert(pci_bus);
488
489 /* Create ISA bus, needed for PS/2 kbd/mouse port emulation */
490 isa_bus = hppa_isa_bus();
491 assert(isa_bus);
492
493 /* Serial ports: Lasi and Dino use a 7.272727 MHz clock. */
494 serial_mm_init(addr_space, LASI_UART_HPA + 0x800, 0,
495 qdev_get_gpio_in(lasi_dev, LASI_IRQ_UART_HPA), 7272727 / 16,
496 serial_hd(0), DEVICE_BIG_ENDIAN);
497
498 serial_mm_init(addr_space, DINO_UART_HPA + 0x800, 0,
499 qdev_get_gpio_in(dino_dev, DINO_IRQ_RS232INT), 7272727 / 16,
500 serial_hd(1), DEVICE_BIG_ENDIAN);
501
502 /* Parallel port */
503 parallel_mm_init(addr_space, LASI_LPT_HPA + 0x800, 0,
504 qdev_get_gpio_in(lasi_dev, LASI_IRQ_LAN_HPA),
505 parallel_hds[0]);
506
507 /* PS/2 Keyboard/Mouse */
508 dev = qdev_new(TYPE_LASIPS2);
509 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
510 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
511 qdev_get_gpio_in(lasi_dev, LASI_IRQ_PS2KBD_HPA));
512 memory_region_add_subregion(addr_space, LASI_PS2KBD_HPA,
513 sysbus_mmio_get_region(SYS_BUS_DEVICE(dev),
514 0));
515 memory_region_add_subregion(addr_space, LASI_PS2KBD_HPA + 0x100,
516 sysbus_mmio_get_region(SYS_BUS_DEVICE(dev),
517 1));
518
519 /* Add SCSI discs, NICs, graphics & load firmware */
520 machine_HP_common_init_tail(machine, pci_bus);
521}
522
496static void hppa_machine_reset(MachineState *ms, ShutdownCause reason)
497{
498 unsigned int smp_cpus = ms->smp.cpus;
499 int i;
500
501 qemu_devices_reset(reason);
502
503 /* Start all CPUs at the firmware entry point.

--- 32 unchanged lines hidden (view full) ---

536{
537 CPUState *cs;
538
539 CPU_FOREACH(cs) {
540 cpu_interrupt(cs, CPU_INTERRUPT_NMI);
541 }
542}
543
523static void hppa_machine_reset(MachineState *ms, ShutdownCause reason)
524{
525 unsigned int smp_cpus = ms->smp.cpus;
526 int i;
527
528 qemu_devices_reset(reason);
529
530 /* Start all CPUs at the firmware entry point.

--- 32 unchanged lines hidden (view full) ---

563{
564 CPUState *cs;
565
566 CPU_FOREACH(cs) {
567 cpu_interrupt(cs, CPU_INTERRUPT_NMI);
568 }
569}
570
544static void hppa_machine_init_class_init(ObjectClass *oc, void *data)
571static void HP_B160L_machine_init_class_init(ObjectClass *oc, void *data)
545{
546 MachineClass *mc = MACHINE_CLASS(oc);
547 NMIClass *nc = NMI_CLASS(oc);
548
572{
573 MachineClass *mc = MACHINE_CLASS(oc);
574 NMIClass *nc = NMI_CLASS(oc);
575
549 mc->desc = "HPPA B160L machine";
576 mc->desc = "HP B160L workstation";
550 mc->default_cpu_type = TYPE_HPPA_CPU;
577 mc->default_cpu_type = TYPE_HPPA_CPU;
551 mc->init = machine_hppa_init;
578 mc->init = machine_HP_B160L_init;
552 mc->reset = hppa_machine_reset;
553 mc->block_default_type = IF_SCSI;
554 mc->max_cpus = HPPA_MAX_CPUS;
555 mc->default_cpus = 1;
556 mc->is_default = true;
557 mc->default_ram_size = 512 * MiB;
558 mc->default_boot_order = "cd";
559 mc->default_ram_id = "ram";
560 mc->default_nic = "tulip";
561
562 nc->nmi_monitor_handler = hppa_nmi;
563}
564
579 mc->reset = hppa_machine_reset;
580 mc->block_default_type = IF_SCSI;
581 mc->max_cpus = HPPA_MAX_CPUS;
582 mc->default_cpus = 1;
583 mc->is_default = true;
584 mc->default_ram_size = 512 * MiB;
585 mc->default_boot_order = "cd";
586 mc->default_ram_id = "ram";
587 mc->default_nic = "tulip";
588
589 nc->nmi_monitor_handler = hppa_nmi;
590}
591
565static const TypeInfo hppa_machine_init_typeinfo = {
566 .name = MACHINE_TYPE_NAME("hppa"),
592static const TypeInfo HP_B160L_machine_init_typeinfo = {
593 .name = MACHINE_TYPE_NAME("B160L"),
567 .parent = TYPE_MACHINE,
594 .parent = TYPE_MACHINE,
568 .class_init = hppa_machine_init_class_init,
595 .class_init = HP_B160L_machine_init_class_init,
569 .interfaces = (InterfaceInfo[]) {
570 { TYPE_NMI },
571 { }
572 },
573};
574
575static void hppa_machine_init_register_types(void)
576{
596 .interfaces = (InterfaceInfo[]) {
597 { TYPE_NMI },
598 { }
599 },
600};
601
602static void hppa_machine_init_register_types(void)
603{
577 type_register_static(&hppa_machine_init_typeinfo);
604 type_register_static(&HP_B160L_machine_init_typeinfo);
578}
579
580type_init(hppa_machine_init_register_types)
605}
606
607type_init(hppa_machine_init_register_types)