/*
 * 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/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;
    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;
    long i;
    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 (nd_table[0].used && enable_lasi_lan()) {
        lasi_82596_init(addr_space, translate(NULL, LASI_LAN_HPA),
                        qdev_get_gpio_in(lasi_dev, LASI_IRQ_LAN_HPA));
    }

    for (i = 0; i < nb_nics; i++) {
        if (!enable_lasi_lan()) {
            pci_nic_init_nofail(&nd_table[i], pci_bus, mc->default_nic, NULL);
        }
    }

    /* 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.  */
    firmware_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS,
                                       machine->firmware ?: "hppa-firmware.img");
    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)
