// Copyright 2018 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include <inttypes.h>
#include <sys/types.h>

#include <fbl/algorithm.h>
#include <fbl/function.h>
#include <trace.h>
#include <vm/bootreserve.h>
#include <vm/pmm.h>

#include "vm_priv.h"


#define LOCAL_TRACE MAX(VM_GLOBAL_TRACE, 0)

static const size_t NUM_RESERVES = 16;
static reserve_range_t res[NUM_RESERVES];
static size_t res_idx;

void boot_reserve_init() {
    // add the kernel to the boot reserve list
    boot_reserve_add_range(get_kernel_base_phys(), get_kernel_size());
}

zx_status_t boot_reserve_add_range(paddr_t pa, size_t len) {
    dprintf(INFO, "PMM: boot reserve add [%#" PRIxPTR ", %#" PRIxPTR "]\n", pa, pa + len - 1);

    if (res_idx == NUM_RESERVES) {
        panic("too many boot reservations\n");
    }

    // insert into the list, sorted
    paddr_t end = pa + len - 1;
    DEBUG_ASSERT(end > pa);
    for (size_t i = 0; i < res_idx; i++) {
        if (Intersects(res[i].pa, res[i].len, pa, len)) {
            // we have a problem that we are not equipped to handle right now
            panic("boot_reserve_add_range: pa %#" PRIxPTR " len %zx intersects existing range\n",
                  pa, len);
        }

        if (res[i].pa > end) {
            // insert before this one
            memmove(&res[i + 1], &res[i], (res_idx - i) * sizeof(res[0]));
            res[i].pa = pa;
            res[i].len = len;
            res_idx++;
            return ZX_OK;
        }
    }

    // insert it at the end
    res[res_idx].pa = pa;
    res[res_idx].len = len;
    res_idx++;
    return ZX_OK;
}

// iterate through the reserved ranges and mark them as WIRED in the pmm
void boot_reserve_wire() {
    static list_node reserved_page_list = LIST_INITIAL_VALUE(reserved_page_list);

    for (size_t i = 0; i < res_idx; i++) {
        dprintf(INFO, "PMM: boot reserve marking WIRED [%#" PRIxPTR ", %#" PRIxPTR "]\n",
                res[i].pa, res[i].pa + res[i].len - 1);

        size_t pages = ROUNDUP_PAGE_SIZE(res[i].len) / PAGE_SIZE;
        zx_status_t status = pmm_alloc_range(res[i].pa, pages, &reserved_page_list);
        if (status != ZX_OK) {
            printf("PMM: unable to reserve reserved range [%#" PRIxPTR ", %#" PRIxPTR "]\n",
                   res[i].pa, res[i].pa + res[i].len - 1);
            continue; // this is probably fatal but go ahead and continue
        }
    }

    // mark all of the pages we allocated as WIRED
    vm_page_t* p;
    list_for_every_entry (&reserved_page_list, p, vm_page_t, queue_node) {
        p->state = VM_PAGE_STATE_WIRED;
    }
}

static paddr_t upper_align(paddr_t range_pa, size_t range_len, size_t len) {
    return (range_pa + range_len - len);
}

zx_status_t boot_reserve_range_search(paddr_t range_pa, size_t range_len, size_t alloc_len,
                                      reserve_range_t* alloc_range) {
    LTRACEF("range pa %#" PRIxPTR " len %#zx alloc_len %#zx\n", range_pa, range_len, alloc_len);

    paddr_t alloc_pa = upper_align(range_pa, range_len, alloc_len);

retry:
    // see if it intersects any reserved range
    LTRACEF("trying alloc range %#" PRIxPTR " len %#zx\n", alloc_pa, alloc_len);
    for (size_t i = 0; i < res_idx; i++) {
        if (Intersects(res[i].pa, res[i].len, alloc_pa, alloc_len)) {
            // it intersects this range, move the search spot back to just before it and try again
            LTRACEF("alloc range %#" PRIxPTR " len %zx intersects with reserve range\n", alloc_pa, alloc_len);
            alloc_pa = res[i].pa - alloc_len;

            LTRACEF("moving and retrying at %#" PRIxPTR "\n", alloc_pa);

            // make sure this still works with our input constraints
            if (alloc_pa < range_pa) {
                LTRACEF("failed to allocate\n");
                return ZX_ERR_NO_MEMORY;
            }

            goto retry;
        }
    }

    // fell off the list without retrying, must have suceeded
    LTRACEF("returning [%#" PRIxPTR ", %#" PRIxPTR "]\n",
            alloc_pa, alloc_pa + alloc_len - 1);

    *alloc_range = {alloc_pa, alloc_len};
    return ZX_OK;
}

// Returns false and exits early if the callback returns false, true otherwise.
bool boot_reserve_foreach(const fbl::Function<bool(const reserve_range_t)>& cb) {
    for (size_t i = 0; i < res_idx; i++) {
        if (!cb(res[i])) {
            return false;
        }
    }

    return true;
};
