/*
 * QEMU HPPA hardware system emulator.
 * (C) Copyright 2018-2023 Helge Deller <deller@gmx.de>
 *
 * This work is licensed under the GNU GPL license version 2 or later.
 */

#include "qemu/osdep.h"
#include "qemu/datadir.h"
#include "cpu.h"
#include "elf.h"
#include "hw/loader.h"
#include "qemu/error-report.h"
#include "sysemu/reset.h"
#include "sysemu/sysemu.h"
#include "sysemu/qtest.h"
#include "sysemu/runstate.h"
#include "hw/rtc/mc146818rtc.h"
#include "hw/timer/i8254.h"
#include "hw/char/serial.h"
#include "hw/char/parallel.h"
#include "hw/intc/i8259.h"
#include "hw/input/lasips2.h"
#include "hw/net/lasi_82596.h"
#include "hw/nmi.h"
#include "hw/usb.h"
#include "hw/pci/pci.h"
#include "hw/pci/pci_device.h"
#include "hw/pci-host/astro.h"
#include "hw/pci-host/dino.h"
#include "hw/misc/lasi.h"
#include "hppa_hardware.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "net/net.h"
#include "qemu/log.h"

#define MIN_SEABIOS_HPPA_VERSION 12 /* require at least this fw version */

#define HPA_POWER_BUTTON        (FIRMWARE_END - 0x10)
static hwaddr soft_power_reg;

#define enable_lasi_lan()       0

static DeviceState *lasi_dev;

static void hppa_powerdown_req(Notifier *n, void *opaque)
{
    uint32_t val;

    val = ldl_be_phys(&address_space_memory, soft_power_reg);
    if ((val >> 8) == 0) {
        /* immediately shut down when under hardware control */
        qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
        return;
    }

    /* clear bit 31 to indicate that the power switch was pressed. */
    val &= ~1;
    stl_be_phys(&address_space_memory, soft_power_reg, val);
}

static Notifier hppa_system_powerdown_notifier = {
    .notify = hppa_powerdown_req
};

/* Fallback for unassigned PCI I/O operations.  Avoids MCHK.  */
static uint64_t ignore_read(void *opaque, hwaddr addr, unsigned size)
{
    return 0;
}

static void ignore_write(void *opaque, hwaddr addr, uint64_t v, unsigned size)
{
}

static const MemoryRegionOps hppa_pci_ignore_ops = {
    .read = ignore_read,
    .write = ignore_write,
    .endianness = DEVICE_BIG_ENDIAN,
    .valid = {
        .min_access_size = 1,
        .max_access_size = 8,
    },
    .impl = {
        .min_access_size = 1,
        .max_access_size = 8,
    },
};

static ISABus *hppa_isa_bus(hwaddr addr)
{
    ISABus *isa_bus;
    qemu_irq *isa_irqs;
    MemoryRegion *isa_region;

    isa_region = g_new(MemoryRegion, 1);
    memory_region_init_io(isa_region, NULL, &hppa_pci_ignore_ops,
                          NULL, "isa-io", 0x800);
    memory_region_add_subregion(get_system_memory(), addr, isa_region);

    isa_bus = isa_bus_new(NULL, get_system_memory(), isa_region,
                          &error_abort);
    isa_irqs = i8259_init(isa_bus, NULL);
    isa_bus_register_input_irqs(isa_bus, isa_irqs);

    return isa_bus;
}

/*
 * Helper functions to emulate RTC clock and DebugOutputPort
 */
static time_t rtc_ref;

static uint64_t io_cpu_read(void *opaque, hwaddr addr, unsigned size)
{
    uint64_t val = 0;

    switch (addr) {
    case 0:             /* RTC clock */
        val = time(NULL);
        val += rtc_ref;
        break;
    case 8:             /* DebugOutputPort */
        return 0xe9;    /* readback */
    }
    return val;
}

static void io_cpu_write(void *opaque, hwaddr addr,
                         uint64_t val, unsigned size)
{
    unsigned char ch;
    Chardev *debugout;

    switch (addr) {
    case 0:             /* RTC clock */
        rtc_ref = val - time(NULL);
        break;
    case 8:             /* DebugOutputPort */
        ch = val;
        debugout = serial_hd(0);
        if (debugout) {
            qemu_chr_fe_write_all(debugout->be, &ch, 1);
        } else {
            fprintf(stderr, "%c", ch);
        }
        break;
    }
}

static const MemoryRegionOps hppa_io_helper_ops = {
    .read = io_cpu_read,
    .write = io_cpu_write,
    .endianness = DEVICE_BIG_ENDIAN,
    .valid = {
        .min_access_size = 1,
        .max_access_size = 8,
    },
    .impl = {
        .min_access_size = 1,
        .max_access_size = 8,
    },
};

typedef uint64_t TranslateFn(void *opaque, uint64_t addr);

static uint64_t linux_kernel_virt_to_phys(void *opaque, uint64_t addr)
{
    addr &= (0x10000000 - 1);
    return addr;
}

static uint64_t translate_pa10(void *dummy, uint64_t addr)
{
    return (uint32_t)addr;
}

static uint64_t translate_pa20(void *dummy, uint64_t addr)
{
    return hppa_abs_to_phys_pa2_w0(addr);
}

static HPPACPU *cpu[HPPA_MAX_CPUS];
static uint64_t firmware_entry;

static void fw_cfg_boot_set(void *opaque, const char *boot_device,
                            Error **errp)
{
    fw_cfg_modify_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]);
}

static FWCfgState *create_fw_cfg(MachineState *ms, PCIBus *pci_bus,
                                 hwaddr addr)
{
    FWCfgState *fw_cfg;
    uint64_t val;
    const char qemu_version[] = QEMU_VERSION;
    MachineClass *mc = MACHINE_GET_CLASS(ms);
    int btlb_entries = HPPA_BTLB_ENTRIES(&cpu[0]->env);
    int len;

    fw_cfg = fw_cfg_init_mem(addr, addr + 4);
    fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, ms->smp.cpus);
    fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, HPPA_MAX_CPUS);
    fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, ms->ram_size);

    val = cpu_to_le64(MIN_SEABIOS_HPPA_VERSION);
    fw_cfg_add_file(fw_cfg, "/etc/firmware-min-version",
                    g_memdup(&val, sizeof(val)), sizeof(val));

    val = cpu_to_le64(HPPA_TLB_ENTRIES - btlb_entries);
    fw_cfg_add_file(fw_cfg, "/etc/cpu/tlb_entries",
                    g_memdup(&val, sizeof(val)), sizeof(val));

    val = cpu_to_le64(btlb_entries);
    fw_cfg_add_file(fw_cfg, "/etc/cpu/btlb_entries",
                    g_memdup(&val, sizeof(val)), sizeof(val));

    len = strlen(mc->name) + 1;
    fw_cfg_add_file(fw_cfg, "/etc/hppa/machine",
                    g_memdup(mc->name, len), len);

    val = cpu_to_le64(soft_power_reg);
    fw_cfg_add_file(fw_cfg, "/etc/hppa/power-button-addr",
                    g_memdup(&val, sizeof(val)), sizeof(val));

    val = cpu_to_le64(CPU_HPA + 16);
    fw_cfg_add_file(fw_cfg, "/etc/hppa/rtc-addr",
                    g_memdup(&val, sizeof(val)), sizeof(val));

    val = cpu_to_le64(CPU_HPA + 24);
    fw_cfg_add_file(fw_cfg, "/etc/hppa/DebugOutputPort",
                    g_memdup(&val, sizeof(val)), sizeof(val));

    fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ms->boot_config.order[0]);
    qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);

    fw_cfg_add_file(fw_cfg, "/etc/qemu-version",
                    g_memdup(qemu_version, sizeof(qemu_version)),
                    sizeof(qemu_version));

    fw_cfg_add_extra_pci_roots(pci_bus, fw_cfg);

    return fw_cfg;
}

static LasiState *lasi_init(void)
{
    DeviceState *dev;

    dev = qdev_new(TYPE_LASI_CHIP);
    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);

    return LASI_CHIP(dev);
}

static DinoState *dino_init(MemoryRegion *addr_space)
{
    DeviceState *dev;

    dev = qdev_new(TYPE_DINO_PCI_HOST_BRIDGE);
    object_property_set_link(OBJECT(dev), "memory-as", OBJECT(addr_space),
                             &error_fatal);
    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);

    return DINO_PCI_HOST_BRIDGE(dev);
}

/*
 * Step 1: Create CPUs and Memory
 */
static TranslateFn *machine_HP_common_init_cpus(MachineState *machine)
{
    MemoryRegion *addr_space = get_system_memory();
    unsigned int smp_cpus = machine->smp.cpus;
    TranslateFn *translate;
    MemoryRegion *cpu_region;
    uint64_t ram_max;

    /* Create CPUs.  */
    for (unsigned int i = 0; i < smp_cpus; i++) {
        cpu[i] = HPPA_CPU(cpu_create(machine->cpu_type));
    }

    /*
     * For now, treat address layout as if PSW_W is clear.
     * TODO: create a proper hppa64 board model and load elf64 firmware.
     */
    if (hppa_is_pa20(&cpu[0]->env)) {
        translate = translate_pa20;
        ram_max = 0xf0000000;      /* 3.75 GB (limited by 32-bit firmware) */
    } else {
        translate = translate_pa10;
        ram_max = 0xf0000000;      /* 3.75 GB (32-bit CPU) */
    }

    soft_power_reg = translate(NULL, HPA_POWER_BUTTON);

    for (unsigned int i = 0; i < smp_cpus; i++) {
        g_autofree char *name = g_strdup_printf("cpu%u-io-eir", i);

        cpu_region = g_new(MemoryRegion, 1);
        memory_region_init_io(cpu_region, OBJECT(cpu[i]), &hppa_io_eir_ops,
                              cpu[i], name, 4);
        memory_region_add_subregion(addr_space,
                                    translate(NULL, CPU_HPA + i * 0x1000),
                                    cpu_region);
    }

    /* RTC and DebugOutputPort on CPU #0 */
    cpu_region = g_new(MemoryRegion, 1);
    memory_region_init_io(cpu_region, OBJECT(cpu[0]), &hppa_io_helper_ops,
                          cpu[0], "cpu0-io-rtc", 2 * sizeof(uint64_t));
    memory_region_add_subregion(addr_space, translate(NULL, CPU_HPA + 16),
                                cpu_region);

    /* Main memory region. */
    if (machine->ram_size > ram_max) {
        info_report("Max RAM size limited to %" PRIu64 " MB", ram_max / MiB);
        machine->ram_size = ram_max;
    }
    memory_region_add_subregion_overlap(addr_space, 0, machine->ram, -1);

    return translate;
}

/*
 * Last creation step: Add SCSI discs, NICs, graphics & load firmware
 */
static void machine_HP_common_init_tail(MachineState *machine, PCIBus *pci_bus,
                                        TranslateFn *translate)
{
    const char *kernel_filename = machine->kernel_filename;
    const char *kernel_cmdline = machine->kernel_cmdline;
    const char *initrd_filename = machine->initrd_filename;
    const char *firmware = machine->firmware;
    MachineClass *mc = MACHINE_GET_CLASS(machine);
    DeviceState *dev;
    PCIDevice *pci_dev;
    char *firmware_filename;
    uint64_t firmware_low, firmware_high;
    long size;
    uint64_t kernel_entry = 0, kernel_low, kernel_high;
    MemoryRegion *addr_space = get_system_memory();
    MemoryRegion *rom_region;
    unsigned int smp_cpus = machine->smp.cpus;
    SysBusDevice *s;

    /* SCSI disk setup. */
    if (drive_get_max_bus(IF_SCSI) >= 0) {
        dev = DEVICE(pci_create_simple(pci_bus, -1, "lsi53c895a"));
        lsi53c8xx_handle_legacy_cmdline(dev);
    }

    /* Graphics setup. */
    if (machine->enable_graphics && vga_interface_type != VGA_NONE) {
        vga_interface_created = true;
        dev = qdev_new("artist");
        s = SYS_BUS_DEVICE(dev);
        sysbus_realize_and_unref(s, &error_fatal);
        sysbus_mmio_map(s, 0, translate(NULL, LASI_GFX_HPA));
        sysbus_mmio_map(s, 1, translate(NULL, ARTIST_FB_ADDR));
    }

    /* Network setup. */
    if (lasi_dev) {
        lasi_82596_init(addr_space, translate(NULL, LASI_LAN_HPA),
                        qdev_get_gpio_in(lasi_dev, LASI_IRQ_LAN_HPA),
                        enable_lasi_lan());
    }

    pci_init_nic_devices(pci_bus, mc->default_nic);

    /* BMC board: HP Powerbar SP2 Diva (with console only) */
    pci_dev = pci_new(-1, "pci-serial");
    if (!lasi_dev) {
        /* bind default keyboard/serial to Diva card */
        qdev_prop_set_chr(DEVICE(pci_dev), "chardev", serial_hd(0));
    }
    qdev_prop_set_uint8(DEVICE(pci_dev), "prog_if", 0);
    pci_realize_and_unref(pci_dev, pci_bus, &error_fatal);
    pci_config_set_vendor_id(pci_dev->config, PCI_VENDOR_ID_HP);
    pci_config_set_device_id(pci_dev->config, 0x1048);
    pci_set_word(&pci_dev->config[PCI_SUBSYSTEM_VENDOR_ID], PCI_VENDOR_ID_HP);
    pci_set_word(&pci_dev->config[PCI_SUBSYSTEM_ID], 0x1227); /* Powerbar */

    /* create a second serial PCI card when running Astro */
    if (serial_hd(1) && !lasi_dev) {
        pci_dev = pci_new(-1, "pci-serial-4x");
        qdev_prop_set_chr(DEVICE(pci_dev), "chardev1", serial_hd(1));
        qdev_prop_set_chr(DEVICE(pci_dev), "chardev2", serial_hd(2));
        qdev_prop_set_chr(DEVICE(pci_dev), "chardev3", serial_hd(3));
        qdev_prop_set_chr(DEVICE(pci_dev), "chardev4", serial_hd(4));
        pci_realize_and_unref(pci_dev, pci_bus, &error_fatal);
    }

    /* create USB OHCI controller for USB keyboard & mouse on Astro machines */
    if (!lasi_dev && machine->enable_graphics) {
        pci_create_simple(pci_bus, -1, "pci-ohci");
        usb_create_simple(usb_bus_find(-1), "usb-kbd");
        usb_create_simple(usb_bus_find(-1), "usb-mouse");
    }

    /* register power switch emulation */
    qemu_register_powerdown_notifier(&hppa_system_powerdown_notifier);

    /* fw_cfg configuration interface */
    create_fw_cfg(machine, pci_bus, translate(NULL, FW_CFG_IO_BASE));

    /* Load firmware.  Given that this is not "real" firmware,
       but one explicitly written for the emulation, we might as
       well load it directly from an ELF image. Load the 64-bit
       firmware on 64-bit machines by default if not specified
       on command line. */
    if (!qtest_enabled()) {
        if (!firmware) {
            firmware = lasi_dev ? "hppa-firmware.img" : "hppa-firmware64.img";
        }
        firmware_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, firmware);
        if (firmware_filename == NULL) {
            error_report("no firmware provided");
            exit(1);
        }

        size = load_elf(firmware_filename, NULL, translate, NULL,
                        &firmware_entry, &firmware_low, &firmware_high, NULL,
                        true, EM_PARISC, 0, 0);

        if (size < 0) {
            error_report("could not load firmware '%s'", firmware_filename);
            exit(1);
        }
        qemu_log_mask(CPU_LOG_PAGE, "Firmware loaded at 0x%08" PRIx64
                      "-0x%08" PRIx64 ", entry at 0x%08" PRIx64 ".\n",
                      firmware_low, firmware_high, firmware_entry);
        if (firmware_low < translate(NULL, FIRMWARE_START) ||
            firmware_high >= translate(NULL, FIRMWARE_END)) {
            error_report("Firmware overlaps with memory or IO space");
            exit(1);
        }
        g_free(firmware_filename);
    }

    rom_region = g_new(MemoryRegion, 1);
    memory_region_init_ram(rom_region, NULL, "firmware",
                           (FIRMWARE_END - FIRMWARE_START), &error_fatal);
    memory_region_add_subregion(addr_space,
                                translate(NULL, FIRMWARE_START), rom_region);

    /* Load kernel */
    if (kernel_filename) {
        size = load_elf(kernel_filename, NULL, linux_kernel_virt_to_phys,
                        NULL, &kernel_entry, &kernel_low, &kernel_high, NULL,
                        true, EM_PARISC, 0, 0);

        kernel_entry = linux_kernel_virt_to_phys(NULL, kernel_entry);

        if (size < 0) {
            error_report("could not load kernel '%s'", kernel_filename);
            exit(1);
        }
        qemu_log_mask(CPU_LOG_PAGE, "Kernel loaded at 0x%08" PRIx64
                      "-0x%08" PRIx64 ", entry at 0x%08" PRIx64
                      ", size %" PRIu64 " kB\n",
                      kernel_low, kernel_high, kernel_entry, size / KiB);

        if (kernel_cmdline) {
            cpu[0]->env.gr[24] = 0x4000;
            pstrcpy_targphys("cmdline", cpu[0]->env.gr[24],
                             TARGET_PAGE_SIZE, kernel_cmdline);
        }

        if (initrd_filename) {
            ram_addr_t initrd_base;
            int64_t initrd_size;

            initrd_size = get_image_size(initrd_filename);
            if (initrd_size < 0) {
                error_report("could not load initial ram disk '%s'",
                             initrd_filename);
                exit(1);
            }

            /* Load the initrd image high in memory.
               Mirror the algorithm used by palo:
               (1) Due to sign-extension problems and PDC,
               put the initrd no higher than 1G.
               (2) Reserve 64k for stack.  */
            initrd_base = MIN(machine->ram_size, 1 * GiB);
            initrd_base = initrd_base - 64 * KiB;
            initrd_base = (initrd_base - initrd_size) & TARGET_PAGE_MASK;

            if (initrd_base < kernel_high) {
                error_report("kernel and initial ram disk too large!");
                exit(1);
            }

            load_image_targphys(initrd_filename, initrd_base, initrd_size);
            cpu[0]->env.gr[23] = initrd_base;
            cpu[0]->env.gr[22] = initrd_base + initrd_size;
        }
    }

    if (!kernel_entry) {
        /* When booting via firmware, tell firmware if we want interactive
         * mode (kernel_entry=1), and to boot from CD (gr[24]='d')
         * or hard disc * (gr[24]='c').
         */
        kernel_entry = machine->boot_config.has_menu ? machine->boot_config.menu : 0;
        cpu[0]->env.gr[24] = machine->boot_config.order[0];
    }

    /* We jump to the firmware entry routine and pass the
     * various parameters in registers. After firmware initialization,
     * firmware will start the Linux kernel with ramdisk and cmdline.
     */
    cpu[0]->env.gr[26] = machine->ram_size;
    cpu[0]->env.gr[25] = kernel_entry;

    /* tell firmware how many SMP CPUs to present in inventory table */
    cpu[0]->env.gr[21] = smp_cpus;

    /* tell firmware fw_cfg port */
    cpu[0]->env.gr[19] = FW_CFG_IO_BASE;
}

/*
 * Create HP B160L workstation
 */
static void machine_HP_B160L_init(MachineState *machine)
{
    DeviceState *dev, *dino_dev;
    MemoryRegion *addr_space = get_system_memory();
    TranslateFn *translate;
    ISABus *isa_bus;
    PCIBus *pci_bus;

    /* Create CPUs and RAM.  */
    translate = machine_HP_common_init_cpus(machine);

    if (hppa_is_pa20(&cpu[0]->env)) {
        error_report("The HP B160L workstation requires a 32-bit "
                     "CPU. Use '-machine C3700' instead.");
        exit(1);
    }

    /* Init Lasi chip */
    lasi_dev = DEVICE(lasi_init());
    memory_region_add_subregion(addr_space, translate(NULL, LASI_HPA),
                                sysbus_mmio_get_region(
                                    SYS_BUS_DEVICE(lasi_dev), 0));

    /* Init Dino (PCI host bus chip).  */
    dino_dev = DEVICE(dino_init(addr_space));
    memory_region_add_subregion(addr_space, translate(NULL, DINO_HPA),
                                sysbus_mmio_get_region(
                                    SYS_BUS_DEVICE(dino_dev), 0));
    pci_bus = PCI_BUS(qdev_get_child_bus(dino_dev, "pci"));
    assert(pci_bus);

    /* Create ISA bus, needed for PS/2 kbd/mouse port emulation */
    isa_bus = hppa_isa_bus(translate(NULL, IDE_HPA));
    assert(isa_bus);

    /* Serial ports: Lasi and Dino use a 7.272727 MHz clock. */
    serial_mm_init(addr_space, translate(NULL, LASI_UART_HPA + 0x800), 0,
        qdev_get_gpio_in(lasi_dev, LASI_IRQ_UART_HPA), 7272727 / 16,
        serial_hd(0), DEVICE_BIG_ENDIAN);

    serial_mm_init(addr_space, translate(NULL, DINO_UART_HPA + 0x800), 0,
        qdev_get_gpio_in(dino_dev, DINO_IRQ_RS232INT), 7272727 / 16,
        serial_hd(1), DEVICE_BIG_ENDIAN);

    /* Parallel port */
    parallel_mm_init(addr_space, translate(NULL, LASI_LPT_HPA + 0x800), 0,
                     qdev_get_gpio_in(lasi_dev, LASI_IRQ_LAN_HPA),
                     parallel_hds[0]);

    /* PS/2 Keyboard/Mouse */
    dev = qdev_new(TYPE_LASIPS2);
    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
                       qdev_get_gpio_in(lasi_dev, LASI_IRQ_PS2KBD_HPA));
    memory_region_add_subregion(addr_space,
                                translate(NULL, LASI_PS2KBD_HPA),
                                sysbus_mmio_get_region(SYS_BUS_DEVICE(dev),
                                                       0));
    memory_region_add_subregion(addr_space,
                                translate(NULL, LASI_PS2KBD_HPA + 0x100),
                                sysbus_mmio_get_region(SYS_BUS_DEVICE(dev),
                                                       1));

    /* Add SCSI discs, NICs, graphics & load firmware */
    machine_HP_common_init_tail(machine, pci_bus, translate);
}

static AstroState *astro_init(void)
{
    DeviceState *dev;

    dev = qdev_new(TYPE_ASTRO_CHIP);
    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);

    return ASTRO_CHIP(dev);
}

/*
 * Create HP C3700 workstation
 */
static void machine_HP_C3700_init(MachineState *machine)
{
    PCIBus *pci_bus;
    AstroState *astro;
    DeviceState *astro_dev;
    MemoryRegion *addr_space = get_system_memory();
    TranslateFn *translate;

    /* Create CPUs and RAM.  */
    translate = machine_HP_common_init_cpus(machine);

    if (!hppa_is_pa20(&cpu[0]->env)) {
        error_report("The HP C3000 workstation requires a 64-bit CPU. "
                     "Use '-machine B160L' instead.");
        exit(1);
    }

    /* Init Astro and the Elroys (PCI host bus chips).  */
    astro = astro_init();
    astro_dev = DEVICE(astro);
    memory_region_add_subregion(addr_space, translate(NULL, ASTRO_HPA),
                                sysbus_mmio_get_region(
                                    SYS_BUS_DEVICE(astro_dev), 0));
    pci_bus = PCI_BUS(qdev_get_child_bus(DEVICE(astro->elroy[0]), "pci"));
    assert(pci_bus);

    /* Add SCSI discs, NICs, graphics & load firmware */
    machine_HP_common_init_tail(machine, pci_bus, translate);
}

static void hppa_machine_reset(MachineState *ms, ShutdownCause reason)
{
    unsigned int smp_cpus = ms->smp.cpus;
    int i;

    qemu_devices_reset(reason);

    /* Start all CPUs at the firmware entry point.
     *  Monarch CPU will initialize firmware, secondary CPUs
     *  will enter a small idle loop and wait for rendevouz. */
    for (i = 0; i < smp_cpus; i++) {
        CPUState *cs = CPU(cpu[i]);

        cpu_set_pc(cs, firmware_entry);
        cpu[i]->env.psw = PSW_Q;
        cpu[i]->env.gr[5] = CPU_HPA + i * 0x1000;

        cs->exception_index = -1;
        cs->halted = 0;
    }

    /* already initialized by machine_hppa_init()? */
    if (cpu[0]->env.gr[26] == ms->ram_size) {
        return;
    }

    cpu[0]->env.gr[26] = ms->ram_size;
    cpu[0]->env.gr[25] = 0; /* no firmware boot menu */
    cpu[0]->env.gr[24] = 'c';
    /* gr22/gr23 unused, no initrd while reboot. */
    cpu[0]->env.gr[21] = smp_cpus;
    /* tell firmware fw_cfg port */
    cpu[0]->env.gr[19] = FW_CFG_IO_BASE;
}

static void hppa_nmi(NMIState *n, int cpu_index, Error **errp)
{
    CPUState *cs;

    CPU_FOREACH(cs) {
        cpu_interrupt(cs, CPU_INTERRUPT_NMI);
    }
}

static void HP_B160L_machine_init_class_init(ObjectClass *oc, void *data)
{
    static const char * const valid_cpu_types[] = {
        TYPE_HPPA_CPU,
        NULL
    };
    MachineClass *mc = MACHINE_CLASS(oc);
    NMIClass *nc = NMI_CLASS(oc);

    mc->desc = "HP B160L workstation";
    mc->default_cpu_type = TYPE_HPPA_CPU;
    mc->valid_cpu_types = valid_cpu_types;
    mc->init = machine_HP_B160L_init;
    mc->reset = hppa_machine_reset;
    mc->block_default_type = IF_SCSI;
    mc->max_cpus = HPPA_MAX_CPUS;
    mc->default_cpus = 1;
    mc->is_default = true;
    mc->default_ram_size = 512 * MiB;
    mc->default_boot_order = "cd";
    mc->default_ram_id = "ram";
    mc->default_nic = "tulip";

    nc->nmi_monitor_handler = hppa_nmi;
}

static const TypeInfo HP_B160L_machine_init_typeinfo = {
    .name = MACHINE_TYPE_NAME("B160L"),
    .parent = TYPE_MACHINE,
    .class_init = HP_B160L_machine_init_class_init,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_NMI },
        { }
    },
};

static void HP_C3700_machine_init_class_init(ObjectClass *oc, void *data)
{
    static const char * const valid_cpu_types[] = {
        TYPE_HPPA64_CPU,
        NULL
    };
    MachineClass *mc = MACHINE_CLASS(oc);
    NMIClass *nc = NMI_CLASS(oc);

    mc->desc = "HP C3700 workstation";
    mc->default_cpu_type = TYPE_HPPA64_CPU;
    mc->valid_cpu_types = valid_cpu_types;
    mc->init = machine_HP_C3700_init;
    mc->reset = hppa_machine_reset;
    mc->block_default_type = IF_SCSI;
    mc->max_cpus = HPPA_MAX_CPUS;
    mc->default_cpus = 1;
    mc->is_default = false;
    mc->default_ram_size = 1024 * MiB;
    mc->default_boot_order = "cd";
    mc->default_ram_id = "ram";
    mc->default_nic = "tulip";

    nc->nmi_monitor_handler = hppa_nmi;
}

static const TypeInfo HP_C3700_machine_init_typeinfo = {
    .name = MACHINE_TYPE_NAME("C3700"),
    .parent = TYPE_MACHINE,
    .class_init = HP_C3700_machine_init_class_init,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_NMI },
        { }
    },
};

static void hppa_machine_init_register_types(void)
{
    type_register_static(&HP_B160L_machine_init_typeinfo);
    type_register_static(&HP_C3700_machine_init_typeinfo);
}

type_init(hppa_machine_init_register_types)
