// Compatibility Support Module (CSM) for UEFI / EDK-II
//
// Copyright © 2013 Intel Corporation
//
// This file may be distributed under the terms of the GNU LGPLv3 license.

#include "bregs.h" // struct bregs
#include "config.h" // CONFIG_*
#include "e820map.h" // e820_add
#include "farptr.h" // MAKE_FLATPTR
#include "hw/pci.h" // pci_to_bdf
#include "hw/pcidevice.h" // pci_probe_devices
#include "hw/pic.h" // pic_irqmask_read
#include "malloc.h" // malloc_csm_preinit
#include "memmap.h" // SYMBOL
#include "output.h" // dprintf
#include "paravirt.h" // qemu_preinit
#include "stacks.h" // wait_threads
#include "std/acpi.h" // RSDP_SIGNATURE
#include "std/bda.h" // struct bios_data_area_s
#include "std/optionrom.h" // struct rom_header
#include "util.h" // copy_smbios

#define UINT8 u8
#define UINT16 u16
#define UINT32 u32
#include "std/LegacyBios.h"

struct rsdp_descriptor csm_rsdp VARFSEG __aligned(16);

EFI_COMPATIBILITY16_TABLE csm_compat_table VARFSEG __aligned(16) = {
    .Signature = 0x24454649,
    .TableChecksum = 0 /* Filled in by checkrom.py */,
    .TableLength = sizeof(csm_compat_table),
    .Compatibility16CallSegment = SEG_BIOS,
    .Compatibility16CallOffset = 0 /* Filled in by checkrom.py */,
    .OemIdStringPointer = (u32)"SeaBIOS",
    .AcpiRsdPtrPointer = (u32)&csm_rsdp,
};

EFI_TO_COMPATIBILITY16_INIT_TABLE *csm_init_table;
EFI_TO_COMPATIBILITY16_BOOT_TABLE *csm_boot_table;

static u16 PICMask = PIC_IRQMASK_DEFAULT;

extern void __csm_return(struct bregs *regs) __noreturn;

static void
csm_return(struct bregs *regs)
{
    u32 rommax = rom_get_max();

    dprintf(3, "handle_csm returning AX=%04x\n", regs->ax);

    csm_compat_table.UmaAddress = rommax;
    csm_compat_table.UmaSize = SYMBOL(final_readonly_start) - rommax;

    PICMask = pic_irqmask_read();
    __csm_return(regs);
}

static void
csm_maininit(struct bregs *regs)
{
    interface_init();
    pci_probe_devices();

    csm_compat_table.PnPInstallationCheckSegment = SEG_BIOS;
    csm_compat_table.PnPInstallationCheckOffset = get_pnp_offset();

    regs->ax = 0;

    csm_return(regs);
}

/* Legacy16InitializeYourself */
static void
handle_csm_0000(struct bregs *regs)
{
    qemu_preinit();

    dprintf(3, "Legacy16InitializeYourself table %04x:%04x\n", regs->es,
            regs->bx);

    csm_init_table = MAKE_FLATPTR(regs->es, regs->bx);

    dprintf(3, "BiosLessThan1MB %08x\n", csm_init_table->BiosLessThan1MB);
    dprintf(3, "HiPmmMemory     %08x\n", csm_init_table->HiPmmMemory);
    dprintf(3, "HiPmmMemorySize %08x\n", csm_init_table->HiPmmMemorySizeInBytes);
    dprintf(3, "ReverseThunk    %04x:%04x\n", csm_init_table->ReverseThunkCallSegment,
            csm_init_table->ReverseThunkCallOffset);
    dprintf(3, "NumE820Entries  %08x\n", csm_init_table->NumberE820Entries);
    dprintf(3, "OsMemoryAbove1M %08x\n", csm_init_table->OsMemoryAbove1Mb);
    dprintf(3, "ThunkStart      %08x\n", csm_init_table->ThunkStart);
    dprintf(3, "ThunkSize       %08x\n", csm_init_table->ThunkSizeInBytes);
    dprintf(3, "LoPmmMemory     %08x\n", csm_init_table->LowPmmMemory);
    dprintf(3, "LoPmmMemorySize %08x\n", csm_init_table->LowPmmMemorySizeInBytes);

    malloc_csm_preinit(csm_init_table->LowPmmMemory,
                       csm_init_table->LowPmmMemorySizeInBytes,
                       csm_init_table->HiPmmMemory,
                       csm_init_table->HiPmmMemorySizeInBytes);
    reloc_preinit(csm_maininit, regs);
}

/* Legacy16UpdateBbs */
static void
handle_csm_0001(struct bregs *regs)
{
    if (!CONFIG_BOOT) {
        regs->ax = 1;
        return;
    }

    dprintf(3, "Legacy16UpdateBbs table %04x:%04x\n", regs->es, regs->bx);

    csm_boot_table = MAKE_FLATPTR(regs->es, regs->bx);
    dprintf(3, "MajorVersion %04x\n", csm_boot_table->MajorVersion);
    dprintf(3, "MinorVersion %04x\n", csm_boot_table->MinorVersion);
    dprintf(3, "AcpiTable %08x\n", csm_boot_table->AcpiTable);
    dprintf(3, "SmbiosTable %08x\n", csm_boot_table->SmbiosTable);
    dprintf(3, "SmbiosTableLength %08x\n", csm_boot_table->SmbiosTableLength);
//    dprintf(3, "SioData %08x\n", csm_boot_table->SioData);
    dprintf(3, "DevicePathType %04x\n", csm_boot_table->DevicePathType);
    dprintf(3, "PciIrqMask %04x\n", csm_boot_table->PciIrqMask);
    dprintf(3, "NumberE820Entries %08x\n", csm_boot_table->NumberE820Entries);
//    dprintf(3, "HddInfo %08x\n", csm_boot_table->HddInfo);
    dprintf(3, "NumberBbsEntries %08x\n", csm_boot_table->NumberBbsEntries);
    dprintf(3, "BBsTable %08x\n", csm_boot_table->BbsTable);
    dprintf(3, "SmmTable %08x\n", csm_boot_table->SmmTable);
    dprintf(3, "OsMemoryAbove1Mb %08x\n", csm_boot_table->OsMemoryAbove1Mb);
    dprintf(3, "UnconventionalDeviceTable %08x\n", csm_boot_table->UnconventionalDeviceTable);

    regs->ax = 0;
}

/* PrepareToBoot */
static void
handle_csm_0002(struct bregs *regs)
{
    if (!CONFIG_BOOT) {
        regs->ax = 1;
        return;
    }

    dprintf(3, "PrepareToBoot table %04x:%04x\n", regs->es, regs->bx);

    struct e820entry *p = (void *)csm_compat_table.E820Pointer;
    int i;
    for (i=0; i < csm_compat_table.E820Length / sizeof(struct e820entry); i++)
        e820_add(p[i].start, p[i].size, p[i].type);

    if (csm_init_table->HiPmmMemorySizeInBytes > BUILD_MAX_HIGHTABLE) {
        u32 hi_pmm_end = csm_init_table->HiPmmMemory + csm_init_table->HiPmmMemorySizeInBytes;
        e820_add(hi_pmm_end - BUILD_MAX_HIGHTABLE, BUILD_MAX_HIGHTABLE, E820_RESERVED);
    }

    // For PCIBIOS 1ab10e
    if (csm_compat_table.IrqRoutingTablePointer &&
        csm_compat_table.IrqRoutingTableLength) {
        PirAddr = (void *)csm_compat_table.IrqRoutingTablePointer;
        dprintf(3, "CSM PIRQ table at %p\n", PirAddr);
    }

    // For find_resume_vector()... and find_acpi_features()
    if (csm_rsdp.signature == RSDP_SIGNATURE) {
        RsdpAddr = &csm_rsdp;
        dprintf(3, "CSM ACPI RSDP at %p\n", RsdpAddr);

        find_acpi_features();
    }

    // SMBIOS table needs to be copied into the f-seg
    // XX: OVMF doesn't seem to set SmbiosTableLength so don't check it
    if (csm_boot_table->SmbiosTable && !SMBiosAddr)
        copy_smbios((void *)csm_boot_table->SmbiosTable);

    // MPTABLE is just there; we don't care where.

    // EFI may have reinitialised the video using its *own* driver.
    enable_vga_console();

    // EFI fills this in for us. Zero it for now...
    struct bios_data_area_s *bda = get_bda_ptr();
    bda->hdcount = 0;

    thread_setup();
    mathcp_setup();
    timer_setup();
    clock_setup();
    device_hardware_setup();
    wait_threads();
    interactive_bootmenu();

    prepareboot();

    regs->ax = 0;
}

/* Boot */
static void
handle_csm_0003(struct bregs *regs)
{
    if (!CONFIG_BOOT) {
        regs->ax = 1;
        return;
    }

    dprintf(3, "Boot\n");

    startBoot();

    regs->ax = 1;
}

/* Legacy16DispatchOprom */
static void
handle_csm_0005(struct bregs *regs)
{
    EFI_DISPATCH_OPROM_TABLE *table = MAKE_FLATPTR(regs->es, regs->bx);
    struct rom_header *rom;
    u16 bdf;

    if (!CONFIG_OPTIONROMS) {
        regs->ax = 1;
        return;
    }

    dprintf(3, "Legacy16DispatchOprom rom %p\n", table);

    dprintf(3, "OpromSegment   %04x\n", table->OpromSegment);
    dprintf(3, "RuntimeSegment %04x\n", table->RuntimeSegment);
    dprintf(3, "PnPInstallationCheck %04x:%04x\n",
            table->PnPInstallationCheckSegment,
            table->PnPInstallationCheckOffset);
    dprintf(3, "RuntimeSegment %04x\n", table->RuntimeSegment);

    rom = MAKE_FLATPTR(table->OpromSegment, 0);
    bdf = pci_bus_devfn_to_bdf(table->PciBus, table->PciDeviceFunction);

    rom_reserve(rom->size * 512);

    // XX PnP seg/ofs should never be other than default
    callrom(rom, bdf);

    rom_confirm(rom->size * 512);

    regs->bx = 0; // FIXME
    regs->ax = 0;
}

/* Legacy16GetTableAddress */
static void
handle_csm_0006(struct bregs *regs)
{
    u16 size = regs->cx;
    u16 align = regs->dx;
    u16 region = regs->bx; // (1 for F000 seg, 2 for E000 seg, 0 for either)
    void *chunk = NULL;

    dprintf(3, "Legacy16GetTableAddress size %x align %x region %d\n",
        size, align, region);

    if (!region)
        region = 3;

    // DX = Required address alignment. Bit mapped.
    // First non-zero bit from the right is the alignment.*/
    if (align) {
        align = 1 << __ffs(align);
        if (align < MALLOC_MIN_ALIGN)
            align = MALLOC_MIN_ALIGN;
    } else {
        align = MALLOC_MIN_ALIGN;
    }

    if (region & 2)
        chunk = _malloc(&ZoneLow, size, align);
    if (!chunk && (region & 1))
        chunk = _malloc(&ZoneFSeg, size, align);

    dprintf(3, "Legacy16GetTableAddress size %x align %x region %d yields %p\n",
        size, align, region, chunk);
    if (chunk) {
        regs->ds = FLATPTR_TO_SEG(chunk);
        regs->bx = FLATPTR_TO_OFFSET(chunk);
        regs->ax = 0;
    } else {
        regs->ax = 1;
    }
}

void VISIBLE32INIT
handle_csm(struct bregs *regs)
{
    ASSERT32FLAT();

    if (!CONFIG_CSM)
        return;

    dprintf(3, "handle_csm regs %p AX=%04x\n", regs, regs->ax);

    code_mutable_preinit();
    pic_irqmask_write(PICMask);

    switch(regs->ax) {
    case 0000: handle_csm_0000(regs); break;
    case 0001: handle_csm_0001(regs); break;
    case 0002: handle_csm_0002(regs); break;
    case 0003: handle_csm_0003(regs); break;
//    case 0004: handle_csm_0004(regs); break;
    case 0005: handle_csm_0005(regs); break;
    case 0006: handle_csm_0006(regs); break;
//    case 0007: handle_csm_0007(regs); break;
//    case 0008: hamdle_csm_0008(regs); break;
    default: regs->al = 1;
    }

    csm_return(regs);
}

static int csm_prio_to_seabios(u16 csm_prio)
{
    switch (csm_prio) {
    case BBS_DO_NOT_BOOT_FROM:
    case BBS_IGNORE_ENTRY:
        return -1;

    case BBS_LOWEST_PRIORITY:
    case BBS_UNPRIORITIZED_ENTRY:
    default:
        // SeaBIOS default priorities start at 1, with 0 being used for
        // an item explicitly selected from interactive_bootmenu().
        // As in find_prio(), add 1 to the value being returned.
        return csm_prio + 1;
    }
}

int csm_bootprio_ata(struct pci_device *pci, int chanid, int slave)
{
    if (!csm_boot_table)
        return -1;
    BBS_TABLE *bbs = (void *)csm_boot_table->BbsTable;
    int index = 1 + (chanid * 2) + slave;
    dprintf(3, "CSM bootprio for ATA%d,%d (index %d) is %d\n", chanid, slave,
            index, bbs[index].BootPriority);
    return csm_prio_to_seabios(bbs[index].BootPriority);
}

int csm_bootprio_fdc(struct pci_device *pci, int port, int fdid)
{
    if (!csm_boot_table)
        return -1;
    BBS_TABLE *bbs = (void *)csm_boot_table->BbsTable;
    dprintf(3, "CSM bootprio for FDC is %d\n", bbs[0].BootPriority);
    return csm_prio_to_seabios(bbs[0].BootPriority);
}

int csm_bootprio_pci(struct pci_device *pci)
{
    if (!csm_boot_table)
        return -1;
    BBS_TABLE *bbs = (void *)csm_boot_table->BbsTable;
    int i;

    for (i = 5; i < csm_boot_table->NumberBbsEntries; i++) {
        if (pci->bdf == pci_to_bdf(bbs[i].Bus, bbs[i].Device, bbs[i].Function)) {
            dprintf(3, "CSM bootprio for PCI(%d,%d,%d) is %d\n", bbs[i].Bus,
                    bbs[i].Device, bbs[i].Function, bbs[i].BootPriority);
            return csm_prio_to_seabios(bbs[i].BootPriority);
        }
    }
    return -1;
}
