/**
 * \file
 * \brief PMAP Implementaiton for AOS
 */

/*
 * Copyright (c) 2019 ETH Zurich.
 * All rights reserved.
 *
 * This file is distributed under the terms in the attached LICENSE file.
 * If you do not find this file, copies can be found by writing to:
 * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
 */

#ifndef PAGING_TYPES_H_
#define PAGING_TYPES_H_ 1

#include <aos/solution.h>

#define VADDR_OFFSET ((lvaddr_t)512UL*1024*1024*1024) // 1GB
#define VADDR_SIZE             (1UL << 48)
#define VREGION_FLAGS_READ     0x01 // Reading allowed
#define VREGION_FLAGS_WRITE    0x02 // Writing allowed
#define VREGION_FLAGS_EXECUTE  0x04 // Execute allowed
#define VREGION_FLAGS_NOCACHE  0x08 // Caching disabled
#define VREGION_FLAGS_MPB      0x10 // Message passing buffer
#define VREGION_FLAGS_GUARD    0x20 // Guard page
#define VREGION_FLAGS_MASK     0x2f // Mask of all individual VREGION_FLAGS

#define VREGION_FLAGS_READ_WRITE \
    (VREGION_FLAGS_READ | VREGION_FLAGS_WRITE)
#define VREGION_FLAGS_READ_EXECUTE \
    (VREGION_FLAGS_READ | VREGION_FLAGS_EXECUTE)
#define VREGION_FLAGS_READ_WRITE_NOCACHE \
    (VREGION_FLAGS_READ | VREGION_FLAGS_WRITE | VREGION_FLAGS_NOCACHE)
#define VREGION_FLAGS_READ_WRITE_MPB \
    (VREGION_FLAGS_READ | VREGION_FLAGS_WRITE | VREGION_FLAGS_MPB)

typedef int paging_flags_t;


// NOTE rueegges: page table metadata used to create child mappings and unmap
struct pt_t {
    // capref that holds this page table
    struct capref cap_pt;
    // capref that maps this page table in the higher level page table
    struct capref cap_mapping;
    // store number of slots that were mapped to be able to unmap later
    size_t mapping_size;

    // NOTE rueegges: points to an array with pointers for every potential next level page table
    // it is NULL for mapping a frame instead of a page table
    // entries are NULL if the corresponding mapping does not yet exist
    struct pt_t **children;
};

// NOTE rueegges: store information about a region of virtual address space
struct pt_vaddr_reg_t {
    lvaddr_t base;
    size_t size;
    uint8_t free;
    struct pt_vaddr_reg_t *next;
};

// struct to store the paging status of a process
struct paging_state {
    struct slot_allocator *slot_alloc;

    // NOTE rueegges: added to keep track of pt metadata
    struct pt_t *l0_pt;

    // NOTE rueegges: added to allocate shadow page table metadata
    struct slab_allocator pt_slabs;
    struct slab_allocator pt_children_slabs;

    // NOTE rueegges: remember if we are refilling so we can skip the checks
    uint8_t refilling;

    // NOTE rueegges: use to track an already allocated page table in failure conditions
    struct capref free_l1_vnode;
    struct capref free_l2_vnode;
    struct capref free_l3_vnode;

    // TODO rueegges: implement more precisely?
    struct pt_vaddr_reg_t *vaddr_head;
};


#endif  /// PAGING_TYPES_H_
