1/* 2 * \brief demandpaging.h 3 * 4 * Copyright (c) 2015 ETH Zurich. 5 * All rights reserved. 6 * 7 * This file is distributed under the terms in the attached LICENSE file. 8 * If you do not find this file, copies can be found by writing to: 9 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group. 10 */ 11#ifndef LIB_DEMANDPAGING_INCLUDE_DEMANDPAGING_INTERNAL_H_ 12#define LIB_DEMANDPAGING_INCLUDE_DEMANDPAGING_INTERNAL_H_ 13 14#include <demandpaging.h> 15 16/* forward declarations */ 17struct dp_frame; 18struct dp_page; 19struct demand_paging_region; 20 21 22#define DP_DEBUG_ENABLE 0 23#define DP_DEBUG_PRINT_LINENUMBERS 0 24 25#define DP_DEBUG_MAP_ENABLE 1 26#define DP_DEBUG_SWAP_ENABLE 1 27#define DP_DEBUG_HANDLER_ENABLE 1 28 29/* default debug print utility */ 30#if !defined(NDEBUG) && DP_DEBUG_ENABLE 31#if DP_DEBUG_PRINT_LINENUMBERS 32#define DP_DEBUG_PRINT(sub, fmt, ...) \ 33 debug_printf("[dp] [%s] %s:%u - " fmt, sub, \ 34 __FUNCTION__, __LINE__, ##__VA_ARGS__) 35#else 36#define DP_DEBUG_PRINT(sub, fmt, ...) \ 37 debug_printf("[dp] [%s] " fmt, sub, ##__VA_ARGS__) 38#endif 39#else 40#define DP_DEBUG_PRINT(fmt, ...) 41#endif 42 43 44#if DP_DEBUG_SWAP_ENABLE 45#define DP_DEBUG_SWAP(fmt, ... ) \ 46 DP_DEBUG_PRINT( "swap", fmt, ##__VA_ARGS__) 47#else 48#define DP_DEBUG_SWAP(fmt, ... ) 49#endif 50 51#if DP_DEBUG_MAP_ENABLE 52#define DP_DEBUG_MAP(fmt, ... ) \ 53 DP_DEBUG_PRINT( "map", fmt, ##__VA_ARGS__) 54#else 55#define DP_DEBUG_MAP(fmt, ... ) 56#endif 57 58#if DP_DEBUG_HANDLER_ENABLE 59#define DP_DEBUG_HANDLER(fmt, ... ) \ 60 DP_DEBUG_PRINT( "handler", fmt, ##__VA_ARGS__) 61#else 62#define DP_DEBUG_HANDLER(fmt, ... ) 63#endif 64 65#if DP_DEBUG_MGMT_ENABLE 66#define DP_DEBUG_MGMT(fmt, ... ) \ 67 DP_DEBUG_PRINT( "mgmt", fmt, ##__VA_ARGS__) 68#else 69#define DP_DEBUG_MGMT(fmt, ... ) 70#endif 71 72 73/* 74 * XXX: for accessing the dirty and accessed bits 75 */ 76 77#ifdef __k1om__ 78#define X86_64_PHYSADDR_BITS 40 // TODO: Take that from offsets target 79#else 80#define X86_64_PHYSADDR_BITS 48 81#endif 82 83#define X86_64_PAGING_ENTRY_SIZE 64 84#define X86_64_PAGING_AVAIL2_BITS 11 85#define X86_64_PAGING_FLAG_BITS 12 86#define X86_64_PAGING_LARGE_FLAGE_BITS 21 87#define X86_64_PAGING_RESERVED_BITS \ 88 (X86_64_PAGING_ENTRY_SIZE - X86_64_PHYSADDR_BITS - \ 89 X86_64_PAGING_AVAIL2_BITS - 1) 90#define X86_64_PAGING_LARGE_BASE_BITS \ 91 (X86_64_PHYSADDR_BITS - X86_64_PAGING_LARGE_FLAGE_BITS) 92#define X86_64_PAGING_BASE_BASE_BITS \ 93 (X86_64_PHYSADDR_BITS - X86_64_PAGING_FLAG_BITS) 94 95/** 96 * A page table entry. 97 */ 98union x86_64_ptable_entry { 99 uint64_t raw; 100 struct { 101 uint64_t present :1; 102 uint64_t read_write :1; 103 uint64_t user_supervisor :1; 104 uint64_t write_through :1; 105 uint64_t cache_disabled :1; 106 uint64_t accessed :1; 107 uint64_t dirty :1; 108 uint64_t always1 :1; 109 uint64_t global :1; 110 uint64_t available :3; 111 uint64_t attr_index :1; 112 uint64_t reserved :17; 113 uint64_t base_addr :10; 114 uint64_t reserved2 :12; 115 uint64_t available2 :11; 116 uint64_t execute_disable :1; 117 } huge; 118 struct { 119 uint64_t present :1; 120 uint64_t read_write :1; 121 uint64_t user_supervisor :1; 122 uint64_t write_through :1; 123 uint64_t cache_disabled :1; 124 uint64_t accessed :1; 125 uint64_t dirty :1; 126 uint64_t always1 :1; 127 uint64_t global :1; 128 uint64_t available :3; 129 uint64_t attr_index :1; 130 uint64_t reserved :8; 131 uint64_t base_addr :X86_64_PAGING_LARGE_BASE_BITS; 132 uint64_t reserved2 :X86_64_PAGING_RESERVED_BITS; 133 uint64_t available2 :11; 134 uint64_t execute_disable :1; 135 } large; 136 struct { 137 uint64_t present :1; 138 uint64_t read_write :1; 139 uint64_t user_supervisor :1; 140 uint64_t write_through :1; 141 uint64_t cache_disabled :1; 142 uint64_t accessed :1; 143 uint64_t dirty :1; 144 uint64_t attr_index :1; 145 uint64_t global :1; 146 uint64_t available :3; 147 uint64_t base_addr :X86_64_PAGING_BASE_BASE_BITS; 148 uint64_t reserved2 :X86_64_PAGING_RESERVED_BITS; 149 uint64_t available2 :11; 150 uint64_t execute_disable :1; 151 } base; 152}; 153 154 155#define EXCEPTION_STACK_SIZE (32UL * 1024) 156#define EXCEPTION_STACK_MIN_SIZE (4UL * 1024) 157 158#define DEMAND_PAGING_SWAP_FILE "/swap" 159#define DEMAND_PAGING_SWAP_FILE_PATHLEN (5 + 18 + 1) 160 161typedef enum { 162 DEMAND_PAGING_PST_UNTOUCHED, 163 DEMAND_PAGING_PST_MEMORY, 164 DEMAND_PAGING_PST_FILE, 165} dp_page_state_t; 166 167///< represent a virtual frame 168struct dp_page 169{ 170 lvaddr_t vaddr; 171 size_t pagenr; 172 struct demand_paging_region *dpr; 173 174 dp_page_state_t state; ///< this slot is page out 175 size_t offset; ///< offset into the file 176 struct dp_frame *frame; 177 178 void *vnode; 179 union x86_64_ptable_entry *vnode_entry; 180}; 181 182///< represent a physical frame 183struct dp_frame 184{ 185 struct capref frame; 186 lpaddr_t paddr; 187 struct dp_page *page; 188 union x86_64_ptable_entry *vnode_entry; 189 struct dp_frame *next; /// to hold the free list 190 uint8_t first; 191}; 192 193struct demand_paging_region 194{ 195 struct vregion vreg; ///< the vregion of this object 196 197 /* swap file */ 198 char swapname[DEMAND_PAGING_SWAP_FILE_PATHLEN]; 199 vfs_handle_t swapfile; 200 201 /* frames */ 202 size_t pagesize; 203 struct dp_page *pages; 204 205 size_t frames_count; ///< total length of all frames 206 size_t frames_victim; ///< total length of all frames 207 struct dp_frame **frames; ///< array of all frames 208 struct dp_frame *frames_free; 209 210 size_t vnodes_count; 211 void **vnodes; 212 213 214 /* next regions */ 215 struct demand_paging_region *next; 216}; 217 218 219#endif /* LIB_DEMANDPAGING_INCLUDE_DEMANDPAGING_INTERNAL_H_ */ 220