/*
 * QEMU HPPA hardware system emulator.
 * Copyright 2018 Helge Deller <deller@gmx.de>
 */

#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/pci/pci.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 6 /* require at least this fw version */

#define HPA_POWER_BUTTON (FIRMWARE_END - 0x10)

#define enable_lasi_lan()       0


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,
                          /* qemu_allocate_irq(dino_set_isa_irq, s, 0)); */
                          NULL);
    isa_bus_irqs(isa_bus, isa_irqs);

    return isa_bus;
}

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)
{
    FWCfgState *fw_cfg;
    uint64_t val;

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

    val = cpu_to_le64(HPA_POWER_BUTTON);
    fw_cfg_add_file(fw_cfg, "/etc/power-button-addr",
                    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);

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

static void machine_hppa_init(MachineState *machine)
{
    const char *kernel_filename = machine->kernel_filename;
    const char *kernel_cmdline = machine->kernel_cmdline;
    const char *initrd_filename = machine->initrd_filename;
    DeviceState *dev, *dino_dev, *lasi_dev;
    PCIBus *pci_bus;
    ISABus *isa_bus;
    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;
    MemoryRegion *cpu_region;
    long i;
    unsigned int smp_cpus = machine->smp.cpus;
    SysBusDevice *s;

    /* Create CPUs.  */
    for (i = 0; i < smp_cpus; i++) {
        char *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);
    }

    /* 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);


    /* 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. */
    isa_bus = hppa_isa_bus();
    assert(isa_bus);

    /* Realtime clock, used by firmware for PDC_TOD call. */
    mc146818_rtc_init(isa_bus, 2000, NULL);

    /* 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]);

    /* fw_cfg configuration interface */
    create_fw_cfg(machine);

    /* 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, "tulip", NULL);
        }
    }

    /* 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));

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

    /* 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;
}

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 look and wait for rendevouz. */
    for (i = 0; i < smp_cpus; i++) {
        cpu_set_pc(CPU(cpu[i]), firmware_entry);
        cpu[i]->env.gr[5] = CPU_HPA + i * 0x1000;
    }

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

    mc->desc = "HPPA B160L machine";
    mc->default_cpu_type = TYPE_HPPA_CPU;
    mc->init = machine_hppa_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";

    nc->nmi_monitor_handler = hppa_nmi;
}

static const TypeInfo hppa_machine_init_typeinfo = {
    .name = MACHINE_TYPE_NAME("hppa"),
    .parent = TYPE_MACHINE,
    .class_init = hppa_machine_init_class_init,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_NMI },
        { }
    },
};

static void hppa_machine_init_register_types(void)
{
    type_register_static(&hppa_machine_init_typeinfo);
}

type_init(hppa_machine_init_register_types)
