/*
 * Copyright 2017, 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)
 */

/*
 * An implementation of the vspace virtual memory allocation interface, using a two
 * level page table.
 *
 * This implementation expects malloc to work, although it only uses it for small amounts of
 * memory.
 *
 * Stack size is constant and be configured in menuconfig.
 *
 * Stacks are allocated with 1 guard page between them, but they are contiguous in the vmem
 * region.
 *
 * Allocation starts at 0x00001000.
 *
 * This library will allow you to map over anything that it doesn't know about, so
 * make sure you tell it if you do any external mapping.
 *
 */
#pragma once

#include <autoconf.h>
#include <sel4utils/gen_config.h>

#include <vspace/vspace.h>
#include <vka/vka.h>
#include <sel4utils/util.h>
#include <sel4utils/arch/vspace.h>

/* These definitions are only here so that you can take the size of them.
 * TOUCHING THESE DATA STRUCTURES IN ANY WAY WILL BREAK THE WORLD
 */
#define KERNEL_RESERVED_START (ALIGN_DOWN(seL4_UserTop, PAGE_SIZE_4K))
#define VSPACE_LEVEL_SIZE BIT(VSPACE_LEVEL_BITS)

typedef struct vspace_mid_level {
    /* there is a clear optimization that could be done where instead of always pointing to a
     * sub table, there is the option of pointing directly to a page. This allows more
     * efficient memory usage for book keeping large pages */
    uintptr_t table[VSPACE_LEVEL_SIZE];
} vspace_mid_level_t;

typedef struct vspace_bottom_level {
    seL4_CPtr cap[VSPACE_LEVEL_SIZE];
    uintptr_t cookie[VSPACE_LEVEL_SIZE];
} vspace_bottom_level_t;

typedef int(*sel4utils_map_page_fn)(vspace_t *vspace, seL4_CPtr cap, void *vaddr, seL4_CapRights_t rights,
                                    int cacheable, size_t size_bits);

struct sel4utils_res {
    uintptr_t start;
    uintptr_t end;
    seL4_CapRights_t rights;
    int cacheable;
    int malloced;
    bool rights_deferred;
    struct sel4utils_res *next;
};

typedef struct sel4utils_res sel4utils_res_t;

typedef struct sel4utils_alloc_data {
    seL4_CPtr vspace_root;
    vka_t *vka;
    vspace_mid_level_t *top_level;
    uintptr_t next_bootstrap_vaddr;
    uintptr_t last_allocated;
    vspace_t *bootstrap;
    sel4utils_map_page_fn map_page;
    sel4utils_res_t *reservation_head;
} sel4utils_alloc_data_t;

static inline sel4utils_res_t *reservation_to_res(reservation_t res)
{
    return (sel4utils_res_t *) res.res;
}

/**
 * This is a mostly internal function for constructing a vspace. Allows a vspace to be created
 * with an arbitrary function to invoke for the mapping of pages. This is useful if you want
 * a vspace manager, but you do not want to use seL4 page directories
 *
 * @param loader                  vspace of the current process, used to allocate
 *                                virtual memory book keeping.
 * @param new_vspace              uninitialised vspace struct to populate.
 * @param data                    uninitialised vspace data struct to populate.
 * @param vka                     initialised vka that this virtual memory allocator will use to
 *                                allocate pages and pagetables. This allocator will never invoke free.
 * @param vspace_root             root object for the new vspace.
 * @param allocated_object_fn     function to call when objects are allocated. Can be null.
 * @param allocated_object_cookie cookie passed when the above function is called. Can be null.
 * @param map_page                Function that will be called to map seL4 pages
 *
 * @return 0 on success.
 */
int
sel4utils_get_vspace_with_map(vspace_t *loader, vspace_t *new_vspace, sel4utils_alloc_data_t *data,
                              vka_t *vka, seL4_CPtr vspace_root,
                              vspace_allocated_object_fn allocated_object_fn, void *allocated_object_cookie, sel4utils_map_page_fn map_page);

/**
 * Initialise a vspace allocator for a new address space (not the current one).
 *
 * @param loader                  vspace of the current process, used to allocate
 *                                virtual memory book keeping.
 * @param new_vspace              uninitialised vspace struct to populate.
 * @param data                    uninitialised vspace data struct to populate.
 * @param vka                     initialised vka that this virtual memory allocator will use to
 *                                allocate pages and pagetables. This allocator will never invoke free.
 * @param vspace_root             root object for the new vspace.
 * @param allocated_object_fn     function to call when objects are allocated. Can be null.
 * @param allocated_object_cookie cookie passed when the above function is called. Can be null.
 *
 * @return 0 on success.
 */
int sel4utils_get_vspace(vspace_t *loader, vspace_t *new_vspace, sel4utils_alloc_data_t *data,
                         vka_t *vka, seL4_CPtr vspace_root, vspace_allocated_object_fn allocated_object_fn,
                         void *allocated_object_cookie);

#ifdef CONFIG_VTX
/**
 * Initialise a vspace allocator for an EPT address space
 *
 * @param loader                  vspace of the current process, used to allocate
 *                                virtual memory book keeping.
 * @param new_vspace              uninitialised vspace struct to populate.
 * @param vka                     initialised vka that this virtual memory allocator will use to
 *                                allocate pages and pagetables. This allocator will never invoke free.
 * @param ept                     EPT page directory for the new vspace.
 * @param allocated_object_fn     function to call when objects are allocated. Can be null.
 * @param allocated_object_cookie cookie passed when the above function is called. Can be null.
 *
 * @return 0 on success.
 */
int sel4utils_get_vspace_ept(vspace_t *loader, vspace_t *new_vspace, vka_t *vka,
                             seL4_CPtr ept, vspace_allocated_object_fn allocated_object_fn, void *allocated_object_cookie);
#endif /* CONFIG_VTX */

/**
 * Initialise a vspace allocator for the current address space (this is intended
 * for use a task that is not the root task but has no vspace, ie one loaded by the capDL loader).
 *
 * @param vspace                  uninitialised vspace struct to populate.
 * @param data                    uninitialised vspace data struct to populate.
 * @param vka                     initialised vka that this virtual memory allocator will use to
 *                                allocate pages and pagetables. This allocator will never invoke free.
 * @param vspace_root             root object for the new vspace.
 * @param allocated_object_fn     function to call when objects are allocated. Can be null.
 * @param allocated_object_cookie cookie passed when the above function is called. Can be null.
 * @param existing_frames         a NULL terminated list of virtual addresses for 4K frames that are
 *                                already allocated. For larger frames, just pass in the virtual
 *                                address range in 4K addresses. This will prevent the allocator
 *                                from overriding these frames.
 *
 * @return 0 on succes.
 *
 */
int sel4utils_bootstrap_vspace(vspace_t *vspace, sel4utils_alloc_data_t *data,
                               seL4_CPtr vspace_root, vka_t *vka,
                               vspace_allocated_object_fn allocated_object_fn, void *allocated_object_cookie,
                               void *existing_frames[]);

/**
 * Initialise a vspace allocator for the current address space (this is intended
 * for use by the root task). Take details of existing frames from bootinfo.
 *
 * @param vspace                  uninitialised vspace struct to populate.
 * @param data                    uninitialised vspace data struct to populate.
 * @param vka                     initialised vka that this virtual memory allocator will use to
 *                                allocate pages and pagetables. This allocator will never invoke free.
 * @param info                    seL4 boot info
 * @param vspace_root             root object for the new vspace.
 * @param allocated_object_fn     function to call when objects are allocated. Can be null.
 * @param allocated_object_cookie cookie passed when the above function is called. Can be null.
 *
 * @return 0 on succes.
 *
 */
int sel4utils_bootstrap_vspace_with_bootinfo(vspace_t *vspace, sel4utils_alloc_data_t *data,
                                             seL4_CPtr vspace_root,
                                             vka_t *vka, seL4_BootInfo *info, vspace_allocated_object_fn allocated_object_fn,
                                             void *allocated_object_cookie);

/* Wrapper function that configures a vspaceator such that all allocated objects are not
 * tracked.
 */
static inline int sel4utils_get_vspace_leaky(vspace_t *loader, vspace_t *new_vspace, sel4utils_alloc_data_t *data,
                                             vka_t *vka, seL4_CPtr vspace_root)
{
    return sel4utils_get_vspace(loader, new_vspace, data, vka, vspace_root,
                                (vspace_allocated_object_fn) NULL, NULL);
}

#ifdef CONFIG_VTX
static inline int sel4utils_get_vspace_ept_leaky(vspace_t *loader, vspace_t *new_vspace,
                                                 vka_t *vka, seL4_CPtr vspace_root)
{
    return sel4utils_get_vspace_ept(loader, new_vspace, vka, vspace_root,
                                    (vspace_allocated_object_fn) NULL, NULL);
}
#endif /* CONFIG_VTX */

static inline int sel4utils_bootstrap_vspace_with_bootinfo_leaky(vspace_t *vspace, sel4utils_alloc_data_t *data,
                                                                 seL4_CPtr vspace_root,
                                                                 vka_t *vka, seL4_BootInfo *info)
{
    return sel4utils_bootstrap_vspace_with_bootinfo(vspace, data, vspace_root, vka, info, NULL, NULL);
}

static inline int sel4utils_bootstrap_vspace_leaky(vspace_t *vspace, sel4utils_alloc_data_t *data,
                                                   seL4_CPtr vspace_root, vka_t *vka,
                                                   void *existing_frames[])
{
    return sel4utils_bootstrap_vspace(vspace, data, vspace_root, vka, NULL, NULL, existing_frames);
}

/**
 * Attempts to create a new vspace reservation. Function behaves similarly to vspace_reserve_range
 * except a reservation struct is passed in, instead of being malloc'ed. This is intended to be
 * used during bootstrapping where malloc has not yet been setup.
 * Reservations created with this function should *only* be freed with sel4utils_reserve_range_at_no_alloc
 *
 * Result will be aligned to 4K.
 *
 * @param vspace the virtual memory allocator to use.
 * @param reservation Allocated reservation struct to fill out
 * @param bytes the size in bytes to map.
 * @param rights the rights to map the pages in with in this reservation
 * @param cacheable 1 if the pages should be mapped with cacheable attributes. 0 for DMA.
 * @param vaddr the virtual address of the reserved range will be returned here.
 *
 * @return 0 on success
 */
int sel4utils_reserve_range_no_alloc(vspace_t *vspace, sel4utils_res_t *reservation, size_t size,
                                     seL4_CapRights_t rights, int cacheable, void **result);

/*
 * @see sel4utils_reserve_range_no_alloc, however result is aligned to size_bits.
 */
int sel4utils_reserve_range_no_alloc_aligned(vspace_t *vspace, sel4utils_res_t *reservation,
                                             size_t size, size_t size_bits, seL4_CapRights_t rights, int cacheable, void **result);

/**
 * Attempts to create a new vspace reservation. Function behaves similarly to vspace_reserve_range_at
 * except a reservation struct is passed in, instead of being malloc'ed. This is intended to be
 * used during bootstrapping where malloc has not yet been setup.
 * Reservations created with this function should *only* be freed with sel4utils_reserve_range_at_no_alloc
 *
 * @param vspace the virtual memory allocator to use.
 * @param reservation Allocated reservation struct to fill out
 * @param vaddr the virtual address to start the range at.
 * @param bytes the size in bytes to map.
 * @param rights the rights to map the pages in with in this reservatio
 * @param cacheable 1 if the pages should be mapped with cacheable attributes. 0 for DMA.
 *
 * @return 0 on success
 */
int sel4utils_reserve_range_at_no_alloc(vspace_t *vspace, sel4utils_res_t *reservation, void *vaddr,
                                        size_t size, seL4_CapRights_t rights, int cacheable);

/**
 * Move and/or resizes a reservation in any direction, allowing for both start and/or end address to
 * be changed. Any overlapping region will keep their reservation, any non-overlapping regions will
 * be unreserved. Does not make any mapping changes.
 * @param vspace the virtual memory allocator to use.
 * @param reservation the reservation to move.
 * @param vaddr the start virtual address to move the reservation to.
 * @param bytes the size in bytes of new reservation.
 * @return 0 on success, -1 if region start could not be moved, -2 if end could not be moved.
 */
int sel4utils_move_resize_reservation(vspace_t *vspace, reservation_t reservation, void *vaddr,
                                      size_t bytes);

/*
 * Copy the code and data segment (the image effectively) from current vspace
 * into clone vspace. The clone vspace should be initialised.
 *
 * @param current the vspace to copy from.
 * @param clone the vspace to copy to.
 * @param reservation the previously established reservation in clone to copy.
 * @return 0 on success.
 */
int sel4utils_bootstrap_clone_into_vspace(vspace_t *current, vspace_t *clone, reservation_t reserve);

/**
 * Get the bounds of _executable_start and _end.
 *
 * @param va_start return va_start.
 * @param va_end return va_end.
 */
void sel4utils_get_image_region(uintptr_t *va_start, uintptr_t *va_end);

/**
 *
 * @return the physical address that vaddr is mapped to.
 *         VKA_NO_PADDR if there is no mapping
 */
uintptr_t sel4utils_get_paddr(vspace_t *vspace, void *vaddr, seL4_Word type, seL4_Word size_bits);

