/*
 * Copyright 2019, Data61
 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
 * ABN 41 687 119 230.
 *
 * This software may be distributed and modified according to the terms of
 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
 * See "LICENSE_BSD2.txt" for details.
 *
 * @TAG(DATA61_BSD)
 */

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include <sel4/sel4.h>

#include <sel4vm/guest_vm.h>
#include <sel4vm/guest_ram.h>
#include <sel4vm/guest_memory.h>

#include "guest_memory_map.h"

struct guest_mem_touch_params {
    void *data;
    size_t size;
    size_t offset;
    uintptr_t current_addr;
    vm_t *vm;
    ram_touch_callback_fn touch_fn;
};

static int push_guest_ram_region(vm_mem_t *guest_memory, uintptr_t start, size_t size, int allocated)
{
    int last_region = guest_memory->num_ram_regions;
    if (size == 0) {
        return -1;
    }
    vm_ram_region_t *extended_regions = realloc(guest_memory->ram_regions, sizeof(vm_ram_region_t) * (last_region + 1));
    if (extended_regions == NULL) {
        return -1;
    }
    guest_memory->ram_regions = extended_regions;

    guest_memory->ram_regions[last_region].start = start;
    guest_memory->ram_regions[last_region].size = size;
    guest_memory->ram_regions[last_region].allocated = allocated;
    guest_memory->num_ram_regions++;
    return 0;
}

static int ram_region_cmp(const void *a, const void *b)
{
    const vm_ram_region_t *aa = a;
    const vm_ram_region_t *bb = b;
    return aa->start - bb->start;
}

static void sort_guest_ram_regions(vm_mem_t *guest_memory)
{
    qsort(guest_memory->ram_regions, guest_memory->num_ram_regions, sizeof(vm_ram_region_t), ram_region_cmp);
}

static void guest_ram_remove_region(vm_mem_t *guest_memory, int region)
{
    if (region >= guest_memory->num_ram_regions) {
        return;
    }
    guest_memory->num_ram_regions--;
    memmove(&guest_memory->ram_regions[region], &guest_memory->ram_regions[region + 1],
            sizeof(vm_ram_region_t) * (guest_memory->num_ram_regions - region));
    /* realloc it smaller */
    guest_memory->ram_regions = realloc(guest_memory->ram_regions, sizeof(vm_ram_region_t) * guest_memory->num_ram_regions);
}

static void collapse_guest_ram_regions(vm_mem_t *guest_memory)
{
    int i;
    for (i = 1; i < guest_memory->num_ram_regions;) {
        /* Only collapse regions with the same allocation flag that are contiguous */
        if (guest_memory->ram_regions[i - 1].allocated == guest_memory->ram_regions[i].allocated &&
            guest_memory->ram_regions[i - 1].start + guest_memory->ram_regions[i - 1].size == guest_memory->ram_regions[i].start) {

            guest_memory->ram_regions[i - 1].size += guest_memory->ram_regions[i].size;
            guest_ram_remove_region(guest_memory, i);
        } else {
            /* We are satisified that this entry cannot be merged. So now we
             * move onto the next one */
            i++;
        }
    }
}

static int expand_guest_ram_region(vm_t *vm, uintptr_t start, size_t bytes)
{
    int err;
    vm_mem_t *guest_memory = &vm->mem;
    /* blindly put a new region at the end */
    err = push_guest_ram_region(guest_memory, start, bytes, 0);
    if (err) {
        ZF_LOGE("Failed to expand guest ram region");
        return err;
    }
    /* sort the region we just added */
    sort_guest_ram_regions(guest_memory);
    /* collapse any contiguous regions */
    collapse_guest_ram_regions(guest_memory);
    return 0;
}

static bool is_ram_region(vm_t *vm, uintptr_t addr, size_t size)
{
    vm_mem_t *guest_memory = &vm->mem;
    for (int i = 0; i < guest_memory->num_ram_regions; i++) {
        if (guest_memory->ram_regions[i].start <= addr &&
            guest_memory->ram_regions[i].start + guest_memory->ram_regions[i].size >= addr + size) {
            /* We are within a ram region*/
            return true;
        }
    }
    return false;
}

static memory_fault_result_t default_ram_fault_callback(vm_t *vm, vm_vcpu_t *vcpu, uintptr_t fault_addr,
                                                        size_t fault_length, void *cookie)
{
    /* We don't handle RAM faults by default unless the callback is specifically overrided, hence we fail here */
    ZF_LOGE("ERROR: UNHANDLED RAM FAULT");
    return FAULT_ERROR;
}

/* Helpers for use with touch below */
int vm_guest_ram_read_callback(vm_t *vm, uintptr_t addr, void *vaddr, size_t size, size_t offset, void *buf)
{
    memcpy(buf, vaddr, size);
    return 0;
}

int vm_guest_ram_write_callback(vm_t *vm, uintptr_t addr, void *vaddr, size_t size, size_t offset, void *buf)
{
    memcpy(vaddr, buf, size);
    return 0;
}

static int touch_access_callback(void *access_addr, void *vaddr, void *cookie)
{
    struct guest_mem_touch_params *guest_touch = (struct guest_mem_touch_params *)cookie;
    uintptr_t vmm_addr = (uintptr_t)vaddr;
    uintptr_t vm_addr = (uintptr_t)access_addr;
    return guest_touch->touch_fn(guest_touch->vm, vm_addr,
                                 (void *)(vmm_addr + (guest_touch->current_addr - vm_addr)),
                                 guest_touch->size, guest_touch->offset, guest_touch->data);
}

int vm_ram_touch(vm_t *vm, uintptr_t addr, size_t size, ram_touch_callback_fn touch_callback, void *cookie)
{
    struct guest_mem_touch_params access_cookie;
    uintptr_t current_addr;
    uintptr_t next_addr;
    uintptr_t end_addr = (uintptr_t)(addr + size);
    if (!is_ram_region(vm, addr, size)) {
        ZF_LOGE("Failed to touch ram region: Not registered RAM region");
        return -1;
    }
    access_cookie.touch_fn = touch_callback;
    access_cookie.data = cookie;
    access_cookie.vm = vm;
    for (current_addr = addr; current_addr < end_addr; current_addr = next_addr) {
        uintptr_t current_aligned = PAGE_ALIGN_4K(current_addr);
        uintptr_t next_page_start = current_aligned + PAGE_SIZE_4K;
        next_addr = MIN(end_addr, next_page_start);
        access_cookie.size = next_addr - current_addr;
        access_cookie.offset = current_addr - addr;
        access_cookie.current_addr = current_addr;
        int result = vspace_access_page_with_callback(&vm->mem.vm_vspace, &vm->mem.vmm_vspace, (void *)current_aligned,
                                                      seL4_PageBits, seL4_AllRights, 1, touch_access_callback, &access_cookie);
        if (result) {
            return result;
        }
    }
    return 0;
}

int vm_ram_find_largest_free_region(vm_t *vm, uintptr_t *addr, size_t *size)
{
    vm_mem_t *guest_memory = &vm->mem;
    int largest = -1;
    int i;
    /* find a first region */
    for (i = 0; i < guest_memory->num_ram_regions && largest == -1; i++) {
        if (!guest_memory->ram_regions[i].allocated) {
            largest = i;
        }
    }
    if (largest == -1) {
        ZF_LOGE("Failed to find free region");
        return -1;
    }
    for (i++; i < guest_memory->num_ram_regions; i++) {
        if (!guest_memory->ram_regions[i].allocated &&
            guest_memory->ram_regions[i].size > guest_memory->ram_regions[largest].size) {
            largest = i;
        }
    }
    *addr = guest_memory->ram_regions[largest].start;
    *size = guest_memory->ram_regions[largest].size;
    return 0;
}

void vm_ram_mark_allocated(vm_t *vm, uintptr_t start, size_t bytes)
{
    vm_mem_t *guest_memory = &vm->mem;
    /* Find the region */
    int i;
    int region = -1;
    for (i = 0; i < guest_memory->num_ram_regions; i++) {
        if (guest_memory->ram_regions[i].start <= start &&
            guest_memory->ram_regions[i].start + guest_memory->ram_regions[i].size >= start + bytes) {
            region = i;
            break;
        }
    }
    if (region == -1 || guest_memory->ram_regions[region].allocated) {
        return;
    }
    /* Remove the region */
    vm_ram_region_t r = guest_memory->ram_regions[region];
    guest_ram_remove_region(guest_memory, region);
    /* Split the region into three pieces and add them */
    push_guest_ram_region(guest_memory, r.start, start - r.start, 0);
    push_guest_ram_region(guest_memory, start, bytes, 1);
    push_guest_ram_region(guest_memory, start + bytes, r.size - bytes - (start - r.start), 0);
    /* sort and collapse */
    sort_guest_ram_regions(guest_memory);
    collapse_guest_ram_regions(guest_memory);
}

uintptr_t vm_ram_allocate(vm_t *vm, size_t bytes)
{
    vm_mem_t *guest_memory = &vm->mem;
    for (int i = 0; i < guest_memory->num_ram_regions; i++) {
        if (!guest_memory->ram_regions[i].allocated && guest_memory->ram_regions[i].size >= bytes) {
            uintptr_t addr = guest_memory->ram_regions[i].start;
            vm_ram_mark_allocated(vm, addr, bytes);
            return addr;
        }
    }
    ZF_LOGE("Failed to allocate %zu bytes of guest RAM", bytes);
    return 0;
}

static vm_frame_t ram_alloc_iterator(uintptr_t addr, void *cookie)
{
    int ret;
    vka_object_t object;
    vm_frame_t frame_result = { seL4_CapNull, seL4_NoRights, 0, 0 };
    vm_t *vm = (vm_t *)cookie;
    if (!vm) {
        return frame_result;
    }
    int page_size = seL4_PageBits;
    uintptr_t frame_start = ROUND_DOWN(addr, BIT(page_size));
    ret = vka_alloc_frame_maybe_device(vm->vka, page_size, true, &object);
    if (ret) {
        ZF_LOGE("Failed to allocate frame for address 0x%x", addr);
        return frame_result;
    }
    frame_result.cptr = object.cptr;
    frame_result.rights = seL4_AllRights;
    frame_result.vaddr = frame_start;
    frame_result.size_bits = page_size;
    return frame_result;
}

static vm_frame_t ram_ut_alloc_iterator(uintptr_t addr, void *cookie)
{
    int ret;
    int error;
    vka_object_t object;
    vm_frame_t frame_result = { seL4_CapNull, seL4_NoRights, 0, 0 };
    vm_t *vm = (vm_t *)cookie;
    if (!vm) {
        return frame_result;
    }
    int page_size = seL4_PageBits;
    uintptr_t frame_start = ROUND_DOWN(addr, BIT(page_size));
    cspacepath_t path;
    error = vka_cspace_alloc_path(vm->vka, &path);
    if (error) {
        ZF_LOGE("Failed to allocate path");
        return frame_result;
    }
    seL4_Word vka_cookie;
    error = vka_utspace_alloc_at(vm->vka, &path, kobject_get_type(KOBJECT_FRAME, page_size), page_size, frame_start,
                                 &vka_cookie);
    if (error) {
        ZF_LOGE("Failed to allocate page");
        vka_cspace_free_path(vm->vka, path);
        return frame_result;
    }
    frame_result.cptr = path.capPtr;
    frame_result.rights = seL4_AllRights;
    frame_result.vaddr = frame_start;
    frame_result.size_bits = page_size;
    return frame_result;
}

static int map_ram_reservation(vm_t *vm, vm_memory_reservation_t *ram_reservation, bool untyped)
{
    int err;
    /* We map the reservation immediately, by-passing the deferred mapping functionality
     * This allows us the allocate, touch and manipulate VM RAM prior to the region needing to be
     * faulted upon first */
    if (untyped) {
        err = map_vm_memory_reservation(vm, ram_reservation, ram_ut_alloc_iterator, (void *)vm);
    } else {
        err = map_vm_memory_reservation(vm, ram_reservation, ram_alloc_iterator, (void *)vm);
    }
    if (err) {
        ZF_LOGE("Failed to map new ram reservation");
        return -1;
    }
    return 0;
}

uintptr_t vm_ram_register(vm_t *vm, size_t bytes)
{
    vm_memory_reservation_t *ram_reservation;
    int err;
    uintptr_t base_addr;

    ram_reservation = vm_reserve_anon_memory(vm, bytes, default_ram_fault_callback, NULL, &base_addr);
    if (!ram_reservation) {
        ZF_LOGE("Unable to reserve ram region of size 0x%x", bytes);
        return 0;
    }
    err = map_ram_reservation(vm, ram_reservation, false);
    if (err) {
        vm_free_reserved_memory(vm, ram_reservation);
        return 0;
    }
    err = expand_guest_ram_region(vm, base_addr, bytes);
    if (err) {
        ZF_LOGE("Failed to register new ram region");
        vm_free_reserved_memory(vm, ram_reservation);
        return 0;
    }

    return base_addr;
}

int vm_ram_register_at(vm_t *vm, uintptr_t start, size_t bytes, bool untyped)
{
    vm_memory_reservation_t *ram_reservation;
    int err;

    ram_reservation = vm_reserve_memory_at(vm, start, bytes, default_ram_fault_callback,
                                           NULL);
    if (!ram_reservation) {
        ZF_LOGE("Unable to reserve ram region at addr 0x%x of size 0x%x", start, bytes);
        return 0;
    }
    err = map_ram_reservation(vm, ram_reservation, untyped);
    if (err) {
        vm_free_reserved_memory(vm, ram_reservation);
        return 0;
    }
    err = expand_guest_ram_region(vm, start, bytes);
    if (err) {
        ZF_LOGE("Failed to register new ram region");
        vm_free_reserved_memory(vm, ram_reservation);
        return 0;
    }
    return 0;
}

void vm_ram_free(vm_t *vm, uintptr_t start, size_t bytes)
{
    return;
}
