/*
 * 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 10 /* require at least this fw version */

#define HPA_POWER_BUTTON (FIRMWARE_END - 0x10)

#define enable_lasi_lan()       0

static DeviceState *lasi_dev;

static void hppa_powerdown_req(Notifier *n, void *opaque)
{
    hwaddr soft_power_reg = HPA_POWER_BUTTON;
    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(void)
{
    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(), IDE_HPA,
                                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,
    },
};


static uint64_t cpu_hppa_to_phys(void *opaque, uint64_t addr)
{
    addr &= (0x10000000 - 1);
    return 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)
{
    FWCfgState *fw_cfg;
    uint64_t val;
    const char qemu_version[] = QEMU_VERSION;
    MachineClass *mc = MACHINE_GET_CLASS(ms);
    int len;

    fw_cfg = fw_cfg_init_mem(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 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 - HPPA_BTLB_ENTRIES);
    fw_cfg_add_file(fw_cfg, "/etc/cpu/tlb_entries",
                    g_memdup(&val, sizeof(val)), sizeof(val));

    val = cpu_to_le64(HPPA_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(HPA_POWER_BUTTON);
    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 void machine_HP_common_init_cpus(MachineState *machine)
{
    MemoryRegion *addr_space = get_system_memory();
    MemoryRegion *cpu_region;
    long i;
    unsigned int smp_cpus = machine->smp.cpus;
    char *name;

    /* Create CPUs.  */
    for (i = 0; i < smp_cpus; i++) {
        name = g_strdup_printf("cpu%ld-io-eir", i);
        cpu[i] = HPPA_CPU(cpu_create(machine->cpu_type));

        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, CPU_HPA + i * 0x1000,
                                    cpu_region);
        g_free(name);
    }

    /* 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, CPU_HPA + 16, cpu_region);

    /* Main memory region. */
    if (machine->ram_size > 3 * GiB) {
        error_report("RAM size is currently restricted to 3GB");
        exit(EXIT_FAILURE);
    }
    memory_region_add_subregion_overlap(addr_space, 0, machine->ram, -1);
}

/*
 * Last creation step: Add SCSI discs, NICs, graphics & load firmware
 */
static void machine_HP_common_init_tail(MachineState *machine, PCIBus *pci_bus)
{
    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. */
    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, LASI_GFX_HPA);
        sysbus_mmio_map(s, 1, ARTIST_FB_ADDR);
    }

    /* Network setup. */
    if (enable_lasi_lan()) {
        lasi_82596_init(addr_space, 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 (!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);

    /* 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, NULL, NULL,
                    &firmware_entry, &firmware_low, &firmware_high, NULL,
                    true, EM_PARISC, 0, 0);

    /* Unfortunately, load_elf sign-extends reading elf32.  */
    firmware_entry = (target_ureg)firmware_entry;
    firmware_low = (target_ureg)firmware_low;
    firmware_high = (target_ureg)firmware_high;

    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 < FIRMWARE_START || firmware_high >= 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, FIRMWARE_START, rom_region);

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

        /* Unfortunately, load_elf sign-extends reading elf32.  */
        kernel_entry = (target_ureg) cpu_hppa_to_phys(NULL, kernel_entry);
        kernel_low = (target_ureg)kernel_low;
        kernel_high = (target_ureg)kernel_high;

        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();
    ISABus *isa_bus;
    PCIBus *pci_bus;

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

    /* Init Lasi chip */
    lasi_dev = DEVICE(lasi_init());
    memory_region_add_subregion(addr_space, 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, 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();
    assert(isa_bus);

    /* Serial ports: Lasi and Dino use a 7.272727 MHz clock. */
    serial_mm_init(addr_space, 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, 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, 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, LASI_PS2KBD_HPA,
                                sysbus_mmio_get_region(SYS_BUS_DEVICE(dev),
                                                       0));
    memory_region_add_subregion(addr_space, 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);
}

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

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

    /* Init Astro and the Elroys (PCI host bus chips).  */
    astro = astro_init();
    astro_dev = DEVICE(astro);
    memory_region_add_subregion(addr_space, 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);
}

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;

        /* clear any existing TLB and BTLB entries */
        memset(cpu[i]->env.tlb, 0, sizeof(cpu[i]->env.tlb));
        cpu[i]->env.tlb_last = HPPA_BTLB_ENTRIES;
    }

    /* 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)
{
    MachineClass *mc = MACHINE_CLASS(oc);
    NMIClass *nc = NMI_CLASS(oc);

    mc->desc = "HP B160L workstation";
    mc->default_cpu_type = TYPE_HPPA_CPU;
    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)
{
    MachineClass *mc = MACHINE_CLASS(oc);
    NMIClass *nc = NMI_CLASS(oc);

    mc->desc = "HP C3700 workstation";
    mc->default_cpu_type = TYPE_HPPA_CPU;
    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)
