/*
 * QEMU Alpha DP264/CLIPPER hardware system emulator.
 *
 * Choose CLIPPER IRQ mappings over, say, DP264, MONET, or WEBBRICK
 * variants because CLIPPER doesn't have an SMC669 SuperIO controller
 * that we need to emulate as well.
 */

#include "hw.h"
#include "elf.h"
#include "loader.h"
#include "boards.h"
#include "alpha_sys.h"
#include "sysemu.h"
#include "mc146818rtc.h"
#include "ide.h"
#include "i8254.h"
#include "serial.h"

#define MAX_IDE_BUS 2

static uint64_t cpu_alpha_superpage_to_phys(void *opaque, uint64_t addr)
{
    if (((addr >> 41) & 3) == 2) {
        addr &= 0xffffffffffull;
    }
    return addr;
}

/* Note that there are at least 3 viewpoints of IRQ numbers on Alpha systems.
    (0) The dev_irq_n lines into the cpu, which we totally ignore,
    (1) The DRIR lines in the typhoon chipset,
    (2) The "vector" aka mangled interrupt number reported by SRM PALcode,
    (3) The interrupt number assigned by the kernel.
   The following function is concerned with (1) only.  */

static int clipper_pci_map_irq(PCIDevice *d, int irq_num)
{
    int slot = d->devfn >> 3;

    assert(irq_num >= 0 && irq_num <= 3);

    return (slot + 1) * 4 + irq_num;
}

static void clipper_init(QEMUMachineInitArgs *args)
{
    ram_addr_t ram_size = args->ram_size;
    const char *cpu_model = args->cpu_model;
    const char *kernel_filename = args->kernel_filename;
    const char *kernel_cmdline = args->kernel_cmdline;
    const char *initrd_filename = args->initrd_filename;
    CPUAlphaState *cpus[4];
    PCIBus *pci_bus;
    ISABus *isa_bus;
    qemu_irq rtc_irq;
    long size, i;
    const char *palcode_filename;
    uint64_t palcode_entry, palcode_low, palcode_high;
    uint64_t kernel_entry, kernel_low, kernel_high;

    /* Create up to 4 cpus.  */
    memset(cpus, 0, sizeof(cpus));
    for (i = 0; i < smp_cpus; ++i) {
        cpus[i] = cpu_init(cpu_model ? cpu_model : "ev67");
    }

    cpus[0]->trap_arg0 = ram_size;
    cpus[0]->trap_arg1 = 0;
    cpus[0]->trap_arg2 = smp_cpus;

    /* Init the chipset.  */
    pci_bus = typhoon_init(ram_size, &isa_bus, &rtc_irq, cpus,
                           clipper_pci_map_irq);

    rtc_init(isa_bus, 1980, rtc_irq);
    pit_init(isa_bus, 0x40, 0, NULL);
    isa_create_simple(isa_bus, "i8042");

    /* VGA setup.  Don't bother loading the bios.  */
    pci_vga_init(pci_bus);

    /* Serial code setup.  */
    for (i = 0; i < MAX_SERIAL_PORTS; ++i) {
        if (serial_hds[i]) {
            serial_isa_init(isa_bus, i, serial_hds[i]);
        }
    }

    /* Network setup.  e1000 is good enough, failing Tulip support.  */
    for (i = 0; i < nb_nics; i++) {
        pci_nic_init_nofail(&nd_table[i], "e1000", NULL);
    }

    /* IDE disk setup.  */
    {
        DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
        ide_drive_get(hd, MAX_IDE_BUS);

        pci_cmd646_ide_init(pci_bus, hd, 0);
    }

    /* Load PALcode.  Given that this is not "real" cpu palcode,
       but one explicitly written for the emulation, we might as
       well load it directly from and ELF image.  */
    palcode_filename = (bios_name ? bios_name : "palcode-clipper");
    palcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, palcode_filename);
    if (palcode_filename == NULL) {
        hw_error("no palcode provided\n");
        exit(1);
    }
    size = load_elf(palcode_filename, cpu_alpha_superpage_to_phys,
                    NULL, &palcode_entry, &palcode_low, &palcode_high,
                    0, EM_ALPHA, 0);
    if (size < 0) {
        hw_error("could not load palcode '%s'\n", palcode_filename);
        exit(1);
    }

    /* Start all cpus at the PALcode RESET entry point.  */
    for (i = 0; i < smp_cpus; ++i) {
        cpus[i]->pal_mode = 1;
        cpus[i]->pc = palcode_entry;
        cpus[i]->palbr = palcode_entry;
    }

    /* Load a kernel.  */
    if (kernel_filename) {
        uint64_t param_offset;

        size = load_elf(kernel_filename, cpu_alpha_superpage_to_phys,
                        NULL, &kernel_entry, &kernel_low, &kernel_high,
                        0, EM_ALPHA, 0);
        if (size < 0) {
            hw_error("could not load kernel '%s'\n", kernel_filename);
            exit(1);
        }

        cpus[0]->trap_arg1 = kernel_entry;

        param_offset = kernel_low - 0x6000;

        if (kernel_cmdline) {
            pstrcpy_targphys("cmdline", param_offset, 0x100, kernel_cmdline);
        }

        if (initrd_filename) {
            long initrd_base, initrd_size;

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

            /* Put the initrd image as high in memory as possible.  */
            initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK;
            load_image_targphys(initrd_filename, initrd_base,
                                ram_size - initrd_base);

            stq_phys(param_offset + 0x100, initrd_base + 0xfffffc0000000000ULL);
            stq_phys(param_offset + 0x108, initrd_size);
        }
    }
}

static QEMUMachine clipper_machine = {
    .name = "clipper",
    .desc = "Alpha DP264/CLIPPER",
    .init = clipper_init,
    .max_cpus = 4,
    .is_default = 1,
};

static void clipper_machine_init(void)
{
    qemu_register_machine(&clipper_machine);
}

machine_init(clipper_machine_init);
