Move system calls to the SDK and normalize their names
[monolithium.git] / kernel / include / memory.h
1 /*
2  * memory.h
3  *
4  * Copyright (C) 2015 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Affero General Public License as
8  * published by the Free Software Foundation, either version 3 of the
9  * License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Affero General Public License for more details.
15  *
16  * You should have received a copy of the GNU Affero General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #ifndef _MEMORY_H_
21 #define _MEMORY_H_
22
23 #include <common.h>
24 #include <interrupt.h>
25 #include <boot/multiboot.h>
26 #include <avl_tree.h>
27 #include <object.h>
28 #include <filesystem.h>
29 #include <sdk/memory.h>
30
31 #define PAGE_SIZE      4096
32 #define PAGE_PRESENT   (1 << 0)
33 #define PAGE_WRITABLE  (1 << 1)
34 #define PAGE_USERMODE  (1 << 2)
35 #define PAGE_ACCESSED  (1 << 5)
36 #define PAGE_DIRTY     (1 << 6)
37 #define PAGE_GLOBAL    (1 << 8)
38 #define PAGE_EVICTABLE (1 << 9)
39
40 #define PAGE_ERROR_PRESENT_FLAG  (1 << 0)
41 #define PAGE_ERROR_WRITE_FLAG    (1 << 1)
42 #define PAGE_ERROR_USERMODE_FLAG (1 << 2)
43
44 #define ADDR_TO_PDE(x)   ((x) >> 22)
45 #define ADDR_TO_PTE(x)   (((x) >> 12) & 0x3FF)
46 #define PAGE_ALIGN(x)    ((x) & 0xFFFFF000)
47 #define PAGE_ALIGN_UP(x) (((x) + 0xFFF) & 0xFFFFF000)
48 #define PAGE_OFFSET(x)   ((x) & 0x00000FFF)
49 #define PAGE_NUMBER(x)   ((x) >> 12)
50
51 #define KERNEL_AREA_START 0x80000000
52 #define KERNEL_AREA_END   0xFFFFFFFF
53 #define KERNEL_POOL_START 0x81000000
54 #define KERNEL_POOL_END   0xBFFFFFFF
55 #define MAPPING_START     0xC8000000
56 #define MAPPING_END       0xFFFFFFFF
57 #define USER_AREA_START   0x00000000
58 #define USER_AREA_END     0x7FFFFFFF
59 #define KERNEL_PAGE_START ADDR_TO_PDE(KERNEL_AREA_START)
60 #define KERNEL_PAGE_END   ADDR_TO_PDE(KERNEL_AREA_END)
61 #define USER_PAGE_START   ADDR_TO_PDE(USER_AREA_START)
62 #define USER_PAGE_END     ADDR_TO_PDE(USER_AREA_END)
63
64 #define PAGEDIR_SELF_ENTRY  768
65 #define PAGE_DIRECTORY_ADDR ((PAGEDIR_SELF_ENTRY << 22) + (PAGEDIR_SELF_ENTRY << 12))
66 #define PAGE_TABLE_ADDR     (PAGEDIR_SELF_ENTRY << 22)
67
68 #define INVALID_PAGE        ((void*)-1)
69 #define TOTAL_PAGES         1048576
70 #define MEM_FIRST_PHYS_ADDR 0x400000
71 #define MEM_STACK_VIRT_ADDR 0xC0400000
72 #define MEM_TREE_BLOCKS     0xC0800000
73 #define TEMPORARY_PAGES     256
74 #define TEMPORARY_ADDR      (0xC8000000 - TEMPORARY_PAGES * PAGE_SIZE)
75 #define EVICTION_THRESHOLD  128
76
77 #define INVALID_STORE_NUMBER        ((dword_t)-1)
78 #define PAGE_STORE_ENTRY_PRESENT    (1 << 31)
79
80 typedef struct memory_block memory_block_t;
81
82 typedef struct
83 {
84     uintptr_t phys_addr;
85     uintptr_t ref_count;
86 } page_t;
87
88 typedef struct
89 {
90     list_entry_t link;
91     void *page_directory;
92     void *pool_address;
93     uintptr_t pool_size;
94     avl_tree_t *by_addr_tree_root;
95     avl_tree_t *by_size_tree_root;
96     resource_t resource;
97     list_entry_t evictable_blocks;
98     list_entry_t *evict_blk_ptr;
99     uintptr_t evict_page_num;
100     memory_stats_t stats;
101 } memory_address_space_t;
102
103 typedef struct
104 {
105     list_entry_t link;
106     void *physical;
107     uintptr_t offset;
108 } shared_page_t;
109
110 typedef struct
111 {
112     object_t header;
113     dword_t flags;
114     list_entry_t page_list;
115     size_t size;
116     file_instance_t *file; /* strong reference */
117 } memory_section_t;
118
119 struct memory_block
120 {
121     avl_tree_t by_addr_tree;
122     avl_tree_t by_size_tree;
123     list_entry_t evict_link;
124     dword_t flags;
125     memory_address_space_t *address_space;
126     memory_section_t *section;
127     qword_t section_offset;
128 };
129
130 typedef struct
131 {
132     list_entry_t link;
133     dword_t num_entries;
134     dword_t max_entries;
135     handle_t file_handle;
136     dword_t *bitmap;
137     list_entry_t entry_list;
138 } page_store_t;
139
140 typedef struct
141 {
142     list_entry_t link;
143     void *address;
144     memory_address_space_t *address_space;
145     dword_t number;
146     void *physical;
147 } page_store_entry_t;
148
149 typedef enum
150 {
151     PAGE_ERROR_NOTPRESENT,
152     PAGE_ERROR_READONLY,
153     PAGE_ERROR_UNPRIVILEGED
154 } page_error_t;
155
156 void set_page_directory(void *phys_addr);
157 void *get_page_directory();
158 void *get_physical_address(void *virtual);
159 dword_t map_memory_internal(void *physical, void *virtual, size_t size, dword_t page_flags);
160 void unmap_memory_internal(void *virtual, size_t size);
161 dword_t read_physical(void *physical, void *buffer, size_t size);
162 dword_t write_physical(void *physical, void *buffer, size_t size);
163 dword_t map_memory_in_address_space(memory_address_space_t *address_space,
164                                     void *physical,
165                                     void **virtual,
166                                     uintptr_t size,
167                                     dword_t block_flags);
168 dword_t unmap_memory_in_address_space(memory_address_space_t *address_space, void *virtual);
169 dword_t pin_memory(const void *virtual, void **pinned, size_t size, bool_t lock_contents);
170 dword_t map_memory(void *physical, void **virtual, size_t size, dword_t page_flags);
171 dword_t unmap_memory(void *virtual);
172 dword_t alloc_memory_in_address_space(
173     memory_address_space_t *address_space,
174     void **address,
175     size_t size,
176     dword_t block_flags,
177     memory_section_t *section,
178     qword_t section_offset);
179 dword_t free_memory_in_address_space(memory_address_space_t *address_space, void *address);
180 dword_t commit_pages(void *address, size_t size);
181 dword_t uncommit_pages(void *address, size_t size);
182 void *alloc_pool(void *address, size_t size, dword_t block_flags);
183 void free_pool(void *address);
184 dword_t create_address_space(void *base_address, dword_t page_count, memory_address_space_t *mem_space);
185 dword_t clone_address_space(memory_address_space_t *original, memory_address_space_t *clone);
186 void bump_address_space(memory_address_space_t *mem_space);
187 void delete_address_space(memory_address_space_t *mem_space);
188 bool_t memory_fault_handler(void *address, registers_t *regs);
189 void memory_init(multiboot_mmap_t *mmap_addr, dword_t mmap_length);
190 void memory_cleanup(object_t *obj);
191
192 #endif