1
0

memory.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * memory.h
  3. *
  4. * Copyright (C) 2019 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 <lock.h>
  22. #include <sdk/list.h>
  23. #include <sdk/memory.h>
  24. #include <sdk/avltree.h>
  25. #include <exception.h>
  26. #include <object.h>
  27. #include <filesystem.h>
  28. #define INVALID_PAGE ((physical_t)-1)
  29. #define PAGE_SIZE 0x1000
  30. #define MAX_PAGING_LEVELS 6
  31. #define MIN_PHYS_ADDR_BITS 16
  32. #define MAX_PHYS_ADDR_BITS 52
  33. #define MEMORY_MAX_BLOCKS 0x80000
  34. #define MEMORY_METADATA_TOP 0xFF000000
  35. #define PAGE_ALIGN(x) ((x) & ~(PAGE_SIZE - 1))
  36. #define PAGE_OFFSET(x) ((x) & (PAGE_SIZE - 1))
  37. #define PAGE_NUMBER(x) (PAGE_ALIGN(x) >> 12)
  38. #define PAGE_ALIGN_UP(x) PAGE_ALIGN((x) + PAGE_SIZE - 1)
  39. typedef qword_t physical_t;
  40. typedef physical_t page_num_t;
  41. typedef void *page_table_t;
  42. typedef enum
  43. {
  44. PAGE_STATUS_ABANDONED = 0,
  45. PAGE_STATUS_FREE,
  46. PAGE_STATUS_ALLOCATED,
  47. PAGE_STATUS_RESERVED,
  48. } page_status_t;
  49. typedef struct
  50. {
  51. mini_list_entry_t stack_link;
  52. page_status_t status : 2;
  53. byte_t map_level : 3;
  54. page_num_t number : 40;
  55. size_t map_count;
  56. } page_t;
  57. _Static_assert(PAGE_SIZE % sizeof(page_t) == 0, "The size of page_t must be a divisor of the page size.");
  58. typedef struct
  59. {
  60. page_t *pages;
  61. page_num_t count;
  62. } area_t;
  63. typedef struct
  64. {
  65. physical_t address;
  66. qword_t length;
  67. page_status_t status;
  68. } memory_map_entry_t;
  69. typedef enum
  70. {
  71. MEMORY_ZERO_BACKED_SECTION,
  72. MEMORY_FILE_BACKED_SECTION,
  73. MEMORY_PHYSICAL_BACKED_SECTION,
  74. } memory_section_backing_t;
  75. typedef struct
  76. {
  77. object_t header;
  78. memory_section_backing_t backing;
  79. page_num_t num_pages;
  80. union
  81. {
  82. page_t *pages;
  83. file_instance_t *file; /* strong reference */
  84. };
  85. } memory_section_t;
  86. typedef struct
  87. {
  88. avl_node_t by_addr_node;
  89. avl_node_t by_size_node;
  90. uintptr_t address;
  91. size_t size;
  92. memory_flags_t flags;
  93. memory_section_t *section;
  94. page_num_t section_offset;
  95. } memory_block_t;
  96. typedef struct
  97. {
  98. memory_block_t *blocks;
  99. dword_t *block_bitmap;
  100. avl_tree_t by_addr_tree;
  101. avl_tree_t by_size_tree;
  102. lock_t lock;
  103. page_t *root_page_table;
  104. } address_space_t;
  105. extern uintptr_t memory_metadata_base;
  106. extern const page_table_t memory_default_table;
  107. extern const page_table_t memory_shadow_table;
  108. extern address_space_t *memory_lower_space;
  109. extern address_space_t *const memory_upper_space;
  110. void memory_init(uintptr_t mboot_tags, size_t mboot_size);
  111. void *memory_request_metadata_space(size_t count, size_t size);
  112. page_t *memory_acquire_page(byte_t min_bits, byte_t max_bits, size_t alignment);
  113. void memory_acquire_area(byte_t min_bits, byte_t max_bits, size_t size, size_t alignment, area_t *area);
  114. void memory_release_page(page_t *page);
  115. void memory_release_area(const area_t *area);
  116. page_t *memory_find_page_by_address(physical_t address);
  117. void memory_claim_physical_region(physical_t address, qword_t size, page_status_t initial_status);
  118. void memory_abandon_physical_region(physical_t address, qword_t size);
  119. void memory_init_physical(memory_map_entry_t *mmap, size_t entry_count);
  120. static inline bool_t is_area_valid(const area_t *area)
  121. {
  122. return area->pages && area->count > 0 ? TRUE : FALSE;
  123. }
  124. page_t *memory_get_page_mapping(page_table_t table, void *address);
  125. sysret_t memory_map_page(page_table_t table, page_t *page, void *address, memory_flags_t access_flags);
  126. sysret_t memory_map_area(page_table_t table, const area_t *area, void *address, memory_flags_t access_flags);
  127. sysret_t memory_query_page_flags(page_table_t table, void *address, memory_flags_t *access_flags);
  128. sysret_t memory_adjust_page_flags(page_table_t table, void *address, memory_flags_t access_flags);
  129. sysret_t memory_unmap_clear_page(page_table_t table, void *address);
  130. sysret_t memory_unmap_keep_page(page_table_t table, void *address);
  131. sysret_t memory_unmap_clear_area(page_table_t table, void *address, size_t size);
  132. sysret_t memory_unmap_keep_area(page_table_t table, void *address, size_t size);
  133. sysret_t memory_load_default_table(page_t *new_default_table);
  134. sysret_t memory_load_shadow_table(page_t *new_shadow_table);
  135. sysret_t memory_unload_shadow_table(void);
  136. page_t *memory_create_page_table(void);
  137. sysret_t memory_commit(void *address, size_t size);
  138. void memory_init_mapping(void);
  139. memory_block_t *memory_get_block_for_address(void *address);
  140. sysret_t memory_allocate(address_space_t *space, void **address, size_t size, memory_flags_t flags, memory_section_t *section, page_num_t section_offset);
  141. sysret_t memory_free(address_space_t *space, void *address);
  142. sysret_t memory_view_area(address_space_t *space, void **address, const area_t *area, memory_flags_t flags);
  143. sysret_t memory_pin_buffer(const void *virtual, void **pinned, size_t size, bool_t lock_contents);
  144. void memory_init_virtual(const area_t *kernel_area);
  145. bool_t memory_fault_handler(void *address, registers_t *regs);
  146. void memory_cleanup(object_t *object);
  147. #endif