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) |