// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "osboot.h"

#include <efi/protocol/graphics-output.h>
#include <efi/runtime-services.h>

#include <cmdline.h>
#include <inttypes.h>
#include <stdio.h>
#include <string.h>
#include <xefi.h>

#include <zircon/boot/image.h>
#include <zircon/pixelformat.h>


static efi_guid zircon_guid = ZIRCON_VENDOR_GUID;
static char16_t crashlog_name[] = ZIRCON_CRASHLOG_EFIVAR;

static size_t get_last_crashlog(efi_system_table* sys, void* ptr, size_t max) {
    efi_runtime_services* rs = sys->RuntimeServices;

    uint32_t attr = ZIRCON_CRASHLOG_EFIATTR;
    size_t sz = max;
    efi_status r = rs->GetVariable(crashlog_name, &zircon_guid, &attr, &sz, ptr);
    if (r == EFI_SUCCESS) {
        // Erase it
        rs->SetVariable(crashlog_name, &zircon_guid, ZIRCON_CRASHLOG_EFIATTR, 0, NULL);
    } else {
        sz = 0;
    }
    return sz;
}

static unsigned char scratch[32768];

static void start_zircon(uint64_t entry, void* bootdata) {
#if __x86_64__
    // ebx = 0, ebp = 0, edi = 0, esi = bootdata
    __asm__ __volatile__(
        "movl $0, %%ebp \n"
        "cli \n"
        "jmp *%[entry] \n" ::[entry] "a"(entry),
        [bootdata] "S"(bootdata),
        "b"(0), "D"(0));
#elif defined(__aarch64__)
    __asm__("mov x0, %[zbi]\n"          // Argument register.
            "mov x29, xzr\n"            // Clear FP.
            "mov x30, xzr\n"            // Clear LR.
            "br %[entry]\n"
            :: [entry] "r"(entry), [zbi] "r"(bootdata) : "x0", "x29", "x30");
#else
# error "add code for other arches here"
#endif
    __builtin_unreachable();
}

static int add_bootdata(void** ptr, size_t* avail,
                        zbi_header_t* bd, void* data) {
    size_t len = ZBI_ALIGN(bd->length);
    if ((sizeof(zbi_header_t) + len) > *avail) {
        printf("boot: no room for bootdata type=%08x size=%08x\n",
               bd->type, bd->length);
        return -1;
    }
    bd->flags |= ZBI_FLAG_VERSION;
    bd->reserved0 = 0;
    bd->reserved1 = 0;
    bd->magic = ZBI_ITEM_MAGIC;
    bd->crc32 = ZBI_ITEM_NO_CRC32;

    memcpy(*ptr, bd, sizeof(zbi_header_t));
    memcpy((*ptr) + sizeof(zbi_header_t), data, len);
    len += sizeof(zbi_header_t);
    (*ptr) += len;
    (*avail) -= len;

    return 0;
}

size_t image_getsize(void* image, size_t sz) {
    if (sz < sizeof(zircon_kernel_t)) {
        return 0;
    }
    zircon_kernel_t* kernel = image;
    if ((kernel->hdr_file.type != ZBI_TYPE_CONTAINER) ||
        (kernel->hdr_file.magic != ZBI_ITEM_MAGIC) ||
        (kernel->hdr_kernel.type != ZBI_TYPE_KERNEL_X64) ||
        (kernel->hdr_kernel.magic != ZBI_ITEM_MAGIC)) {
        return 0;
    }
    return ZBI_ALIGN(kernel->hdr_file.length) + sizeof(zbi_header_t);
}

static int header_check(void* image, size_t sz, uint64_t* _entry,
                        size_t* _flen, size_t* _klen) {
    zbi_header_t* bd = image;
    size_t flen, klen;
    uint64_t entry;

    if (!(bd->flags & ZBI_FLAG_VERSION)) {
        printf("boot: v1 bootdata kernel no longer supported\n");
        return -1;
    }
    zircon_kernel_t* kernel = image;
    if ((sz < sizeof(zircon_kernel_t)) ||
        (kernel->hdr_kernel.type != ZBI_TYPE_KERNEL_X64) ||
        ((kernel->hdr_kernel.flags & ZBI_FLAG_VERSION) == 0)) {
        printf("boot: invalid zircon kernel header\n");
        return -1;
    }
    flen = ZBI_ALIGN(kernel->hdr_file.length);
    klen = ZBI_ALIGN(kernel->hdr_kernel.length);
    entry = kernel->data_kernel.entry;
    if (flen > (sz - sizeof(zbi_header_t))) {
        printf("boot: invalid zircon kernel header (bad flen)\n");
        return -1;
    }

    if (klen > (sz - (sizeof(zbi_header_t) * 2))) {
        printf("boot: invalid zircon kernel header (bad klen)\n");
        return -1;
    }
    if (_entry) {
        *_entry = entry;
    }
    if (_flen) {
        *_flen = flen;
        *_klen = klen;
    }

    return 0;
}

static int item_check(zbi_header_t* bd, size_t sz) {
    if (sz > 0x7FFFFFFF) {
        // disallow 2GB+ items to avoid wrap on align issues
        return -1;
    }
    if ((bd->magic != ZBI_ITEM_MAGIC) ||
        ((bd->flags & ZBI_FLAG_VERSION) == 0) ||
        (ZBI_ALIGN(bd->length) > sz)) {
        return -1;
    } else {
        return 0;
    }
}

//TODO: verify crc32 when present
unsigned identify_image(void* image, size_t sz) {
    if (sz == 0) {
        return IMAGE_EMPTY;
    }
    if (sz < sizeof(zbi_header_t)) {
        printf("image is too small\n");
        return IMAGE_INVALID;
    }
    zbi_header_t* bd = image;
    sz -= sizeof(zbi_header_t);
    if ((bd->type != ZBI_TYPE_CONTAINER) ||
        item_check(bd, sz)) {
        printf("image has invalid header\n");
        return IMAGE_INVALID;
    }
    image += sizeof(zbi_header_t);
    unsigned n = 0;
    unsigned r = 0;
    while (sz > sizeof(zbi_header_t)) {
        bd = image;
        sz -= sizeof(zbi_header_t);
        if (item_check(image, sz)) {
            printf("image has invalid bootitem\n");
            return IMAGE_INVALID;
        }
        if (ZBI_IS_KERNEL_BOOTITEM(bd->type)) {
            if (n != 0) {
                printf("image has kernel in middle\n");
                return IMAGE_INVALID;
            } else {
                r = IMAGE_KERNEL;
            }
        }
        if (bd->type == ZBI_TYPE_STORAGE_BOOTFS) {
            if ((r == IMAGE_KERNEL) || (r == IMAGE_COMBO)) {
                r = IMAGE_COMBO;
            } else {
                r = IMAGE_RAMDISK;
            }
        }
        image += ZBI_ALIGN(bd->length) + sizeof(zbi_header_t);
        sz -= ZBI_ALIGN(bd->length);
        n++;
    }

    return r;
}

int boot_zircon(efi_handle img, efi_system_table* sys,
                 void* image, size_t isz, void* ramdisk, size_t rsz,
                 void* cmdline, size_t csz) {

    efi_boot_services* bs = sys->BootServices;
    uint64_t entry;

    if (header_check(image, isz, &entry, NULL, NULL)) {
        return -1;
    }
    if ((ramdisk == NULL) || (rsz < sizeof(zbi_header_t))) {
        printf("boot: ramdisk missing or too small\n");
        return -1;
    }
    if (isz > kernel_zone_size) {
        printf("boot: kernel image too large\n");
        return -1;
    }

    zbi_header_t* hdr0 = ramdisk;
    if ((hdr0->type != ZBI_TYPE_CONTAINER) ||
        (hdr0->extra != ZBI_CONTAINER_MAGIC) ||
        !(hdr0->flags & ZBI_FLAG_VERSION)) {
        printf("boot: ramdisk has invalid bootdata header\n");
        return -1;
    }

    if ((hdr0->length > (rsz - sizeof(zbi_header_t)))) {
        printf("boot: ramdisk has invalid bootdata length\n");
        return -1;
    }

    // osboot ensures we have FRONT_BYTES ahead of the
    // ramdisk to prepend our own bootdata items.
    void* bptr = ramdisk - FRONT_BYTES;
    size_t blen = FRONT_BYTES;

    // We create a new container header of the same size
    // as the one at the start of the ramdisk
    zbi_header_t hdr = ZBI_CONTAINER_HEADER(hdr0->length + FRONT_BYTES);
    memcpy(bptr, &hdr, sizeof(hdr));
    bptr += sizeof(hdr);

    // pass kernel commandline
    hdr.type = ZBI_TYPE_CMDLINE;
    hdr.length = csz;
    hdr.extra = 0;
    hdr.flags = ZBI_FLAG_VERSION;
    if (add_bootdata(&bptr, &blen, &hdr, cmdline)) {
        return -1;
    }

    // pass ACPI root pointer
    uint64_t rsdp = find_acpi_root(img, sys);
    if (rsdp != 0) {
        hdr.type = ZBI_TYPE_ACPI_RSDP;
        hdr.length = sizeof(rsdp);
        if (add_bootdata(&bptr, &blen, &hdr, &rsdp)) {
            return -1;
        }
    }

    // pass SMBIOS entry point pointer
    uint64_t smbios = find_smbios(img, sys);
    if (smbios != 0) {
        hdr.type = ZBI_TYPE_SMBIOS;
        hdr.length = sizeof(smbios);
        if (add_bootdata(&bptr, &blen, &hdr, &smbios)) {
            return -1;
        }
    }

    // pass EFI system table
    uint64_t addr = (uintptr_t) sys;
    hdr.type = ZBI_TYPE_EFI_SYSTEM_TABLE;
    hdr.length = sizeof(sys);
    if (add_bootdata(&bptr, &blen, &hdr, &addr)) {
        return -1;
    }

    // pass framebuffer data
    efi_graphics_output_protocol* gop = NULL;
    bs->LocateProtocol(&GraphicsOutputProtocol, NULL, (void**)&gop);
    if (gop) {
        zbi_swfb_t fb = {
            .base = gop->Mode->FrameBufferBase,
            .width = gop->Mode->Info->HorizontalResolution,
            .height = gop->Mode->Info->VerticalResolution,
            .stride = gop->Mode->Info->PixelsPerScanLine,
            .format = get_zx_pixel_format(gop),
        };
        hdr.type = ZBI_TYPE_FRAMEBUFFER;
        hdr.length = sizeof(fb);
        if (add_bootdata(&bptr, &blen, &hdr, &fb)) {
            return -1;
        }
    }

    memcpy((void*)kernel_zone_base, image, isz);

    // Obtain the system memory map
    size_t msize, dsize;
    for (int attempts = 0;;attempts++) {
        efi_memory_descriptor* mmap = (efi_memory_descriptor*) (scratch + sizeof(uint64_t));
        uint32_t dversion = 0;
        size_t mkey = 0;
        msize = sizeof(scratch) - sizeof(uint64_t);
        dsize = 0;
        efi_status r = sys->BootServices->GetMemoryMap(&msize, mmap, &mkey, &dsize, &dversion);
        if (r != EFI_SUCCESS) {
            printf("boot: cannot GetMemoryMap()\n");
            goto fail;
        }

        r = sys->BootServices->ExitBootServices(img, mkey);
        if (r == EFI_SUCCESS) {
            break;
        }
        if (r == EFI_INVALID_PARAMETER) {
            if (attempts > 0) {
                printf("boot: cannot ExitBootServices(): %s\n", xefi_strerror(r));
                goto fail;
            }
            // Attempting to exit may cause us to have to re-grab the
            // memory map, but if it happens more than once something's
            // broken.
            continue;
        }
        printf("boot: cannot ExitBootServices(): %s\n", xefi_strerror(r));
        goto fail;
    }
    memcpy(scratch, &dsize, sizeof(uint64_t));

    // install memory map
    hdr.type = ZBI_TYPE_EFI_MEMORY_MAP;
    hdr.length = msize + sizeof(uint64_t);
    if (add_bootdata(&bptr, &blen, &hdr, scratch)) {
        goto fail;
    }

    // obtain the last crashlog if we can
    size_t sz = get_last_crashlog(sys, scratch, 4096);
    if (sz > 0) {
        hdr.type = ZBI_TYPE_CRASHLOG;
        hdr.length = sz;
        add_bootdata(&bptr, &blen, &hdr, scratch);
    }

    // fill the remaining gap between pre-data and ramdisk image
    if ((blen < sizeof(hdr)) || (blen & 7)) {
        goto fail;
    }
    hdr.type = ZBI_TYPE_DISCARD;
    hdr.length = blen - sizeof(hdr);
    hdr.flags = ZBI_FLAG_VERSION;
    memcpy(bptr, &hdr, sizeof(hdr));

    // jump to the kernel
    start_zircon(entry, ramdisk - FRONT_BYTES);

fail:
    return -1;
}

static char cmdline[CMDLINE_MAX];

int zedboot(efi_handle img, efi_system_table* sys,
            void* image, size_t sz) {

    size_t flen, klen;
    if (header_check(image, sz, NULL, &flen, &klen)) {
        return -1;
    }

    // ramdisk portion is file - headers - kernel len
    uint32_t rlen = flen - sizeof(zbi_header_t) - klen;
    uint32_t roff = (sizeof(zbi_header_t) * 2) + klen;
    if (rlen == 0) {
        printf("zedboot: no ramdisk?!\n");
        return -1;
    }

    // allocate space for the ramdisk
    efi_boot_services* bs = sys->BootServices;
    size_t rsz = rlen + sizeof(zbi_header_t) + FRONT_BYTES;
    size_t pages = BYTES_TO_PAGES(rsz);
    void* ramdisk = NULL;
    efi_status r = bs->AllocatePages(AllocateAnyPages, EfiLoaderData, pages,
                                     (efi_physical_addr*)&ramdisk);
    if (r) {
        printf("zedboot: cannot allocate ramdisk buffer\n");
        return -1;
    }

    ramdisk += FRONT_BYTES;
    *(zbi_header_t*)ramdisk = (zbi_header_t)ZBI_CONTAINER_HEADER(rlen);
    memcpy(ramdisk + sizeof(zbi_header_t), image + roff, rlen);
    rlen += sizeof(zbi_header_t);

    printf("ramdisk @ %p\n", ramdisk);

    size_t csz = cmdline_to_string(cmdline, sizeof(cmdline));

    // shrink original image header to include only the kernel
    zircon_kernel_t* kernel = image;
    kernel->hdr_file.length = sizeof(zbi_header_t) + klen;

    return boot_zircon(img, sys, image, roff, ramdisk, rlen, cmdline, csz);
}

int boot_kernel(efi_handle img, efi_system_table* sys,
                void* image, size_t sz,
                void* ramdisk, size_t rsz) {

    size_t csz = cmdline_to_string(cmdline, sizeof(cmdline));

    zbi_header_t* bd = image;
    if ((bd->type == ZBI_TYPE_CONTAINER) &&
        (bd->extra == ZBI_CONTAINER_MAGIC)) {
        return boot_zircon(img, sys, image, sz, ramdisk, rsz, cmdline, csz);
    } else {
        return -1;
    }
}
