First commit, Vystem v0.1
This commit is contained in:
159
shelter/lib/include/memory/page.h
Normal file
159
shelter/lib/include/memory/page.h
Normal file
@@ -0,0 +1,159 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
#ifndef SH_LIB_PAGE_H
|
||||
#define SH_LIB_PAGE_H
|
||||
#include "std/type.h"
|
||||
#include "std/status.h"
|
||||
#include "memory/vmem_layout.h"
|
||||
#define SH_PAGE_KERNEL_PERM_VA_BASE SH_VMEM_LAYOUT_KERNEL_ALLOC_SPACE_VA
|
||||
#define SH_PAGE_KERNEL_PERM_VA_END SH_VMEM_LAYOUT_KERNEL_ALLOC_SPACE_VA_END
|
||||
#define SH_PAGE_MEMORY_MAP_VA SH_VMEM_LAYOUT_MEMORY_MAP_VA
|
||||
#define SH_PAGE_SIZE 4096
|
||||
#define SH_PAGE_MAX_MEM_COUNT 16ULL*1024*1024*1024*1024
|
||||
#define SH_PAGE_MAX_PAGES_COUNT (SH_PAGE_MAX_MEM_COUNT/SH_PAGE_SIZE)
|
||||
#define SH_PAGE_PTP_ALLOCATOR_PAGES_COUNT 4096
|
||||
#define SH_PAGE_PTP_ALLOCATOR_BITMAP_UINT64 SH_PAGE_PTP_ALLOCATOR_PAGES_COUNT/64
|
||||
typedef sh_uint32 sh_page_MEMORY_TYPE;
|
||||
#define SH_PAGE_RESERVED_MEMORY_TYPE (sh_page_MEMORY_TYPE)0
|
||||
#define SH_PAGE_LOADER_CODE (sh_page_MEMORY_TYPE)1
|
||||
#define SH_PAGE_LOADER_DATA (sh_page_MEMORY_TYPE)2
|
||||
#define SH_PAGE_BOOT_SERVICES_CODE (sh_page_MEMORY_TYPE)3
|
||||
#define SH_PAGE_BOOT_SERVICES_DATA (sh_page_MEMORY_TYPE)4
|
||||
#define SH_PAGE_RUNTIME_SERVICES_CODE (sh_page_MEMORY_TYPE)5
|
||||
#define SH_PAGE_RUNTIME_SERVICES_DATA (sh_page_MEMORY_TYPE)6
|
||||
#define SH_PAGE_CONVENTIONAL_MEMORY (sh_page_MEMORY_TYPE)7
|
||||
#define SH_PAGE_UNUSABLE_MEMORY (sh_page_MEMORY_TYPE)8
|
||||
#define SH_PAGE_ACPI_RECLAIM_MEMORY (sh_page_MEMORY_TYPE)9
|
||||
#define SH_PAGE_ACPI_MEMORY_NVS (sh_page_MEMORY_TYPE)10
|
||||
#define SH_PAGE_MEMORY_MAPPED_IO (sh_page_MEMORY_TYPE)11
|
||||
#define SH_PAGE_MEMORY_MAPPED_IO_PORT_SPACE (sh_page_MEMORY_TYPE)12
|
||||
#define SH_PAGE_PAL_CODE (sh_page_MEMORY_TYPE)13
|
||||
#define SH_PAGE_PERSISTENT_MEMORY (sh_page_MEMORY_TYPE)14
|
||||
#define SH_PAGE_RESERVED (sh_page_MEMORY_TYPE)15
|
||||
typedef sh_uint64 sh_page_PHYSICAL_ADDRESS;
|
||||
typedef sh_uint64 sh_page_VIRTUAL_ADDRESS;
|
||||
#define SH_PAGE_NULL_PA (sh_page_PHYSICAL_ADDRESS)0
|
||||
#define SH_PAGE_NULL_VA (sh_page_VIRTUAL_ADDRESS)0
|
||||
#define SH_PAGE_PRESENT (1ULL<<0)
|
||||
#define SH_PAGE_TABLE_FLAGS (1ULL<<1)
|
||||
#define SH_PAGE_RW (1ULL<<1)
|
||||
#define SH_PAGE_US (1ULL<<2)
|
||||
#define SH_PAGE_PWT (1ULL<<3)
|
||||
#define SH_PAGE_PCD (1ULL<<4)
|
||||
#define SH_PAGE_ACCESSED (1ULL<<5)
|
||||
#define SH_PAGE_DIRTY (1ULL<<6)
|
||||
#define SH_PAGE_PS (1ULL<<7)
|
||||
#define SH_PAGE_GLOBAL (1ULL<<8)
|
||||
#define SH_PAGE_NX (1ULL<<63)
|
||||
// Memory map entry structure.
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
sh_uint32 type;
|
||||
sh_uint64 physical_start;
|
||||
sh_uint64 pages_count;
|
||||
sh_uint64 attributes;
|
||||
} sh_page_MEMORY_MAP_ENTRY;
|
||||
#pragma pack()
|
||||
// Memory map header structure.
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
sh_uint8 sig_start[8];
|
||||
sh_uint64 entry_count;
|
||||
sh_uint64 entry_size;
|
||||
sh_uint8 mmap_syntax_version;
|
||||
} sh_page_MEMORY_MAP_HEADER;
|
||||
#pragma pack()
|
||||
// Page table pool structure.
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
sh_page_PHYSICAL_ADDRESS page_table_pa;
|
||||
sh_page_VIRTUAL_ADDRESS page_table_va;
|
||||
sh_uint64 ptp_alloc_bitmap[SH_PAGE_PTP_ALLOCATOR_BITMAP_UINT64];
|
||||
sh_uint64 ptp_pages_count;
|
||||
sh_uint64 ptp_alloc_bitmap_uint64_count;
|
||||
} sh_page_PAGE_TABLE_POOL;
|
||||
#pragma pack()
|
||||
// Memory statistics structure
|
||||
typedef struct {
|
||||
sh_uint64 memory_total_pages; // memory_total is the size of the addressable physical space
|
||||
sh_uint64 memory_total_bytes;
|
||||
sh_uint64 memory_installed_pages; // memory_installed is the sum of the size of all free regions at kernel boot
|
||||
sh_uint64 memory_installed_bytes;
|
||||
sh_uint64 free_pages;
|
||||
sh_uint64 used_pages;
|
||||
double free_ratio;
|
||||
double used_ratio;
|
||||
sh_uint64 largest_free_block;
|
||||
sh_uint64 largest_used_block;
|
||||
sh_uint64 free_blocks_count;
|
||||
sh_uint64 used_blocks_count;
|
||||
sh_uint64 physical_bitmap_size_pages;
|
||||
sh_uint64 physical_bitmap_size_bytes;
|
||||
} sh_page_MEM_STATS;
|
||||
// Load boot PTP VA. Intended for one usage only.
|
||||
SH_STATUS sh_page_load_boot_ptp_va(sh_page_VIRTUAL_ADDRESS pt_pool_va);
|
||||
// Return boot PTP VA.
|
||||
sh_page_VIRTUAL_ADDRESS sh_page_get_boot_ptp_va();
|
||||
// Copy memory map provided bootloader into dedicated buffer. Intended for one usage only.
|
||||
SH_STATUS sh_page_copy_memory_map();
|
||||
// Check for memory map signatures and read memory map header.
|
||||
SH_STATUS sh_page_check_memory_map();
|
||||
// Return the amount of physical memory in pages
|
||||
sh_uint64 sh_page_get_physical_memory_amount_pages();
|
||||
// Return the amount of physical memory in bytes
|
||||
sh_uint64 sh_page_get_physical_memory_amount_bytes();
|
||||
// Return the first available physical page in physical bitmap.
|
||||
sh_uint64 sh_page_get_one_page_na();
|
||||
// Set pages ranges into provided bitmap.
|
||||
SH_STATUS sh_page_set_pages_range_bitmap(sh_uint8 *bitmap,sh_uint64 page_count_in_bitmap,sh_uint64 page_index,sh_uint64 page_count,sh_bool state);
|
||||
// Return the status of a page inside the provided bitmap.
|
||||
static inline sh_bool sh_page_is_allocated(sh_uint8 *bitmap,sh_uint64 page_index) {
|
||||
sh_uint64 byte_index=page_index/8;
|
||||
sh_uint8 bit_index=page_index%8;
|
||||
return (bitmap[byte_index] & (1u<<bit_index))!=0;
|
||||
}
|
||||
// Initialize PTP structure.
|
||||
SH_STATUS sh_page_init_ptp(sh_page_PHYSICAL_ADDRESS ptp_pa,sh_page_VIRTUAL_ADDRESS ptp_va,sh_uint64 initial_fill_level,sh_page_PAGE_TABLE_POOL *page_table_pool);
|
||||
// Dump provided PTP bitmap, intented for debug.
|
||||
SH_STATUS sh_page_dump_ptp_bitmap(sh_page_PAGE_TABLE_POOL *ptp);
|
||||
// Allocate one page from a PTP internal bitmap.
|
||||
sh_page_PHYSICAL_ADDRESS sh_page_ptp_alloc_one_page(sh_page_PAGE_TABLE_POOL *pt_pool);
|
||||
// Convert a PA provided by any layer of the PTP into a valid VA. Return 0 if PA isn't in expected range.
|
||||
static inline sh_uint64 *sh_page_ptp_pa_to_va(sh_page_PAGE_TABLE_POOL *ptp,sh_uint64 pa) {
|
||||
sh_uint64 base=ptp->page_table_pa;
|
||||
sh_uint64 size=ptp->ptp_pages_count*4096;
|
||||
if (pa<base || pa>=base+size) return 0;
|
||||
return (sh_uint64 *)(ptp->page_table_va+(pa-base));
|
||||
}
|
||||
// Map one physical page to VA to provided PTP.
|
||||
SH_STATUS sh_page_map_one_page_ptp(sh_page_PAGE_TABLE_POOL *ptp,sh_page_VIRTUAL_ADDRESS va,sh_page_PHYSICAL_ADDRESS pa,sh_uint64 flags);
|
||||
// Return according SH_STATUS if provided VA is mapped inside provided PTP.
|
||||
SH_STATUS sh_page_is_va_mapped_ptp(sh_page_PAGE_TABLE_POOL *ptp,sh_page_VIRTUAL_ADDRESS va);
|
||||
// Return according SH_STATUS if provided VA is mapped inside provided PTP for all the range provided
|
||||
SH_STATUS sh_page_is_va_range_mapped_ptp(sh_page_PAGE_TABLE_POOL *ptp,sh_page_VIRTUAL_ADDRESS va,sh_uint64 size_bytes);
|
||||
// Search for an available amount of virtual memory inside provided range with the provided size
|
||||
SH_STATUS sh_page_search_available_va_range(sh_page_PAGE_TABLE_POOL *ptp,sh_page_VIRTUAL_ADDRESS range_base,sh_page_VIRTUAL_ADDRESS range_size_bytes,sh_uint64 size_bytes,sh_page_VIRTUAL_ADDRESS *address_found);
|
||||
// Map a range of pages from PA to VA. Both virtual and physic area has to be continuous. VAs availability is checked, not physical pages availability.
|
||||
SH_STATUS sh_page_map_contiguous_pages_range_ptp(sh_page_PAGE_TABLE_POOL *ptp,sh_page_VIRTUAL_ADDRESS va,sh_page_PHYSICAL_ADDRESS pa,sh_uint64 flags,sh_uint64 size_bytes);
|
||||
// Search for an available amount of pages inside physical bitmap
|
||||
SH_STATUS sh_page_search_physical_contiguous_block_na(sh_uint64 pages_needed,sh_page_PHYSICAL_ADDRESS *pa);
|
||||
// Allocate the corresponding amount of pages to size_bytes.
|
||||
SH_STATUS sh_page_alloc_contiguous(sh_page_PAGE_TABLE_POOL *ptp,sh_uint64 size_bytes,sh_page_VIRTUAL_ADDRESS* va);
|
||||
// Allocate the corresponding amount of pages to size_bytes. Provide support for custom flags and VA range search.
|
||||
SH_STATUS sh_page_alloc_contiguous_extended(sh_page_PAGE_TABLE_POOL *ptp,sh_uint64 size_bytes,sh_page_VIRTUAL_ADDRESS* va,DEFAULT sh_uint64 flags,DEFAULT sh_page_VIRTUAL_ADDRESS va_range_start,DEFAULT sh_uint64 va_range_size_bytes);
|
||||
// Unmap one page from a PTP, assume VA is mapped. Does not unallocate associed physical page
|
||||
SH_STATUS sh_page_unmap_one_page_ptp(sh_page_PAGE_TABLE_POOL *ptp,sh_page_VIRTUAL_ADDRESS va);
|
||||
// Map a range of pages to VA. Both virtual and physic area has to be continuous. VAs mapping is checked, not physical pages occupation.
|
||||
SH_STATUS sh_page_unmap_contiguous_pages_range_ptp(sh_page_PAGE_TABLE_POOL *ptp,sh_page_VIRTUAL_ADDRESS va,sh_uint64 size_bytes);
|
||||
// Convert a VA allocated in a PTP into his equivalent PA by searching inside the PTP
|
||||
SH_STATUS sh_page_ptp_va_to_pa(sh_page_PAGE_TABLE_POOL *ptp,sh_page_VIRTUAL_ADDRESS va,sh_page_PHYSICAL_ADDRESS *pa);
|
||||
// Unalloc one page from a VA. Check if VA is mapped or not. PA is calculted trough searching in PTP
|
||||
SH_STATUS sh_page_unalloc_one_page(sh_page_PAGE_TABLE_POOL *ptp,sh_page_VIRTUAL_ADDRESS va);
|
||||
// Unalloc a range of virtually contiguous pages. Check if the entire range is allocated before unallocating anything.
|
||||
SH_STATUS sh_page_unalloc_contiguous(sh_page_PAGE_TABLE_POOL *ptp,sh_page_VIRTUAL_ADDRESS va,sh_uint64 size_bytes);
|
||||
// Parse memory map, set all non usable pages into physical bitmap and compute available amount of physical memory. Intended for one usage only.
|
||||
SH_STATUS sh_page_analyse_memory_map(sh_page_PAGE_TABLE_POOL *ptp);
|
||||
// Return physical bitmap pointer
|
||||
sh_page_VIRTUAL_ADDRESS sh_page_get_physical_bitmap_ptr();
|
||||
// Get physical memory statistics
|
||||
SH_STATUS sh_page_get_memory_stats(sh_page_MEM_STATS *mem_stats);
|
||||
#endif
|
||||
Reference in New Issue
Block a user