123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- /*
- * memory.h
- *
- * Copyright (C) 2019 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- #ifndef _MEMORY_H_
- #define _MEMORY_H_
- #include <lock.h>
- #include <sdk/list.h>
- #include <sdk/memory.h>
- #include <sdk/avltree.h>
- #include <exception.h>
- #include <object.h>
- #include <filesystem.h>
- #define INVALID_PAGE ((physical_t)-1)
- #define PAGE_SIZE 0x1000
- #define MAX_PAGING_LEVELS 6
- #define MIN_PHYS_ADDR_BITS 16
- #define MAX_PHYS_ADDR_BITS 52
- #define MEMORY_MAX_BLOCKS 0x80000
- #define MEMORY_METADATA_TOP 0xFF000000
- #define PAGE_ALIGN(x) ((x) & ~(PAGE_SIZE - 1))
- #define PAGE_OFFSET(x) ((x) & (PAGE_SIZE - 1))
- #define PAGE_NUMBER(x) (PAGE_ALIGN(x) >> 12)
- #define PAGE_ALIGN_UP(x) PAGE_ALIGN((x) + PAGE_SIZE - 1)
- typedef qword_t physical_t;
- typedef physical_t page_num_t;
- typedef void *page_table_t;
- typedef enum
- {
- PAGE_STATUS_ABANDONED = 0,
- PAGE_STATUS_FREE,
- PAGE_STATUS_ALLOCATED,
- PAGE_STATUS_RESERVED,
- } page_status_t;
- typedef struct
- {
- mini_list_entry_t stack_link;
- page_status_t status : 2;
- byte_t map_level : 3;
- page_num_t number : 40;
- size_t map_count;
- } page_t;
- _Static_assert(PAGE_SIZE % sizeof(page_t) == 0, "The size of page_t must be a divisor of the page size.");
- typedef struct
- {
- page_t *pages;
- page_num_t count;
- } area_t;
- typedef struct
- {
- physical_t address;
- qword_t length;
- page_status_t status;
- } memory_map_entry_t;
- typedef enum
- {
- MEMORY_ZERO_BACKED_SECTION,
- MEMORY_FILE_BACKED_SECTION,
- MEMORY_PHYSICAL_BACKED_SECTION,
- } memory_section_backing_t;
- typedef struct
- {
- object_t header;
- memory_section_backing_t backing;
- page_num_t num_pages;
- union
- {
- page_t *pages;
- file_instance_t *file; /* strong reference */
- };
- } memory_section_t;
- typedef struct
- {
- avl_node_t by_addr_node;
- avl_node_t by_size_node;
- uintptr_t address;
- size_t size;
- memory_flags_t flags;
- memory_section_t *section;
- page_num_t section_offset;
- } memory_block_t;
- typedef struct
- {
- memory_block_t *blocks;
- dword_t *block_bitmap;
- avl_tree_t by_addr_tree;
- avl_tree_t by_size_tree;
- lock_t lock;
- page_t *root_page_table;
- } address_space_t;
- extern uintptr_t memory_metadata_base;
- extern const page_table_t memory_default_table;
- extern const page_table_t memory_shadow_table;
- extern address_space_t *memory_lower_space;
- extern address_space_t *const memory_upper_space;
- void memory_init(uintptr_t mboot_tags, size_t mboot_size);
- void *memory_request_metadata_space(size_t count, size_t size);
- page_t *memory_acquire_page(byte_t min_bits, byte_t max_bits, size_t alignment);
- void memory_acquire_area(byte_t min_bits, byte_t max_bits, size_t size, size_t alignment, area_t *area);
- void memory_release_page(page_t *page);
- void memory_release_area(const area_t *area);
- page_t *memory_find_page_by_address(physical_t address);
- void memory_claim_physical_region(physical_t address, qword_t size, page_status_t initial_status);
- void memory_abandon_physical_region(physical_t address, qword_t size);
- void memory_init_physical(memory_map_entry_t *mmap, size_t entry_count);
- static inline bool_t is_area_valid(const area_t *area)
- {
- return area->pages && area->count > 0 ? TRUE : FALSE;
- }
- page_t *memory_get_page_mapping(page_table_t table, void *address);
- sysret_t memory_map_page(page_table_t table, page_t *page, void *address, memory_flags_t access_flags);
- sysret_t memory_map_area(page_table_t table, const area_t *area, void *address, memory_flags_t access_flags);
- sysret_t memory_query_page_flags(page_table_t table, void *address, memory_flags_t *access_flags);
- sysret_t memory_adjust_page_flags(page_table_t table, void *address, memory_flags_t access_flags);
- sysret_t memory_unmap_clear_page(page_table_t table, void *address);
- sysret_t memory_unmap_keep_page(page_table_t table, void *address);
- sysret_t memory_unmap_clear_area(page_table_t table, void *address, size_t size);
- sysret_t memory_unmap_keep_area(page_table_t table, void *address, size_t size);
- sysret_t memory_load_default_table(page_t *new_default_table);
- sysret_t memory_load_shadow_table(page_t *new_shadow_table);
- sysret_t memory_unload_shadow_table(void);
- page_t *memory_create_page_table(void);
- sysret_t memory_commit(void *address, size_t size);
- void memory_init_mapping(void);
- memory_block_t *memory_get_block_for_address(void *address);
- 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);
- sysret_t memory_free(address_space_t *space, void *address);
- sysret_t memory_view_area(address_space_t *space, void **address, const area_t *area, memory_flags_t flags);
- sysret_t memory_pin_buffer(const void *virtual, void **pinned, size_t size, bool_t lock_contents);
- void memory_init_virtual(const area_t *kernel_area);
- bool_t memory_fault_handler(void *address, registers_t *regs);
- void memory_cleanup(object_t *object);
- #endif
|