memory.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  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. #ifndef _MEMORY_H_
  20. #define _MEMORY_H_
  21. #include <common.h>
  22. #include <interrupt.h>
  23. #include <boot/multiboot.h>
  24. #include <object.h>
  25. #include <filesystem.h>
  26. #include <sdk/avltree.h>
  27. #include <sdk/memory.h>
  28. #define PAGE_SIZE 4096
  29. #define PAGE_PRESENT (1 << 0)
  30. #define PAGE_WRITABLE (1 << 1)
  31. #define PAGE_USERMODE (1 << 2)
  32. #define PAGE_ACCESSED (1 << 5)
  33. #define PAGE_DIRTY (1 << 6)
  34. #define PAGE_GLOBAL (1 << 8)
  35. #define PAGE_EVICTABLE (1 << 9)
  36. #define PAGE_ERROR_PRESENT_FLAG (1 << 0)
  37. #define PAGE_ERROR_WRITE_FLAG (1 << 1)
  38. #define PAGE_ERROR_USERMODE_FLAG (1 << 2)
  39. #define ADDR_TO_PDE(x) ((x) >> 22)
  40. #define ADDR_TO_PTE(x) (((x) >> 12) & 0x3FF)
  41. #define PAGE_ALIGN(x) ((x) & 0xFFFFF000)
  42. #define PAGE_ALIGN_UP(x) (((x) + 0xFFF) & 0xFFFFF000)
  43. #define PAGE_OFFSET(x) ((x) & 0x00000FFF)
  44. #define PAGE_NUMBER(x) ((x) >> 12)
  45. #define KERNEL_AREA_START 0x80000000
  46. #define KERNEL_AREA_END 0xFFFFFFFF
  47. #define KERNEL_POOL_START 0x81000000
  48. #define KERNEL_POOL_END 0xBFFFFFFF
  49. #define MAPPING_START 0xC8000000
  50. #define MAPPING_END 0xFFFFFFFF
  51. #define USER_AREA_START 0x00000000
  52. #define USER_AREA_END 0x7FFFFFFF
  53. #define KERNEL_PAGE_START ADDR_TO_PDE(KERNEL_AREA_START)
  54. #define KERNEL_PAGE_END ADDR_TO_PDE(KERNEL_AREA_END)
  55. #define USER_PAGE_START ADDR_TO_PDE(USER_AREA_START)
  56. #define USER_PAGE_END ADDR_TO_PDE(USER_AREA_END)
  57. #define PAGEDIR_SELF_ENTRY 768
  58. #define PAGE_DIRECTORY_ADDR ((PAGEDIR_SELF_ENTRY << 22) + (PAGEDIR_SELF_ENTRY << 12))
  59. #define PAGE_TABLE_ADDR (PAGEDIR_SELF_ENTRY << 22)
  60. #define INVALID_PAGE ((void*)-1)
  61. #define TOTAL_PAGES 1048576
  62. #define MEM_STACK_VIRT_ADDR 0xC0400000
  63. #define MEM_TREE_BLOCKS 0xC0800000
  64. #define TEMPORARY_PAGES 256
  65. #define TEMPORARY_ADDR (0xC8000000 - TEMPORARY_PAGES * PAGE_SIZE)
  66. #define EVICTION_THRESHOLD 128
  67. #define INVALID_STORE_NUMBER ((dword_t)-1)
  68. #define PAGE_STORE_ENTRY_PRESENT (1 << 31)
  69. typedef struct memory_block memory_block_t;
  70. typedef struct
  71. {
  72. uintptr_t phys_addr;
  73. uintptr_t ref_count;
  74. } page_t;
  75. typedef struct
  76. {
  77. list_entry_t link;
  78. void *page_directory;
  79. void *pool_address;
  80. uintptr_t pool_size;
  81. avl_tree_t by_addr_tree;
  82. avl_tree_t by_size_tree;
  83. lock_t lock;
  84. list_entry_t evictable_blocks;
  85. list_entry_t *evict_blk_ptr;
  86. uintptr_t evict_page_num;
  87. memory_stats_t stats;
  88. } memory_address_space_t;
  89. typedef struct
  90. {
  91. list_entry_t link;
  92. void *physical;
  93. uintptr_t offset;
  94. } shared_page_t;
  95. typedef struct
  96. {
  97. object_t header;
  98. dword_t flags;
  99. list_entry_t page_list;
  100. size_t size;
  101. file_instance_t *file; /* strong reference */
  102. } memory_section_t;
  103. struct memory_block
  104. {
  105. avl_node_t by_addr_node;
  106. avl_node_t by_size_node;
  107. list_entry_t evict_link;
  108. uintptr_t address;
  109. size_t size;
  110. dword_t flags;
  111. memory_address_space_t *address_space;
  112. memory_section_t *section;
  113. qword_t section_offset;
  114. };
  115. typedef struct
  116. {
  117. list_entry_t link;
  118. dword_t num_entries;
  119. dword_t max_entries;
  120. handle_t file_handle;
  121. dword_t *bitmap;
  122. list_entry_t entry_list;
  123. } page_store_t;
  124. typedef struct
  125. {
  126. list_entry_t link;
  127. void *address;
  128. memory_address_space_t *address_space;
  129. dword_t number;
  130. void *physical;
  131. } page_store_entry_t;
  132. typedef enum
  133. {
  134. PAGE_ERROR_NOTPRESENT,
  135. PAGE_ERROR_READONLY,
  136. PAGE_ERROR_UNPRIVILEGED
  137. } page_error_t;
  138. void set_page_directory(void *phys_addr);
  139. void *get_page_directory();
  140. void *get_physical_address(void *virtual);
  141. dword_t map_memory_internal(void *physical, void *virtual, size_t size, dword_t page_flags);
  142. void unmap_memory_internal(void *virtual, size_t size);
  143. dword_t read_physical(void *physical, void *buffer, size_t size);
  144. dword_t write_physical(void *physical, void *buffer, size_t size);
  145. dword_t map_memory_in_address_space(memory_address_space_t *address_space,
  146. void *physical,
  147. void **virtual,
  148. uintptr_t size,
  149. dword_t block_flags);
  150. dword_t unmap_memory_in_address_space(memory_address_space_t *address_space, void *virtual);
  151. dword_t pin_memory(const void *virtual, void **pinned, size_t size, bool_t lock_contents);
  152. dword_t map_memory(void *physical, void **virtual, size_t size, dword_t page_flags);
  153. dword_t unmap_memory(void *virtual);
  154. dword_t alloc_memory_in_address_space(
  155. memory_address_space_t *address_space,
  156. void **address,
  157. size_t size,
  158. dword_t block_flags,
  159. memory_section_t *section,
  160. qword_t section_offset);
  161. dword_t free_memory_in_address_space(memory_address_space_t *address_space, void *address);
  162. dword_t commit_pages(void *address, size_t size);
  163. dword_t uncommit_pages(void *address, size_t size);
  164. void *alloc_pool(void *address, size_t size, dword_t block_flags);
  165. void free_pool(void *address);
  166. dword_t create_address_space(void *base_address, dword_t page_count, memory_address_space_t *mem_space);
  167. dword_t clone_address_space(memory_address_space_t *original, memory_address_space_t *clone);
  168. void bump_address_space(memory_address_space_t *mem_space);
  169. void delete_address_space(memory_address_space_t *mem_space);
  170. bool_t memory_fault_handler(void *address, registers_t *regs);
  171. void memory_init(multiboot_tag_mmap_t *mmap, uintptr_t lowest_physical);
  172. void memory_cleanup(object_t *obj);
  173. #endif