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