1
0
bifurqué depuis xt-sys/exectos

261 Révisions

Auteur SHA1 Message Date
4e02664977 Merge branch 'master' into memmgr 2026-03-26 23:48:49 +01:00
bad3aaf6e0 Export memory manager pool allocation and free functions 2026-03-26 23:46:50 +01:00
9b19bc94b3 Replace manual IDT manipulation with SetIdtGate function call 2026-03-26 23:10:00 +01:00
9479f3d364 Implement APIC presence check and panic if unsupported 2026-03-25 22:52:58 +01:00
8d97ea4112 Merge branch 'master' into memmgr 2026-03-25 15:06:14 +01:00
40d54743e0 Enhance kernel panic output 2026-03-25 15:02:26 +01:00
576a2b7f1b Enhance kernel panic output 2026-03-25 14:59:40 +01:00
3c2ad358ef Implement MM::KernelPool::FreeProcessorStructures 2026-03-25 14:11:24 +01:00
e734ddda65 Implement TLB flushing for cache attribute changes during page removal 2026-03-25 13:24:44 +01:00
a79f26250a Fix check for PTE removal flag 2026-03-25 09:53:57 +01:00
441e4f510b Mark PFN as deleted instead of clearing PteAddress when freeing pages 2026-03-25 09:51:09 +01:00
33665839ad Revert 1e01c52c0c 2026-03-25 08:59:46 +01:00
1e01c52c0c Clear the internal list links to prevent corruption 2026-03-25 07:48:13 +01:00
970902f3f9 Rephrase comments for consistency 2026-03-24 23:07:06 +01:00
adff181f5a Add bounds checking and implement reclamation for large expansion pool allocations 2026-03-24 23:00:28 +01:00
92986e1386 Set PTE frame for non-paged pool allocations 2026-03-24 20:03:23 +01:00
9a34a5f735 Precommit page map to allocate memory 2026-03-24 16:54:17 +01:00
398db4bde1 Fix memory map size tracking and memory leak 2026-03-24 16:12:33 +01:00
719564ba74 Fix memory corruption caused by UEFI memory map size changes during allocation 2026-03-24 16:04:53 +01:00
b95613787a Strip MM_POOL_PROTECTED flag to maintain NT compatibility and ensure correct pool tracking hash lookups 2026-03-24 08:39:47 +01:00
4292d89185 Add expansion table and overflow handling for pool tag tracking 2026-03-24 08:13:05 +01:00
214051e873 Update pool tracking statistics when resizing big allocations table 2026-03-23 20:36:24 +01:00
3c52b88802 Unify naming convention for pool tracking structures 2026-03-23 20:12:18 +01:00
944d5b5c0a Implement pool allocations and frees tracking 2026-03-23 18:54:18 +01:00
597628a644 Refactor big allocation tracker to use Tag 2026-03-23 12:38:31 +01:00
b97babb2bf Remove temporary hack and allocate processor structures from non-paged pool 2026-03-22 23:40:15 +01:00
caacd9e275 Separate synchronization guards from spinlock implementation 2026-03-21 22:46:56 +01:00
916d124c9b Separate synchronization guards from spinlock implementation 2026-03-21 22:44:00 +01:00
d85e313c15 Implement core pool allocation and deallocation logic 2026-03-21 20:35:02 +01:00
b83eaaa820 Add definitions for pool management structures 2026-03-21 19:10:58 +01:00
233440c8be Merge branch 'master' into memmgr 2026-03-21 18:30:45 +01:00
140af4278e Fix uninitialized member in SpinLockGuard 2026-03-21 18:29:19 +01:00
c67372d747 Revert e2eff2b836 2026-03-19 20:13:07 +01:00
e2eff2b836 Fix DebugPrint definition 2026-03-19 20:07:30 +01:00
930c9d3193 Replace NULL with NULLPTR 2026-03-19 20:03:26 +01:00
f862871a1f Implement RAII guard for memory pool synchronization 2026-03-19 19:59:40 +01:00
afb20a1796 Decouple pool initialization and validation from allocation logic 2026-03-18 20:31:06 +01:00
876923e107 Track valid physical memory pages using a PFN bitmap 2026-03-17 00:05:33 +01:00
3d7fe25471 Update panic invocations with detailed error context 2026-03-16 16:00:21 +01:00
184ce5735e Add runlevel verification to memory pool allocations 2026-03-16 15:33:36 +01:00
76d99dc9db Introduce pool allocation and free routines 2026-03-16 13:54:42 +01:00
d401ac4540 Remove redundant comments from panic calls 2026-03-16 09:55:26 +01:00
22f9525e92 Fix critical memory corruption bug caused by overwriting active page tables marked as free memory 2026-03-15 22:34:58 +01:00
80092a299e Ensure correct PTE value assignment via accessors 2026-03-15 20:31:33 +01:00
42525e5993 Unify PTE type definitions across architectures 2026-03-15 20:23:44 +01:00
0fed593147 Ensure SS and RSP are saved in trap frame 2026-03-15 17:32:01 +01:00
6cdb66cbb3 Ensure SS and ESP are saved in trap frame 2026-03-15 00:33:09 +01:00
d263f17831 Refactor panic calls in memory manager 2026-03-13 19:44:29 +01:00
6175413db2 Merge branch 'master' into memmgr 2026-03-13 19:43:01 +01:00
428928c7e1 Simplify panic interface by using C++ overloading 2026-03-13 19:42:03 +01:00
7d2b41a044 Calculate virtual address per page when initializing PFN entries 2026-03-13 19:35:29 +01:00
5fe0740c2e Initialize system PTE pool for non-paged expansion pool 2026-03-10 23:09:40 +01:00
35eac9d34c Make MM::Pte::InitializeSystemPtePool public 2026-03-10 23:01:50 +01:00
5a78512561 Correct PTE mapping logic during multiple page allocation 2026-03-05 17:47:03 +01:00
b7a92ccce4 Implement memory deallocation and coalescing for non-paged pool 2026-03-05 10:08:54 +01:00
8d2dfa6f62 Set up owner pointers for all pages during pool initialization 2026-03-04 22:44:45 +01:00
5a9b7c0258 Implement canonical address validation routine 2026-03-04 14:15:33 +01:00
5368fe2e8d Remove redundant static initialization of LowestPhysicalPage 2026-03-03 22:42:55 +01:00
3e1f57f67c Improve type safety of physical page boundaries initialization 2026-03-03 08:51:22 +01:00
44f27fad28 Correct physical memory range detection 2026-03-03 08:22:31 +01:00
ae8ac1eacb Fix uninitialized PTE pages causing memory corruption 2026-03-03 06:44:40 +01:00
a72bfd3902 Add MIN and MAX helper macros 2026-02-26 20:12:28 +01:00
7bdd0dfe2c Implement basic non-paged pool allocator 2026-02-26 20:10:03 +01:00
5778a761b5 Initialize paged pool after PFN database setup 2026-02-26 16:42:18 +01:00
d7d125dd50 Initialize paged pool alongside non-paged pool 2026-02-26 13:54:10 +01:00
511dd15c0c Implement page allocation interface 2026-02-26 13:42:58 +01:00
278def3081 Correct comment phrasing 2026-02-26 10:57:19 +01:00
0658e98436 Expose the number of available physical pages 2026-02-25 20:25:50 +01:00
bfdb7bc476 Refactor PFN linking logic 2026-02-25 19:27:53 +01:00
44fa2ca13a Merge branch 'master' into memmgr 2026-02-25 13:08:48 +01:00
7a44901064 Add definition for guarded PTE flag and remove hardcoded value 2026-02-25 12:14:26 +01:00
7144242613 Maintain sequence counter 2026-02-24 17:40:45 +01:00
7e62919c6b Rework singly linked list API 2026-02-24 14:49:56 +01:00
a136f21f4b Merge branch 'master' into memmgr 2026-02-23 09:31:53 +01:00
2bbc21b667 Implement singly linked list support 2026-02-22 12:25:51 +01:00
70d758ec5b Improve comments 2026-02-22 12:21:43 +01:00
d1553ff84a Add SHA-1 hashing support 2026-02-19 18:49:29 +01:00
94a8917c5c Revert RTL::LinkedList::RemoveEntryList() routine signature and extend RTL::LinkedList API 2026-02-16 15:43:00 +01:00
f7b7b61ea4 Add interface to retrieve page map level (PML) 2026-02-11 20:23:24 +01:00
2af94a1c3b Use RTL::LinkedList::ListEmpty() routine to check if list is empty after removal 2026-02-11 19:15:57 +01:00
4b5188260f Fix build 2026-02-11 17:43:07 +01:00
47ec89a85e Forgotten to change signature in bootloader 2026-02-10 18:26:50 +01:00
edb40dd62b Change RTL::LinkedList::RemoveEntryList() routine signature 2026-02-10 18:24:26 +01:00
e2da6220f2 Fix PFN calculation truncation for memory above 4GB to prevent memory descriptor aliasing on PAE systems 2026-02-09 23:17:58 +01:00
53f7945771 Reorder initialization sequence and flush TLB 2026-02-07 20:37:23 +01:00
9a5ef6fc00 Map PDE and PTE ranges for i686 non-paged pool 2026-02-07 20:01:17 +01:00
fa64507350 Refactor EFI memory mapping to support distinct mapping strategies 2026-02-07 00:42:03 +01:00
80ea0b49d0 Fix boot image size alignment calculation 2026-02-07 00:30:41 +01:00
2e0e085acb Minor style fixes 2026-02-06 20:52:59 +01:00
0ce2741e18 Deduplicate PFN descriptor processing logic across architectures 2026-02-06 09:08:59 +01:00
a46f30045a Fix stale comment 2026-02-06 08:51:23 +01:00
0763a9522b Ensure paging hierarchy exists before processing memory descriptors 2026-02-06 08:40:24 +01:00
b51f21f55c Introduce page directory initialization helper 2026-02-06 00:20:01 +01:00
0590ad3bcd Remove explicit identity mapping for internal page tables 2026-02-04 19:21:23 +01:00
9b8417565b Fix coding style 2026-02-04 19:19:06 +01:00
bc391d6e1e Map and zero entire PFN database upfront 2026-02-03 22:32:10 +01:00
7b6e284d39 Refactor PFN database initialization loop on i686 2026-02-03 22:28:17 +01:00
fae72f5326 Fix missing assignment of PointerPte 2026-02-03 20:17:28 +01:00
eb0957dbd4 Refactor PFN initialization to ensure proper page table setup 2026-02-02 19:06:14 +01:00
3d7f512377 Use 64-bit format specifiers for memory mapping logs 2026-02-01 16:02:27 +01:00
7f0341bb83 Fix physical address limit checks 2026-02-01 11:11:59 +01:00
ba4ac6cec8 Fix PFN truncation on i686 with PAE enabled 2026-02-01 10:18:13 +01:00
b16dbb19f8 Centralize memory layout dumping 2026-01-30 18:47:46 +01:00
19f5307be6 Handle non-paged pool overflow 2026-01-30 18:38:54 +01:00
825de8b471 Remove redundant PFN database alignment 2026-01-30 17:46:20 +01:00
6a7bc64ac7 Overhaul kernel memory layout initialization and pool sizing 2026-01-30 14:47:13 +01:00
726fd84241 Enable non-paged pool setup 2026-01-29 22:34:44 +01:00
54e75c9345 Fix PFN database size calculation call sites 2026-01-29 22:29:02 +01:00
5e3fb7a5a3 Move PFN database size tracking to memory layout 2026-01-29 22:26:31 +01:00
58669d3074 Refactor memory layout structure 2026-01-29 22:10:26 +01:00
72f34c8286 Add private helper declaration 2026-01-29 20:10:48 +01:00
a7820ff568 Calculate aligned boot image size from loader parameters 2026-01-29 20:08:27 +01:00
7f6114f8e5 Add skeleton for memory pool allocator 2026-01-29 20:00:09 +01:00
fd29cf55ef Fix incorrect header guard comment 2026-01-29 19:49:54 +01:00
446ce920ec Limit system PTE space mapping to calculated pool size 2026-01-27 16:56:40 +01:00
a4b9f495e5 Calculate total boot image size and pass it to kernel 2026-01-27 16:50:11 +01:00
2c8eb6d692 Remove unused kernel base address definition 2026-01-23 20:59:10 +01:00
31b0e4f441 Ensure contiguous virtual memory mapping 2026-01-23 20:55:56 +01:00
b5f220a2ae Correctly advance virtual address after mapping non-free regions 2026-01-23 20:52:45 +01:00
0b1b76e9df Rollback bootloader memory management changes 2026-01-20 16:04:07 +01:00
d3edfef53b Fix broken PPE check on i686 2026-01-19 11:16:59 +01:00
46c24e653e Add routine to retrieve installed memory size 2026-01-15 19:09:10 +01:00
c3607ea943 Add missing annotations 2026-01-14 22:48:25 +01:00
7da6bcc75e Standardize ValidPte setup across architectures 2026-01-14 22:42:14 +01:00
0f38d39705 Correctly initialize PFN entries for pre-mapped KSEG0 based memory 2026-01-14 17:44:50 +01:00
587b85d0a4 Annotate input parameters 2026-01-13 15:39:16 +01:00
0766eb4566 Drop obsolete KSEG0_KERNEL_BASE definition 2026-01-12 23:05:01 +01:00
11f7c25713 Abstract base mapping address retrieval 2026-01-12 23:03:13 +01:00
15edd98242 Extract MapDescriptor logic and simplify memory mapping API 2026-01-12 22:46:04 +01:00
34c33a3b53 Clean up unused physical-to-virtual conversion routines 2026-01-12 19:40:27 +01:00
032cab7f2f Update function documentation and remove debug prints 2026-01-12 19:26:07 +01:00
5500192575 Remove manual virtual address tracking from boot sequence 2026-01-11 23:14:10 +01:00
ec94e2341c Relocate kernel and modules to KSEG0 memory space 2026-01-11 13:15:28 +01:00
9ed851ed1f Temporary fix for PAE addressing limits and KSEG0 base mapping 2026-01-09 20:54:13 +01:00
b91c79e090 Prevent adding referenced pages to the free list 2026-01-06 15:01:05 +01:00
bee91d0c71 Correctly setup PFN database for ROM and in-use pages 2026-01-06 14:49:30 +01:00
36e53bfc8c Ensure every page in a bad memory region is marked as bad 2026-01-06 14:05:09 +01:00
9027632c4f Make memory descriptor processing architecture-dependent 2026-01-05 23:39:42 +01:00
bd1a3605d2 Add logic to insert pages at the head of standby list 2026-01-05 23:12:58 +01:00
4b50278ac9 Add temporary fallback for BeginStandbyList insertion 2026-01-05 19:41:46 +01:00
154ca7be35 Allow PFN insertion at the beginning of standby list 2026-01-05 19:36:12 +01:00
3a087766cc Optimize system PTE deallocation by avoiding immediate and expensive TLB flush 2026-01-05 16:59:35 +01:00
410286d012 Replace ULONG with PFN_COUNT in system PTE variables 2026-01-05 16:48:26 +01:00
e66baa0da0 Fix deadlock by reducing lock scope 2026-01-05 01:28:09 +01:00
46576398a2 Add missing semicolon 2026-01-05 01:22:41 +01:00
cb6efc648f Implement kernel stack deallocation and physical page freeing logic 2026-01-05 01:20:21 +01:00
0a43a93f41 Add mechanism to free system PTEs and merge adjacent clusters 2026-01-04 21:11:33 +01:00
9f359c10ed Clean up paging code 2026-01-03 23:39:02 +01:00
455349f2d7 Remove dead code from paging and PTE management 2026-01-03 23:27:24 +01:00
5e5b4a8392 Initialize system PTEs with arch-specific list terminator 2026-01-03 21:11:29 +01:00
329143b4f6 Abstract PTE list terminator into paging layer 2026-01-03 21:03:14 +01:00
cc76ea40ee Add support for transitioning PTE to invalid state 2026-01-03 00:41:56 +01:00
0159262ee0 Add explicit default initialization for MM::Colors::ModifiedPages list 2026-01-01 20:59:31 +01:00
f653b9f79c Properly handle bad physical pages 2026-01-01 20:51:30 +01:00
7bcd78fdf3 Implement generic PFN list linking function 2026-01-01 20:40:45 +01:00
c080f74714 Introduce helper functions for querying the software prototype and transition bits of PTE 2026-01-01 19:40:23 +01:00
5ff0cad094 Introduce per-page-color modified page lists 2026-01-01 16:54:26 +01:00
00702bfb23 Remove redundant check for invisible memory regions 2025-12-30 13:10:32 +01:00
dbda6bbb29 Initialize PTE template dynamically to resolve build warnings 2025-12-29 23:49:29 +01:00
aced62e790 Prevent initialization of invisible memory ranges 2025-12-29 19:27:30 +01:00
53116b86a3 Improve formatting 2025-12-29 19:19:45 +01:00
d8fc223140 Adjust thread initialization to match new stack allocator signature 2025-12-29 19:16:13 +01:00
f4c49e2f25 Simplify stack page count calculation 2025-12-29 19:14:49 +01:00
4c7c914a1c Implement kernel stack allocation logic 2025-12-29 19:10:25 +01:00
4a00179af2 Implement logic to link physical pages to PTEs 2025-12-29 18:31:16 +01:00
0d2d41dcda Introduce page fault handling infrastructure 2025-12-29 14:53:43 +01:00
c1514557f6 Merge branch 'master' into memmgr 2025-12-29 14:35:10 +01:00
49e97fb8b4 Reserve space for color tables to fix invalid memory access 2025-12-29 13:17:41 +01:00
28f49dd545 Ensure page map structures are self-mapped 2025-12-29 10:56:43 +01:00
7cb3d1764b Initialize paged pool sizing logic 2025-12-29 10:28:12 +01:00
200e9132b1 Minor style fixes in MM includes 2025-12-28 23:51:34 +01:00
d891088b1a Update PTE support to use safe write accessors 2025-12-28 23:39:08 +01:00
04599161da Refactor memory clearing calls and cleanup code style 2025-12-28 23:36:20 +01:00
0880a0f344 Implement PFN database initialization and memory descriptor processing 2025-12-28 23:25:07 +01:00
4593a89a9b Expose PFN database lookup via GetPfnEntry 2025-12-28 21:18:17 +01:00
874d303f83 Update requirements 2025-12-26 10:39:55 +01:00
b7c004528a Implement tracking of available physical pages 2025-12-23 22:13:09 +01:00
5012c8dc37 Initialize system PTE pools and implement reservation routines 2025-12-23 20:16:08 +01:00
1e3917882c Initialize system page tables and configure kernel mappings 2025-12-23 18:03:02 +01:00
b3b874d3ce Include mm/colors.cc in kernel build configuration 2025-12-23 14:29:26 +01:00
288b2f8b24 Introduce page coloring support to memory manager 2025-12-23 14:27:12 +01:00
c7cc536685 Add storage for PFN database size 2025-12-23 14:13:33 +01:00
b8e81e2223 Initialize memory manager during kernel startup 2025-12-23 14:05:07 +01:00
0fd2b8b729 Update modified page list enum terminology 2025-12-23 13:55:42 +01:00
560cd43b34 Update memory manager type definitions and constants 2025-12-23 12:04:43 +01:00
f0a06db7d2 Bring up i686 page table initialization 2025-12-22 23:48:04 +01:00
7575526f07 Fix physical page count overflow by using 64-bit type 2025-12-22 23:32:54 +01:00
643fd0d1e8 Fix PTE free list sentinel handling 2025-12-22 15:00:14 +01:00
6aa148784b Select correct self-map base for PAE and non-PAE paging 2025-12-22 10:14:11 +01:00
e237a944cc Extend PTE helpers with raw read and write support 2025-12-22 08:21:43 +01:00
755a167f2c Respect architecture-specific PTE layouts and write PTEs via PML-aware helpers 2025-12-22 00:07:48 +01:00
24dccf4bed Make PPE mapping architecture-specific 2025-12-19 20:25:43 +01:00
7b93c39348 Add early spin lock initialization 2025-12-19 19:12:50 +01:00
570301bb35 Clarify page table entry offset semantics 2025-12-18 22:38:59 +01:00
b183d52806 Fix paging abstraction for PDE/PTE virtual address calculation 2025-12-18 22:26:31 +01:00
687c58d923 Implement initial virtual memory layout setup 2025-12-17 22:28:08 +01:00
049c9c6bbd Update SelfMapAddress 2025-12-17 20:35:28 +01:00
f1a76bc01a Call page table initialization 2025-12-16 22:34:41 +01:00
cb4d113e31 Add virtual address validation and system PTE helpers 2025-12-16 22:31:15 +01:00
728241f998 Move memory layout initialization to architecture-specific code 2025-12-16 20:36:16 +01:00
00d428d8de Architecture-specific system PTE limits 2025-12-16 20:05:51 +01:00
020b7c7676 Extend memory layout 2025-12-16 18:37:28 +01:00
2265a4a522 Remove unsupported PML4/PML5 PTE interfaces 2025-12-16 14:13:55 +01:00
dc23f91110 Split PTE implementation per architecture 2025-12-16 14:08:32 +01:00
7f0ca6a948 Compute PTE count per page from entry size 2025-12-15 13:56:39 +01:00
36c273ea13 Implement early page table mapping routines 2025-12-15 13:24:02 +01:00
5cf3dfa844 Add bootstrap physical page allocator 2025-12-15 12:38:08 +01:00
070c508e42 Introduce kernel virtual memory layout 2025-12-14 15:35:24 +01:00
5224dc315f Compute PFN database size during MM initialization 2025-12-13 22:50:27 +01:00
b7bbf9ffa8 Tidy up memory type verification helpers 2025-12-13 21:04:55 +01:00
eae48320f3 Harden PFN initialization and expose page count 2025-12-13 21:01:13 +01:00
17b5649362 Make memory type verification helpers accessible to PFN 2025-12-13 20:50:32 +01:00
783a9eea3a Extract PFN management into separate module 2025-12-13 20:42:48 +01:00
237f6a2974 Refactor memory manager initialization into MM::Manager 2025-12-13 20:21:08 +01:00
ee9514fd5c Fix GetP5eAddress return type 2025-12-13 19:58:49 +01:00
63c27a149a Add missing virtual GetPteDistance to pagemap interface 2025-12-06 00:29:51 +01:00
7694df7744 Add architecture-specific GetPteDistance 2025-12-06 00:19:24 +01:00
c710ec4688 Refactor XPA detection API 2025-12-04 23:07:59 +01:00
8054bb915a Fix incorrect pointer types 2025-11-30 20:06:51 +01:00
86aa22e5f8 Fix incorrect pointer types 2025-11-30 20:03:12 +01:00
4a7494ad3f Split paging interface into arch-specific code 2025-11-30 19:19:32 +01:00
d4287198b0 Implement virtual address resolvers for all page map levels and add XPA status accessor 2025-11-30 18:23:51 +01:00
4265ae92d0 Add MM::PageMap::GetXpaStatus() for querying PML level 2025-11-29 23:45:00 +01:00
931586eebd Refactor PageMap to enable architecture-specific VA translation 2025-11-29 23:37:08 +01:00
c099882866 Add PFN_COUNT typedef 2025-11-29 23:14:30 +01:00
0097cb88d7 Correct LA57 paging base addresses, add self-map constants and extend PTE structures 2025-11-29 23:11:54 +01:00
20b0bfdfad Add kernel parameters section and fix minor formatting issues 2025-11-17 23:19:16 +01:00
35523a230a Prevent duplicate object generation by linking xtoskrnl with libxtos 2025-11-17 23:15:22 +01:00
7b11a8feb1 Add page list and PTE pool type enums 2025-11-06 06:55:31 +01:00
0cf178a648 Fix class name 2025-11-04 23:10:02 +01:00
66f27e4b9a Add GetPageFrameNumber() to PTE interfaces 2025-11-04 23:03:47 +01:00
10b8ab347a Make MM::Paging::GetExtendedPhysicalAddressingStatus public 2025-11-04 22:51:34 +01:00
071c840ca8 Replace writable flag with AttributesMask in PTE setup 2025-11-04 17:34:49 +01:00
dda8f88830 Add PTE attribute definitions 2025-11-04 17:26:47 +01:00
cb2da54956 Unify PTE pointer types across MM subsystem 2025-11-03 22:13:32 +01:00
fd13091476 Unify MMPML2_PTE field naming convention 2025-11-03 22:02:59 +01:00
c28c3f8344 Add input qualifiers to page map interface definitions 2025-11-03 20:04:21 +01:00
dfb0284427 Add input qualifiers to paging interface definitions 2025-11-03 16:00:46 +01:00
1150b9ecdb Add PTE management routines 2025-10-30 22:03:25 +01:00
f6dac12057 Add missing EmptyPteList field to MMPAGEMAP_INFO 2025-10-30 20:19:35 +01:00
ffa480d69a Implement unified PTE accessors and management helpers 2025-10-30 20:14:02 +01:00
0120ba167f Introduce RAII helpers for runlevel transitions 2025-10-29 23:07:27 +01:00
4e9dc15501 Define VIRTUAL macro 2025-10-29 22:32:07 +01:00
164ff0c135 Expand spinlock queue levels 2025-10-28 08:35:34 +01:00
f538d035e2 Introduce global spinlock initialization and RAII guard classes 2025-10-27 20:48:44 +01:00
72b92f853e Use PTE base from PageMapInfo 2025-10-23 08:54:57 +02:00
00b04f5405 Refactor IDT gate setup to use explicit DPL and type fields 2025-10-18 18:29:49 +02:00
52afd31e77 Implement Stage2 loading in VBR code 2025-10-17 20:44:57 +02:00
7f06abf236 New message for unsupported CPUs 2025-10-17 09:18:49 +02:00
4f4df52d3d Include architecture-specific code in VBR 2025-10-17 09:12:54 +02:00
764fec4d75 Implement low-level CPU initialization support for i686 and AMD64 boot sectors 2025-10-17 09:05:24 +02:00
ca8a539c0e Change message labels naming convention 2025-10-17 08:58:41 +02:00
c206b443ed Move XTLDR image base definition to arch-specific config 2025-10-16 12:22:30 +02:00
b19b27a621 Build relocatable image to allow proper UEFI loading 2025-10-16 12:10:00 +02:00
56b81f5d73 Set fixed image base 2025-10-15 23:06:12 +02:00
1e99a3f4a9 Set fixed alignment and base address to allow execution under BIOS 2025-10-15 21:03:03 +02:00
0a71bc3995 Print fallback message in non-EFI environment 2025-10-15 20:55:16 +02:00
13a9d4c522 Introduce legacy VGA text mode support 2025-10-15 20:49:17 +02:00
9bf867af95 Propagate compile definitions to bootsector sources 2025-10-11 23:18:14 +02:00
a7be533521 Improve reliability and correctness of the PowerShell configure script (#21)
Co-authored-by: Pedro Valadés <perikiyoxd@gmail.com>
Co-committed-by: Pedro Valadés <perikiyoxd@gmail.com>
2025-10-10 20:18:05 +02:00
fdbe157c18 Fix CHS sector-by-sector read loop 2025-10-10 19:05:23 +02:00
120 fichiers modifiés avec 13959 ajouts et 934 suppressions

Voir le fichier

@@ -53,8 +53,9 @@ implement any environment subsystem to support applications that are strictly wr
* NT drivers compatibility layer
# Requirements
ExectOS is in very early development stage, thus its requirements have been not specified yet. However according to its
design, it requires a modern EFI enabled hardware. It is not possible currently to boot ExectOS on a legacy BIOS.
ExectOS is currently in a very early stage of development, so its specific requirements are not fully defined yet.
However, based on the current design, it requires modern EFI hardware. You cannot boot ExectOS on a legacy BIOS
right now, but there are plans to add BIOS support in the future.
# Source structure
| Directory | Description |

Voir le fichier

@@ -1,6 +1,8 @@
# XT Boot Sector
PROJECT(BOOTSECT)
add_definitions("-DARCH_ESP_SOURCE=\\\"${ARCH}/cpu.S\\\"")
# Compile boot sectors
compile_bootsector(mbrboot ${BOOTSECT_SOURCE_DIR}/mbrboot.S 0x7C00 Start)
compile_bootsector(espboot ${BOOTSECT_SOURCE_DIR}/espboot.S 0x7C00 Start)

144
boot/bootsect/amd64/cpu.S Fichier normal
Voir le fichier

@@ -0,0 +1,144 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: boot/bootsect/amd64/cpu.S
* DESCRIPTION: Low-level support for CPU initialization
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
BuildPageMap:
/* Generate page map for first 1GB of memory */
pushaw
pushw %es
cld
movw $(0x1000 / 16), %ax
movw %ax, %es
xorw %di, %di
movl $(0x2000 | 0x07), %eax
stosl
xorl %eax, %eax
movw $1021, %cx
rep stosl
movw $(0x2000 / 16), %ax
movw %ax, %es
xorw %di, %di
movl $(0x3000 | 0x07), %eax
stosl
xorl %eax, %eax
movw $1021, %cx
rep stosl
movw $(0x3000 / 16), %ax
movw %ax, %es
xorw %di, %di
movw $512, %cx
movl $0x00000083, %eax
.BuildPageMapLoop:
/* Identity map 512 pages of 2MB */
movl %eax, %es:(%di)
addl $2097152, %eax
addw $0x08, %di
loop .BuildPageMapLoop
popw %es
popaw
ret
InitializeCpu:
/* Check if CPU supports CPUID, long mode and PAE */
pushal
pushfl
popl %eax
movl %eax, %ebx
xorl $0x00200000, %eax
pushl %eax
popfl
pushfl
popl %eax
cmpl %ebx, %eax
je CpuUnsupported
movl $0x01, %eax
cpuid
testl $0x40, %edx
jz CpuUnsupported
movl $0x80000000, %eax
cpuid
cmpl $0x80000000, %eax
jbe CpuUnsupported
movl $0x80000001, %eax
cpuid
testl $0x20000000, %edx
jz CpuUnsupported
popal
call LoadGdt
ret
LoadGdt:
/* Load Global Descriptor Table */
lgdt .GdtPointer
ret
RunStage2:
/* Switch to long mode and pass control to Stage 2 */
call BuildPageMap
call ParseExecutableHeader
xorl %edx, %edx
pushl %edx
pushl %eax
cli
xorw %ax, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
movl %cr4, %eax
orl $0x00A0, %eax
movl %eax, %cr4
movl $0x00001000, %eax
movl %eax, %cr3
movl $0xC0000080, %ecx
rdmsr
orl $0x00000100, %eax
wrmsr
movl %cr0, %eax
orl $0x80000001, %eax
movl %eax, %cr0
ljmp $0x10, $.Stage2LongMode
.code64
.Stage2LongMode:
/* Set segments and stack, then jump to Stage 2 */
movw $0x18, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
xorw %ax, %ax
movw %ax, %fs
movw %ax, %gs
popq %rax
xorq %rbx, %rbx
xorq %rcx, %rcx
xorq %rdx, %rdx
xorq %rsi, %rsi
xorq %rdi, %rdi
xorq %rbp, %rbp
jmp *%rax
.code16
.GdtDescriptor:
/* Global Descriptor Table */
.quad 0x0000000000000000
.quad 0x0000000000000000
.quad 0x00AF9A000000FFFF
.quad 0x00CF92000000FFFF
.quad 0x00009E000000FFFF
.quad 0x000092000000FFFF
.quad 0x00CF9B000000FFFF
.GdtPointer:
/* Pointer to Global Descriptor Table */
.word .GdtPointer - .GdtDescriptor - 1
.long .GdtDescriptor
.Stage2FileName:
/* Name of Stage 2 executable file */
.ascii "BOOTX64 EFI"

Voir le fichier

@@ -121,15 +121,15 @@ VerifyBiosParameterBlock:
ja FsError
ReadExtraCode:
/* Read second VBR sector with extra boot code */
/* Read second VBR sector with extra boot code (3 sectors starting from sector 2) */
movl HiddenSectors - Start(%bp), %eax
addl $0x02, %eax
movw $0x01, %cx
movw $0x03, %cx
xorw %bx, %bx
movw %bx, %es
movw $0x7E00, %bx
call ReadSectors
jmp StartSectors
jmp StartExtraCode
ReadSectors:
/* Check for extended BIOS functions and use it only if available */
@@ -139,18 +139,22 @@ ReadSectors:
movw $0x55AA, %bx
movb DriveNumber - Start(%bp), %dl
int $0x13
jc ReadCHS
jc .ReadCHS
cmpw $0xAA55, %bx
jne ReadCHS
jne .ReadCHS
testb $0x01, %cl
jz ReadCHS
jz .ReadCHS
/* Verify drive size and determine whether to use CHS or LBA */
cmpl %edi, %eax
jnb ReadLBA
jnb .ReadLBA
ReadCHS:
.ReadCHS:
/* Read sectors using CHS */
popal
.CHSLoop:
/* Read sector by sector using CHS */
pushw %cx
pushal
xorl %edx, %edx
@@ -176,11 +180,11 @@ ReadCHS:
movw %es, %dx
addw $0x20, %dx
movw %dx, %es
loop ReadCHS
loop .CHSLoop
popw %es
ret
ReadLBA:
.ReadLBA:
/* Prepare DAP packet and read sectors using LBA */
popal
pushw %cx
@@ -209,19 +213,19 @@ ReadLBA:
movw %dx, %es
popw %bx
subw %si, %cx
jnz ReadLBA
jnz .ReadLBA
popw %es
ret
DiskError:
/* Display disk error message and reboot */
movw $msgDiskError, %si
movw $.MsgDiskError, %si
call Print
jmp Reboot
FsError:
/* Display FS error message and reboot */
movw $msgFsError, %si
movw $.MsgFsError, %si
call Print
jmp Reboot
@@ -229,48 +233,297 @@ Print:
/* Simple routine to print messages */
lodsb
orb %al, %al
jz DonePrint
jz .DonePrint
movb $0x0E, %ah
movw $0x07, %bx
int $0x10
jmp Print
DonePrint:
.DonePrint:
retw
Reboot:
/* Display a message, wait for a key press and reboot */
movw $msgAnyKey, %si
movw $.MsgAnyKey, %si
call Print
xorw %ax, %ax
int $0x16
int $0x19
msgAnyKey:
.ascii "Press any key to restart\r\n"
.MsgAnyKey:
.ascii "Press any key to restart...\r\n\0"
msgDiskError:
.ascii "Disk error\r\n"
.MsgDiskError:
.ascii "Disk error!\r\n\0"
msgFsError:
.ascii "File system error\r\n"
.MsgFsError:
.ascii "File system error!\r\n\0"
/* Fill the rest of the VBR with zeros and add VBR signature at the end */
.fill (510 - (. - Start)), 1, 0
.word 0xAA55
StartSectors:
/* Print message */
movw $msgUnavailable, %si
StartExtraCode:
/* Load XTLDR file from disk */
call LoadStage2
/* Enable A20 gate */
call EnableA20
/* Call architecture specific initialization code */
call InitializeCpu
/* Jump to Stage2 */
call RunStage2
Clear8042:
/* Clear 8042 PS/2 buffer */
nop
nop
nop
nop
inb $0x64, %al
cmpb $0xff, %al
je .Clear8042_Done
testb $0x02, %al
jnz Clear8042
.Clear8042_Done:
ret
EnableA20:
/* Enable A20 gate */
pushaw
call Clear8042
movb $0xD1, %al
outb %al, $0x64
call Clear8042
movb $0xDF, %al
outb %al, $0x60
call Clear8042
movb $0xFF, %al
outb %al, $0x64
call Clear8042
popaw
ret
FindFatEntry:
/* Find a file or directory in the FAT table */
pushw %bx
pushw %cx
pushw %dx
pushw %si
pushw %di
.FindFatCluster:
/* Find FAT32 cluster holding the entry */
cmp $0x0FFFFFF8, %eax
jae .FindEntryFail
pushl %eax
movw $0x0200, %bx
movw %bx, %es
call ReadCluster
popl %eax
movb SectorsPerCluster - Start(%bp), %cl
shlw $0x04, %cx
xorw %di, %di
.FindEntryLoop:
/* Find the entry */
movb %es:(%di), %al
cmpb $0x00, %al
je .FindEntryFail
cmpb $0xE5, %al
je .FindSkipEntry
movb %es:0x0B(%di), %ah
cmpb $0x0F, %ah
je .FindSkipEntry
pushw %di
pushw %si
pushw %cx
movw $0x0B, %cx
repe cmpsb
popw %cx
popw %si
popw %di
jnz .FindSkipEntry
movw %es:0x1A(%di), %ax
movw %es:0x14(%di), %dx
shll $0x10, %edx
orl %edx, %eax
clc
jmp .FindEntryDone
.FindSkipEntry:
/* Skip to the next entry */
addw $0x20, %di
decw %cx
jnz .FindEntryLoop
call GetFatEntry
jmp .FindFatCluster
.FindEntryFail:
/* Error, file/directory not found */
stc
.FindEntryDone:
/* Clean up the stack */
popw %di
popw %si
popw %dx
popw %cx
popw %bx
ret
GetFatEntry:
/* Get FAT32 sector and offset from FAT table */
shll $0x02, %eax
movl %eax, %ecx
xorl %edx, %edx
movzwl BytesPerSector - Start(%bp), %ebx
pushl %ebx
divl %ebx
movzwl ReservedSectors - Start(%bp), %ebx
addl %ebx, %eax
movl HiddenSectors - Start(%bp), %ebx
addl %ebx, %eax
popl %ebx
decl %ebx
andl %ebx, %ecx
movzwl ExtendedFlags - Start(%bp), %ebx
andw $0x0F, %bx
jz LoadFatSector
cmpb FatCopies - Start(%bp), %bl
jae FsError
pushl %eax
movl BigSectorsPerFat - Start(%bp), %eax
mull %ebx
popl %edx
addl %edx, %eax
LoadFatSector:
/* Load FAT32 sector from disk */
pushl %ecx
movw $0x9000, %bx
movw %bx, %es
cmpl %esi, %eax
je .LoadFatSectorDone
movl %eax, %esi
xorw %bx, %bx
movw $0x01, %cx
call ReadSectors
.LoadFatSectorDone:
/* Clean up the stack */
popl %ecx
movl %es:(%ecx), %eax
andl $0x0FFFFFFF, %eax
ret
LoadStage2:
/* Load Stage2 executable, first find file in the path */
movl $0xFFFFFFFF, %esi
pushl %esi
movl 0x7C2C, %eax
movw $.EfiDirName, %si
call FindFatEntry
jc Stage2NotLoaded
movw $.BootDirName, %si
call FindFatEntry
jc Stage2NotLoaded
movw $.Stage2FileName, %si
call FindFatEntry
jc Stage2NotLoaded
popl %esi
/* Load XTLDR file from disk */
cmpl $0x02, %eax
jb FileNotFound
cmpl $0x0FFFFFF8, %eax
jae FileNotFound
movw $(0xF800 / 16), %bx
movw %bx, %es
.LoadStage2Loop:
/* Load file data from disk */
pushl %eax
xorw %bx, %bx
pushw %es
call ReadCluster
popw %es
xorw %bx, %bx
movb SectorsPerCluster - Start(%bp), %bl
shlw $0x05, %bx
movw %es, %ax
addw %bx, %ax
movw %ax, %es
popl %eax
pushw %es
call GetFatEntry
popw %es
cmpl $0x0FFFFFF8, %eax
jb .LoadStage2Loop
ret
ParseExecutableHeader:
/* Parse Stage2 PE/COFF executable header */
pushw %es
movw $(0xF800 / 16), %ax
movw %ax, %es
movl %es:60, %eax
addl $(4 + 20), %eax
movl %es:16(%eax), %eax
addl $0xF800, %eax
popw %es
ret
ReadCluster:
/* Read FAT32 cluster from disk */
decl %eax
decl %eax
xorl %edx, %edx
movzbl SectorsPerCluster - Start(%bp), %ebx
mull %ebx
pushl %eax
xorl %edx, %edx
movzbl FatCopies - Start(%bp), %eax
mull BigSectorsPerFat - Start(%bp)
movzwl ReservedSectors - Start(%bp), %ebx
addl %ebx, %eax
addl HiddenSectors - Start(%bp), %eax
popl %ebx
addl %ebx, %eax
xorw %bx, %bx
movzbw SectorsPerCluster - Start(%bp), %cx
call ReadSectors
ret
/* Include architecture specific code */
.include ARCH_ESP_SOURCE
CpuUnsupported:
/* Display CPU unsupported message and reboot */
popal
movw $.MsgCpuUnsupported, %si
call Print
jmp Reboot
/* Wait for key press and reboot */
xorw %ax, %ax
int $0x16
int $0x19
FileNotFound:
/* Display XTLDR not found message and reboot */
movw $.MsgXtLdrNotFound, %si
call Print
jmp Reboot
msgUnavailable:
.ascii "XTLDR requires EFI-based system!\r\nPress any key to restart\r\n"
Stage2NotLoaded:
/* Clean up the stack and display XTLDR not found message and reboot */
popl %esi
jmp FileNotFound
/* Fill the rest of the extra VBR with zeros */
.fill (1024 - (. - Start)), 1, 0
.BootDirName:
/* Boot directory name */
.ascii "BOOT "
.EfiDirName:
/* EFI directory name */
.ascii "EFI "
.MsgCpuUnsupported:
.ascii "CPU not supported!\r\n\0"
.MsgXtLdrNotFound:
.ascii "XTLDR Stage2 not found!\r\n\0"
/* Fill the rest of the extra VBR with zeros and add signature */
.fill (2043 - (. - Start)), 1, 0
.ascii "XTLDR"

124
boot/bootsect/i686/cpu.S Fichier normal
Voir le fichier

@@ -0,0 +1,124 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: boot/bootsect/i686/cpu.S
* DESCRIPTION: Low-level support for CPU initialization
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
BuildPageMap:
/* Generate page map for first 16MB of memory */
pushaw
pushw %es
cld
movw $(0x1000 >> 0x04), %ax
movw %ax, %es
xorw %di, %di
movl $(0x2000 | 0x03), %eax
stosl
movl $(0x3000 | 0x03), %eax
stosl
movl $(0x4000 | 0x03), %eax
stosl
movl $(0x5000 | 0x03), %eax
stosl
xorl %eax, %eax
movw $(1024 - 4), %cx
rep stosl
movl $0x00000003, %eax
movl $4, %edx
movw $(0x2000 >> 0x04), %bx
.BuildPageMapLoop:
/* Identity map 1024 pages of 4KB */
movw %bx, %es
xorw %di, %di
pushl %edx
movw $1024, %cx
.FillPageMapTable:
/* Fill the page table */
movl %eax, %es:(%di)
addl $4096, %eax
addw $0x04, %di
loop .FillPageMapTable
popl %edx
addw $(0x1000 >> 0x04), %bx
decl %edx
jnz .BuildPageMapLoop
popw %es
popaw
ret
InitializeCpu:
/* Check if CPU supports CPUID */
pushal
pushfl
popl %eax
movl %eax, %ebx
xorl $0x00200000, %eax
pushl %eax
popfl
pushfl
popl %eax
cmpl %ebx, %eax
je CpuUnsupported
popal
call LoadGdt
ret
LoadGdt:
/* Load Global Descriptor Table */
lgdt .GdtPointer
ret
RunStage2:
/* Switch to protected mode and pass control to Stage 2 */
call BuildPageMap
call ParseExecutableHeader
pushl %eax
cli
movl %cr0, %eax
orl $0x01, %eax
movl %eax, %cr0
ljmp $0x08, $.Stage2ProtectedMode
.code32
.Stage2ProtectedMode:
/* Set segments and stack, then jump to Stage 2 */
movw $0x10, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
xorw %ax, %ax
movw %ax, %fs
movw %ax, %gs
popl %eax
xorl %ebx, %ebx
xorl %ecx, %ecx
xorl %edx, %edx
xorl %esi, %esi
xorl %edi, %edi
xorl %ebp, %ebp
movl $0x1000, %ebx
movl %ebx, %cr3
movl %cr0, %ebx
orl $0x80000000, %ebx
movl %ebx, %cr0
jmp *%eax
.code16
.GdtDescriptor:
/* Global Descriptor Table */
.quad 0x0000000000000000
.quad 0x00CF9A000000FFFF
.quad 0x00CF92000000FFFF
.quad 0x00009E000000FFFF
.quad 0x000092000000FFFF
.GdtPointer:
/* Pointer to Global Descriptor Table */
.word .GdtPointer - .GdtDescriptor - 1
.long .GdtDescriptor
.Stage2FileName:
/* Name of Stage 2 executable file */
.ascii "BOOTIA32EFI"

Voir le fichier

@@ -4,6 +4,7 @@
* FILE: boot/bootsect/amd64/mbrboot.S
* DESCRIPTION: XT Boot Loader MBR boot code
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <aiken@codingworkshop.eu.org>
*/
.text
@@ -41,7 +42,7 @@ RealStart:
movw %ax, %ss
/* Print welcome message */
leaw msgXtosBoot, %si
leaw .MsgXtosBoot, %si
call Print
/* Get BIOS boot drive and partition table offset */
@@ -90,19 +91,19 @@ PartitionFound:
InvalidSignature:
/* Invalid signature error */
leaw msgInvalidSignature, %si
leaw .MsgInvalidSignature, %si
call Print
jmp HaltSystem
PartitionNotFound:
/* Active partition not found error */
leaw msgPartitionNotFound, %si
leaw .MsgPartitionNotFound, %si
call Print
jmp HaltSystem
VbrReadFail:
/* VBR read failed error */
leaw msgVbrReadFail, %si
leaw .MsgVbrReadFail, %si
call Print
jmp HaltSystem
@@ -136,16 +137,16 @@ DonePrint:
/* Storage for the LBA start */
.long 0
msgInvalidSignature:
.MsgInvalidSignature:
.asciz "Invalid partition signature!"
msgPartitionNotFound:
.MsgPartitionNotFound:
.asciz "Bootable partition not found!"
msgVbrReadFail:
.MsgVbrReadFail:
.asciz "VBR read failed!"
msgXtosBoot:
.MsgXtosBoot:
.asciz "Starting XTOS boot loader...\r\n"
/* Fill the rest of the MBR with zeros and add MBR signature at the end */

Voir le fichier

@@ -16,6 +16,7 @@ list(APPEND LIBXTLDR_SOURCE
# Specify list of source code files
list(APPEND XTLDR_SOURCE
${XTLDR_SOURCE_DIR}/arch/${ARCH}/memory.cc
${XTLDR_SOURCE_DIR}/biosutil.cc
${XTLDR_SOURCE_DIR}/bootutil.cc
${XTLDR_SOURCE_DIR}/config.cc
${XTLDR_SOURCE_DIR}/console.cc
@@ -38,6 +39,9 @@ add_executable(xtldr ${XTLDR_SOURCE})
# Add linker libraries
target_link_libraries(xtldr libxtos)
# Add linker options
target_link_options(xtldr PRIVATE /ALIGN:512)
# Set proper binary name and install target
if(ARCH STREQUAL "i686")
set(BINARY_NAME "bootia32")
@@ -49,5 +53,6 @@ set_install_target(xtldr efi/boot)
# Set loader entrypoint and subsystem
set_entrypoint(xtldr "BlStartXtLoader")
set_imagebase(xtldr ${BASEADDRESS_XTLDR})
set_linker_map(xtldr TRUE)
set_subsystem(xtldr efi_application)

Voir le fichier

@@ -28,13 +28,12 @@ EFI_STATUS
Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress)
{
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
PXTBL_MEMORY_MAPPING Mapping;
PLIST_ENTRY ModulesList, ModulesListEntry;
PXTBL_MODULE_INFO ModuleInfo;
EFI_PHYSICAL_ADDRESS Address;
PVOID LoaderBase;
ULONGLONG LoaderSize;
EFI_STATUS Status;
PVOID LoaderBase;
/* Allocate pages for the Page Map */
Status = AllocatePages(AllocateAnyPages, 1, &Address);
@@ -44,6 +43,14 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
return Status;
}
/* Add new memory mapping for the page map itself */
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
return Status;
}
/* Assign and zero-fill memory used by page mappings */
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
@@ -57,7 +64,7 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
}
/* Map the trampoline code area */
Status = MapVirtualMemory(PageMap, (PVOID)MM_TRAMPOLINE_ADDRESS,(PVOID)MM_TRAMPOLINE_ADDRESS,
Status = MapVirtualMemory(PageMap, MM_TRAMPOLINE_ADDRESS, MM_TRAMPOLINE_ADDRESS,
1, LoaderFirmwareTemporary);
if(Status != STATUS_EFI_SUCCESS)
{
@@ -74,7 +81,7 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
/* Map module code */
Status = MapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase,
Status = MapVirtualMemory(PageMap, (ULONGLONG)ModuleInfo->ModuleBase, (ULONGLONG)ModuleInfo->ModuleBase,
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
/* Check if mapping succeeded */
@@ -95,7 +102,7 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
if(LoaderBase && LoaderSize)
{
/* Map boot loader code as well */
Status = MapVirtualMemory(PageMap, LoaderBase, LoaderBase,
Status = MapVirtualMemory(PageMap, (ULONGLONG)LoaderBase, (ULONGLONG)LoaderBase,
EFI_SIZE_TO_PAGES(LoaderSize), LoaderFirmwareTemporary);
if(Status != STATUS_EFI_SUCCESS)
{
@@ -109,6 +116,28 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
return STATUS_EFI_PROTOCOL_ERROR;
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
/**
* Iterates through the memory map and physically maps all virtual addresses to page tables.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
Memory::CommitPageMap(IN PXTBL_PAGE_MAPPING PageMap)
{
PXTBL_MEMORY_MAPPING Mapping;
PLIST_ENTRY ListEntry;
EFI_STATUS Status;
/* Iterate through and map all the mappings*/
Debug::Print(L"Mapping and dumping EFI memory:\n");
ListEntry = PageMap->MemoryMap.Flink;
@@ -193,7 +222,7 @@ Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
}
/* Add new memory mapping */
Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
@@ -239,9 +268,9 @@ Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
XTCDECL
EFI_STATUS
Memory::MapPage(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR VirtualAddress,
IN ULONG_PTR PhysicalAddress,
IN ULONG NumberOfPages)
IN ULONGLONG VirtualAddress,
IN ULONGLONG PhysicalAddress,
IN ULONGLONG NumberOfPages)
{
PVOID Pml1, Pml2, Pml3, Pml4, Pml5;
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry, Pml4Entry, Pml5Entry;

Voir le fichier

@@ -25,13 +25,12 @@ EFI_STATUS
Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress)
{
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
EFI_PHYSICAL_ADDRESS Address, DirectoryAddress;
PLIST_ENTRY ModulesList, ModulesListEntry;
PXTBL_MODULE_INFO ModuleInfo;
PXTBL_MEMORY_MAPPING Mapping;
PVOID LoaderBase;
ULONGLONG LoaderSize;
EFI_STATUS Status;
PVOID LoaderBase;
ULONG Index;
/* Check the page map level to determine which paging structure to create */
@@ -45,6 +44,14 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
return Status;
}
/* Add new memory mapping for the page map itself */
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
return Status;
}
/* Assign the allocated page to the page map and zero it out */
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
@@ -57,6 +64,14 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
return Status;
}
/* Add new memory mapping for the Page Directories (PDs) */
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, DirectoryAddress, 4, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
return Status;
}
/* Zero-fill the allocated memory for the Page Directories */
RTL::Memory::ZeroMemory((PVOID)DirectoryAddress, EFI_PAGE_SIZE * 4);
@@ -79,6 +94,14 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
return Status;
}
/* Add new memory mapping for the page map itself */
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
return Status;
}
/* Assign the allocated page to the page map and zero it out */
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
@@ -93,8 +116,7 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
}
/* Map the trampoline code area */
Status = MapVirtualMemory(PageMap, (PVOID)MM_TRAMPOLINE_ADDRESS,(PVOID)MM_TRAMPOLINE_ADDRESS,
1, LoaderFirmwareTemporary);
Status = MapVirtualMemory(PageMap, MM_TRAMPOLINE_ADDRESS, MM_TRAMPOLINE_ADDRESS, 1, LoaderFirmwareTemporary);
if(Status != STATUS_EFI_SUCCESS)
{
/* Mapping trampoline code failed */
@@ -110,7 +132,7 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
/* Map module code */
Status = MapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase,
Status = MapVirtualMemory(PageMap, (ULONGLONG)ModuleInfo->ModuleBase, (ULONGLONG)ModuleInfo->ModuleBase,
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
/* Check if mapping succeeded */
@@ -131,7 +153,7 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
if(LoaderBase && LoaderSize)
{
/* Map boot loader code as well */
Status = MapVirtualMemory(PageMap, LoaderBase, LoaderBase,
Status = MapVirtualMemory(PageMap, (ULONGLONG)LoaderBase, (ULONGLONG)LoaderBase,
EFI_SIZE_TO_PAGES(LoaderSize), LoaderFirmwareTemporary);
if(Status != STATUS_EFI_SUCCESS)
{
@@ -145,6 +167,28 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
return STATUS_EFI_PROTOCOL_ERROR;
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
/**
* Iterates through the memory map and physically maps all virtual addresses to page tables.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
Memory::CommitPageMap(IN PXTBL_PAGE_MAPPING PageMap)
{
PXTBL_MEMORY_MAPPING Mapping;
PLIST_ENTRY ListEntry;
EFI_STATUS Status;
/* Iterate through and map all the mappings*/
Debug::Print(L"Mapping and dumping EFI memory:\n");
ListEntry = PageMap->MemoryMap.Flink;
@@ -157,8 +201,9 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
if(Mapping->VirtualAddress)
{
/* Dump memory mapping */
Debug::Print(L" Type=%02lu, PhysicalBase=%.8P, VirtualBase=%.8P, Pages=%llu\n", Mapping->MemoryType,
Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages);
Debug::Print(L" Type=%02lu, PhysicalBase=0x%.8llX, VirtualBase=0x%.8llX, Pages=%llu\n",
Mapping->MemoryType, Mapping->PhysicalAddress,
Mapping->VirtualAddress, Mapping->NumberOfPages);
/* Map memory */
Status = MapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress,
@@ -252,7 +297,7 @@ Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
}
/* Add new memory mapping */
Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
@@ -313,11 +358,11 @@ Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
XTCDECL
EFI_STATUS
Memory::MapPage(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR VirtualAddress,
IN ULONG_PTR PhysicalAddress,
IN ULONG NumberOfPages)
IN ULONGLONG VirtualAddress,
IN ULONGLONG PhysicalAddress,
IN ULONGLONG NumberOfPages)
{
SIZE_T PageFrameNumber;
ULONGLONG PageFrameNumber;
PVOID Pml1, Pml2, Pml3;
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry;
PHARDWARE_LEGACY_PTE LegacyPmlTable;

190
boot/xtldr/biosutil.cc Fichier normal
Voir le fichier

@@ -0,0 +1,190 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/biosutil.cc
* DESCRIPTION: Legacy BIOS support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtldr.hh>
/**
* Clears the entire screen and moves the cursor to the top-left corner.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BiosUtils::ClearScreen()
{
VOLATILE PUSHORT VgaBuffer = (PUSHORT)0xB8000;
USHORT Blank;
UINT Index;
/* Set blank character */
Blank = (0x0F << 8) | L' ';
/* Fill the entire screen with blank characters */
for(Index = 0; Index < VgaWidth * VgaHeight; Index++)
{
VgaBuffer[Index] = Blank;
}
/* Reset cursor position to the top-left corner */
CursorX = 0;
CursorY = 0;
/* Update the hardware cursor position */
UpdateCursor();
}
/**
* Formats the input string and prints it out to the screen.
*
* @param Format
* The formatted string that is to be written to the output.
*
* @param ...
* Depending on the format string, this routine might expect a sequence of additional arguments.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BiosUtils::Print(IN PCWSTR Format,
IN ...)
{
RTL_PRINT_CONTEXT PrintContext;
VA_LIST Arguments;
/* Initialise the print contexts */
PrintContext.WriteWideCharacter = PutChar;
/* Initialise the va_list */
VA_START(Arguments, Format);
/* Format and print the string to the stdout */
RTL::WideString::FormatWideString(&PrintContext, (PWCHAR)Format, Arguments);
/* Clean up the va_list */
VA_END(Arguments);
}
/**
* Writes a single wide character to the screen using legacy BIOS VGA text mode.
*
* @param Character
* The wide character to be printed.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
XTSTATUS
BiosUtils::PutChar(IN WCHAR Character)
{
VOLATILE PUSHORT VgaBuffer = (PUSHORT)0xB8000;
USHORT VgaCharacter;
/* Handle special characters */
if(Character == L'\n')
{
/* Move to the next line */
CursorX = 0;
CursorY++;
}
else if(Character == L'\r')
{
/* Move to the beginning of the current line */
CursorX = 0;
}
else
{
/* Print character and move cursor to the right */
VgaCharacter = (0x0F << 8) | (Character & 0xFF);
VgaBuffer[CursorY * VgaWidth + CursorX] = VgaCharacter;
CursorX++;
}
/* Handle moving to the next line if cursor is at the end of the line */
if(CursorX >= VgaWidth)
{
CursorX = 0;
CursorY++;
}
/* Handle scrolling if cursor is at the end of the screen */
if(CursorY >= VgaHeight)
{
ScrollScreen();
CursorY = VgaHeight - 1;
}
/* Update the hardware cursor position */
UpdateCursor();
/* Return success */
return STATUS_EFI_SUCCESS;
}
/**
* Scrolls the entire screen content up by one line and clears the last line.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BiosUtils::ScrollScreen()
{
VOLATILE PUSHORT VgaBuffer = (PUSHORT)0xB8000;
USHORT Blank;
UINT Index;
/* Set blank character */
Blank = (0x0F << 8) | L' ';
/* Move every line up by one */
for(Index = 0; Index < (VgaHeight - 1) * VgaWidth; Index++)
{
VgaBuffer[Index] = VgaBuffer[Index + VgaWidth];
}
/* Clear the last line */
for(Index = (VgaHeight - 1) * VgaWidth; Index < VgaHeight * VgaWidth; Index++)
{
VgaBuffer[Index] = Blank;
}
}
/**
* Updates the hardware cursor position on the screen.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BiosUtils::UpdateCursor()
{
USHORT Position;
/* Calculate cursor position */
Position = CursorY * VgaWidth + CursorX;
/* Send command to set the high byte of the cursor position */
HL::IoPort::WritePort8(0x3D4, 0x0E);
HL::IoPort::WritePort8(0x3D5, (UCHAR)((Position >> 8) & 0xFF));
/* Send command to set the low byte of the cursor position */
HL::IoPort::WritePort8(0x3D4, 0x0F);
HL::IoPort::WritePort8(0x3D5, (UCHAR)(Position & 0xFF));
}

Voir le fichier

@@ -10,6 +10,18 @@
#include <xtldr.hh>
/* Legacy BIOS cursor X position */
USHORT BiosUtils::CursorX = 0;
/* Legacy BIOS cursor Y position */
USHORT BiosUtils::CursorY = 0;
/* Legacy BIOS screen height */
CONST USHORT BiosUtils::VgaHeight = 25;
/* Legacy BIOS screen width */
CONST USHORT BiosUtils::VgaWidth = 80;
/* XT Boot Loader menu list */
PLIST_ENTRY Configuration::BootMenuList = NULLPTR;

Voir le fichier

@@ -15,6 +15,25 @@
#include <libxtos.hh>
class BiosUtils
{
private:
STATIC USHORT CursorX;
STATIC USHORT CursorY;
STATIC CONST USHORT VgaHeight;
STATIC CONST USHORT VgaWidth;
public:
STATIC XTCDECL VOID ClearScreen();
STATIC XTCDECL VOID Print(IN PCWSTR Format,
IN ...);
STATIC XTCDECL XTSTATUS PutChar(IN WCHAR Character);
private:
STATIC XTCDECL VOID ScrollScreen();
STATIC XTCDECL VOID UpdateCursor();
};
class BootUtils
{
public:
@@ -146,6 +165,7 @@ class Memory
OUT PVOID *Memory);
STATIC XTCDECL EFI_STATUS BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress);
STATIC XTCDECL EFI_STATUS CommitPageMap(IN PXTBL_PAGE_MAPPING PageMap);
STATIC XTCDECL EFI_STATUS FreePages(IN ULONGLONG NumberOfPages,
IN EFI_PHYSICAL_ADDRESS Memory);
STATIC XTCDECL EFI_STATUS FreePool(IN PVOID Memory);
@@ -158,15 +178,16 @@ class Memory
IN SHORT PageMapLevel,
IN PAGE_SIZE PageSize);
STATIC XTCDECL EFI_STATUS MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
IN OUT PVOID *MemoryMapAddress,
IN OUT PVOID *BaseAddress,
IN BOOLEAN IdentityMapping,
IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine);
STATIC XTCDECL EFI_STATUS MapPage(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR VirtualAddress,
IN ULONG_PTR PhysicalAddress,
IN ULONG NumberOfPages);
IN ULONGLONG VirtualAddress,
IN ULONGLONG PhysicalAddress,
IN ULONGLONG NumberOfPages);
STATIC XTCDECL EFI_STATUS MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
IN PVOID VirtualAddress,
IN PVOID PhysicalAddress,
IN ULONGLONG VirtualAddress,
IN ULONGLONG PhysicalAddress,
IN ULONGLONG NumberOfPages,
IN LOADER_MEMORY_TYPE MemoryType);
STATIC XTCDECL PVOID PhysicalAddressToVirtual(IN PVOID PhysicalAddress,

Voir le fichier

@@ -314,9 +314,12 @@ Memory::InitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap,
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @param MemoryMapAddress
* @param BaseAddress
* Supplies a virtual address, where EFI memory will be mapped.
*
* @param IdentityMapping
* Specifies whether EFI non-free memory should be mapped by identity or sequential mapping.
*
* @param GetMemoryTypeRoutine
* Supplies a pointer to the routine which will be used to match EFI memory type to the OS memory type.
*
@@ -327,19 +330,20 @@ Memory::InitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap,
XTCDECL
EFI_STATUS
Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
IN OUT PVOID *MemoryMapAddress,
IN OUT PVOID *BaseAddress,
IN BOOLEAN IdentityMapping,
IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine)
{
ULONGLONG MaxAddress, VirtualAddress;
PEFI_MEMORY_DESCRIPTOR Descriptor;
LOADER_MEMORY_TYPE MemoryType;
PEFI_MEMORY_MAP MemoryMap;
SIZE_T DescriptorCount;
PUCHAR VirtualAddress;
EFI_STATUS Status;
SIZE_T Index;
/* Set virtual address as specified in argument */
VirtualAddress = (PUCHAR)*MemoryMapAddress;
VirtualAddress = (ULONGLONG)*BaseAddress;
/* Check if custom memory type routine is specified */
if(GetMemoryTypeRoutine == NULLPTR)
@@ -367,8 +371,37 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
/* Iterate through all descriptors from the memory map */
for(Index = 0; Index < DescriptorCount; Index++)
{
/* Make sure descriptor does not start beyond lowest physical page */
if(Descriptor->PhysicalStart <= MAXUINT_PTR)
/* Check page map level */
if(PageMap->PageMapLevel == 2)
{
/* Limit physical address to 4GB in legacy mode */
MaxAddress = 0xFFFFFFFF;
}
else if(PageMap->PageMapLevel == 3)
{
/* Limit physical address to 64GB in PAE mode */
MaxAddress = 0xFFFFFFFFFULL;
}
/* Check page map level */
if(PageMap->PageMapLevel == 2 || PageMap->PageMapLevel == 3)
{
/* Check if physical address starts beyond limit */
if(Descriptor->PhysicalStart >= MaxAddress)
{
/* Go to the next descriptor */
Descriptor = (PEFI_MEMORY_DESCRIPTOR)((PUCHAR)Descriptor + MemoryMap->DescriptorSize);
continue;
}
/* Check if memory descriptor exceeds the lowest physical page */
if(Descriptor->PhysicalStart + (Descriptor->NumberOfPages << EFI_PAGE_SHIFT) > MaxAddress)
{
/* Truncate memory descriptor to the lowest supported physical page */
Descriptor->NumberOfPages = (MaxAddress - Descriptor->PhysicalStart) >> EFI_PAGE_SHIFT;
}
}
{
/* Skip EFI reserved memory */
if(Descriptor->Type == EfiReservedMemoryType)
@@ -378,25 +411,6 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
continue;
}
/* Check if preparing page map level 2 (non-PAE i686) */
if(PageMap->PageMapLevel == 2)
{
/* Check if physical address starts beyond 4GB */
if(Descriptor->PhysicalStart > 0xFFFFFFFF)
{
/* Go to the next descriptor */
Descriptor = (PEFI_MEMORY_DESCRIPTOR)((PUCHAR)Descriptor + MemoryMap->DescriptorSize);
continue;
}
/* Check if memory descriptor exceeds the lowest physical page */
if(Descriptor->PhysicalStart + (Descriptor->NumberOfPages << EFI_PAGE_SHIFT) > MAXULONG)
{
/* Truncate memory descriptor to the 4GB */
Descriptor->NumberOfPages = (((ULONGLONG)MAXULONG + 1) - Descriptor->PhysicalStart) >> EFI_PAGE_SHIFT;
}
}
/* Convert EFI memory type into XTLDR memory type */
MemoryType = GetMemoryTypeRoutine((EFI_MEMORY_TYPE)Descriptor->Type);
@@ -404,22 +418,32 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
if(MemoryType == LoaderFirmwareTemporary)
{
/* Map EFI firmware code */
Status = MapVirtualMemory(PageMap, (PVOID)Descriptor->PhysicalStart,
(PVOID)Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType);
Status = MapVirtualMemory(PageMap, Descriptor->PhysicalStart,
Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType);
}
else if(MemoryType != LoaderFree)
{
/* Add any non-free memory mapping */
Status = MapVirtualMemory(PageMap, VirtualAddress, (PVOID)Descriptor->PhysicalStart,
Descriptor->NumberOfPages, MemoryType);
/* Check mapping strategy */
if(IdentityMapping)
{
/* Add any non-free memory using identity mapping */
Status = MapVirtualMemory(PageMap, Descriptor->PhysicalStart + KSEG0_BASE, Descriptor->PhysicalStart,
Descriptor->NumberOfPages, MemoryType);
}
else
{
/* Add any non-free memory using sequential mapping */
Status = MapVirtualMemory(PageMap, VirtualAddress, Descriptor->PhysicalStart,
Descriptor->NumberOfPages, MemoryType);
/* Calculate next valid virtual address */
VirtualAddress += Descriptor->NumberOfPages * EFI_PAGE_SIZE;
/* Update virtual address */
VirtualAddress = VirtualAddress + (Descriptor->NumberOfPages * MM_PAGE_SIZE);
}
}
else
{
/* Map all other memory as loader free */
Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)Descriptor->PhysicalStart,
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Descriptor->PhysicalStart,
Descriptor->NumberOfPages, LoaderFree);
}
@@ -436,7 +460,7 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
}
/* Always map first page */
Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)0, 1, LoaderFirmwarePermanent);
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, 0, 1, LoaderFirmwarePermanent);
if(Status != STATUS_EFI_SUCCESS)
{
/* Mapping failed */
@@ -444,7 +468,7 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
}
/* Map BIOS ROM and VRAM */
Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)0xA0000, 0x60, LoaderFirmwarePermanent);
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, 0xA0000, 0x60, LoaderFirmwarePermanent);
if(Status != STATUS_EFI_SUCCESS)
{
/* Mapping failed */
@@ -452,7 +476,7 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
}
/* Store next valid virtual address and return success */
*MemoryMapAddress = VirtualAddress;
*BaseAddress = (PVOID)VirtualAddress;
return STATUS_EFI_SUCCESS;
}
@@ -481,13 +505,13 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
XTCDECL
EFI_STATUS
Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
IN PVOID VirtualAddress,
IN PVOID PhysicalAddress,
IN ULONGLONG VirtualAddress,
IN ULONGLONG PhysicalAddress,
IN ULONGLONG NumberOfPages,
IN LOADER_MEMORY_TYPE MemoryType)
{
PXTBL_MEMORY_MAPPING Mapping1, Mapping2, Mapping3;
PVOID PhysicalAddressEnd, PhysicalAddress2End;
ULONGLONG PhysicalAddressEnd, PhysicalAddress2End;
PLIST_ENTRY ListEntry, MappingListEntry;
SIZE_T NumberOfMappedPages;
EFI_STATUS Status;
@@ -507,7 +531,7 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
Mapping1->MemoryType = MemoryType;
/* Calculate the end of the physical address */
PhysicalAddressEnd = (PVOID)((ULONG_PTR)PhysicalAddress + (NumberOfPages * EFI_PAGE_SIZE) - 1);
PhysicalAddressEnd = PhysicalAddress + (NumberOfPages * EFI_PAGE_SIZE) - 1;
/* Iterate through all the mappings already set to insert new mapping at the correct place */
ListEntry = PageMap->MemoryMap.Flink;
@@ -515,7 +539,7 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
{
/* Take a mapping from the list and calculate its end of physical address */
Mapping2 = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);
PhysicalAddress2End = (PVOID)((ULONG_PTR)Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1);
PhysicalAddress2End = Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1;
/* Check if new mapping is a subset of an existing mapping */
if(Mapping1->PhysicalAddress >= Mapping2->PhysicalAddress && PhysicalAddressEnd <= PhysicalAddress2End)
@@ -523,7 +547,8 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
/* Make sure it's memory type is the same */
if(Mapping1->MemoryType == Mapping2->MemoryType)
{
/* It is already mapped */
/* Free the unused mapping structure and return success */
FreePool(Mapping1);
return STATUS_EFI_SUCCESS;
}
}
@@ -539,7 +564,7 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
}
/* Calculate number of pages for this mapping */
NumberOfMappedPages = ((PUCHAR)PhysicalAddress2End - (PUCHAR)PhysicalAddressEnd) / EFI_PAGE_SIZE;
NumberOfMappedPages = (PhysicalAddress2End - PhysicalAddressEnd) / EFI_PAGE_SIZE;
if(NumberOfMappedPages > 0)
{
/* Pages associated to the mapping, allocate memory for it */
@@ -550,18 +575,21 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
return Status;
}
/* Set mapping fields and insert it on the top */
Mapping3->PhysicalAddress = (PUCHAR)PhysicalAddressEnd + 1;
Mapping3->VirtualAddress = NULLPTR;
/* Set mapping fields */
Mapping3->PhysicalAddress = PhysicalAddressEnd + 1;
Mapping3->VirtualAddress = (ULONGLONG)NULLPTR;
Mapping3->NumberOfPages = NumberOfMappedPages;
Mapping3->MemoryType = Mapping2->MemoryType;
/* Insert new mapping in front of the list and increase page map size */
RTL::LinkedList::InsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry);
PageMap->MapSize++;
}
/* Calculate number of pages and the end of the physical address */
Mapping2->NumberOfPages = ((PUCHAR)PhysicalAddressEnd + 1 -
(PUCHAR)Mapping2->PhysicalAddress) / EFI_PAGE_SIZE;
PhysicalAddress2End = (PVOID)((ULONG_PTR)Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1);
PhysicalAddress2End = Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1;
}
/* Check if they overlap */
@@ -586,18 +614,21 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
return Status;
}
/* Set mapping fields and insert it on the top */
/* Set mapping fields */
Mapping3->PhysicalAddress = Mapping1->PhysicalAddress;
Mapping3->VirtualAddress = NULLPTR;
Mapping3->VirtualAddress = (ULONGLONG)NULLPTR;
Mapping3->NumberOfPages = NumberOfMappedPages;
Mapping3->MemoryType = Mapping2->MemoryType;
/* Insert new mapping in front of the list and increase page map size */
RTL::LinkedList::InsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry);
PageMap->MapSize++;
}
/* Calculate number of pages and the end of the physical address */
Mapping2->NumberOfPages = ((PUCHAR)Mapping1->PhysicalAddress -
(PUCHAR)Mapping2->PhysicalAddress) / EFI_PAGE_SIZE;
PhysicalAddress2End = (PVOID)((ULONG_PTR)Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1);
PhysicalAddress2End = Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1;
}
/* Check if mapping is really needed */
@@ -619,15 +650,19 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
Status = FreePool(Mapping2);
ListEntry = MappingListEntry;
/* Go to the next mapping */
/* Decrease page map size and go to the next mapping */
PageMap->MapSize--;
continue;
}
/* Determine physical address order */
if(Mapping2->PhysicalAddress > Mapping1->PhysicalAddress)
{
/* Insert new mapping in front */
/* Insert new mapping in front of the list and increase page map size */
RTL::LinkedList::InsertHeadList(Mapping2->ListEntry.Blink, &Mapping1->ListEntry);
PageMap->MapSize++;
/* Return success */
return STATUS_EFI_SUCCESS;
}
@@ -635,7 +670,7 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
ListEntry = ListEntry->Flink;
}
/* Insert new mapping to the list and increase page map size */
/* Insert new mapping to the tail of the list and increase page map size */
RTL::LinkedList::InsertTailList(&PageMap->MemoryMap, &Mapping1->ListEntry);
PageMap->MapSize++;

Voir le fichier

@@ -729,11 +729,11 @@ PeCoff::RelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image)
}
else
{
/* Check if loaded 32-bit PE32 image should be relocated */
/* Set relocation data directory and image base address */
DataDirectory = &Image->PeHeader->OptionalHeader32.DataDirectory[PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC];
ImageBase = Image->PeHeader->OptionalHeader32.ImageBase;
/* Check if loaded 32-bit PE32 image should be relocated */
if(Image->PeHeader->OptionalHeader32.NumberOfRvaAndSizes <= PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC ||
DataDirectory->VirtualAddress == 0 || DataDirectory->Size < sizeof(PECOFF_IMAGE_BASE_RELOCATION))
{

Voir le fichier

@@ -10,6 +10,49 @@
#include <xtos.hh>
XTCDECL
EFI_STATUS
Xtos::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap)
{
EFI_STATUS Status;
/* Build page map */
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, (PageMap->PageMapLevel > 4) ? MM_P5E_LA57_BASE : MM_PXE_BASE);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to build page map */
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
return Status;
}
/* Map memory for hardware layer */
Status = MapHardwareMemoryPool(PageMap);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to map memory for hardware layer */
XtLdrProtocol->Debug.Print(L"Failed to map memory for hardware leyer (Status code: %zX)\n", Status);
return Status;
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
/**
* Determines the appropriate EFI memory mapping strategy for the AMD64 architecture.
*
* @return This routine returns TRUE, what results in an identity mapping.
*
* @since XT 1.0
*/
XTCDECL
BOOLEAN
Xtos::DetermineMappingStrategy()
{
/* Use an identity mapping strategy */
return TRUE;
}
/**
* Determines the appropriate paging level (PML) for the AMD64 architecture.
*
@@ -76,24 +119,6 @@ Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
ULONG_PTR TrampolineSize;
PVOID TrampolineCode;
/* Build page map */
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, (PageMap->PageMapLevel > 4) ? MM_P5E_LA57_BASE : MM_PXE_BASE);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to build page map */
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
return Status;
}
/* Map memory for hardware layer */
Status = MapHardwareMemoryPool(PageMap);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to map memory for hardware layer */
XtLdrProtocol->Debug.Print(L"Failed to map memory for hardware leyer (Status code: %zX)\n", Status);
return Status;
}
/* Check the configured page map level to set the LA57 state accordingly */
if(PageMap->PageMapLevel == 5)
{
@@ -173,6 +198,7 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
PHARDWARE_PTE P5eBase, PdeBase, PpeBase, PxeBase;
EFI_PHYSICAL_ADDRESS Address;
EFI_STATUS Status;
ULONG Index;
if(PageMap->PageMapLevel == 5)
{
@@ -190,6 +216,9 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
return Status;
}
/* Map hardware memory */
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
/* Zero fill memory used by P5E */
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
@@ -224,6 +253,9 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
return Status;
}
/* Map hardware memory */
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
/* Zero fill memory used by PXE */
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
@@ -252,6 +284,9 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
return Status;
}
/* Map hardware memory */
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
/* Zero fill memory used by PPE */
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
@@ -270,7 +305,7 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
}
/* Loop through 2 PDE entries */
for(UINT Index = 0 ; Index < 2 ; Index++)
for(Index = 0 ; Index < 2 ; Index++)
{
/* Check if PDE entry already exists */
if(!PdeBase[((MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF) + Index].Valid)
@@ -283,6 +318,9 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
return Status;
}
/* Map hardware memory */
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
/* Zero fill memory used by PDE */
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);

Voir le fichier

@@ -9,6 +9,62 @@
#include <xtos.hh>
XTCDECL
EFI_STATUS
Xtos::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap)
{
ULONG_PTR SelfMapAddress;
EFI_STATUS Status;
/* Initialize self map address */
if(PageMap->PageMapLevel == 3)
{
/* For PML3 (PAE) use PTE base address */
SelfMapAddress = MM_PTE_BASE;
}
else
{
/* For PML2 (PAE disabled) use legacy PDE base address */
SelfMapAddress = MM_PDE_LEGACY_BASE;
}
/* Build page map */
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, SelfMapAddress);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to build page map */
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
return Status;
}
/* Map memory for hardware layer */
Status = MapHardwareMemoryPool(PageMap);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to map memory for hardware layer */
XtLdrProtocol->Debug.Print(L"Failed to map memory for hardware layer (Status code: %zX)\n", Status);
return Status;
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
/**
* Determines the appropriate EFI memory mapping strategy for the i686 architecture.
*
* @return This routine returns FALSE, what results in a sequential mapping.
*
* @since XT 1.0
*/
XTCDECL
BOOLEAN
Xtos::DetermineMappingStrategy()
{
/* Use a sequential mapping strategy */
return FALSE;
}
/**
* Determines the appropriate paging level (PML) for the i686 architecture.
*
@@ -60,24 +116,6 @@ Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
{
EFI_STATUS Status;
/* Build page map */
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, MM_PTE_BASE);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to build page map */
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
return Status;
}
/* Map memory for hardware layer */
Status = MapHardwareMemoryPool(PageMap);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to map memory for hardware layer */
XtLdrProtocol->Debug.Print(L"Failed to map memory for hardware layer (Status code: %zX)\n", Status);
return Status;
}
/* Exit EFI Boot Services */
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
Status = XtLdrProtocol->Utils.ExitBootServices();
@@ -145,6 +183,9 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
/* Zero fill allocated memory */
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
/* Map hardware memory */
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
/* Check if PAE is enabled (3-level paging) */
if(PageMap->PageMapLevel == 3)
{

Voir le fichier

@@ -38,7 +38,9 @@ class Xtos
IN PVOID PhysicalAddress,
IN UINT NumberOfPages,
IN LOADER_MEMORY_TYPE MemoryType);
STATIC XTCDECL EFI_STATUS BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap);
STATIC XTCDECL LOADER_MEMORY_TYPE ConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType);
STATIC XTCDECL BOOLEAN DetermineMappingStrategy();
STATIC XTCDECL ULONG DeterminePagingLevel(IN CONST PWCHAR Parameters);
STATIC XTCDECL EFI_STATUS EnablePaging(IN PXTBL_PAGE_MAPPING PageMap);
STATIC XTCDECL VOID GetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource,
@@ -46,10 +48,13 @@ class Xtos
IN PULONG_PTR FrameBufferSize,
IN PXTBL_FRAMEBUFFER_MODE_INFORMATION FrameBufferModeInfo);
STATIC XTCDECL EFI_STATUS GetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID *VirtualAddress,
IN EFI_PHYSICAL_ADDRESS PhysicalBase,
IN PVOID VirtualBase,
OUT PLIST_ENTRY MemoryDescriptorList);
STATIC XTCDECL EFI_STATUS GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID *VirtualAddress,
IN EFI_PHYSICAL_ADDRESS PhysicalBase,
IN PVOID VirtualBase,
IN PVOID FrameBufferVirtualBase,
OUT PLIST_ENTRY SystemResourcesList);
STATIC XTCDECL EFI_STATUS GetVirtualAddress(IN PLIST_ENTRY MemoryMappings,
IN PVOID PhysicalAddress,

Voir le fichier

@@ -191,56 +191,52 @@ Xtos::GetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource
XTCDECL
EFI_STATUS
Xtos::GetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID *VirtualAddress,
IN EFI_PHYSICAL_ADDRESS PhysicalBase,
IN PVOID VirtualBase,
OUT PLIST_ENTRY MemoryDescriptorList)
{
EFI_PHYSICAL_ADDRESS Address;
EFI_STATUS Status;
ULONGLONG Pages;
Pages = (ULONGLONG)EFI_SIZE_TO_PAGES((PageMap->MapSize + 1) * sizeof(LOADER_MEMORY_DESCRIPTOR));
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, Pages, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
return Status;
}
Status = XtLdrProtocol->Memory.MapVirtualMemory(PageMap, *VirtualAddress, (PVOID)Address, Pages, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS)
{
XtLdrProtocol->Memory.FreePages(Address, Pages);
return Status;
}
PVOID PhysicalBase = (PVOID)Address;
PLOADER_MEMORY_DESCRIPTOR Descriptor;
PXTBL_MEMORY_MAPPING MemoryMapping;
PLIST_ENTRY ListEntry;
/* Initialize the descriptor pointer to the start of the allocated physical buffer */
Descriptor = (PLOADER_MEMORY_DESCRIPTOR)PhysicalBase;
/* Get the first entry from the internal boot loader memory map */
ListEntry = PageMap->MemoryMap.Flink;
/* Iterate through the internal memory map and populate the loader descriptor list */
while(ListEntry != &PageMap->MemoryMap)
{
PXTBL_MEMORY_MAPPING MemoryMapping = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);
PLOADER_MEMORY_DESCRIPTOR MemoryDescriptor = (PLOADER_MEMORY_DESCRIPTOR)Address;
/* Retrieve the internal memory mapping record from the current list entry */
MemoryMapping = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);
MemoryDescriptor->MemoryType = MemoryMapping->MemoryType;
MemoryDescriptor->BasePage = (UINT_PTR)MemoryMapping->PhysicalAddress / EFI_PAGE_SIZE;
MemoryDescriptor->PageCount = MemoryMapping->NumberOfPages;
/* Transfer memory type and address information to the kernel descriptor */
Descriptor->MemoryType = MemoryMapping->MemoryType;
Descriptor->BasePage = (UINT_PTR)(MemoryMapping->PhysicalAddress / EFI_PAGE_SIZE);
Descriptor->PageCount = (ULONG)MemoryMapping->NumberOfPages;
XtLdrProtocol->LinkedList.InsertTail(MemoryDescriptorList, &MemoryDescriptor->ListEntry);
/* Link the entry */
XtLdrProtocol->LinkedList.InsertTail(MemoryDescriptorList, &Descriptor->ListEntry);
Address = Address + sizeof(LOADER_MEMORY_DESCRIPTOR);
/* Move to the next slot in the allocated buffer */
Descriptor++;
ListEntry = ListEntry->Flink;
}
XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, MemoryDescriptorList, PhysicalBase, *VirtualAddress);
/* Convert all physical link pointers in the list to their corresponding virtual addresses */
XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, MemoryDescriptorList, (PVOID)PhysicalBase, VirtualBase);
/* Return success */
return STATUS_EFI_SUCCESS;
}
XTCDECL
EFI_STATUS
Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID *VirtualAddress,
IN EFI_PHYSICAL_ADDRESS PhysicalBase,
IN PVOID VirtualBase,
IN PVOID FrameBufferVirtualBase,
OUT PLIST_ENTRY SystemResourcesList)
{
XTSTATUS Status;
@@ -251,39 +247,18 @@ Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
XTBL_FRAMEBUFFER_MODE_INFORMATION FbModeInfo;
EFI_PHYSICAL_ADDRESS FbAddress;
EFI_PHYSICAL_ADDRESS OriginalPhysicalBase;
ULONG_PTR FbSize;
UINT FrameBufferPages;
PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource;
PSYSTEM_RESOURCE_ACPI AcpiResource;
ULONGLONG Pages;
EFI_PHYSICAL_ADDRESS Address;
PVOID PhysicalBase, VirtualBase;
Pages = (ULONGLONG)EFI_SIZE_TO_PAGES(sizeof(SYSTEM_RESOURCE_ACPI) + sizeof(SYSTEM_RESOURCE_FRAMEBUFFER));
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, Pages, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
return Status;
}
Status = XtLdrProtocol->Memory.MapVirtualMemory(PageMap, *VirtualAddress, (PVOID)Address, Pages, LoaderFirmwarePermanent);
if(Status != STATUS_EFI_SUCCESS)
{
XtLdrProtocol->Memory.FreePages(Address, Pages);
return Status;
}
PhysicalBase = (PVOID)Address;
VirtualBase = *VirtualAddress;
/* Calculate next valid virtual address */
*VirtualAddress = (PUINT8)*VirtualAddress + (Pages * EFI_PAGE_SIZE);
AcpiResource = (PSYSTEM_RESOURCE_ACPI)Address;
/* Save original physical base */
OriginalPhysicalBase = PhysicalBase;
AcpiResource = (PSYSTEM_RESOURCE_ACPI)PhysicalBase;
XtLdrProtocol->Memory.ZeroMemory(AcpiResource, sizeof(SYSTEM_RESOURCE_ACPI));
/* Load FrameBuffer protocol */
/* Load ACPI protocol */
Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&AcpiProtocol, &AcpiGuid);
if(Status != STATUS_EFI_SUCCESS)
{
@@ -302,13 +277,11 @@ Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
XtLdrProtocol->LinkedList.InsertTail(SystemResourcesList, &AcpiResource->Header.ListEntry);
/* Close FrameBuffer protocol */
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
Address = Address + sizeof(SYSTEM_RESOURCE_ACPI);
FrameBufferResource = (PSYSTEM_RESOURCE_FRAMEBUFFER)Address;
/* Close ACPI protocol */
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &AcpiGuid);
PhysicalBase = PhysicalBase + sizeof(SYSTEM_RESOURCE_ACPI);
FrameBufferResource = (PSYSTEM_RESOURCE_FRAMEBUFFER)PhysicalBase;
XtLdrProtocol->Memory.ZeroMemory(FrameBufferResource, sizeof(SYSTEM_RESOURCE_FRAMEBUFFER));
/* Load FrameBuffer protocol */
@@ -329,26 +302,16 @@ Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
return Status;
}
/* Calculate pages needed to map framebuffer */
FrameBufferPages = EFI_SIZE_TO_PAGES(FbSize);
/* Rewrite framebuffer address by using virtual address */
FrameBufferResource->Header.VirtualAddress = *VirtualAddress;
/* Map frame buffer memory */
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, FrameBufferResource->Header.VirtualAddress,
FrameBufferResource->Header.PhysicalAddress,
FrameBufferPages, LoaderFirmwarePermanent);
/* Close FrameBuffer protocol */
/* Assign the pre-mapped virtual address to the resource block */
FrameBufferResource->Header.VirtualAddress = FrameBufferVirtualBase;
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
*VirtualAddress = (PUINT8)*VirtualAddress + (FrameBufferPages * EFI_PAGE_SIZE);
XtLdrProtocol->LinkedList.InsertTail(SystemResourcesList, &FrameBufferResource->Header.ListEntry);
XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, SystemResourcesList, PhysicalBase, VirtualBase);
/* Convert list pointers to virtual */
XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, SystemResourcesList, (PVOID)OriginalPhysicalBase, VirtualBase);
/* Return success */
return STATUS_EFI_SUCCESS;
}
@@ -389,7 +352,7 @@ Xtos::InitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap)
}
/* Map APIC base address */
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (PVOID)APIC_BASE, ApicBaseAddress, 1, LoaderFirmwarePermanent);
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, APIC_BASE, (ULONGLONG)ApicBaseAddress, 1, LoaderFirmwarePermanent);
return STATUS_EFI_SUCCESS;
}
@@ -409,34 +372,100 @@ Xtos::InitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap)
XTCDECL
EFI_STATUS
Xtos::InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID *VirtualAddress,
IN OUT PVOID *VirtualAddress,
IN PXTBL_BOOT_PARAMETERS Parameters)
{
EFI_PHYSICAL_ADDRESS FbPhysicalAddress, PhysicalBlock, PhysicalDescriptor, PhysicalResources;
PVOID FbVirtualAddress, VirtualBlock, VirtualResources, VirtualDescriptor;
UINT BlockPages, DescriptorPages, FbPages, ParametersSize, ResourcesPages;
XTBL_FRAMEBUFFER_MODE_INFORMATION FbModeInfo;
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
PKERNEL_INITIALIZATION_BLOCK LoaderBlock;
EFI_PHYSICAL_ADDRESS Address;
EFI_HANDLE ProtocolHandle;
EFI_STATUS Status;
UINT BlockPages;
UINT ParametersSize;
ULONG_PTR FbSize;
EFI_GUID FrameBufGuid = XT_FRAMEBUFFER_PROTOCOL_GUID;
/* Initialize Framebuffer information */
FbPhysicalAddress = 0;
FbSize = 0;
FbVirtualAddress = NULLPTR;
FbPages = 0;
/* Calculate size of parameters */
ParametersSize = (XtLdrProtocol->WideString.Length(Parameters->Parameters, 0) + 1) * sizeof(WCHAR);
/* Calculate number of pages needed for initialization block */
BlockPages = EFI_SIZE_TO_PAGES(sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize);
ResourcesPages = EFI_SIZE_TO_PAGES(sizeof(SYSTEM_RESOURCE_ACPI) + sizeof(SYSTEM_RESOURCE_FRAMEBUFFER));
/* Allocate memory for kernel initialization block */
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, BlockPages, &Address);
/* Query Framebuffer size for allocation */
if(XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&FrameBufProtocol, &FrameBufGuid) == STATUS_EFI_SUCCESS)
{
/* Get FrameBuffer information */
FrameBufProtocol->GetDisplayInformation(&FbPhysicalAddress, &FbSize, &FbModeInfo);
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
}
FbPages = EFI_SIZE_TO_PAGES(FbSize);
/* Precommit page map to allocate memory */
XtLdrProtocol->Memory.CommitPageMap(PageMap);
/* Calculate number of pages needed for memory descriptor list */
DescriptorPages = EFI_SIZE_TO_PAGES(PageMap->MapSize * sizeof(LOADER_MEMORY_DESCRIPTOR) * 2);
/* Allocate memory for the kernel initialization block and boot parameters */
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, BlockPages, &PhysicalBlock);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
/* Memory allocation failure, return status code */
return Status;
}
/* Initialize and zero-fill kernel initialization block */
LoaderBlock = (PKERNEL_INITIALIZATION_BLOCK)(UINT_PTR)Address;
XtLdrProtocol->Memory.ZeroMemory(LoaderBlock, sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize);
/* Allocate memory for the system resources data structures */
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, ResourcesPages, &PhysicalResources);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, return status code */
return Status;
}
/* Allocate memory for the memory descriptor list */
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, DescriptorPages, &PhysicalDescriptor);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, return status code */
return Status;
}
/* Map the Kernel Initialization Block into virtual memory and advance the virtual address pointer */
VirtualBlock = *VirtualAddress;
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)VirtualBlock, PhysicalBlock, BlockPages, LoaderSystemBlock);
*VirtualAddress = (PUINT8)*VirtualAddress + (BlockPages * EFI_PAGE_SIZE);
/* Map the system resources physical memory into virtual address space and update the allocation pointer */
VirtualResources = *VirtualAddress;
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)VirtualResources, PhysicalResources, ResourcesPages, LoaderFirmwarePermanent);
*VirtualAddress = (PUINT8)*VirtualAddress + (ResourcesPages * EFI_PAGE_SIZE);
/* Check if a framebuffer was detected and requires memory mapping */
if(FbPages > 0)
{
/* Map the framebuffer physical memory range into virtual address space */
FbVirtualAddress = *VirtualAddress;
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)FbVirtualAddress, FbPhysicalAddress, FbPages, LoaderFirmwarePermanent);
*VirtualAddress = (PUINT8)*VirtualAddress + (FbPages * EFI_PAGE_SIZE);
}
/* Map the allocated physical memory for memory descriptors into the virtual address space */
VirtualDescriptor = *VirtualAddress;
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)VirtualDescriptor, PhysicalDescriptor, DescriptorPages, LoaderMemoryData);
*VirtualAddress = (PUINT8)*VirtualAddress + (DescriptorPages * EFI_PAGE_SIZE);
/* Set basic loader block properties */
XtLdrProtocol->Memory.ZeroMemory((PVOID)PhysicalBlock, sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize);
LoaderBlock = (PKERNEL_INITIALIZATION_BLOCK)PhysicalBlock;
LoaderBlock->BlockSize = sizeof(KERNEL_INITIALIZATION_BLOCK);
LoaderBlock->BlockVersion = INITIALIZATION_BLOCK_VERSION;
LoaderBlock->ProtocolVersion = BOOT_PROTOCOL_VERSION;
@@ -450,24 +479,33 @@ Xtos::InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
LoaderBlock->FirmwareInformation.EfiFirmware.EfiRuntimeServices = NULLPTR;
/* Copy parameters to kernel initialization block */
LoaderBlock->KernelParameters = (PWCHAR)((UINT_PTR)*VirtualAddress + sizeof(KERNEL_INITIALIZATION_BLOCK));
LoaderBlock->KernelParameters = (PWCHAR)((UINT_PTR)VirtualBlock + sizeof(KERNEL_INITIALIZATION_BLOCK));
XtLdrProtocol->Memory.CopyMemory((PVOID)((UINT_PTR)LoaderBlock + sizeof(KERNEL_INITIALIZATION_BLOCK)),
Parameters->Parameters,
ParametersSize);
Parameters->Parameters, ParametersSize);
/* Map kernel initialization block */
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, *VirtualAddress, (PVOID)LoaderBlock,
BlockPages, LoaderSystemBlock);
/* Calculate next valid virtual address */
*VirtualAddress = (PUINT8)*VirtualAddress + (BlockPages * EFI_PAGE_SIZE);
/* Commit mappings */
XtLdrProtocol->Memory.CommitPageMap(PageMap);
/* Initialize system resources list */
XtLdrProtocol->LinkedList.InitializeHead(&LoaderBlock->SystemResourcesListHead);
GetSystemResourcesList(PageMap, VirtualAddress, &LoaderBlock->SystemResourcesListHead);
Status = GetSystemResourcesList(PageMap, PhysicalResources, VirtualResources, FbVirtualAddress, &LoaderBlock->SystemResourcesListHead);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to initialize system resources list, return status code */
return Status;
}
/* Initialize memory descriptor list */
XtLdrProtocol->LinkedList.InitializeHead(&LoaderBlock->MemoryDescriptorListHead);
GetMemoryDescriptorList(PageMap, VirtualAddress, &LoaderBlock->MemoryDescriptorListHead);
Status = GetMemoryDescriptorList(PageMap, PhysicalDescriptor, VirtualDescriptor, &LoaderBlock->MemoryDescriptorListHead);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to initialize memory descriptor list, return status code */
return Status;
}
/* Set boot image size */
LoaderBlock->BootImageSize = (PFN_NUMBER)(((ULONGLONG)*VirtualAddress - KSEG0_BASE) / EFI_PAGE_SIZE);
/* Return success */
return STATUS_EFI_SUCCESS;
@@ -607,11 +645,12 @@ Xtos::RunBootSequence(IN PEFI_FILE_HANDLE BootDir,
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
PPECOFF_IMAGE_CONTEXT ImageContext = NULLPTR;
PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol;
PVOID VirtualAddress, VirtualMemoryArea;
PVOID VirtualAddress;
PXT_ENTRY_POINT KernelEntryPoint;
EFI_HANDLE ProtocolHandle;
EFI_STATUS Status;
XTBL_PAGE_MAPPING PageMap;
BOOLEAN IdentityMapping;
/* Initialize XTOS startup sequence */
XtLdrProtocol->Debug.Print(L"Initializing XTOS startup sequence\n");
@@ -628,19 +667,30 @@ Xtos::RunBootSequence(IN PEFI_FILE_HANDLE BootDir,
/* Close FrameBuffer protocol */
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
/* Determine whether to use a sequential or an identity mapping strategy */
IdentityMapping = DetermineMappingStrategy();
/* Set base virtual memory area for the kernel mappings */
VirtualMemoryArea = (PVOID)KSEG0_BASE;
VirtualAddress = (PVOID)(KSEG0_BASE + KSEG0_KERNEL_BASE);
VirtualAddress = (PVOID)(KSEG0_BASE);
/* Initialize virtual memory mappings */
XtLdrProtocol->Memory.InitializePageMap(&PageMap, DeterminePagingLevel(Parameters->Parameters), Size4K);
Status = XtLdrProtocol->Memory.MapEfiMemory(&PageMap, &VirtualMemoryArea, NULLPTR);
/* Map all EFI memory regions */
Status = XtLdrProtocol->Memory.MapEfiMemory(&PageMap, &VirtualAddress, IdentityMapping, NULLPTR);
if(Status != STATUS_EFI_SUCCESS)
{
/* Mapping failed */
return Status;
}
/* Check mapping strategy */
if(IdentityMapping)
{
/* Adjust virtual address to skip the identity-mapped physical range */
VirtualAddress = (PVOID)((ULONGLONG)VirtualAddress + 0x800000000);
}
/* Load the kernel */
Status = LoadModule(BootDir, Parameters->KernelFile, VirtualAddress, LoaderSystemCode, &ImageContext);
if(Status != STATUS_EFI_SUCCESS)
@@ -650,8 +700,8 @@ Xtos::RunBootSequence(IN PEFI_FILE_HANDLE BootDir,
}
/* Add kernel image memory mapping */
Status = XtLdrProtocol->Memory.MapVirtualMemory(&PageMap, ImageContext->VirtualAddress,
ImageContext->PhysicalAddress, ImageContext->ImagePages,
Status = XtLdrProtocol->Memory.MapVirtualMemory(&PageMap, (ULONGLONG)ImageContext->VirtualAddress,
(ULONGLONG)ImageContext->PhysicalAddress, ImageContext->ImagePages,
LoaderSystemCode);
if(Status != STATUS_EFI_SUCCESS)
{
@@ -670,6 +720,14 @@ Xtos::RunBootSequence(IN PEFI_FILE_HANDLE BootDir,
return Status;
}
/* Build page map */
Status = BuildPageMap(&PageMap);
if(Status != STATUS_EFI_SUCCESS)
{
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
return Status;
}
/* Store virtual address of kernel initialization block for future kernel call */
KernelParameters = (PKERNEL_INITIALIZATION_BLOCK)VirtualAddress;

Voir le fichier

@@ -1054,6 +1054,7 @@ Protocol::InstallXtLoaderProtocol()
LoaderProtocol.Memory.AllocatePages = Memory::AllocatePages;
LoaderProtocol.Memory.AllocatePool = Memory::AllocatePool;
LoaderProtocol.Memory.BuildPageMap = Memory::BuildPageMap;
LoaderProtocol.Memory.CommitPageMap = Memory::CommitPageMap;
LoaderProtocol.Memory.CompareMemory = RTL::Memory::CompareMemory;
LoaderProtocol.Memory.CopyMemory = RTL::Memory::CopyMemory;
LoaderProtocol.Memory.FreePages = Memory::FreePages;

Voir le fichier

@@ -236,6 +236,15 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle,
PWCHAR Modules;
EFI_STATUS Status;
/* Check if system is EFI-based and provided parameters are valid */
if(ImageHandle == NULLPTR || SystemTable == NULLPTR)
{
/* Invalid parameters, print error message using BIOS calls and hang */
BiosUtils::ClearScreen();
BiosUtils::Print(L"XTLDR requires EFI-based system!");
for(;;);
}
/* Initialize XTLDR and */
XtLoader::InitializeBootLoader(ImageHandle, SystemTable);

Voir le fichier

@@ -1,2 +1,3 @@
# Set base addresses for all modules
set(BASEADDRESS_XTLDR 0x000000000000F800)
set(BASEADDRESS_XTOSKRNL 0x0000000140000000)

Voir le fichier

@@ -1,2 +1,3 @@
# Set base addresses for all modules
set(BASEADDRESS_XTLDR 0x0000F800)
set(BASEADDRESS_XTOSKRNL 0x00400000)

Voir le fichier

@@ -64,11 +64,17 @@ function(compile_bootsector NAME SOURCE BASEADDR ENTRYPOINT)
set(BINARY_NAME "${NAME}.bin")
set(OBJECT_NAME "${NAME}.obj")
get_directory_property(DEFS COMPILE_DEFINITIONS)
foreach(def ${DEFS})
list(APPEND ASM_DEFS "-D${def}")
endforeach()
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${BINARY_NAME}
COMMAND ${CMAKE_ASM_COMPILER}
/nologo
--target=i386-none-elf
${ASM_DEFS}
-I${CMAKE_CURRENT_SOURCE_DIR}
/Fo${CMAKE_CURRENT_BINARY_DIR}/${OBJECT_NAME}
-c -- ${SOURCE}

Voir le fichier

@@ -108,9 +108,6 @@
/* Static Kernel-Mode address start */
#define KSEG0_BASE 0xFFFFF80000000000
/* XTOS Kernel address base */
#define KSEG0_KERNEL_BASE 0x0000000800000000
/* XTOS Kernel stack size */
#define KERNEL_STACK_SIZE 0x8000
@@ -272,11 +269,18 @@ typedef struct _KIDTENTRY
{
USHORT OffsetLow;
USHORT Selector;
USHORT IstIndex:3;
USHORT Reserved0:5;
USHORT Type:5;
USHORT Dpl:2;
USHORT Present:1;
union
{
struct
{
USHORT IstIndex:3;
USHORT Reserved0:5;
USHORT Type:5;
USHORT Dpl:2;
USHORT Present:1;
};
USHORT Access;
};
USHORT OffsetMiddle;
ULONG OffsetHigh;
ULONG Reserved1;

Voir le fichier

@@ -25,11 +25,11 @@
#define MM_PXE_BASE 0xFFFFF6FB7DBED000ULL
/* Page directory and page base addresses for 5-level paging */
#define MM_PTE_LA57_BASE 0xFFFF000000000000ULL
#define MM_PDE_LA57_BASE 0xFFFF010000000000ULL
#define MM_PPE_LA57_BASE 0xFFFF010800000000ULL
#define MM_PXE_LA57_BASE 0xFFFF010840000000ULL
#define MM_P5E_LA57_BASE 0xFFFF010840200000ULL
#define MM_PTE_LA57_BASE 0xFFED000000000000ULL
#define MM_PDE_LA57_BASE 0xFFEDF68000000000ULL
#define MM_PPE_LA57_BASE 0xFFEDF6FB40000000ULL
#define MM_PXE_LA57_BASE 0xFFEDF6FB7DA00000ULL
#define MM_P5E_LA57_BASE 0xFFEDF6FB7DBED000ULL
/* PTE shift values */
#define MM_PTE_SHIFT 3
@@ -39,15 +39,56 @@
#define MM_PXI_SHIFT 39
#define MM_P5I_SHIFT 48
/* Number of PTEs per page */
#define MM_PTE_PER_PAGE 512
#define MM_PDE_PER_PAGE 512
#define MM_PPE_PER_PAGE 512
#define MM_PXE_PER_PAGE 512
/* PTE state flags */
#define MM_PTE_VALID 0x0000000000000001ULL
#define MM_PTE_ACCESSED 0x0000000000000020ULL
#define MM_PTE_DIRTY 0x0000000000000040ULL
/* PTE scope flags */
#define MM_PTE_LARGE_PAGE 0x0000000000000080ULL
#define MM_PTE_GLOBAL 0x0000000000000100ULL
/* PTE access flags */
#define MM_PTE_NOACCESS 0x0000000000000000ULL
#define MM_PTE_READONLY 0x0000000000000000ULL
#define MM_PTE_EXECUTE 0x0000000000000000ULL
#define MM_PTE_EXECUTE_READ 0x0000000000000000ULL
#define MM_PTE_READWRITE 0x8000000000000002ULL
#define MM_PTE_WRITECOPY 0x8000000000000200ULL
#define MM_PTE_EXECUTE_READWRITE 0x0000000000000002ULL
#define MM_PTE_EXECUTE_WRITECOPY 0x0000000000000200ULL
/* PTE protection flags */
#define MM_PTE_NOEXECUTE 0x8000000000000000ULL
#define MM_PTE_GUARDED 0x8000000000000018ULL
#define MM_PTE_PROTECT 0x8000000000000612ULL
/* PTE cache flags */
#define MM_PTE_CACHE_ENABLE 0x0000000000000000ULL
#define MM_PTE_CACHE_DISABLE 0x0000000000000010ULL
#define MM_PTE_CACHE_WRITECOMBINED 0x0000000000000010ULL
#define MM_PTE_CACHE_WRITETHROUGH 0x0000000000000008ULL
/* PTE software flags */
#define MM_PTE_COPY_ON_WRITE 0x0000000000000200ULL
#define MM_PTE_PROTOTYPE 0x0000000000000400ULL
#define MM_PTE_TRANSITION 0x0000000000000800ULL
/* PTE frame bits */
#define MM_PTE_FRAME_BITS 57
/* PTE protection bits */
#define MM_PTE_PROTECTION_BITS 5
/* Base address of the system page table */
#define MM_SYSTEM_PTE_BASE KSEG0_BASE
/* Minimum number of physical pages needed by the system */
#define MM_MINIMUM_PHYSICAL_PAGES 2048
/* Number of system PTEs */
#define MM_DEFAULT_NUMBER_SYSTEM_PTES 22000
/* Default number of secondary colors */
#define MM_DEFAULT_SECONDARY_COLORS 64
@@ -63,9 +104,21 @@
/* Maximum physical address used by HAL allocations */
#define MM_MAXIMUM_PHYSICAL_ADDRESS 0x00000000FFFFFFFFULL
/* Highest system address */
#define MM_HIGHEST_SYSTEM_ADDRESS 0xFFFFFFFFFFFFFFFFULL
/* Trampoline code address */
#define MM_TRAMPOLINE_ADDRESS 0x80000
/* Pool block size */
#define MM_POOL_BLOCK_SIZE 16
/* Number of pool lists per page */
#define MM_POOL_LISTS_PER_PAGE (MM_PAGE_SIZE / MM_POOL_BLOCK_SIZE)
/* Number of pool tracking tables */
#define MM_POOL_TRACKING_TABLES 64
/* Page size enumeration list */
typedef enum _PAGE_SIZE
{
@@ -252,6 +305,7 @@ typedef struct _MMPFN
USHORT ReferenceCount;
} e2;
} u3;
ULONG UsedPageTableEntries;
union
{
MMPTE OriginalPte;
@@ -262,15 +316,32 @@ typedef struct _MMPFN
ULONG_PTR EntireFrame;
struct
{
ULONG_PTR PteFrame:58;
ULONG_PTR PteFrame:57;
ULONG_PTR InPageError:1;
ULONG_PTR VerifierAllocation:1;
ULONG_PTR AweAllocation:1;
ULONG_PTR LockCharged:1;
ULONG_PTR KernelStack:1;
ULONG_PTR Priority:3;
ULONG_PTR MustBeCached:1;
};
} u4;
} MMPFN, *PMMPFN;
/* Pool descriptor structure definition */
typedef struct _POOL_DESCRIPTOR
{
LIST_ENTRY ListHeads[MM_POOL_LISTS_PER_PAGE];
PVOID LockAddress;
ULONG PoolIndex;
LONG PendingFreeDepth;
PVOID PendingFrees;
MMPOOL_TYPE PoolType;
ULONG RunningFrees;
ULONG RunningAllocations;
ULONG Threshold;
ULONG TotalPages;
ULONG TotalBigAllocations;
SIZE_T TotalBytes;
SIZE_T Reserved;
} POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
#endif /* __XTDK_AMD64_MMTYPES_H */

Voir le fichier

@@ -61,6 +61,7 @@ typedef struct _MMPTE_PROTOTYPE MMPTE_PROTOTYPE, *PMMPTE_PROTOTYPE;
typedef struct _MMPTE_SOFTWARE MMPTE_SOFTWARE, *PMMPTE_SOFTWARE;
typedef struct _MMPTE_SUBSECTION MMPTE_SUBSECTION, *PMMPTE_SUBSECTION;
typedef struct _MMPTE_TRANSITION MMPTE_TRANSITION, *PMMPTE_TRANSITION;
typedef struct _POOL_DESCRIPTOR POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
/* Unions forward references */

Voir le fichier

@@ -51,6 +51,7 @@ typedef EFI_STATUS (XTCDECL *PBL_BOOTMENU_INITIALIZE_OS_LIST)(IN ULONG MaxNameLe
typedef BOOLEAN (XTCDECL *PBL_BOOTUTILS_GET_BOOLEAN_PARAMETER)(IN PCWSTR Parameters, IN PCWSTR Needle);
typedef VOID (XTAPI *PBL_BOOTUTILS_GET_TRAMPOLINE_INFORMATION)(IN TRAMPOLINE_TYPE TrampolineType, OUT PVOID *TrampolineCode, OUT PULONG_PTR TrampolineSize);
typedef EFI_STATUS (XTCDECL *PBL_BUILD_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR SelfMapAddress);
typedef EFI_STATUS (XTCDECL *PBL_COMMIT_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap);
typedef EFI_STATUS (XTCDECL *PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle);
typedef VOID (XTCDECL *PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo);
typedef BOOLEAN (XTCDECL *PBL_CPU_CPUID)(IN OUT PCPUID_REGISTERS Registers);
@@ -100,9 +101,9 @@ typedef VOID (XTCDECL *PBL_LLIST_INITIALIZE_HEAD)(IN PLIST_ENTRY ListHead);
typedef VOID (XTCDECL *PBL_LLIST_INSERT_HEAD)(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry);
typedef VOID (XTCDECL *PBL_LLIST_INSERT_TAIL)(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry);
typedef VOID (XTCDECL *PBL_LLIST_REMOVE_ENTRY)(IN PLIST_ENTRY Entry);
typedef EFI_STATUS (XTCDECL *PBL_MAP_EFI_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN OUT PVOID *MemoryMapAddress, IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine);
typedef EFI_STATUS (XTCDECL *PBL_MAP_PAGE)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR VirtualAddress, IN ULONG_PTR PhysicalAddress, IN ULONG NumberOfPages);
typedef EFI_STATUS (XTCDECL *PBL_MAP_VIRTUAL_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN PVOID VirtualAddress, IN PVOID PhysicalAddress, IN ULONGLONG NumberOfPages, IN LOADER_MEMORY_TYPE MemoryType);
typedef EFI_STATUS (XTCDECL *PBL_MAP_EFI_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN OUT PVOID *BaseAddress, IN BOOLEAN IdentityMapping, IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine);
typedef EFI_STATUS (XTCDECL *PBL_MAP_PAGE)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONGLONG VirtualAddress, IN ULONGLONG PhysicalAddress, IN ULONGLONG NumberOfPages);
typedef EFI_STATUS (XTCDECL *PBL_MAP_VIRTUAL_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN ULONGLONG VirtualAddress, IN ULONGLONG PhysicalAddress, IN ULONGLONG NumberOfPages, IN LOADER_MEMORY_TYPE MemoryType);
typedef VOID (XTAPI *PBL_MOVE_MEMORY)(IN OUT PVOID Destination, IN PCVOID Source, IN SIZE_T Length);
typedef EFI_STATUS (XTCDECL *PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle);
typedef EFI_STATUS (XTCDECL *PBL_OPEN_PROTOCOL)(OUT PEFI_HANDLE Handle, OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid);
@@ -232,8 +233,8 @@ typedef struct _XTBL_KNOWN_BOOT_PROTOCOL
typedef struct _XTBL_MEMORY_MAPPING
{
LIST_ENTRY ListEntry;
PVOID VirtualAddress;
PVOID PhysicalAddress;
ULONGLONG VirtualAddress;
ULONGLONG PhysicalAddress;
ULONGLONG NumberOfPages;
LOADER_MEMORY_TYPE MemoryType;
} XTBL_MEMORY_MAPPING, *PXTBL_MEMORY_MAPPING;
@@ -449,6 +450,7 @@ typedef struct _XTBL_LOADER_PROTOCOL
PBL_ALLOCATE_PAGES AllocatePages;
PBL_ALLOCATE_POOL AllocatePool;
PBL_BUILD_PAGE_MAP BuildPageMap;
PBL_COMMIT_PAGE_MAP CommitPageMap;
PBL_COMPARE_MEMORY CompareMemory;
PBL_COPY_MEMORY CopyMemory;
PBL_FREE_PAGES FreePages;

Voir le fichier

@@ -58,12 +58,6 @@
#define KIDT_ACCESS_RING0 0x00
#define KIDT_ACCESS_RING3 0x60
/* IDT gate types */
#define KIDT_TASK 0x05
#define KIDT_CALL 0x0C
#define KIDT_INTERRUPT 0x0E
#define KIDT_TRAP 0x0F
/* TSS Offsets */
#define KTSS_ESP0 0x04
#define KTSS_CR3 0x1C
@@ -134,9 +128,6 @@
/* Static Kernel-Mode address start */
#define KSEG0_BASE 0x80000000
/* XTOS Kernel address base */
#define KSEG0_KERNEL_BASE 0x01800000
/* XTOS Kernel stack size */
#define KERNEL_STACK_SIZE 0x4000
@@ -284,7 +275,18 @@ typedef struct _KIDTENTRY
{
USHORT Offset;
USHORT Selector;
USHORT Access;
union
{
struct
{
UCHAR Reserved;
UCHAR Type:4;
UCHAR Flag:1;
UCHAR Dpl:2;
UCHAR Present:1;
};
USHORT Access;
};
USHORT ExtendedOffset;
} KIDTENTRY, *PKIDTENTRY;

Voir le fichier

@@ -35,9 +35,58 @@
#define MM_PTE_LEGACY_SHIFT 2
#define MM_PDI_LEGACY_SHIFT 22
/* PTE state flags */
#define MM_PTE_VALID 0x00000001
#define MM_PTE_ACCESSED 0x00000020
#define MM_PTE_DIRTY 0x00000040
/* PTE scope flags */
#define MM_PTE_LARGE_PAGE 0x00000080
#define MM_PTE_GLOBAL 0x00000100
/* PTE access flags */
#define MM_PTE_NOACCESS 0x00000000
#define MM_PTE_READONLY 0x00000000
#define MM_PTE_EXECUTE 0x00000000
#define MM_PTE_EXECUTE_READ 0x00000000
#define MM_PTE_READWRITE 0x00000002
#define MM_PTE_WRITECOPY 0x00000200
#define MM_PTE_EXECUTE_READWRITE 0x00000002
#define MM_PTE_EXECUTE_WRITECOPY 0x00000200
/* PTE protection flags */
#define MM_PTE_NOEXECUTE 0x00000000
#define MM_PTE_GUARDED 0x00000018
#define MM_PTE_PROTECT 0x00000612
/* PTE cache flags */
#define MM_PTE_CACHE_ENABLE 0x00000000
#define MM_PTE_CACHE_DISABLE 0x00000010
#define MM_PTE_CACHE_WRITECOMBINED 0x00000010
#define MM_PTE_CACHE_WRITETHROUGH 0x00000008
/* PTE software flags */
#define MM_PTE_COPY_ON_WRITE 0x00000200
#define MM_PTE_PROTOTYPE 0x00000400
#define MM_PTE_TRANSITION 0x00000800
/* PTE frame bits */
#define MM_PTE_FRAME_BITS 25
/* PTE protection bits */
#define MM_PTE_PROTECTION_BITS 5
/* Base address of the system page table */
#define MM_SYSTEM_PTE_BASE NULLPTR
/* Minimum number of physical pages needed by the system */
#define MM_MINIMUM_PHYSICAL_PAGES 1100
/* Number of system PTEs */
#define MM_MINIMUM_NUMBER_SYSTEM_PTES 7000
#define MM_DEFAULT_NUMBER_SYSTEM_PTES 11000
#define MM_MAXIMUM_NUMBER_SYSTEM_PTES 22000
/* Default number of secondary colors */
#define MM_DEFAULT_SECONDARY_COLORS 64
@@ -53,9 +102,21 @@
/* Maximum physical address used by HAL allocations */
#define MM_MAXIMUM_PHYSICAL_ADDRESS 0xFFFFFFFF
/* Highest system address */
#define MM_HIGHEST_SYSTEM_ADDRESS 0xFFFFFFFF
/* Trampoline code address */
#define MM_TRAMPOLINE_ADDRESS 0x80000
/* Pool block size */
#define MM_POOL_BLOCK_SIZE 8
/* Number of pool lists per page */
#define MM_POOL_LISTS_PER_PAGE (MM_PAGE_SIZE / MM_POOL_BLOCK_SIZE)
/* Number of pool tracking tables */
#define MM_POOL_TRACKING_TABLES 32
/* Page size enumeration list */
typedef enum _PAGE_SIZE
{
@@ -106,7 +167,6 @@ typedef struct _HARDWARE_MODERN_PTE
/* Generic Page Table entry union to abstract PML2 and PML3 formats */
typedef union _HARDWARE_PTE
{
ULONGLONG Long;
HARDWARE_LEGACY_PTE Pml2;
HARDWARE_MODERN_PTE Pml3;
} HARDWARE_PTE, *PHARDWARE_PTE;
@@ -201,12 +261,12 @@ typedef struct _MMPML2_PTE_TRANSITION
typedef union _MMPML2_PTE
{
ULONG Long;
HARDWARE_PTE Flush;
MMPML2_PTE_HARDWARE Hard;
MMPML2_PTE_PROTOTYPE Proto;
MMPML2_PTE_SOFTWARE Soft;
MMPML2_PTE_TRANSITION Trans;
MMPML2_PTE_SUBSECTION Subsect;
HARDWARE_LEGACY_PTE Flush;
MMPML2_PTE_HARDWARE Hardware;
MMPML2_PTE_PROTOTYPE Prototype;
MMPML2_PTE_SOFTWARE Software;
MMPML2_PTE_TRANSITION Transition;
MMPML2_PTE_SUBSECTION Subsection;
MMPML2_PTE_LIST List;
} MMPML2_PTE, *PMMPML2_PTE;
@@ -296,7 +356,7 @@ typedef struct _MMPML3_PTE_TRANSITION
typedef union _MMPML3_PTE
{
ULONGLONG Long;
HARDWARE_PTE Flush;
HARDWARE_MODERN_PTE Flush;
MMPML3_PTE_HARDWARE Hardware;
MMPML3_PTE_PROTOTYPE Prototype;
MMPML3_PTE_SOFTWARE Software;
@@ -308,7 +368,6 @@ typedef union _MMPML3_PTE
/* Generic Page Table Entry union to abstract PML2 and PML3 formats */
typedef union _MMPTE
{
ULONGLONG Long;
MMPML2_PTE Pml2;
MMPML3_PTE Pml3;
} MMPTE, *PMMPTE;
@@ -339,6 +398,7 @@ typedef struct _MMPFN
USHORT ReferenceCount;
} e2;
} u3;
ULONG UsedPageTableEntries;
union
{
MMPTE OriginalPte;
@@ -349,15 +409,32 @@ typedef struct _MMPFN
ULONG_PTR EntireFrame;
struct
{
ULONG_PTR PteFrame:26;
ULONG_PTR PteFrame:25;
ULONG_PTR InPageError:1;
ULONG_PTR VerifierAllocation:1;
ULONG_PTR AweAllocation:1;
ULONG_PTR LockCharged:1;
ULONG_PTR KernelStack:1;
ULONG_PTR Priority:3;
ULONG_PTR MustBeCached:1;
};
} u4;
} MMPFN, *PMMPFN;
/* Pool descriptor structure definition */
typedef struct _POOL_DESCRIPTOR
{
LIST_ENTRY ListHeads[MM_POOL_LISTS_PER_PAGE];
PVOID LockAddress;
ULONG PoolIndex;
LONG PendingFreeDepth;
PVOID PendingFrees;
MMPOOL_TYPE PoolType;
ULONG RunningFrees;
ULONG RunningAllocations;
ULONG Threshold;
ULONG TotalPages;
ULONG TotalBigAllocations;
SIZE_T TotalBytes;
SIZE_T Reserved;
} POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
#endif /* __XTDK_I686_MMTYPES_H */

Voir le fichier

@@ -70,6 +70,7 @@ typedef struct _MMPML3_PTE_PROTOTYPE MMPML3_PTE_PROTOTYPE, *PMMPML3_PTE_PROTOTYP
typedef struct _MMPML3_PTE_SOFTWARE MMPML3_PTE_SOFTWARE, *PMMPML3_PTE_SOFTWARE;
typedef struct _MMPML3_PTE_SUBSECTION MMPML3_PTE_SUBSECTION, *PMMPML3_PTE_SUBSECTION;
typedef struct _MMPML3_PTE_TRANSITION MMPML3_PTE_TRANSITION, *PMMPML3_PTE_TRANSITION;
typedef struct _POOL_DESCRIPTOR POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
/* Unions forward references */

Voir le fichier

@@ -150,21 +150,23 @@ typedef enum _KTHREAD_STATE
typedef enum _KSPIN_LOCK_QUEUE_LEVEL
{
DispatcherLock,
UnusedSpareLock,
ExpansionLock,
PfnLock,
SystemSpaceLock,
VacbLock,
MasterLock,
NonPagedPoolLock,
NonPagedAllocPoolLock,
IoCancelLock,
WorkQueueLock,
IoVpbLock,
IoDatabaseLock,
IoCompletionLock,
FsStructLock,
FileSystemLock,
AfdWorkQueueLock,
BcbLock,
MmNonPagedPoolLock,
NonPagedPoolLock,
ReservedSystemLock,
TimerTableLock,
MaximumLock
} KSPIN_LOCK_QUEUE_LEVEL, *PKSPIN_LOCK_QUEUE_LEVEL;

40
sdk/xtdk/mmfuncs.h Fichier normal
Voir le fichier

@@ -0,0 +1,40 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: sdk/xtdk/mmfuncs.h
* DESCRIPTION: XTOS memory manager routine definitions
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTDK_MMFUNCS_H
#define __XTDK_MMFUNCS_H
#include <xtdefs.h>
#include <xtstruct.h>
#include <xttypes.h>
/* Memory manager routines forward references */
XTAPI
XTSTATUS
MmAllocatePool(IN MMPOOL_TYPE PoolType,
IN SIZE_T Bytes,
OUT PVOID *Memory);
XTAPI
XTSTATUS
MmAllocatePoolWithTag(IN MMPOOL_TYPE PoolType,
IN SIZE_T Bytes,
OUT PVOID *Memory,
IN ULONG Tag);
XTAPI
XTSTATUS
MmFreePool(IN PVOID VirtualAddress);
XTAPI
XTSTATUS
MmFreePoolWithTag(IN PVOID VirtualAddress,
IN ULONG Tag);
#endif /* __XTDK_MMFUNCS_H */

Voir le fichier

@@ -4,6 +4,7 @@
* FILE: sdk/xtdk/mmtypes.h
* DESCRIPTION: Memory management data structures
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTDK_MMTYPES_H
@@ -13,6 +14,95 @@
#include ARCH_HEADER(xtstruct.h)
/* Number of hyper space pages */
#define MM_HYPERSPACE_PAGE_COUNT 255
/* Number of free page list heads */
#define MM_MAX_FREE_PAGE_LIST_HEADS 4
/* Number of paging colors */
#define MM_PAGING_COLORS 64
/* PTE frame mask definition */
#define MM_PFN_PTE_FRAME (((ULONG_PTR)1 << MM_PTE_FRAME_BITS) - 1)
/* Memory manager pool type mask definition */
#define MM_POOL_TYPE_MASK 1
/* Bad pool caller reasons */
#define MM_POOL_INVALID_ALLOC_RUNLEVEL 8
#define MM_POOL_INVALID_FREE_RUNLEVEL 9
/* Pool flags */
#define MM_POOL_BIG_ALLOCATIONS_ENTRY_FREE 0x1
#define MM_POOL_PROTECTED 0x80000000
#define MM_POOL_RAISE_EXCEPTION 0x10
/* Number of reserved zeroed PTEs */
#define MM_RESERVED_ZERO_PTES 32
/* Memory Manager Protection Bits */
#define MM_ZERO_ACCESS 0
#define MM_READONLY 1
#define MM_EXECUTE 2
#define MM_EXECUTE_READ 3
#define MM_READWRITE 4
#define MM_WRITECOPY 5
#define MM_EXECUTE_READWRITE 6
#define MM_EXECUTE_WRITECOPY 7
#define MM_PROTECT_ACCESS 7
/* Protection field shift */
#define MM_PROTECT_FIELD_SHIFT 5
/* Memory manager page lists */
typedef enum _MMPAGELISTS
{
ZeroedPageList = 0,
FreePageList = 1,
StandbyPageList = 2,
ModifiedPageList = 3,
ModifiedReadOnlyPageList = 4,
BadPageList = 5,
ActiveAndValid = 6,
TransitionPage = 7
} MMPAGELISTS, *PMMPAGELISTS;
/* Page cache attributes */
typedef enum _MMPFN_CACHE_ATTRIBUTE
{
PfnNonCached,
PfnCached,
PfnWriteCombined,
PfnNotMapped
} MMPFN_CACHE_ATTRIBUTE, *PMMPFN_CACHE_ATTRIBUTE;
/* Memory Manager pool types */
typedef enum _MMPOOL_TYPE
{
NonPagedPool = 0,
PagedPool = 1,
NonPagedPoolMustSucceed = 2,
NonPagedPoolCacheAligned = 4,
PagedPoolCacheAligned = 5,
NonPagedPoolCacheAlignedMustSucceed = 6,
MaxPoolType = 7,
NonPagedPoolSession = 32,
PagedPoolSession = 33,
NonPagedPoolMustSucceedSession = 34,
NonPagedPoolCacheAlignedSession = 36,
PagedPoolCacheAlignedSession = 37,
NonPagedPoolCacheAlignedMustSucceedSession = 38
} MMPOOL_TYPE, *PMMPOOL_TYPE;
/* Page table pool types */
typedef enum _MMSYSTEM_PTE_POOL_TYPE
{
SystemPteSpace,
NonPagedPoolExpansion,
MaximumPtePoolTypes
} MMSYSTEM_PTE_POOL_TYPE, *PMMSYSTEM_PTE_POOL_TYPE;
/* Page map routines structure definition */
typedef CONST STRUCT _CMMPAGEMAP_ROUTINES
{
@@ -30,6 +120,58 @@ typedef struct _MMCOLOR_TABLES
ULONG_PTR Count;
} MMCOLOR_TABLES, *PMMCOLOR_TABLES;
/* Free pool entry structure definition */
typedef struct _MMFREE_POOL_ENTRY
{
LIST_ENTRY List;
PFN_COUNT Size;
PMMFREE_POOL_ENTRY Owner;
} MMFREE_POOL_ENTRY, *PMMFREE_POOL_ENTRY;
/* Memory layout structure definition */
typedef struct _MMMEMORY_LAYOUT
{
PMMPFN PfnDatabase;
PFN_NUMBER PfnDatabaseSize;
PVOID SelfMapAddress;
PVOID HardwarePoolStart;
PVOID HardwarePoolEnd;
PVOID HyperSpaceStart;
PVOID HyperSpaceEnd;
PVOID LoaderMappingsStart;
PVOID LoaderMappingsEnd;
PFN_NUMBER LoaderMappingsSize;
PVOID NonCanonicalStart;
PVOID NonCanonicalEnd;
PVOID NonPagedPoolStart;
PVOID NonPagedPoolEnd;
PFN_NUMBER NonPagedPoolSize;
PVOID NonPagedExpansionPoolStart;
PVOID NonPagedExpansionPoolEnd;
PFN_NUMBER NonPagedExpansionPoolSize;
PVOID NonPagedSystemPoolStart;
PVOID NonPagedSystemPoolEnd;
PFN_NUMBER NonPagedSystemPoolSize;
PVOID PagedPoolStart;
PVOID PagedPoolEnd;
PFN_NUMBER PagedPoolSize;
PVOID ReservedSystemPoolStart;
PVOID ReservedSystemPoolEnd;
PVOID SessionSpaceStart;
PVOID SessionSpaceEnd;
PFN_NUMBER SessionSpaceSize;
PVOID SharedSystemPageStart;
PVOID SharedSystemPageEnd;
PVOID SystemCacheStart;
PVOID SystemCacheEnd;
PVOID SystemWorkingSetStart;
PVOID SystemWorkingSetEnd;
PVOID UserSpaceStart;
PVOID UserSpaceEnd;
PVOID PteSpaceStart;
PVOID PteSpaceEnd;
} MMMEMORY_LAYOUT, *PMMMEMORY_LAYOUT;
/* Page Frame Entry structure definition */
typedef struct _MMPFNENTRY
{
@@ -45,4 +187,75 @@ typedef struct _MMPFNENTRY
USHORT ParityError:1;
} MMPFNENTRY, *PMMPFNENTRY;
/* Page Frame List structure definition */
typedef struct _MMPFNLIST
{
PFN_NUMBER Total;
MMPAGELISTS ListName;
PFN_NUMBER Flink;
PFN_NUMBER Blink;
} MMPFNLIST, *PMMPFNLIST;
/* Physical memory run structure definition */
typedef struct _PHYSICAL_MEMORY_RUN
{
PFN_NUMBER BasePage;
PFN_NUMBER PageCount;
} PHYSICAL_MEMORY_RUN, *PPHYSICAL_MEMORY_RUN;
/* Physical memory descriptor structure definition */
typedef struct _PHYSICAL_MEMORY_DESCRIPTOR
{
ULONG NumberOfRuns;
PFN_NUMBER NumberOfPages;
PHYSICAL_MEMORY_RUN Run[1];
} PHYSICAL_MEMORY_DESCRIPTOR, *PPHYSICAL_MEMORY_DESCRIPTOR;
/* Pool header structure definition */
typedef struct _POOL_HEADER
{
union
{
struct
{
USHORT PreviousSize:9;
USHORT PoolIndex:7;
USHORT BlockSize:9;
USHORT PoolType:7;
};
ULONG Long;
};
union
{
ULONG PoolTag;
PEPROCESS ProcessBilled;
struct
{
USHORT AllocatorBackTraceIndex;
USHORT PoolTagHash;
};
};
} POOL_HEADER, *PPOOL_HEADER;
/* Pool descriptor structure definition */
typedef struct _POOL_TRACKING_BIG_ALLOCATIONS
{
ULONG NumberOfPages;
PVOID QuotaObject;
ULONG Tag;
PVOID VirtualAddress;
} POOL_TRACKING_BIG_ALLOCATIONS, *PPOOL_TRACKING_BIG_ALLOCATIONS;
/* Pool tracking table structure definition */
typedef struct _POOL_TRACKING_TABLE
{
LONG NonPagedAllocations;
SIZE_T NonPagedBytes;
LONG NonPagedFrees;
LONG PagedAllocations;
SIZE_T PagedBytes;
LONG PagedFrees;
ULONG Tag;
} POOL_TRACKING_TABLE, *PPOOL_TRACKING_TABLE;
#endif /* __XTDK_MMTYPES_H */

Voir le fichier

@@ -49,6 +49,10 @@
#define PFL_DIGIT_PRECISION 0x00002000
#define PFL_THOUSANDS_GROUPING 0x00004000
/* Cryptographic related definitions */
#define SHA1_BLOCK_SIZE 64
#define SHA1_DIGEST_SIZE 20
/* Runtime Library routine callbacks */
typedef XTSTATUS (*PWRITE_CHARACTER)(IN CHAR Character);
typedef XTSTATUS (*PWRITE_WIDE_CHARACTER)(IN WCHAR Character);
@@ -95,4 +99,12 @@ typedef struct _RTL_PRINT_FORMAT_PROPERTIES
LONG Flags;
} RTL_PRINT_FORMAT_PROPERTIES, *PRTL_PRINT_FORMAT_PROPERTIES;
/* Runtime Library SHA-1 context structure definition */
typedef struct _RTL_SHA1_CONTEXT
{
ULONG State[5];
ULONG Count[2];
UCHAR Buffer[SHA1_BLOCK_SIZE];
} RTL_SHA1_CONTEXT, *PRTL_SHA1_CONTEXT;
#endif /* __XTDK_RTLTYPES_H */

Voir le fichier

@@ -29,6 +29,9 @@ typedef UCHAR KRUNLEVEL, *PKRUNLEVEL;
/* Spin locks synchronization mechanism */
typedef ULONG_PTR KSPIN_LOCK, *PKSPIN_LOCK;
/* Page Frame Number count */
typedef ULONG PFN_COUNT;
/* Page Frame Number */
typedef ULONG_PTR PFN_NUMBER, *PPFN_NUMBER;

Voir le fichier

@@ -12,8 +12,9 @@
#ifdef __cplusplus
/* C++ definitions */
#define XTCLINK extern "C"
#define NULLPTR nullptr
#define VIRTUAL virtual
#define XTCLINK extern "C"
/* C++ boolean type */
typedef bool BOOLEAN, *PBOOLEAN;
@@ -24,8 +25,9 @@
typedef wchar_t wchar;
#else
/* C definitions */
#define XTCLINK
#define NULLPTR ((void *)0)
#define VIRTUAL
#define XTCLINK
/* C boolean type */
typedef enum _BOOLEAN

Voir le fichier

@@ -23,7 +23,7 @@
#define DebugPrint(Format, ...) DbgPrint(Format, __VA_ARGS__);
#else
#define DEBUG 0
#define DebugPrint(Format, ...) ((VOID)NULL)
#define DebugPrint(Format, ...) ((VOID)NULLPTR)
#endif
#endif /* __XTDK_XTDEBUG_H */

Voir le fichier

@@ -74,12 +74,20 @@
/* Macro for calculating size of a field in the structure */
#define FIELD_SIZE(Structure, Field) (sizeof(((Structure *)0)->Field))
/* Macros for calculating minimum and maximum of two values */
#define MIN(A, B) (((A) < (B)) ? (A) : (B))
#define MAX(A, B) (((A) > (B)) ? (A) : (B))
/* Macro that page-aligns a virtual address */
#define PAGE_ALIGN(VirtualAddress) ((PVOID)((ULONG_PTR)VirtualAddress & ~MM_PAGE_MASK))
/* Macro that returns offset of the virtual address */
#define PAGE_OFFSET(VirtualAddress) ((ULONG)((ULONG_PTR)VirtualAddress & MM_PAGE_MASK))
/* Macros for bitwise rotating */
#define ROTATE_LEFT(Value, Count) ((Value << Count) | (Value >> (32 - Count)))
#define ROTATE_RIGHT(Value, Count) ((Value >> Count) | (Value << (32 - Count)))
/* Macro for rounding down */
#define ROUND_DOWN(Value, Alignment) ((Value) & ~((Alignment) - 1))
@@ -104,7 +112,7 @@
/* Variadic ABI functions */
typedef __builtin_va_list VA_LIST, *PVA_LIST;
#define VA_ARG(Marker, Type) ((sizeof (Type) < sizeof(UINT_PTR)) ? \
#define VA_ARG(Marker, Type) ((sizeof(Type) < sizeof(UINT_PTR)) ? \
(Type)(__builtin_va_arg(Marker, UINT_PTR)) : \
(Type)(__builtin_va_arg(Marker, Type)))
#define VA_COPY(Dest, Start) __builtin_va_copy(Dest, Start)

Voir le fichier

@@ -107,6 +107,7 @@ typedef struct _KERNEL_INITIALIZATION_BLOCK
ULONG BlockVersion;
ULONG ProtocolVersion;
PWCHAR KernelParameters;
PFN_NUMBER BootImageSize;
LIST_ENTRY LoadOrderListHead;
LIST_ENTRY MemoryDescriptorListHead;
LIST_ENTRY BootDriverListHead;

Voir le fichier

@@ -50,6 +50,7 @@
#include <hlfuncs.h>
#include <kdfuncs.h>
#include <kefuncs.h>
#include <mmfuncs.h>
#include <rtlfuncs.h>
/* Architecture specific XT routines */

Voir le fichier

@@ -48,6 +48,10 @@ typedef enum _KTHREAD_STATE KTHREAD_STATE, *PKTHREAD_STATE;
typedef enum _KTIMER_TYPE KTIMER_TYPE, *PKTIMER_TYPE;
typedef enum _KUBSAN_DATA_TYPE KUBSAN_DATA_TYPE, *PKUBSAN_DATA_TYPE;
typedef enum _LOADER_MEMORY_TYPE LOADER_MEMORY_TYPE, *PLOADER_MEMORY_TYPE;
typedef enum _MMPAGELISTS MMPAGELISTS, *PMMPAGELISTS;
typedef enum _MMPFN_CACHE_ATTRIBUTE MMPFN_CACHE_ATTRIBUTE, *PMMPFN_CACHE_ATTRIBUTE;
typedef enum _MMPOOL_TYPE MMPOOL_TYPE, *PMMPOOL_TYPE;
typedef enum _MMSYSTEM_PTE_POOL_TYPE MMSYSTEM_PTE_POOL_TYPE, *PMMSYSTEM_PTE_POOL_TYPE;
typedef enum _MODE MODE, *PMODE;
typedef enum _RTL_VARIABLE_TYPE RTL_VARIABLE_TYPE, *PRTL_VARIABLE_TYPE;
typedef enum _SYSTEM_FIRMWARE_TYPE SYSTEM_FIRMWARE_TYPE, *PSYSTEM_FIRMWARE_TYPE;
@@ -274,7 +278,10 @@ typedef struct _LOADER_INFORMATION_BLOCK LOADER_INFORMATION_BLOCK, *PLOADER_INFO
typedef struct _LOADER_MEMORY_DESCRIPTOR LOADER_MEMORY_DESCRIPTOR, *PLOADER_MEMORY_DESCRIPTOR;
typedef struct _M128 M128, *PM128;
typedef struct _MMCOLOR_TABLES MMCOLOR_TABLES, *PMMCOLOR_TABLES;
typedef struct _MMFREE_POOL_ENTRY MMFREE_POOL_ENTRY, *PMMFREE_POOL_ENTRY;
typedef struct _MMMEMORY_LAYOUT MMMEMORY_LAYOUT, *PMMMEMORY_LAYOUT;
typedef struct _MMPFNENTRY MMPFNENTRY, *PMMPFNENTRY;
typedef struct _MMPFNLIST MMPFNLIST, *PMMPFNLIST;
typedef struct _PCAT_FIRMWARE_INFORMATION PCAT_FIRMWARE_INFORMATION, *PPCAT_FIRMWARE_INFORMATION;
typedef struct _PCI_BRIDGE_CONTROL_REGISTER PCI_BRIDGE_CONTROL_REGISTER, *PPCI_BRIDGE_CONTROL_REGISTER;
typedef struct _PCI_COMMON_CONFIG PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG;
@@ -303,6 +310,11 @@ typedef struct _PECOFF_IMAGE_ROM_HEADER PECOFF_IMAGE_ROM_HEADER, *PPECOFF_IMAGE_
typedef struct _PECOFF_IMAGE_ROM_OPTIONAL_HEADER PECOFF_IMAGE_ROM_OPTIONAL_HEADER, *PPECOFF_IMAGE_ROM_OPTIONAL_HEADER;
typedef struct _PECOFF_IMAGE_SECTION_HEADER PECOFF_IMAGE_SECTION_HEADER, *PPECOFF_IMAGE_SECTION_HEADER;
typedef struct _PECOFF_IMAGE_VXD_HEADER PECOFF_IMAGE_VXD_HEADER, *PPECOFF_IMAGE_VXD_HEADER;
typedef struct _PHYSICAL_MEMORY_DESCRIPTOR PHYSICAL_MEMORY_DESCRIPTOR, *PPHYSICAL_MEMORY_DESCRIPTOR;
typedef struct _PHYSICAL_MEMORY_RUN PHYSICAL_MEMORY_RUN, *PPHYSICAL_MEMORY_RUN;
typedef struct _POOL_HEADER POOL_HEADER, *PPOOL_HEADER;
typedef struct _POOL_TRACKING_BIG_ALLOCATIONS POOL_TRACKING_BIG_ALLOCATIONS, *PPOOL_TRACKING_BIG_ALLOCATIONS;
typedef struct _POOL_TRACKING_TABLE POOL_TRACKING_TABLE, *PPOOL_TRACKING_TABLE;
typedef struct _PROCESSOR_IDENTITY PROCESSOR_IDENTITY, *PPROCESSOR_IDENTITY;
typedef struct _PROCESSOR_POWER_STATE PROCESSOR_POWER_STATE, *PPROCESSOR_POWER_STATE;
typedef struct _RTL_BITMAP RTL_BITMAP, *PRTL_BITMAP;

Voir le fichier

@@ -51,14 +51,24 @@ list(APPEND XTOSKRNL_SOURCE
${XTOSKRNL_SOURCE_DIR}/ke/spinlock.cc
${XTOSKRNL_SOURCE_DIR}/ke/sysres.cc
${XTOSKRNL_SOURCE_DIR}/ke/timer.cc
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/init.cc
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/mmgr.cc
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pagemap.cc
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/paging.cc
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pfault.cc
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pfn.cc
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pool.cc
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pte.cc
${XTOSKRNL_SOURCE_DIR}/mm/alloc.cc
${XTOSKRNL_SOURCE_DIR}/mm/colors.cc
${XTOSKRNL_SOURCE_DIR}/mm/data.cc
${XTOSKRNL_SOURCE_DIR}/mm/exports.cc
${XTOSKRNL_SOURCE_DIR}/mm/hlpool.cc
${XTOSKRNL_SOURCE_DIR}/mm/init.cc
${XTOSKRNL_SOURCE_DIR}/mm/kpool.cc
${XTOSKRNL_SOURCE_DIR}/mm/mmgr.cc
${XTOSKRNL_SOURCE_DIR}/mm/paging.cc
${XTOSKRNL_SOURCE_DIR}/mm/pfn.cc
${XTOSKRNL_SOURCE_DIR}/mm/pool.cc
${XTOSKRNL_SOURCE_DIR}/mm/pte.cc
${XTOSKRNL_SOURCE_DIR}/po/idle.cc
${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/dispatch.cc
${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/exsup.cc
@@ -71,6 +81,8 @@ list(APPEND XTOSKRNL_SOURCE
${XTOSKRNL_SOURCE_DIR}/rtl/llist.cc
${XTOSKRNL_SOURCE_DIR}/rtl/math.cc
${XTOSKRNL_SOURCE_DIR}/rtl/memory.cc
${XTOSKRNL_SOURCE_DIR}/rtl/sha1.cc
${XTOSKRNL_SOURCE_DIR}/rtl/slist.cc
${XTOSKRNL_SOURCE_DIR}/rtl/string.cc
${XTOSKRNL_SOURCE_DIR}/rtl/widestr.cc)
@@ -82,11 +94,12 @@ add_library(libxtos ${XTOSKRNL_SOURCE})
# Link kernel executable
add_executable(xtoskrnl
${XTOSKRNL_SOURCE}
${CMAKE_CURRENT_BINARY_DIR}/xtoskrnl.def)
# Add linker libraries
target_link_libraries(xtoskrnl)
target_link_libraries(xtoskrnl
PRIVATE
libxtos)
# Set proper binary name and install target
set_target_properties(xtoskrnl PROPERTIES SUFFIX .exe)

Voir le fichier

@@ -4,6 +4,18 @@ within the XTOS kernel space. It is responsible for various core services, such
management, and process scheduling. The kernel contains the scheduler (sometimes referred to as the Dispatcher), the
cache, object, and memory managers, the security manager, and other executive components described below.
## Kernel Parameters
Kernel parameters are XTOS boot-time options used to ensure proper initialization and handling of hardware peripherals.
These parameters can be configured either temporarily by editing the boot entry in the bootloader’s selection menu, or
permanently by modifying the XTLDR configuration file.
The following is a consolidated list of available kernel parameters:
* **NOXPA**: Disables PAE or LA57 support, depending on the CPU architecture. This parameter is handled by the
bootloader, which configures paging and selects the appropriate Page Map Level (PML) before transferring control to
the kernel.
## Source Code
The source code of the kernel is organized into subsystem-specific directories. Each directory name also defines the
corresponding C++ namespace in which the subsystem's classes and routines reside. These subsystems include:
@@ -68,8 +80,8 @@ routine:
For all C++ code inside the kernel the naming model has evolved. Consider the **KE::KThread::InitializeThread()**
routine:
* **KE** - The namespace replaces the prefix and indicates the subsystem. Namespaces are written in uppercase and no
longer use the trailing p for private routines, because classes use C++ visibility to control access.
longer use the trailing p for private routines, because classes use C++ visibility to control access.
* **KThread** - Within each namespace, related functionality is grouped into classes, which encapsulate variables and
methods.
methods.
* **InitializeThread** - Method names follow the `<Operation><Object>` pattern.

Voir le fichier

@@ -104,12 +104,20 @@ ArTrap\Vector:
/* Test previous mode and swap GS if needed */
movl $0, TrapPreviousMode(%rbp)
mov %cs, %ax
and $1, %al
and $3, %al
mov %al, TrapPreviousMode(%rbp)
jz KernelMode$\Vector
swapgs
jmp UserMode$\Vector
KernelMode$\Vector:
/* Save kernel stack pointer (SS:RSP) */
movl %ss, %eax
mov %eax, TrapSegSs(%rbp)
lea TRAP_FRAME_SIZE(%rbp), %rax
mov %rax, TrapRsp(%rbp)
UserMode$\Vector:
/* Push Frame Pointer, clear direction flag and pass to trap dispatcher */
mov %rsp, %rcx
cld

Voir le fichier

@@ -249,34 +249,34 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
{
/* Set the IDT to handle unexpected interrupts */
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
}
/* Setup IDT handlers for known interrupts and traps */
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x1F, (PVOID)ArTrap0x1F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrap0x2F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArTrap0xE1, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x1F, (PVOID)ArTrap0x1F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrap0x2F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArTrap0xE1, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
}
/**
@@ -636,6 +636,9 @@ AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
* @param Access
* Supplies the gate access rights.
*
* @param Type
* Supplies the gate type.
*
* @return This routine does not return any value.
*
* @since XT 1.0
@@ -647,15 +650,22 @@ AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Access)
IN USHORT Dpl,
IN USHORT Type)
{
/* Setup the gate */
/* Set the handler's address */
Idt[Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF);
Idt[Vector].OffsetMiddle = (((ULONG_PTR)Handler >> 16) & 0xFFFF);
Idt[Vector].OffsetHigh = (ULONG_PTR)Handler >> 32;
Idt[Vector].Dpl = Access;
/* Set the code segment selector */
Idt[Vector].Selector = Selector;
/* Initialize the gate's attributes and flags */
Idt[Vector].Access = 0;
Idt[Vector].Dpl = Dpl;
Idt[Vector].IstIndex = Ist;
Idt[Vector].Present = 1;
Idt[Vector].Selector = Selector;
Idt[Vector].Type = 0xE;
Idt[Vector].Reserved1 = 0;
Idt[Vector].Type = Type;
}

Voir le fichier

@@ -75,12 +75,20 @@ _ArTrap\Vector:
/* Test previous mode and swap GS if needed */
movl $0, TrapPreviousMode(%ebp)
mov %cs, %ax
and $1, %al
and $3, %al
mov %al, TrapPreviousMode(%ebp)
jz KernelMode$\Vector
swapgs
jmp UserMode$\Vector
KernelMode$\Vector:
/* Save kernel stack pointer (SS:ESP) as CPU did not push them */
movl %ss, %eax
mov %eax, TrapSegSs(%ebp)
lea TrapEsp(%ebp), %eax
mov %eax, TrapEsp(%ebp)
UserMode$\Vector:
/* Push Frame Pointer, clear direction flag and pass to trap dispatcher */
push %esp
cld
@@ -100,6 +108,7 @@ KernelModeReturn$\Vector:
mov TrapSegDs(%ebp), %ds
mov TrapSegEs(%ebp), %es
mov TrapSegFs(%ebp), %fs
mov TrapSegGs(%ebp), %gs
/* Free stack space */
add $(TRAP_FRAME_SIZE - TRAP_REGISTERS_SIZE), %esp

Voir le fichier

@@ -242,34 +242,34 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
{
/* Set the IDT to handle unexpected interrupts */
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
}
/* Setup IDT handlers for known interrupts and traps */
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrap0x2A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrap0x2B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrap0x2E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrap0x2A, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrap0x2B, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrap0x2E, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
}
/**
@@ -656,6 +656,9 @@ AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
* @param Access
* Supplies the gate access rights.
*
* @param Type
* Supplies the gate type.
*
* @return This routine does not return any value.
*
* @since XT 1.0
@@ -667,13 +670,21 @@ AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Access)
IN USHORT Dpl,
IN USHORT Type)
{
/* Setup the gate */
/* Set the handler's address */
Idt[Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF);
Idt[Vector].ExtendedOffset = (USHORT)((ULONG)Handler >> 16);
Idt[Vector].Access = 0x8000 | (Access << 8);
/* Set the code segment selector */
Idt[Vector].Selector = Selector;
/* Initialize the gate's attributes and flags */
Idt[Vector].Access = 0;
Idt[Vector].Dpl = Dpl;
Idt[Vector].Present = 1;
Idt[Vector].Type = Type;
}
/**

Voir le fichier

@@ -9,6 +9,41 @@
#include <xtos.hh>
/**
* Checks whether the APIC is supported by the processor.
*
* @return This routine returns TRUE if APIC is supported, or FALSE otherwise.
*
* @since XT 1.0
*/
XTAPI
BOOLEAN
HL::Pic::CheckApicSupport(VOID)
{
CPUID_REGISTERS CpuRegisters;
/* Prepare CPUID registers */
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
CpuRegisters.SubLeaf = 0;
CpuRegisters.Eax = 0;
CpuRegisters.Ebx = 0;
CpuRegisters.Ecx = 0;
CpuRegisters.Edx = 0;
/* Get CPUID */
AR::CpuFunc::CpuId(&CpuRegisters);
/* Check APIC status from the CPUID results */
if(!(CpuRegisters.Edx & CPUID_FEATURES_EDX_APIC))
{
/* APIC is not supported */
return FALSE;
}
/* APIC is supported */
return TRUE;
}
/**
* Checks whether the x2APIC extension is supported by the processor.
*
@@ -124,6 +159,14 @@ HL::Pic::InitializeApic(VOID)
APIC_LVT_REGISTER LvtRegister;
ULONG CpuNumber;
/* Check APIC support */
if(!CheckApicSupport())
{
/* APIC is not supported, raise kernel panic */
DebugPrint(L"FATAL ERROR: Local APIC not present.\n");
KE::Crash::Panic(0x5D, CPUID_GET_STANDARD1_FEATURES, 0x0, 0x0, CPUID_FEATURES_EDX_APIC);
}
/* Determine APIC mode (xAPIC compatibility or x2APIC) */
if(CheckX2ApicSupport())
{

Voir le fichier

@@ -56,6 +56,8 @@
#define TrapSegEs 330
#define TrapSegFs 332
#define TrapSegGs 334
#define TrapRsp 496
#define TrapSegSs 504
/* KTRAP_FRAME length related definitions */
#define TRAP_FRAME_SIZE 512

Voir le fichier

@@ -31,6 +31,13 @@ namespace AR
OUT PVOID *TrampolineCode,
OUT PULONG_PTR TrampolineSize);
STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures);
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Dpl,
IN USHORT Type);
private:
STATIC XTAPI VOID IdentifyProcessor(VOID);
@@ -62,12 +69,6 @@ namespace AR
STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base);
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Access);
};
}

Voir le fichier

@@ -24,9 +24,11 @@
#define TrapSegEs 38
#define TrapSegFs 40
#define TrapSegGs 42
#define TrapEsp 92
#define TrapSegSs 96
/* KTRAP_FRAME length related definitions */
#define TRAP_FRAME_SIZE 100
#define TRAP_REGISTERS_SIZE 56
#endif /* __XTOSKRNL_AMD64_ASMSUP_H */
#endif /* __XTOSKRNL_I686_ASMSUP_H */

Voir le fichier

@@ -34,6 +34,13 @@ namespace AR
OUT PVOID *TrampolineCode,
OUT PULONG_PTR TrampolineSize);
STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures);
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Dpl,
IN USHORT Type);
private:
STATIC XTAPI VOID IdentifyProcessor(VOID);
@@ -67,12 +74,6 @@ namespace AR
STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base);
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Access);
STATIC XTAPI VOID SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelFaultStack);

Voir le fichier

@@ -32,6 +32,7 @@ namespace HL
IN ULONGLONG Value);
private:
STATIC XTAPI BOOLEAN CheckApicSupport(VOID);
STATIC XTAPI BOOLEAN CheckX2ApicSupport(VOID);
STATIC XTCDECL VOID HandleApicSpuriousService(VOID);
STATIC XTCDECL VOID HandlePicSpuriousService(VOID);

Voir le fichier

@@ -16,6 +16,7 @@
#include <ke/crash.hh>
#include <ke/dpc.hh>
#include <ke/event.hh>
#include <ke/guard.hh>
#include <ke/irq.hh>
#include <ke/kprocess.hh>
#include <ke/krnlinit.hh>

Voir le fichier

@@ -20,11 +20,11 @@ namespace KE
public:
STATIC XTAPI VOID HaltSystem(VOID);
STATIC XTAPI VOID Panic(IN ULONG Code);
STATIC XTAPI VOID PanicEx(IN ULONG Code,
IN ULONG_PTR Parameter1,
IN ULONG_PTR Parameter2,
IN ULONG_PTR Parameter3,
IN ULONG_PTR Parameter4);
STATIC XTAPI VOID Panic(IN ULONG Code,
IN ULONG_PTR Parameter1,
IN ULONG_PTR Parameter2,
IN ULONG_PTR Parameter3,
IN ULONG_PTR Parameter4);
};
}

61
xtoskrnl/includes/ke/guard.hh Fichier normal
Voir le fichier

@@ -0,0 +1,61 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ke/guard.hh
* DESCRIPTION: Kernel synchronization guard
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_GUARD_HH
#define __XTOSKRNL_KE_GUARD_HH
#include <xtos.hh>
#include <ke/spinlock.hh>
/* Kernel Library */
namespace KE
{
class QueuedSpinLockGuard
{
private:
KSPIN_LOCK_QUEUE_LEVEL QueuedLockLevel;
public:
QueuedSpinLockGuard(IN OUT KSPIN_LOCK_QUEUE_LEVEL LockLevel)
{
QueuedLockLevel = LockLevel;
KE::SpinLock::AcquireQueuedSpinLock(QueuedLockLevel);
}
~QueuedSpinLockGuard()
{
KE::SpinLock::ReleaseQueuedSpinLock(QueuedLockLevel);
}
QueuedSpinLockGuard(const QueuedSpinLockGuard&) = delete;
QueuedSpinLockGuard& operator=(const QueuedSpinLockGuard&) = delete;
};
class SpinLockGuard
{
private:
PKSPIN_LOCK Lock;
public:
SpinLockGuard(IN OUT PKSPIN_LOCK SpinLock)
{
Lock = SpinLock;
KE::SpinLock::AcquireSpinLock(Lock);
}
~SpinLockGuard()
{
KE::SpinLock::ReleaseSpinLock(Lock);
}
SpinLockGuard(const SpinLockGuard&) = delete;
SpinLockGuard& operator=(const SpinLockGuard&) = delete;
};
}
#endif /* __XTOSKRNL_KE_GUARD_HH */

Voir le fichier

@@ -22,6 +22,48 @@ namespace KE
STATIC XTFASTCALL VOID LowerRunLevel(IN KRUNLEVEL RunLevel);
STATIC XTFASTCALL KRUNLEVEL RaiseRunLevel(IN KRUNLEVEL RunLevel);
};
class LowerRunLevel
{
private:
KRUNLEVEL PreviousRunLevel;
public:
LowerRunLevel(KRUNLEVEL RunLevel)
{
PreviousRunLevel = KE::RunLevel::GetCurrentRunLevel();
KE::RunLevel::LowerRunLevel(RunLevel);
}
~LowerRunLevel()
{
KE::RunLevel::RaiseRunLevel(PreviousRunLevel);
}
LowerRunLevel(const LowerRunLevel&) = delete;
LowerRunLevel& operator=(const LowerRunLevel&) = delete;
};
class RaiseRunLevel
{
private:
KRUNLEVEL PreviousRunLevel;
public:
RaiseRunLevel(KRUNLEVEL RunLevel)
{
PreviousRunLevel = KE::RunLevel::GetCurrentRunLevel();
KE::RunLevel::RaiseRunLevel(RunLevel);
}
~RaiseRunLevel()
{
KE::RunLevel::LowerRunLevel(PreviousRunLevel);
}
RaiseRunLevel(const RaiseRunLevel&) = delete;
RaiseRunLevel& operator=(const RaiseRunLevel&) = delete;
};
}
#endif /* __XTOSKRNL_KE_RUNLEVEL_HH */

Voir le fichier

@@ -17,12 +17,32 @@ namespace KE
{
class SpinLock
{
private:
STATIC KSPIN_LOCK DispatcherLockQueue;
STATIC KSPIN_LOCK ExpansionLockQueue;
STATIC KSPIN_LOCK FileSystemLockQueue;
STATIC KSPIN_LOCK IoCancelLockQueue;
STATIC KSPIN_LOCK IoCompletionLockQueue;
STATIC KSPIN_LOCK IoDatabaseLockQueue;
STATIC KSPIN_LOCK IoVpbLockQueue;
STATIC KSPIN_LOCK MasterLockQueue;
STATIC KSPIN_LOCK NonPagedAllocLockQueue;
STATIC KSPIN_LOCK NonPagedPoolLockQueue;
STATIC KSPIN_LOCK PfnLockQueue;
STATIC KSPIN_LOCK SystemSpaceLockQueue;
STATIC KSPIN_LOCK TimerTableLockQueue;
STATIC KSPIN_LOCK VacbLockQueue;
STATIC KSPIN_LOCK WorkLockQueue;
public:
STATIC XTFASTCALL VOID AcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
STATIC XTFASTCALL VOID AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock);
STATIC XTAPI VOID InitializeAllLocks();
STATIC XTAPI VOID InitializeLockQueues();
STATIC XTAPI VOID InitializeSpinLock(IN PKSPIN_LOCK SpinLock);
STATIC XTFASTCALL VOID ReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
STATIC XTFASTCALL VOID ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock);
STATIC XTFASTCALL BOOLEAN TestSpinLock(IN PKSPIN_LOCK SpinLock);
};
}

Voir le fichier

@@ -12,10 +12,17 @@
#include <xtos.hh>
#include XTOS_ARCH_HEADER(mm, pagemap.hh)
#include XTOS_ARCH_HEADER(mm, paging.hh)
#include XTOS_ARCH_HEADER(mm, pte.hh)
#include <mm/alloc.hh>
#include <mm/colors.hh>
#include <mm/guard.hh>
#include <mm/hlpool.hh>
#include <mm/init.hh>
#include <mm/kpool.hh>
#include <mm/paging.hh>
#include <mm/mmgr.hh>
#include <mm/pfault.hh>
#include <mm/pfn.hh>
#include <mm/pool.hh>
#endif /* __XTOSKRNL_MM_HH */

90
xtoskrnl/includes/mm/alloc.hh Fichier normal
Voir le fichier

@@ -0,0 +1,90 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/mm/alloc.hh
* DESCRIPTION: Memory Manager pool allocator
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_MM_ALLOC_HH
#define __XTOSKRNL_MM_ALLOC_HH
#include <xtos.hh>
#include <mm/pool.hh>
/* Memory Manager */
namespace MM
{
class Allocator final : private Pool
{
private:
STATIC PPOOL_TRACKING_TABLE AllocationsTrackingExpansionTable;
STATIC SIZE_T AllocationsTrackingExpansionTableSize;
STATIC PPOOL_TRACKING_TABLE AllocationsTrackingTable;
STATIC KSPIN_LOCK AllocationsTrackingTableLock;
STATIC SIZE_T AllocationsTrackingTableMask;
STATIC SIZE_T AllocationsTrackingTableSize;
STATIC ULONG BigAllocationsInUse;
STATIC PPOOL_TRACKING_BIG_ALLOCATIONS BigAllocationsTrackingTable;
STATIC SIZE_T BigAllocationsTrackingTableHash;
STATIC KSPIN_LOCK BigAllocationsTrackingTableLock;
STATIC SIZE_T BigAllocationsTrackingTableSize;
STATIC PPOOL_TRACKING_TABLE TagTables[MM_POOL_TRACKING_TABLES];
public:
STATIC XTAPI XTSTATUS AllocatePages(IN MMPOOL_TYPE PoolType,
IN SIZE_T Bytes,
OUT PVOID *Memory);
STATIC XTAPI XTSTATUS AllocatePool(IN MMPOOL_TYPE PoolType,
IN SIZE_T Bytes,
OUT PVOID *Memory);
STATIC XTAPI XTSTATUS AllocatePool(IN MMPOOL_TYPE PoolType,
IN SIZE_T Bytes,
OUT PVOID *Memory,
IN ULONG Tag);
STATIC XTAPI XTSTATUS FreePages(IN PVOID VirtualAddress);
STATIC XTAPI XTSTATUS FreePages(IN PVOID VirtualAddress,
OUT PPFN_NUMBER PagesFreed);
STATIC XTAPI XTSTATUS FreePool(IN PVOID VirtualAddress);
STATIC XTAPI XTSTATUS FreePool(IN PVOID VirtualAddress,
IN ULONG Tag);
STATIC XTAPI VOID InitializeAllocationsTracking(VOID);
STATIC XTAPI VOID InitializeBigAllocationsTracking(VOID);
private:
STATIC XTAPI XTSTATUS AllocateNonPagedPoolPages(IN PFN_COUNT Pages,
OUT PVOID *Memory);
STATIC XTAPI XTSTATUS AllocatePagedPoolPages(IN PFN_COUNT Pages,
OUT PVOID *Memory);
STATIC XTINLINE ULONG ComputeHash(IN PVOID VirtualAddress);
STATIC XTINLINE ULONG ComputeHash(IN ULONG Tag,
IN ULONG TableMask);
STATIC XTAPI BOOLEAN ExpandBigAllocationsTable(VOID);
STATIC XTAPI XTSTATUS FreeNonPagedPoolPages(IN PVOID VirtualAddress,
OUT PPFN_NUMBER PagesFreed);
STATIC XTAPI XTSTATUS FreePagedPoolPages(IN PVOID VirtualAddress,
OUT PPFN_NUMBER PagesFreed);
STATIC XTAPI VOID RegisterAllocationTag(IN ULONG Tag,
IN SIZE_T Bytes,
IN MMPOOL_TYPE PoolType);
STATIC XTAPI VOID RegisterAllocationTagExpansion(IN ULONG Tag,
IN SIZE_T Bytes,
IN MMPOOL_TYPE PoolType);
STATIC XTAPI BOOLEAN RegisterBigAllocationTag(IN PVOID VirtualAddress,
IN ULONG Tag,
IN ULONG Pages,
IN MMPOOL_TYPE PoolType);
STATIC XTAPI VOID UnregisterAllocationTag(IN ULONG Tag,
IN SIZE_T Bytes,
IN MMPOOL_TYPE PoolType);
STATIC XTAPI VOID UnregisterAllocationTagExpansion(IN ULONG Tag,
IN SIZE_T Bytes,
IN MMPOOL_TYPE PoolType);
STATIC XTAPI ULONG UnregisterBigAllocationTag(IN PVOID VirtualAddress,
OUT PULONG_PTR Pages,
IN MMPOOL_TYPE PoolType);
};
}
#endif /* __XTOSKRNL_MM_ALLOC_HH */

Voir le fichier

@@ -1,13 +1,13 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/mm/pagemap.hh
* FILE: xtoskrnl/includes/mm/amd64/pagemap.hh
* DESCRIPTION: Low-level support for page map manipulation
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_MM_PAGEMAP_HH
#define __XTOSKRNL_MM_PAGEMAP_HH
#ifndef __XTOSKRNL_MM_AMD64_PAGEMAP_HH
#define __XTOSKRNL_MM_AMD64_PAGEMAP_HH
#include <xtos.hh>
@@ -21,33 +21,77 @@ namespace MM
MMPAGEMAP_INFO PageMapInfo;
public:
XTAPI VOID ClearPte(PHARDWARE_PTE PtePointer);
XTAPI PMMP5E GetP5eAddress(PVOID Address);
XTAPI PMMPDE GetPdeAddress(PVOID Address);
XTAPI PMMPPE GetPpeAddress(PVOID Address);
XTAPI PMMPTE GetPteAddress(PVOID Address);
XTAPI PMMPXE GetPxeAddress(PVOID Address);
virtual XTAPI VOID InitializePageMapInfo(VOID) = 0;
XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer);
XTAPI VOID SetPte(PHARDWARE_PTE PtePointer,
PFN_NUMBER PageFrameNumber,
BOOLEAN Writable);
XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer,
BOOLEAN CacheDisable,
BOOLEAN WriteThrough);
XTAPI PMMPTE AdvancePte(IN PMMPTE Pte,
IN LONG Count);
XTAPI BOOLEAN CanonicalAddress(IN PVOID VirtualAddress);
XTAPI VOID ClearPte(IN PMMPTE PtePointer);
XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte);
XTAPI PMMPTE GetNextPte(IN PMMPTE Pte);
XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte);
XTAPI PMMP5E GetP5eAddress(IN PVOID Address);
XTAPI ULONG GetP5eOffset(IN PVOID Address);
XTAPI PVOID GetP5eVirtualAddress(IN PMMP5E P5ePointer);
XTAPI USHORT GetPageMapLevel();
XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte);
XTAPI PMMPDE GetPdeAddress(IN PVOID Address);
XTAPI ULONG GetPdeOffset(IN PVOID Address);
VIRTUAL XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer) = 0;
XTAPI PMMPPE GetPpeAddress(IN PVOID Address);
XTAPI ULONG GetPpeOffset(IN PVOID Address);
VIRTUAL XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer) = 0;
XTAPI ULONGLONG GetPte(IN PMMPTE PtePointer);
XTAPI PMMPTE GetPteAddress(IN PVOID Address);
XTAPI LONG GetPteDistance(PMMPTE EndPte,
PMMPTE StartPte);
XTAPI ULONG GetPteOffset(IN PVOID Address);
XTAPI ULONG GetPteSize(VOID);
XTAPI ULONG GetPteSoftwareProtection(IN PMMPTE PtePointer);
XTAPI ULONG GetPteSoftwarePrototype(IN PMMPTE PtePointer);
XTAPI ULONG GetPteSoftwareTransition(IN PMMPTE PtePointer);
VIRTUAL XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer) = 0;
XTAPI PMMPXE GetPxeAddress(IN PVOID Address);
XTAPI ULONG GetPxeOffset(IN PVOID Address);
VIRTUAL XTAPI PVOID GetPxeVirtualAddress(IN PMMPXE PxePointer) = 0;
XTAPI BOOLEAN GetXpaStatus();
VIRTUAL XTAPI VOID InitializePageMapInfo(VOID) = 0;
XTAPI BOOLEAN PteValid(IN PMMPTE PtePointer);
XTAPI VOID SetNextEntry(IN PMMPTE Pte,
IN ULONG_PTR Value);
XTAPI VOID SetOneEntry(IN PMMPTE Pte,
IN BOOLEAN Value);
XTAPI VOID SetPte(IN PMMPTE PtePointer,
IN PFN_NUMBER PageFrameNumber,
IN ULONGLONG AttributesMask);
XTAPI VOID SetPte(IN PMMPTE PtePointer,
IN ULONGLONG Attributes);
XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
IN BOOLEAN CacheDisable,
IN BOOLEAN WriteThrough);
XTAPI VOID TransitionPte(IN PMMPTE PointerPte,
IN ULONG_PTR Protection);
XTAPI VOID WritePte(IN PMMPTE Pte,
IN MMPTE Value);
} PAGEMAP, *PPAGEMAP;
class PageMapBasic final : public PageMap
{
public:
XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);
XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer);
XTAPI PVOID GetPxeVirtualAddress(IN PMMPXE PxePointer);
XTAPI VOID InitializePageMapInfo(VOID);
};
class PageMapXpa final : public PageMap
{
public:
XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);
XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer);
XTAPI PVOID GetPxeVirtualAddress(IN PMMPXE PxePointer);
XTAPI VOID InitializePageMapInfo(VOID);
};
}
#endif /* __XTOSKRNL_MM_PAGEMAP_HH */
#endif /* __XTOSKRNL_MM_AMD64_PAGEMAP_HH */

Voir le fichier

@@ -0,0 +1,81 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/mm/amd64/paging.hh
* DESCRIPTION: Low level page management support for AMD64
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_MM_AMD64_PAGING_HH
#define __XTOSKRNL_MM_AMD64_PAGING_HH
#include <xtos.hh>
/* Memory Manager */
namespace MM
{
class Paging
{
private:
STATIC PPAGEMAP PmlRoutines;
public:
STATIC XTAPI PMMPTE AdvancePte(IN PMMPTE Pte,
IN LONG Count);
STATIC XTAPI BOOLEAN CanonicalAddress(IN PVOID VirtualAddress);
STATIC XTAPI VOID ClearPte(IN PMMPTE PtePointer);
STATIC XTAPI VOID FlushEntireTlb(VOID);
STATIC XTAPI VOID FlushTlb(VOID);
STATIC XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte);
STATIC XTAPI PMMPTE GetNextPte(IN PMMPTE Pte);
STATIC XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte);
STATIC XTAPI PMMP5E GetP5eAddress(IN PVOID Address);
STATIC XTAPI PVOID GetP5eVirtualAddress(IN PMMP5E P5ePointer);
STATIC XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte);
STATIC XTAPI USHORT GetPageMapLevel();
STATIC XTAPI PMMPDE GetPdeAddress(IN PVOID Address);
STATIC XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
STATIC XTAPI PMMPPE GetPpeAddress(IN PVOID Address);
STATIC XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);
STATIC XTAPI ULONGLONG GetPte(IN PMMPTE PtePointer);
STATIC XTAPI PMMPTE GetPteAddress(IN PVOID Address);
STATIC XTAPI LONG GetPteDistance(PMMPTE EndPte,
PMMPTE StartPte);
STATIC XTAPI ULONG GetPteSize(VOID);
STATIC XTAPI ULONG GetPteSoftwareProtection(IN PMMPTE PtePointer);
STATIC XTAPI ULONG GetPteSoftwarePrototype(IN PMMPTE PtePointer);
STATIC XTAPI ULONG GetPteSoftwareTransition(IN PMMPTE PtePointer);
STATIC XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer);
STATIC XTAPI PMMPXE GetPxeAddress(IN PVOID Address);
STATIC XTAPI PVOID GetPxeVirtualAddress(IN PMMPXE PxePointer);
STATIC XTAPI BOOLEAN GetXpaStatus(VOID);
STATIC XTAPI VOID InitializePageMapSupport(VOID);
STATIC XTAPI BOOLEAN PteValid(IN PMMPTE PtePointer);
STATIC XTAPI VOID SetNextEntry(IN PMMPTE Pte,
IN ULONG_PTR Value);
STATIC XTAPI VOID SetOneEntry(IN PMMPTE Pte,
IN BOOLEAN Value);
STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer,
IN PFN_NUMBER PageFrameNumber,
IN ULONGLONG AttributesMask);
STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer,
IN ULONGLONG Attributes);
STATIC XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
IN BOOLEAN CacheDisable,
IN BOOLEAN WriteThrough);
STATIC XTAPI VOID WritePte(IN PMMPTE Pte,
IN MMPTE Value);
STATIC XTAPI VOID TransitionPte(IN PMMPTE PointerPte,
IN ULONG_PTR Protection);
STATIC XTFASTCALL VOID ZeroPages(IN PVOID Address,
IN ULONG Size);
private:
STATIC XTAPI BOOLEAN GetExtendedPhysicalAddressingStatus(VOID);
STATIC XTAPI PPAGEMAP GetPageMapBasicRoutines(VOID);
STATIC XTAPI PPAGEMAP GetPageMapXpaRoutines(VOID);
};
}
#endif /* __XTOSKRNL_MM_AMD64_PAGING_HH */

Voir le fichier

@@ -0,0 +1,69 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/mm/amd64/pte.hh
* DESCRIPTION: Page Table Entry (PTE) for AMD64 support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_MM_AMD64_PTE_HH
#define __XTOSKRNL_MM_AMD64_PTE_HH
#include <xtos.hh>
/* Memory Manager */
namespace MM
{
class Pte
{
private:
STATIC MMPTE FirstSystemFreePte[MaximumPtePoolTypes];
STATIC PMMPTE SystemPteBase;
STATIC PMMPTE SystemPtesEnd[MaximumPtePoolTypes];
STATIC PMMPTE SystemPtesStart[MaximumPtePoolTypes];
STATIC PFN_COUNT TotalSystemFreePtes[MaximumPtePoolTypes];
STATIC MMPTE ValidPte;
public:
STATIC XTAPI BOOLEAN AddressValid(IN PVOID VirtualAddress);
STATIC XTAPI PFN_COUNT GetPtesPerPage(VOID);
STATIC XTAPI PMMPTE GetSystemPteBaseAddress(VOID);
STATIC XTAPI PMMPTE GetValidPte(VOID);
STATIC XTAPI VOID InitializePageTable(VOID);
STATIC XTAPI VOID InitializeSystemPte(VOID);
STATIC XTAPI VOID InitializeSystemPtePool(IN PMMPTE StartingPte,
IN PFN_COUNT NumberOfPtes,
IN MMSYSTEM_PTE_POOL_TYPE PoolType);
STATIC XTAPI VOID InitializeSystemPteSpace(VOID);
STATIC XTAPI VOID MapP5E(IN PVOID StartAddress,
IN PVOID EndAddress,
IN PMMP5E TemplateP5e);
STATIC XTAPI VOID MapPDE(IN PVOID StartAddress,
IN PVOID EndAddress,
IN PMMPDE TemplatePde);
STATIC XTAPI VOID MapPPE(IN PVOID StartAddress,
IN PVOID EndAddress,
IN PMMPPE TemplatePpe);
STATIC XTAPI VOID MapPTE(IN PVOID StartAddress,
IN PVOID EndAddress,
IN PMMPTE TemplatePte);
STATIC XTAPI VOID MapPXE(IN PVOID StartAddress,
IN PVOID EndAddress,
IN PMMPXE TemplatePxe);
STATIC XTAPI VOID ReleaseSystemPtes(IN PMMPTE StartingPte,
IN PFN_COUNT NumberOfPtes,
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType);
STATIC XTAPI PMMPTE ReserveSystemPtes(IN PFN_COUNT NumberOfPtes,
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType);
private:
STATIC XTAPI BOOLEAN FindFreeCluster(IN PFN_COUNT NumberOfPtes,
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType,
OUT PMMPTE *FoundCluster,
OUT PMMPTE *PreviousClusterNode);
STATIC XTAPI ULONG GetClusterSize(IN PMMPTE Pte);
};
}
#endif /* __XTOSKRNL_MM_AMD64_PTE_HH */

38
xtoskrnl/includes/mm/colors.hh Fichier normal
Voir le fichier

@@ -0,0 +1,38 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/mm/colors.hh
* DESCRIPTION: Memory manager page coloring subsystem
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_MM_COLORS_HH
#define __XTOSKRNL_MM_COLORS_HH
#include <xtos.hh>
/* Memory Manager */
namespace MM
{
class Colors
{
private:
STATIC PMMCOLOR_TABLES FreePages[FreePageList + 1];
STATIC MMPFNLIST ModifiedPages[MM_PAGING_COLORS];
STATIC ULONG PagingColors;
STATIC ULONG PagingColorsMask;
public:
STATIC XTAPI VOID ComputePageColoring(VOID);
STATIC XTAPI PMMCOLOR_TABLES GetFreePages(IN MMPAGELISTS PageList,
IN ULONG Color);
STATIC XTAPI PMMPFNLIST GetModifiedPages(IN ULONG Color);
STATIC XTAPI ULONG GetNextColor(VOID);
STATIC XTAPI ULONG GetPagingColors(VOID);
STATIC XTAPI ULONG GetPagingColorsMask(VOID);
STATIC XTAPI VOID InitializeColorTables(VOID);
};
}
#endif /* __XTOSKRNL_MM_COLORS_HH */

88
xtoskrnl/includes/mm/guard.hh Fichier normal
Voir le fichier

@@ -0,0 +1,88 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/mm/guard.hh
* DESCRIPTION: Memory Manager synchronization guard
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_MM_GUARD_HH
#define __XTOSKRNL_MM_GUARD_HH
#include <xtos.hh>
#include <ke/runlevel.hh>
#include <ke/spinlock.hh>
/* Memory Manager */
namespace MM
{
class PoolLockGuard
{
private:
BOOLEAN Locked;
MMPOOL_TYPE LockPoolType;
KRUNLEVEL PreviousRunLevel;
public:
PoolLockGuard(IN MMPOOL_TYPE PoolType)
{
LockPoolType = PoolType;
/* Determine the appropriate synchronization mechanism based on the requested pool type */
if(LockPoolType == NonPagedPool)
{
/* Elevate the runlevel to DISPATCH_LEVEL */
PreviousRunLevel = KE::RunLevel::RaiseRunLevel(DISPATCH_LEVEL);
/* Acquire the global queued spinlock protecting the non-paged pool */
KE::SpinLock::AcquireQueuedSpinLock(NonPagedPoolLock);
}
else
{
/* Paged pool requires a mutex, currently unimplemented */
UNIMPLEMENTED;
}
/* Mark the guard as actively holding the lock */
Locked = TRUE;
}
~PoolLockGuard(VOID)
{
/* Automatically release the held lock upon going out of scope */
Release();
}
PoolLockGuard(const PoolLockGuard&) = delete;
PoolLockGuard& operator=(const PoolLockGuard&) = delete;
VOID Release(VOID)
{
/* Check if the guard is currently holding a lock */
if(!Locked)
{
/* Return, to prevent a double-free */
return;
}
/* Determine the appropriate synchronization mechanism based on the requested pool type */
if(LockPoolType == NonPagedPool)
{
/* Release the non-paged pool spinlock and subsequently restore the original runlevel */
KE::SpinLock::ReleaseQueuedSpinLock(NonPagedPoolLock);
KE::RunLevel::LowerRunLevel(PreviousRunLevel);
}
else
{
/* Paged pool requires a mutex, currently unimplemented */
UNIMPLEMENTED;
}
/* Update the internal state, indicating that the lock is no longer held */
Locked = FALSE;
}
};
}
#endif /* __XTOSKRNL_MM_GUARD_HH */

Voir le fichier

@@ -1,13 +1,13 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/mm/pagemap.hh
* FILE: xtoskrnl/includes/mm/i686/pagemap.hh
* DESCRIPTION: Low-level support for page map manipulation
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_MM_PAGEMAP_HH
#define __XTOSKRNL_MM_PAGEMAP_HH
#ifndef __XTOSKRNL_MM_I686_PAGEMAP_HH
#define __XTOSKRNL_MM_I686_PAGEMAP_HH
#include <xtos.hh>
@@ -21,45 +21,130 @@ namespace MM
MMPAGEMAP_INFO PageMapInfo;
public:
XTAPI VOID ClearPte(PHARDWARE_PTE PtePointer);
XTAPI PMMPDE GetPdeAddress(PVOID Address);
XTAPI PMMPPE GetPpeAddress(PVOID Address);
XTAPI PMMPTE GetPteAddress(PVOID Address);
virtual XTAPI VOID InitializePageMapInfo(VOID) = 0;
virtual XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer) = 0;
virtual XTAPI VOID SetPte(PHARDWARE_PTE PtePointer,
PFN_NUMBER PageFrameNumber,
BOOLEAN Writable) = 0;
virtual XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer,
BOOLEAN CacheDisable,
BOOLEAN WriteThrough) = 0;
VIRTUAL XTAPI PMMPTE AdvancePte(IN PMMPTE Pte,
IN ULONG Count) = 0;
XTAPI BOOLEAN CanonicalAddress(IN PVOID VirtualAddress);
VIRTUAL XTAPI VOID ClearPte(IN PMMPTE PtePointer) = 0;
VIRTUAL XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte) = 0;
VIRTUAL XTAPI PMMPTE GetNextPte(IN PMMPTE Pte) = 0;
VIRTUAL XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte) = 0;
VIRTUAL XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte) = 0;
XTAPI USHORT GetPageMapLevel();
XTAPI PMMPDE GetPdeAddress(IN PVOID Address);
XTAPI ULONG GetPdeOffset(IN PVOID Address);
VIRTUAL XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer) = 0;
XTAPI PMMPPE GetPpeAddress(IN PVOID Address);
XTAPI ULONG GetPpeOffset(IN PVOID Address);
XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);
VIRTUAL XTAPI ULONGLONG GetPte(IN PMMPTE PtePointer) = 0;
XTAPI PMMPTE GetPteAddress(IN PVOID Address);
XTAPI ULONG GetPteOffset(IN PVOID Address);
VIRTUAL XTAPI LONG GetPteDistance(PMMPTE EndPte,
PMMPTE StartPte) = 0;
VIRTUAL XTAPI ULONG GetPteSize(VOID) = 0;
VIRTUAL XTAPI ULONG GetPteSoftwareProtection(IN PMMPTE PtePointer) = 0;
VIRTUAL XTAPI ULONG GetPteSoftwarePrototype(IN PMMPTE PtePointer) = 0;
VIRTUAL XTAPI ULONG GetPteSoftwareTransition(IN PMMPTE PtePointer) = 0;
VIRTUAL XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer) = 0;
XTAPI BOOLEAN GetXpaStatus();
VIRTUAL XTAPI VOID InitializePageMapInfo(VOID) = 0;
VIRTUAL XTAPI BOOLEAN PteValid(IN PMMPTE PtePointer) = 0;
VIRTUAL XTAPI VOID SetNextEntry(IN PMMPTE Pte,
IN ULONG_PTR Value) = 0;
VIRTUAL XTAPI VOID SetOneEntry(IN PMMPTE Pte,
IN BOOLEAN Value) = 0;
VIRTUAL XTAPI VOID SetPte(IN PMMPTE PtePointer,
IN PFN_NUMBER PageFrameNumber,
IN ULONGLONG AttributesMask) = 0;
VIRTUAL XTAPI VOID SetPte(IN PMMPTE PtePointer,
IN ULONGLONG Attributes) = 0;
VIRTUAL XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
IN BOOLEAN CacheDisable,
IN BOOLEAN WriteThrough) = 0;
VIRTUAL XTAPI VOID TransitionPte(IN PMMPTE PointerPte,
IN ULONG_PTR Protection) = 0;
VIRTUAL XTAPI VOID WritePte(IN PMMPTE Pte,
IN MMPTE Value) = 0;
} PAGEMAP, *PPAGEMAP;
class PageMapBasic final : public PageMap
{
public:
XTAPI PMMPTE AdvancePte(IN PMMPTE Pte,
IN ULONG Count);
XTAPI VOID ClearPte(IN PMMPTE PtePointer);
XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte);
XTAPI PMMPTE GetNextPte(IN PMMPTE Pte);
XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte);
XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte);
XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
XTAPI ULONGLONG GetPte(IN PMMPTE PtePointer);
XTAPI LONG GetPteDistance(PMMPTE EndPte,
PMMPTE StartPte);
XTAPI ULONG GetPteSize(VOID);
XTAPI ULONG GetPteSoftwareProtection(IN PMMPTE PtePointer);
XTAPI ULONG GetPteSoftwarePrototype(IN PMMPTE PtePointer);
XTAPI ULONG GetPteSoftwareTransition(IN PMMPTE PtePointer);
XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer);
XTAPI VOID InitializePageMapInfo(VOID);
XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer);
XTAPI VOID SetPte(PHARDWARE_PTE PtePointer,
PFN_NUMBER PageFrameNumber,
BOOLEAN Writable);
XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer,
BOOLEAN CacheDisable,
BOOLEAN WriteThrough);
XTAPI BOOLEAN PteValid(IN PMMPTE PtePointer);
XTAPI VOID SetNextEntry(IN PMMPTE Pte,
IN ULONG_PTR Value);
XTAPI VOID SetOneEntry(IN PMMPTE Pte,
IN BOOLEAN Value);
XTAPI VOID SetPte(IN PMMPTE PtePointer,
IN PFN_NUMBER PageFrameNumber,
IN ULONGLONG AttributesMask);
XTAPI VOID SetPte(IN PMMPTE PtePointer,
IN ULONGLONG Attributes);
XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
IN BOOLEAN CacheDisable,
IN BOOLEAN WriteThrough);
XTAPI VOID TransitionPte(IN PMMPTE PointerPte,
IN ULONG_PTR Protection);
XTAPI VOID WritePte(IN PMMPTE Pte,
IN MMPTE Value);
};
class PageMapXpa final : public PageMap
{
public:
XTAPI PMMPTE AdvancePte(IN PMMPTE Pte,
IN ULONG Count);
XTAPI VOID ClearPte(IN PMMPTE PtePointer);
XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte);
XTAPI PMMPTE GetNextPte(IN PMMPTE Pte);
XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte);
XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte);
XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
XTAPI ULONGLONG GetPte(IN PMMPTE PtePointer);
XTAPI LONG GetPteDistance(PMMPTE EndPte,
PMMPTE StartPte);
XTAPI ULONG GetPteSize(VOID);
XTAPI ULONG GetPteSoftwareProtection(IN PMMPTE PtePointer);
XTAPI ULONG GetPteSoftwarePrototype(IN PMMPTE PtePointer);
XTAPI ULONG GetPteSoftwareTransition(IN PMMPTE PtePointer);
XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer);
XTAPI VOID InitializePageMapInfo(VOID);
XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer);
XTAPI VOID SetPte(PHARDWARE_PTE PtePointer,
PFN_NUMBER PageFrameNumber,
BOOLEAN Writable);
XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer,
BOOLEAN CacheDisable,
BOOLEAN WriteThrough);
XTAPI BOOLEAN PteValid(IN PMMPTE PtePointer);
XTAPI VOID SetNextEntry(IN PMMPTE Pte,
IN ULONG_PTR Value);
XTAPI VOID SetOneEntry(IN PMMPTE Pte,
IN BOOLEAN Value);
XTAPI VOID SetPte(IN PMMPTE PtePointer,
IN PFN_NUMBER PageFrameNumber,
IN ULONGLONG AttributesMask);
XTAPI VOID SetPte(IN PMMPTE PtePointer,
IN ULONGLONG Attributes);
XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
IN BOOLEAN CacheDisable,
IN BOOLEAN WriteThrough);
XTAPI VOID TransitionPte(IN PMMPTE PointerPte,
IN ULONG_PTR Protection);
XTAPI VOID WritePte(IN PMMPTE Pte,
IN MMPTE Value);
};
}
#endif /* __XTOSKRNL_MM_PAGEMAP_HH */
#endif /* __XTOSKRNL_MM_I686_PAGEMAP_HH */

Voir le fichier

@@ -0,0 +1,77 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/mm/i686/paging.hh
* DESCRIPTION: Low level page management support for i686
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_MM_I686_PAGING_HH
#define __XTOSKRNL_MM_I686_PAGING_HH
#include <xtos.hh>
/* Memory Manager */
namespace MM
{
class Paging
{
private:
STATIC PPAGEMAP PmlRoutines;
public:
STATIC XTAPI PMMPTE AdvancePte(IN PMMPTE Pte,
IN LONG Count);
STATIC XTAPI BOOLEAN CanonicalAddress(IN PVOID VirtualAddress);
STATIC XTAPI VOID ClearPte(IN PMMPTE PtePointer);
STATIC XTAPI VOID FlushEntireTlb(VOID);
STATIC XTAPI VOID FlushTlb(VOID);
STATIC XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte);
STATIC XTAPI PMMPTE GetNextPte(IN PMMPTE Pte);
STATIC XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte);
STATIC XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte);
STATIC XTAPI USHORT GetPageMapLevel();
STATIC XTAPI PMMPDE GetPdeAddress(IN PVOID Address);
STATIC XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
STATIC XTAPI PMMPPE GetPpeAddress(IN PVOID Address);
STATIC XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);
STATIC XTAPI ULONGLONG GetPte(IN PMMPTE PtePointer);
STATIC XTAPI PMMPTE GetPteAddress(IN PVOID Address);
STATIC XTAPI LONG GetPteDistance(PMMPTE EndPte,
PMMPTE StartPte);
STATIC XTAPI ULONG GetPteSize(VOID);
STATIC XTAPI ULONG GetPteSoftwareProtection(IN PMMPTE PtePointer);
STATIC XTAPI ULONG GetPteSoftwarePrototype(IN PMMPTE PtePointer);
STATIC XTAPI ULONG GetPteSoftwareTransition(IN PMMPTE PtePointer);
STATIC XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer);
STATIC XTAPI BOOLEAN GetXpaStatus(VOID);
STATIC XTAPI VOID InitializePageMapSupport(VOID);
STATIC XTAPI BOOLEAN PteValid(IN PMMPTE PtePointer);
STATIC XTAPI VOID SetNextEntry(IN PMMPTE Pte,
IN ULONG_PTR Value);
STATIC XTAPI VOID SetOneEntry(IN PMMPTE Pte,
IN BOOLEAN Value);
STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer,
IN PFN_NUMBER PageFrameNumber,
IN ULONGLONG AttributesMask);
STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer,
IN ULONGLONG Attributes);
STATIC XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
IN BOOLEAN CacheDisable,
IN BOOLEAN WriteThrough);
STATIC XTAPI VOID WritePte(IN PMMPTE Pte,
IN MMPTE Value);
STATIC XTAPI VOID TransitionPte(IN PMMPTE PointerPte,
IN ULONG_PTR Protection);
STATIC XTFASTCALL VOID ZeroPages(IN PVOID Address,
IN ULONG Size);
private:
STATIC XTAPI BOOLEAN GetExtendedPhysicalAddressingStatus(VOID);
STATIC XTAPI PPAGEMAP GetPageMapBasicRoutines(VOID);
STATIC XTAPI PPAGEMAP GetPageMapXpaRoutines(VOID);
};
}
#endif /* __XTOSKRNL_MM_I686_PAGING_HH */

Voir le fichier

@@ -0,0 +1,63 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/mm/i686/pte.hh
* DESCRIPTION: Page Table Entry (PTE) for i686 support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_MM_I686_PTE_HH
#define __XTOSKRNL_MM_I686_PTE_HH
#include <xtos.hh>
/* Memory Manager */
namespace MM
{
class Pte
{
private:
STATIC MMPTE FirstSystemFreePte[MaximumPtePoolTypes];
STATIC PMMPTE SystemPteBase;
STATIC PMMPTE SystemPtesEnd[MaximumPtePoolTypes];
STATIC PMMPTE SystemPtesStart[MaximumPtePoolTypes];
STATIC PFN_COUNT TotalSystemFreePtes[MaximumPtePoolTypes];
STATIC MMPTE ValidPte;
public:
STATIC XTAPI BOOLEAN AddressValid(IN PVOID VirtualAddress);
STATIC XTAPI PFN_COUNT GetPtesPerPage(VOID);
STATIC XTAPI PMMPTE GetSystemPteBaseAddress(VOID);
STATIC XTAPI PMMPTE GetValidPte(VOID);
STATIC XTAPI VOID InitializePageTable(VOID);
STATIC XTAPI VOID InitializeSystemPte(VOID);
STATIC XTAPI VOID InitializeSystemPtePool(IN PMMPTE StartingPte,
IN PFN_COUNT NumberOfPtes,
IN MMSYSTEM_PTE_POOL_TYPE PoolType);
STATIC XTAPI VOID InitializeSystemPteSpace(VOID);
STATIC XTAPI VOID MapPDE(IN PVOID StartAddress,
IN PVOID EndAddress,
IN PMMPDE TemplatePde);
STATIC XTAPI VOID MapPPE(IN PVOID StartAddress,
IN PVOID EndAddress,
IN PMMPPE TemplatePpe);
STATIC XTAPI VOID MapPTE(IN PVOID StartAddress,
IN PVOID EndAddress,
IN PMMPTE TemplatePte);
STATIC XTAPI VOID ReleaseSystemPtes(IN PMMPTE StartingPte,
IN PFN_COUNT NumberOfPtes,
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType);
STATIC XTAPI PMMPTE ReserveSystemPtes(IN PFN_COUNT NumberOfPtes,
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType);
private:
STATIC XTAPI BOOLEAN FindFreeCluster(IN PFN_COUNT NumberOfPtes,
IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType,
OUT PMMPTE *FoundCluster,
OUT PMMPTE *PreviousClusterNode);
STATIC XTAPI ULONG GetClusterSize(IN PMMPTE Pte);
};
}
#endif /* __XTOSKRNL_MM_I686_PTE_HH */

Voir le fichier

@@ -1,39 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/mm/init.hh
* DESCRIPTION: Memory Manager initialization
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_MM_INIT_HH
#define __XTOSKRNL_MM_INIT_HH
#include <xtos.hh>
/* Memory Manager */
namespace MM
{
class Init
{
private:
STATIC PLOADER_MEMORY_DESCRIPTOR FreeDescriptor;
STATIC ULONG_PTR HighestPhysicalPage;
STATIC ULONG_PTR LowestPhysicalPage;
STATIC ULONG NumberOfPhysicalPages;
STATIC LOADER_MEMORY_DESCRIPTOR OldFreeDescriptor;
public:
STATIC XTAPI VOID InitializeMemoryManager(VOID);
STATIC XTAPI VOID InitializePageMapSupport(VOID);
STATIC XTAPI VOID ScanMemoryDescriptors(VOID);
private:
STATIC XTAPI VOID InitializeArchitecture(VOID);
STATIC XTAPI BOOLEAN VerifyMemoryTypeFree(LOADER_MEMORY_TYPE MemoryType);
STATIC XTAPI BOOLEAN VerifyMemoryTypeInvisible(LOADER_MEMORY_TYPE MemoryType);
};
}
#endif /* __XTOSKRNL_MM_INIT_HH */

Voir le fichier

@@ -17,17 +17,13 @@ namespace MM
{
class KernelPool
{
private:
STATIC UCHAR ProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE];
public:
STATIC XTAPI XTSTATUS AllocateKernelStack(IN PVOID *Stack,
IN BOOLEAN LargeStack,
IN UCHAR SystemNode);
STATIC XTAPI XTSTATUS AllocateKernelStack(OUT PVOID *Stack,
IN ULONG StackSize);
STATIC XTAPI XTSTATUS AllocateProcessorStructures(IN ULONG CpuNumber,
OUT PVOID *StructuresData);
OUT PVOID *StructuresData);
STATIC XTAPI VOID FreeKernelStack(IN PVOID Stack,
IN BOOLEAN LargeStack);
IN ULONG StackSize);
STATIC XTAPI VOID FreeProcessorStructures(IN PVOID StructuresData);
};
}

46
xtoskrnl/includes/mm/mmgr.hh Fichier normal
Voir le fichier

@@ -0,0 +1,46 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/mm/mmgr.hh
* DESCRIPTION: Memory Manager
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_MM_MMGR_HH
#define __XTOSKRNL_MM_MMGR_HH
#include <xtos.hh>
/* Memory Manager */
namespace MM
{
class Manager
{
private:
STATIC MMMEMORY_LAYOUT MemoryLayout;
STATIC PFN_NUMBER NumberOfSystemPtes;
STATIC PPHYSICAL_MEMORY_DESCRIPTOR PhysicalMemoryBlock;
public:
STATIC XTAPI ULONG_PTR GetInstalledMemorySize(VOID);
STATIC XTAPI PMMMEMORY_LAYOUT GetMemoryLayout(VOID);
STATIC XTAPI PFN_NUMBER GetNumberOfSystemPtes(VOID);
STATIC XTAPI PPHYSICAL_MEMORY_DESCRIPTOR GetPhysicalMemoryBlock(VOID);
STATIC XTAPI VOID InitializeMemoryLayout(VOID);
STATIC XTAPI VOID InitializeMemoryManager(VOID);
STATIC XTAPI BOOLEAN VerifyMemoryTypeFree(IN LOADER_MEMORY_TYPE MemoryType);
STATIC XTAPI BOOLEAN VerifyMemoryTypeInvisible(IN LOADER_MEMORY_TYPE MemoryType);
private:
STATIC XTAPI VOID ComputeBootImageSize(OUT PPFN_NUMBER BootImageSize);
STATIC XTAPI VOID ComputeMaximumNonPagedPoolSize(OUT PPFN_NUMBER PoolSize);
STATIC XTAPI VOID ComputeNonPagedPoolSize(OUT PPFN_NUMBER PoolSize);
STATIC XTAPI VOID ComputePagedPoolSize(OUT PPFN_NUMBER PoolSize);
STATIC XTAPI VOID ComputeSessionSpaceSize(OUT PPFN_NUMBER SpaceSize);
STATIC XTAPI VOID ComputeSystemPteSize(OUT PPFN_NUMBER PteSize);
STATIC XTAPI VOID DumpMemoryLayout(VOID);
};
}
#endif /* __XTOSKRNL_MM_MMGR_HH */

Voir le fichier

@@ -1,47 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/mm/paging.hh
* DESCRIPTION: Low level page management support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_MM_PAGING_HH
#define __XTOSKRNL_MM_PAGING_HH
#include <xtos.hh>
/* Memory Manager */
namespace MM
{
class Paging
{
private:
STATIC PPAGEMAP PmlRoutines;
public:
STATIC XTAPI VOID ClearPte(PHARDWARE_PTE PtePointer);
STATIC XTAPI VOID FlushTlb(VOID);
STATIC XTAPI PMMPDE GetPdeAddress(PVOID Address);
STATIC XTAPI PMMPPE GetPpeAddress(PVOID Address);
STATIC XTAPI PMMPTE GetPteAddress(PVOID Address);
STATIC XTAPI VOID InitializePageMapSupport(VOID);
STATIC XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer);
STATIC XTAPI VOID SetPte(PHARDWARE_PTE PtePointer,
PFN_NUMBER PageFrameNumber,
BOOLEAN Writable);
STATIC XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer,
BOOLEAN CacheDisable,
BOOLEAN WriteThrough);
STATIC XTFASTCALL VOID ZeroPages(IN PVOID Address,
IN ULONG Size);
private:
STATIC XTAPI BOOLEAN GetExtendedPhysicalAddressingStatus(VOID);
STATIC XTAPI PPAGEMAP GetPageMapBasicRoutines(VOID);
STATIC XTAPI PPAGEMAP GetPageMapXpaRoutines(VOID);
};
}
#endif /* __XTOSKRNL_MM_PAGING_HH */

25
xtoskrnl/includes/mm/pfault.hh Fichier normal
Voir le fichier

@@ -0,0 +1,25 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/mm/pfault.hh
* DESCRIPTION: Page fault support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_MM_PFAULT_HH
#define __XTOSKRNL_MM_PFAULT_HH
#include <xtos.hh>
/* Memory Manager */
namespace MM
{
class PageFault
{
public:
STATIC XTFASTCALL XTSTATUS CheckPdeForPagedPool(IN PVOID VirtualAddress);
};
}
#endif /* __XTOSKRNL_MM_PFAULT_HH */

85
xtoskrnl/includes/mm/pfn.hh Fichier normal
Voir le fichier

@@ -0,0 +1,85 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/mm/pfn.hh
* DESCRIPTION: Physical Frame Number (PFN) support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_MM_PFN_HH
#define __XTOSKRNL_MM_PFN_HH
#include <xtos.hh>
/* Memory Manager */
namespace MM
{
class Pfn
{
private:
STATIC PFN_NUMBER AvailablePages;
STATIC MMPFNLIST BadPagesList;
STATIC PLOADER_MEMORY_DESCRIPTOR FreeDescriptor;
STATIC MMPFNLIST FreePagesList;
STATIC ULONG_PTR HighestPhysicalPage;
STATIC PVOID HighestUserAddress;
STATIC ULONG_PTR LowestPhysicalPage;
STATIC MMPFNLIST ModifiedPagesList;
STATIC MMPFNLIST ModifiedReadOnlyPagesList;
STATIC ULONGLONG NumberOfPhysicalPages;
STATIC LOADER_MEMORY_DESCRIPTOR OriginalFreeDescriptor;
STATIC PMMPFNLIST PageLocationList[];
STATIC RTL_BITMAP PfnBitMap;
STATIC MMPFNLIST RomPagesList;
STATIC MMPFNLIST StandbyPagesList;
STATIC MMPFNLIST ZeroedPagesList;
public:
STATIC XTAPI PFN_NUMBER AllocateBootstrapPages(IN PFN_NUMBER NumberOfPages);
STATIC XTAPI PFN_NUMBER AllocatePhysicalPage(IN ULONG Color);
STATIC XTAPI VOID ComputePfnDatabaseSize(OUT PPFN_NUMBER DatabaseSize);
STATIC XTAPI VOID DecrementReferenceCount(IN PMMPFN Pfn1,
IN PFN_NUMBER PageFrameIndex,
IN BOOLEAN BeginStandbyList = FALSE);
STATIC XTAPI VOID DecrementShareCount(IN PMMPFN Pfn1,
IN PFN_NUMBER PageFrameIndex,
IN BOOLEAN BeginStandbyList = FALSE);
STATIC XTAPI VOID FreePhysicalPage(IN PMMPTE PointerPte);
STATIC XTAPI PFN_NUMBER GetAvailablePages(VOID);
STATIC XTAPI ULONG_PTR GetHighestPhysicalPage(VOID);
STATIC XTAPI ULONGLONG GetNumberOfPhysicalPages(VOID);
STATIC XTAPI PMMPFN GetPfnEntry(IN PFN_NUMBER Pfn);
STATIC XTAPI VOID InitializePfnBitmap(VOID);
STATIC XTAPI VOID InitializePfnDatabase(VOID);
STATIC XTAPI VOID LinkPfn(IN PFN_NUMBER PageFrameIndex,
IN PMMPTE PointerPte,
IN BOOLEAN Modified);
STATIC XTAPI VOID LinkPfnWithParent(IN PFN_NUMBER PageFrameIndex,
IN PMMPTE PointerPte,
IN PFN_NUMBER ParentFrame);
STATIC XTAPI VOID ScanMemoryDescriptors(VOID);
private:
STATIC XTAPI VOID DecrementAvailablePages(VOID);
STATIC XTAPI VOID IncrementAvailablePages(VOID);
STATIC XTAPI VOID InitializePageDirectory(IN PMMPDE StartingPde,
IN PMMPDE EndingPde);
STATIC XTAPI VOID InitializePageTablePfns(VOID);
STATIC XTAPI VOID LinkFreePage(IN PFN_NUMBER PageFrameIndex);
STATIC XTAPI VOID LinkPage(IN PMMPFNLIST ListHead,
IN PFN_NUMBER PageFrameIndex);
STATIC XTAPI VOID LinkPfnForPageTable(IN PFN_NUMBER PageFrameIndex,
IN PMMPTE PointerPte);
STATIC XTFASTCALL VOID LinkStandbyPage(IN PFN_NUMBER PageFrameIndex);
STATIC XTAPI VOID ProcessMemoryDescriptor(IN PFN_NUMBER BasePage,
IN PFN_NUMBER PageCount,
IN LOADER_MEMORY_TYPE MemoryType);
STATIC XTAPI VOID ScanPageTable(IN PMMPTE PointerPte,
IN ULONG Level);
STATIC XTAPI PFN_NUMBER UnlinkFreePage(IN PFN_NUMBER PageFrameIndex,
IN ULONG Color);
};
}
#endif /* __XTOSKRNL_MM_PFN_HH */

68
xtoskrnl/includes/mm/pool.hh Fichier normal
Voir le fichier

@@ -0,0 +1,68 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/mm/pool.hh
* DESCRIPTION: Memory Manager pool manager
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_MM_POOL_HH
#define __XTOSKRNL_MM_POOL_HH
#include <xtos.hh>
/* Memory Manager */
namespace MM
{
class Pool
{
protected:
STATIC POOL_DESCRIPTOR NonPagedPoolDescriptor;
STATIC PFN_NUMBER NonPagedPoolFrameEnd;
STATIC PFN_NUMBER NonPagedPoolFrameStart;
STATIC LIST_ENTRY NonPagedPoolFreeList[MM_MAX_FREE_PAGE_LIST_HEADS];
STATIC ULONG PoolSecureCookie;
STATIC PPOOL_DESCRIPTOR PoolVector[2];
public:
STATIC XTAPI MMPOOL_TYPE DeterminePoolType(IN PVOID VirtualAddress);
STATIC XTAPI VOID InitializeNonPagedPool(VOID);
STATIC XTAPI VOID InitializePagedPool(VOID);
STATIC XTAPI VOID InitializePoolSecurity(VOID);
protected:
STATIC XTAPI PLIST_ENTRY DecodePoolLink(IN PLIST_ENTRY PoolLink);
STATIC XTAPI PLIST_ENTRY EncodePoolLink(IN PLIST_ENTRY PoolLink);
STATIC XTAPI PPOOL_HEADER GetPoolBlock(IN PPOOL_HEADER Header, IN SSIZE_T Index);
STATIC XTAPI PPOOL_HEADER GetPoolEntry(IN PVOID Payload);
STATIC XTAPI PLIST_ENTRY GetPoolFreeBlock(IN PPOOL_HEADER Header);
STATIC XTAPI PPOOL_HEADER GetPoolNextBlock(IN PPOOL_HEADER Header);
STATIC XTAPI PPOOL_HEADER GetPoolPreviousBlock(IN PPOOL_HEADER Header);
STATIC XTAPI VOID InsertPoolHeadList(IN PLIST_ENTRY ListHead,
IN PLIST_ENTRY Entry);
STATIC XTAPI VOID InsertPoolTailList(IN PLIST_ENTRY ListHead,
IN PLIST_ENTRY Entry);
STATIC XTAPI BOOLEAN PoolListEmpty(IN PLIST_ENTRY ListHead);
STATIC XTAPI VOID RemovePoolEntryList(IN PLIST_ENTRY Entry);
STATIC XTAPI PLIST_ENTRY RemovePoolHeadList(IN PLIST_ENTRY ListHead);
STATIC XTAPI PLIST_ENTRY RemovePoolTailList(IN PLIST_ENTRY ListHead);
STATIC XTAPI VOID VerifyPoolBlocks(IN PVOID Block);
STATIC XTAPI VOID VerifyPoolHeader(IN PPOOL_HEADER Entry);
STATIC XTAPI VOID VerifyPoolLinks(IN PLIST_ENTRY ListHead);
STATIC XTAPI VOID VerifyRunLevel(IN MMPOOL_TYPE PoolType,
IN SIZE_T Bytes,
IN PVOID Entry);
private:
STATIC XTAPI VOID InitializePoolDescriptor(IN PPOOL_DESCRIPTOR Descriptor,
IN MMPOOL_TYPE PoolType,
IN ULONG Index,
IN ULONG Threshold,
IN PVOID LockAddress);
STATIC XTAPI VOID InitializePoolListHead(IN PLIST_ENTRY ListHead);
STATIC XTAPI VOID MapNonPagedPool(VOID);
};
}
#endif /* __XTOSKRNL_MM_POOL_HH */

Voir le fichier

@@ -19,6 +19,8 @@
#include <rtl/llist.hh>
#include <rtl/math.hh>
#include <rtl/memory.hh>
#include <rtl/sha1.hh>
#include <rtl/slist.hh>
#include <rtl/string.hh>
#include <rtl/widestr.hh>

Voir le fichier

@@ -4,6 +4,7 @@
* FILE: xtoskrnl/includes/rtl/llist.hh
* DESCRIPTION: Linked list manipulation routines
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
* Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTOSKRNL_RTL_LLIST_HH
@@ -18,6 +19,7 @@ namespace RTL
class LinkedList
{
public:
STATIC XTCDECL PLIST_ENTRY GetFirstEntry(IN PLIST_ENTRY ListHead);
STATIC XTCDECL VOID InitializeListHead(IN PLIST_ENTRY ListHead);
STATIC XTCDECL VOID InitializeListHead32(IN PLIST_ENTRY32 ListHead);
STATIC XTCDECL VOID InsertHeadList(IN OUT PLIST_ENTRY ListHead,
@@ -27,6 +29,10 @@ namespace RTL
STATIC XTCDECL BOOLEAN ListEmpty(IN PLIST_ENTRY ListHead);
STATIC XTCDECL BOOLEAN ListLoop(IN PLIST_ENTRY ListHead);
STATIC XTCDECL VOID RemoveEntryList(IN PLIST_ENTRY Entry);
STATIC XTCDECL VOID SpliceHeadList(IN OUT PLIST_ENTRY ListHead,
IN OUT PLIST_ENTRY SpliceList);
STATIC XTCDECL VOID SpliceTailList(IN OUT PLIST_ENTRY ListHead,
IN OUT PLIST_ENTRY SpliceList);
};
}

37
xtoskrnl/includes/rtl/sha1.hh Fichier normal
Voir le fichier

@@ -0,0 +1,37 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/rtl/sha1.hh
* DESCRIPTION: SHA1 computation support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTOSKRNL_RTL_SHA1_HH
#define __XTOSKRNL_RTL_SHA1_HH
#include <xtos.hh>
/* Runtime Library */
namespace RTL
{
class SHA1
{
public:
STATIC XTAPI XTSTATUS ComputeDigest(IN PCUCHAR Buffer,
IN SIZE_T BufferSize,
OUT PUCHAR Digest);
private:
STATIC XTAPI VOID ComputeHash(IN OUT PRTL_SHA1_CONTEXT Context,
OUT PUCHAR Digest);
STATIC XTAPI VOID HashData(IN OUT PRTL_SHA1_CONTEXT Context,
IN PCUCHAR Data,
IN ULONG Length);
STATIC XTAPI XTSTATUS InitializeContext(OUT PRTL_SHA1_CONTEXT Context);
STATIC XTAPI VOID TransformData(IN OUT PULONG State,
IN PCUCHAR Buffer);
};
}
#endif /* __XTOSKRNL_RTL_SHA1_HH */

39
xtoskrnl/includes/rtl/slist.hh Fichier normal
Voir le fichier

@@ -0,0 +1,39 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/rtl/slist.hh
* DESCRIPTION: Singly linked list manipulation routines
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTOSKRNL_RTL_SLIST_HH
#define __XTOSKRNL_RTL_SLIST_HH
#include <xtos.hh>
/* Runtime Library */
namespace RTL
{
class SinglyList
{
public:
STATIC XTCDECL PSINGLE_LIST_ENTRY GetFirstEntry(IN PSINGLE_LIST_HEADER ListHead);
STATIC XTCDECL VOID InitializeListHead(IN PSINGLE_LIST_HEADER ListHead);
STATIC XTCDECL PSINGLE_LIST_ENTRY InsertHeadList(IN OUT PSINGLE_LIST_HEADER ListHead,
IN PSINGLE_LIST_ENTRY Entry);
STATIC XTCDECL PSINGLE_LIST_ENTRY InsertTailList(IN OUT PSINGLE_LIST_HEADER ListHead,
IN PSINGLE_LIST_ENTRY Entry);
STATIC XTCDECL BOOLEAN ListEmpty(IN PSINGLE_LIST_HEADER ListHead);
STATIC XTAPI USHORT QueryListDepth(IN PSINGLE_LIST_HEADER ListHead);
STATIC XTCDECL VOID RemoveEntryList(IN PSINGLE_LIST_HEADER ListHead,
IN PSINGLE_LIST_ENTRY Entry);
STATIC XTCDECL PSINGLE_LIST_ENTRY SpliceHeadList(IN OUT PSINGLE_LIST_HEADER ListHead,
IN OUT PSINGLE_LIST_HEADER SpliceList);
STATIC XTCDECL PSINGLE_LIST_ENTRY SpliceTailList(IN OUT PSINGLE_LIST_HEADER ListHead,
IN OUT PSINGLE_LIST_HEADER SpliceList);
STATIC XTCDECL PSINGLE_LIST_ENTRY TakeFirstEntry(IN PSINGLE_LIST_HEADER ListHead);
};
}
#endif /* __XTOSKRNL_RTL_SLIST_HH */

Voir le fichier

@@ -33,7 +33,11 @@ KE::Irq::SetInterruptHandler(IN ULONG Vector,
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
/* Update interrupt handler */
ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF);
ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetMiddle = (((ULONG_PTR)Handler >> 16) & 0xFFFF);
ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetHigh = (ULONG_PTR)Handler >> 32;
AR::ProcSup::SetIdtGate(ProcessorBlock->IdtBase,
Vector,
Handler,
KGDT_R0_CODE,
0,
KIDT_ACCESS_RING0,
AMD64_INTERRUPT_GATE);
}

Voir le fichier

@@ -86,6 +86,10 @@ KE::KernelInit::StartKernel(VOID)
/* Save processor state */
Processor::SaveProcessorState(&Prcb->ProcessorState);
/* Initialize spin locks */
SpinLock::InitializeAllLocks();
SpinLock::InitializeLockQueues();
/* Lower to APC runlevel */
RunLevel::LowerRunLevel(APC_LEVEL);
@@ -108,6 +112,9 @@ KE::KernelInit::StartKernel(VOID)
CurrentThread->WaitRunLevel = DISPATCH_LEVEL;
CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber;
/* Initialize Memory Manager */
MM::Manager::InitializeMemoryManager();
/* Enter infinite loop */
DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n");
Crash::HaltSystem();

Voir le fichier

@@ -43,7 +43,7 @@ XTAPI
VOID
KE::Crash::Panic(IN ULONG Code)
{
PanicEx(Code, 0, 0, 0, 0);
Panic(Code, 0, 0, 0, 0);
}
/**
@@ -70,12 +70,13 @@ KE::Crash::Panic(IN ULONG Code)
*/
XTAPI
VOID
KE::Crash::PanicEx(IN ULONG Code,
IN ULONG_PTR Parameter1,
IN ULONG_PTR Parameter2,
IN ULONG_PTR Parameter3,
IN ULONG_PTR Parameter4)
KE::Crash::Panic(IN ULONG Code,
IN ULONG_PTR Parameter1,
IN ULONG_PTR Parameter2,
IN ULONG_PTR Parameter3,
IN ULONG_PTR Parameter4)
{
KD::DebugIo::KdPrint(L"Fatal System Error: 0x%08lx\nKernel Panic!\n\n", Code);
KD::DebugIo::KdPrint(L"Fatal System Error: 0x%08lx (0x%zx 0x%zx 0x%zx 0x%zx)\nKernel Panic!\n\n",
Code, Parameter1, Parameter2, Parameter3, Parameter4);
HaltSystem();
}

Voir le fichier

@@ -12,12 +12,6 @@
/* Kernel initialization block passed by boot loader */
PKERNEL_INITIALIZATION_BLOCK KE::BootInformation::InitializationBlock = {};
/* Kernel boot resources list */
LIST_ENTRY KE::SystemResources::ResourcesListHead;
/* Kernel boot resources lock */
KSPIN_LOCK KE::SystemResources::ResourcesLock;
/* Kernel initial process */
EPROCESS KE::KProcess::InitialProcess;
@@ -26,3 +20,54 @@ ETHREAD KE::KThread::InitialThread = {};
/* Kernel UBSAN active frame flag */
BOOLEAN KE::KUbsan::ActiveFrame = FALSE;
/* Kernel dispatcher lock queue */
KSPIN_LOCK KE::SpinLock::DispatcherLockQueue;
/* Kernel expansion lock queue */
KSPIN_LOCK KE::SpinLock::ExpansionLockQueue;
/* Kernel file system structures lock queue */
KSPIN_LOCK KE::SpinLock::FileSystemLockQueue;
/* Kernel IO cancel lock queue */
KSPIN_LOCK KE::SpinLock::IoCancelLockQueue;
/* Kernel IO completion lock queue */
KSPIN_LOCK KE::SpinLock::IoCompletionLockQueue;
/* Kernel IO database lock queue */
KSPIN_LOCK KE::SpinLock::IoDatabaseLockQueue;
/* Kernel IO VPB lock queue */
KSPIN_LOCK KE::SpinLock::IoVpbLockQueue;
/* Kernel cache master lock queue */
KSPIN_LOCK KE::SpinLock::MasterLockQueue;
/* Kernel non-paged allocator lock queue */
KSPIN_LOCK KE::SpinLock::NonPagedAllocLockQueue;
/* Kernel non-paged pool lock queue */
KSPIN_LOCK KE::SpinLock::NonPagedPoolLockQueue;
/* Kernel PFN lock queue */
KSPIN_LOCK KE::SpinLock::PfnLockQueue;
/* Kernel system space lock queue */
KSPIN_LOCK KE::SpinLock::SystemSpaceLockQueue;
/* Kernel Timer table lock queue */
KSPIN_LOCK KE::SpinLock::TimerTableLockQueue;
/* Kernel VACB lock queue */
KSPIN_LOCK KE::SpinLock::VacbLockQueue;
/* Kernel work queue lock queue */
KSPIN_LOCK KE::SpinLock::WorkLockQueue;
/* Kernel boot resources list */
LIST_ENTRY KE::SystemResources::ResourcesListHead;
/* Kernel boot resources lock */
KSPIN_LOCK KE::SystemResources::ResourcesLock;

Voir le fichier

@@ -33,6 +33,11 @@ KE::Irq::SetInterruptHandler(IN ULONG Vector,
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
/* Update interrupt handler */
ProcessorBlock->IdtBase[(UCHAR) Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF);
ProcessorBlock->IdtBase[(UCHAR) Vector].ExtendedOffset = (USHORT)((ULONG)Handler >> 16);
AR::ProcSup::SetIdtGate(ProcessorBlock->IdtBase,
Vector,
Handler,
KGDT_R0_CODE,
0,
KIDT_ACCESS_RING0,
I686_INTERRUPT_GATE);
}

Voir le fichier

@@ -86,6 +86,10 @@ KE::KernelInit::StartKernel(VOID)
/* Save processor state */
Processor::SaveProcessorState(&Prcb->ProcessorState);
/* Initialize spin locks */
SpinLock::InitializeAllLocks();
SpinLock::InitializeLockQueues();
/* Lower to APC runlevel */
RunLevel::LowerRunLevel(APC_LEVEL);
@@ -108,6 +112,9 @@ KE::KernelInit::StartKernel(VOID)
CurrentThread->WaitRunLevel = DISPATCH_LEVEL;
CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber;
/* Initialize Memory Manager */
MM::Manager::InitializeMemoryManager();
/* Enter infinite loop */
DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n");
Crash::HaltSystem();

Voir le fichier

@@ -152,7 +152,7 @@ KE::KThread::InitializeThread(IN PKPROCESS Process,
if(!Stack)
{
/* Allocate new stack */
Status = MM::KernelPool::AllocateKernelStack(&Stack, FALSE, 0);
Status = MM::KernelPool::AllocateKernelStack(&Stack, KERNEL_STACK_SIZE);
if(Status != STATUS_SUCCESS || !Stack)
{
/* Stack allocation failed */

Voir le fichier

@@ -4,6 +4,7 @@
* FILE: xtoskrnl/ke/spinlock.cc
* DESCRIPTION: Spinlocks support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
@@ -56,6 +57,78 @@ KE::SpinLock::AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock)
AR::CpuFunc::ReadWriteBarrier();
}
/**
* Initializes all kernel spinlocks.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
KE::SpinLock::InitializeAllLocks()
{
/* Initialize all spin locks */
InitializeSpinLock(&DispatcherLockQueue);
InitializeSpinLock(&PfnLockQueue);
InitializeSpinLock(&SystemSpaceLockQueue);
}
/**
* Initializes spinlock queues for current processor.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
KE::SpinLock::InitializeLockQueues()
{
PKPROCESSOR_CONTROL_BLOCK ControlBlock;
/* Get current processor control block */
ControlBlock = KE::Processor::GetCurrentProcessorControlBlock();
/* Initialize PCB lock queues */
ControlBlock->LockQueue[DispatcherLock].Lock = &DispatcherLockQueue;
ControlBlock->LockQueue[DispatcherLock].Next = NULLPTR;
ControlBlock->LockQueue[ExpansionLock].Lock = &ExpansionLockQueue;
ControlBlock->LockQueue[ExpansionLock].Next = NULLPTR;
ControlBlock->LockQueue[PfnLock].Lock = &PfnLockQueue;
ControlBlock->LockQueue[PfnLock].Next = NULLPTR;
ControlBlock->LockQueue[SystemSpaceLock].Lock = &SystemSpaceLockQueue;
ControlBlock->LockQueue[SystemSpaceLock].Next = NULLPTR;
ControlBlock->LockQueue[VacbLock].Lock = &VacbLockQueue;
ControlBlock->LockQueue[VacbLock].Next = NULLPTR;
ControlBlock->LockQueue[MasterLock].Lock = &MasterLockQueue;
ControlBlock->LockQueue[MasterLock].Next = NULLPTR;
ControlBlock->LockQueue[NonPagedAllocPoolLock].Lock = &NonPagedAllocLockQueue;
ControlBlock->LockQueue[NonPagedAllocPoolLock].Next = NULLPTR;
ControlBlock->LockQueue[IoCancelLock].Lock = &IoCancelLockQueue;
ControlBlock->LockQueue[IoCancelLock].Next = NULLPTR;
ControlBlock->LockQueue[WorkQueueLock].Lock = &WorkLockQueue;
ControlBlock->LockQueue[WorkQueueLock].Next = NULLPTR;
ControlBlock->LockQueue[IoVpbLock].Lock = &IoVpbLockQueue;
ControlBlock->LockQueue[IoVpbLock].Next = NULLPTR;
ControlBlock->LockQueue[IoDatabaseLock].Lock = &IoDatabaseLockQueue;
ControlBlock->LockQueue[IoDatabaseLock].Next = NULLPTR;
ControlBlock->LockQueue[IoCompletionLock].Lock = &IoCompletionLockQueue;
ControlBlock->LockQueue[IoCompletionLock].Next = NULLPTR;
ControlBlock->LockQueue[FileSystemLock].Lock = &FileSystemLockQueue;
ControlBlock->LockQueue[FileSystemLock].Next = NULLPTR;
ControlBlock->LockQueue[AfdWorkQueueLock].Lock = NULLPTR;
ControlBlock->LockQueue[AfdWorkQueueLock].Next = NULLPTR;
ControlBlock->LockQueue[BcbLock].Lock = NULLPTR;
ControlBlock->LockQueue[BcbLock].Next = NULLPTR;
ControlBlock->LockQueue[NonPagedPoolLock].Lock = &NonPagedPoolLockQueue;
ControlBlock->LockQueue[NonPagedPoolLock].Next = NULLPTR;
ControlBlock->LockQueue[ReservedSystemLock].Lock = NULLPTR;
ControlBlock->LockQueue[ReservedSystemLock].Next = NULLPTR;
ControlBlock->LockQueue[TimerTableLock].Lock = &TimerTableLockQueue;
ControlBlock->LockQueue[TimerTableLock].Next = NULLPTR;
}
/**
* Initializes a kernel spinlock object.
*
@@ -112,3 +185,29 @@ KE::SpinLock::ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock)
/* Add an explicit memory barrier */
AR::CpuFunc::ReadWriteBarrier();
}
/**
* Tests a kernel spin lock.
*
* @param SpinLock
* Supplies a pointer to the kernel spin lock.
*
* @return This routine returns TRUE if the lock is free, FALSE otherwise.
*
* @since XT 1.0
*/
XTFASTCALL
BOOLEAN
TestSpinLock(IN PKSPIN_LOCK SpinLock)
{
/* Check if the lock is free */
if(*SpinLock)
{
/* Spinlock is busy, yield processor and return FALSE */
AR::CpuFunc::YieldProcessor();
return FALSE;
}
/* Spinlock is free, return TRUE */
return TRUE;
}

2170
xtoskrnl/mm/alloc.cc Fichier normal

Fichier diff supprimé car celui-ci est trop grand Voir la Diff

Voir le fichier

@@ -1,25 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/mm/amd64/init.cc
* DESCRIPTION: Architecture specific Memory Manager initialization routines
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
/**
* Performs architecture specific initialization of the XTOS Memory Manager.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Init::InitializeArchitecture(VOID)
{
UNIMPLEMENTED;
}

390
xtoskrnl/mm/amd64/mmgr.cc Fichier normal
Voir le fichier

@@ -0,0 +1,390 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/mm/amd64/mmgr.cc
* DESCRIPTION: Memory Manager
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
/**
* Calculates the maximum possible size of the non-paged pool.
*
* @param PoolSize
* A pointer to a variable that will receive the number of pages available for the non-paged pool.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Manager::ComputeMaximumNonPagedPoolSize(OUT PPFN_NUMBER PoolSize)
{
ULONG_PTR MaximumNonPagedPoolSize;
/* Start with the 1MiB and add 400KiB for each MiB above 16MiB */
MaximumNonPagedPoolSize = 1048576 + (((MM::Pfn::GetNumberOfPhysicalPages() - 4096) / 256) * 409600);
/* Check if non-paged pool does not exceed 128GiB */
if(MaximumNonPagedPoolSize > 137438953472)
{
/* Limit non-paged pool size to 128GiB */
MaximumNonPagedPoolSize = 137438953472;
}
/* Return non-paged pool size */
*PoolSize = SIZE_TO_PAGES(MaximumNonPagedPoolSize);
}
/**
* Calculates the size of the non-paged pool.
*
* @param PoolSize
* A pointer to a variable that will receive the number of pages available for the non-paged pool.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Manager::ComputeNonPagedPoolSize(OUT PPFN_NUMBER PoolSize)
{
ULONG_PTR NonPagedPoolSize;
/* Start with 1MiB and add 32KiB for each MiB above 16MiB */
NonPagedPoolSize = 1048576 + (((MM::Pfn::GetNumberOfPhysicalPages() - 4096) / 256) * 32768);
/* Check if non-paged pool does not exceed 128GiB */
if(NonPagedPoolSize > 137438953472)
{
/* Limit non-paged pool size to 128GiB */
NonPagedPoolSize = 137438953472;
}
/* Return non-paged pool size in pages, aligned up to page size boundary */
*PoolSize = SIZE_TO_PAGES(ROUND_UP(NonPagedPoolSize, MM_PAGE_SIZE));
}
/**
* Calculates the size of the paged pool.
*
* @param PoolSize
* A pointer to a variable that will receive the number of pages available for the paged pool.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Manager::ComputePagedPoolSize(OUT PPFN_NUMBER PoolSize)
{
ULONGLONG PagedPoolSize, PteCount;
ULONG PtesPerPage;
/* Start with 4x maximum non-paged pool size and at least 48MiB */
ComputeMaximumNonPagedPoolSize(&PagedPoolSize);
PagedPoolSize *= 4 * MM_PAGE_SIZE;
/* Ensure that paged pool size is at least 48MiB */
if(PagedPoolSize < 50331648)
{
/* Increase paged pool size to at least 48MiB */
PagedPoolSize = 50331648;
}
/* Check if paged pool does not overlap non-paged pool */
if(PagedPoolSize > (ULONGLONG)MemoryLayout.NonPagedSystemPoolStart - (ULONGLONG)MemoryLayout.PagedPoolStart)
{
/* Limit paged pool size to maximum possible */
PagedPoolSize = (ULONGLONG)MemoryLayout.NonPagedSystemPoolStart - (ULONGLONG)MemoryLayout.PagedPoolStart;
}
/* Check if paged pool does not exceed 128GiB */
if(PagedPoolSize > 137438953472)
{
/* Limit paged pool size to 128GiB */
PagedPoolSize = 137438953472;
}
/* Get the number of PTEs per page and calculate size of paged pool */
PtesPerPage = MM::Pte::GetPtesPerPage();
PteCount = ((SIZE_TO_PAGES(PagedPoolSize) + (PtesPerPage - 1)) / PtesPerPage);
/* Return paged pool size */
*PoolSize = PteCount * PtesPerPage;
}
/**
* Calculates the size of the session space.
*
* @param SpaceSize
* A pointer to a variable that will receive the number of pages available by the session space.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Manager::ComputeSessionSpaceSize(OUT PPFN_NUMBER SpaceSize)
{
PFN_NUMBER SessionSpaceSize;
/* Session Pool, Session View, Session Image, Session Working Set and System View takes 1120MiB */
SessionSpaceSize = 1174405120;
/* Return number of pages used by the session space */
*SpaceSize = SessionSpaceSize / MM_PAGE_SIZE;
}
/**
* Calculates the size of the system PTEs.
*
* @param PteSize
* A pointer to a variable that will receive the number of system PTEs.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Manager::ComputeSystemPteSize(OUT PPFN_NUMBER PteSize)
{
PFN_NUMBER SystemPteSize;
/* Check if system has less than 24MiB of physical memory */
if(MM::Pfn::GetNumberOfPhysicalPages() < 6144)
{
/* Set minimal system PTE size */
SystemPteSize = 7000;
}
else
{
/* Use standard system PTE size */
SystemPteSize = 11000;
/* Check if system has more than 32MiB of physical memory */
if(MM::Pfn::GetNumberOfPhysicalPages() > 8192)
{
/* Double system PTE size */
SystemPteSize *= 2;
/* Check if system has more than 256MiB of physical memory */
if(MM::Pfn::GetNumberOfPhysicalPages() > 65536)
{
/* Double system PTE size */
SystemPteSize *= 2;
}
}
}
/* Return system PTE size */
*PteSize = SystemPteSize;
}
/**
* Dumps the kernel's memory layout.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Manager::DumpMemoryLayout(VOID)
{
/* Dump memory layout */
DebugPrint(L"System with %zu MiB of installed memory:\n"
L"User Space: %.16P - %.16P\n"
L"Non-Canonical: %.16P - %.16P\n"
L"Reserved System Pool: %.16P - %.16P\n"
L"PTE Space: %.16P - %.16P\n"
L"Hyper Space: %.16P - %.16P\n"
L"Shared System Page: %.16P - %.16P\n"
L"System Working Set: %.16P - %.16P\n"
L"Loader Mappings: %.16P - %.16P\n"
L"Non-Paged System Pool: %.16P - %.16P\n"
L"Paged Pool: %.16P - %.16P\n"
L"Session Space: %.16P - %.16P\n"
L"System Cache: %.16P - %.16P\n"
L"PFN Database: %.16P - %.16P\n"
L"Non-Paged Pool: %.16P - %.16P\n"
L"Non-Paged Expansion Pool: %.16P - %.16P\n"
L"Hardware Pool: %.16P - %.16P\n",
GetInstalledMemorySize(),
MemoryLayout.UserSpaceStart,
MemoryLayout.UserSpaceEnd,
MemoryLayout.NonCanonicalStart,
MemoryLayout.NonCanonicalEnd,
MemoryLayout.ReservedSystemPoolStart,
MemoryLayout.ReservedSystemPoolEnd,
MemoryLayout.PteSpaceStart,
MemoryLayout.PteSpaceEnd,
MemoryLayout.HyperSpaceStart,
MemoryLayout.HyperSpaceEnd,
MemoryLayout.SharedSystemPageStart,
MemoryLayout.SharedSystemPageEnd,
MemoryLayout.SystemWorkingSetStart,
MemoryLayout.SystemWorkingSetEnd,
MemoryLayout.LoaderMappingsStart,
MemoryLayout.LoaderMappingsEnd,
MemoryLayout.NonPagedSystemPoolStart,
MemoryLayout.NonPagedSystemPoolEnd,
MemoryLayout.PagedPoolStart,
MemoryLayout.PagedPoolEnd,
MemoryLayout.SessionSpaceStart,
MemoryLayout.SessionSpaceEnd,
MemoryLayout.SystemCacheStart,
MemoryLayout.SystemCacheEnd,
MemoryLayout.PfnDatabase,
(PVOID)((ULONG_PTR)MemoryLayout.PfnDatabase + (ULONG_PTR)MemoryLayout.PfnDatabaseSize * MM_PAGE_SIZE),
MemoryLayout.NonPagedPoolStart,
MemoryLayout.NonPagedPoolEnd,
MemoryLayout.NonPagedExpansionPoolStart,
MemoryLayout.NonPagedExpansionPoolEnd,
MemoryLayout.HardwarePoolStart,
MemoryLayout.HardwarePoolEnd);
}
/**
* Initializes the kernel's virtual memory layout.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Manager::InitializeMemoryLayout(VOID)
{
PFN_NUMBER MaximumNonPagedPoolSize;
ULONG_PTR PfnDatabaseEnd;
/* Check if 5-level paging (LA57) is enabled */
if(MM::Paging::GetXpaStatus())
{
/* Set PML5 base address */
MemoryLayout.SelfMapAddress = (PVOID)MM_P5E_LA57_BASE;
/* Define memory layout for 5-level paging */
MemoryLayout.UserSpaceStart = (PVOID)0x0000000000010000;
MemoryLayout.UserSpaceEnd = (PVOID)0x00FFFFFFFFFEFFFF;
MemoryLayout.NonCanonicalStart = (PVOID)0x0080000000000000;
MemoryLayout.NonCanonicalEnd = (PVOID)0xFEFFFFFFFFFFFFFF;
MemoryLayout.ReservedSystemPoolStart = (PVOID)0xFF00000000000000;
MemoryLayout.ReservedSystemPoolEnd = (PVOID)0xFFECFFFFFFFFFFFF;
MemoryLayout.PteSpaceStart = (PVOID)0xFFED000000000000;
MemoryLayout.PteSpaceEnd = (PVOID)0xFFEDFFFFFFFFFFFF;
MemoryLayout.HyperSpaceStart = (PVOID)0xFFFFF70000000000;
MemoryLayout.HyperSpaceEnd = (PVOID)0xFFFFF77FFFFFFFFF;
MemoryLayout.SharedSystemPageStart = (PVOID)0xFFFFF78000000000;
MemoryLayout.SharedSystemPageEnd = (PVOID)0xFFFFF78000000FFF;
MemoryLayout.SystemWorkingSetStart = (PVOID)0xFFFFF78000001000;
MemoryLayout.SystemWorkingSetEnd = (PVOID)0xFFFFF7FFFFFFFFFF;
MemoryLayout.LoaderMappingsStart = (PVOID)0xFFFFF80000000000;
MemoryLayout.LoaderMappingsEnd = (PVOID)0xFFFFF87FFFFFFFFF;
MemoryLayout.NonPagedSystemPoolStart = (PVOID)0xFFFFF88000000000;
MemoryLayout.NonPagedSystemPoolEnd = (PVOID)0xFFFFF89FFFFFFFFF;
MemoryLayout.PagedPoolStart = (PVOID)0xFFFFF8A000000000;
MemoryLayout.PagedPoolEnd = (PVOID)0xFFFFF8BFFFFFFFFF;
MemoryLayout.SessionSpaceStart = (PVOID)0xFFFFF90000000000;
MemoryLayout.SessionSpaceEnd = (PVOID)0xFFFFF98000000000;
MemoryLayout.SystemCacheStart = (PVOID)0xFFFFF98000000000;
MemoryLayout.SystemCacheEnd = (PVOID)0xFFFFFA7FFFFFFFFF;
MemoryLayout.NonPagedPoolStart = (PVOID)0xFFFFFA8000000000;
MemoryLayout.NonPagedPoolEnd = (PVOID)0xFFFFFFFFFFBFFFFF;
MemoryLayout.HardwarePoolStart = (PVOID)0xFFFFFFFFFFC00000;
MemoryLayout.HardwarePoolEnd = (PVOID)0xFFFFFFFFFFFFFFFF;
}
else
{
/* Set PML4 base address */
MemoryLayout.SelfMapAddress = (PVOID)MM_PXE_BASE;
/* Define memory layout for 4-level paging */
MemoryLayout.UserSpaceStart = (PVOID)0x0000000000010000;
MemoryLayout.UserSpaceEnd = (PVOID)0x000007FFFFFEFFFF;
MemoryLayout.NonCanonicalStart = (PVOID)0x0000800000000000;
MemoryLayout.NonCanonicalEnd = (PVOID)0xFFFF7FFFFFFFFFFF;
MemoryLayout.ReservedSystemPoolStart = (PVOID)0xFFFF800000000000;
MemoryLayout.ReservedSystemPoolEnd = (PVOID)0xFFFFF67FFFFFFFFF;
MemoryLayout.PteSpaceStart = (PVOID)0xFFFFF68000000000;
MemoryLayout.PteSpaceEnd = (PVOID)0xFFFFF6FFFFFFFFFF;
MemoryLayout.HyperSpaceStart = (PVOID)0xFFFFF70000000000;
MemoryLayout.HyperSpaceEnd = (PVOID)0xFFFFF77FFFFFFFFF;
MemoryLayout.SharedSystemPageStart = (PVOID)0xFFFFF78000000000;
MemoryLayout.SharedSystemPageEnd = (PVOID)0xFFFFF78000000FFF;
MemoryLayout.SystemWorkingSetStart = (PVOID)0xFFFFF78000001000;
MemoryLayout.SystemWorkingSetEnd = (PVOID)0xFFFFF7FFFFFFFFFF;
MemoryLayout.LoaderMappingsStart = (PVOID)0xFFFFF80000000000;
MemoryLayout.LoaderMappingsEnd = (PVOID)0xFFFFF87FFFFFFFFF;
MemoryLayout.NonPagedSystemPoolStart = (PVOID)0xFFFFF88000000000;
MemoryLayout.NonPagedSystemPoolEnd = (PVOID)0xFFFFF89FFFFFFFFF;
MemoryLayout.PagedPoolStart = (PVOID)0xFFFFF8A000000000;
MemoryLayout.PagedPoolEnd = (PVOID)0xFFFFF8BFFFFFFFFF;
MemoryLayout.SessionSpaceStart = (PVOID)0xFFFFF90000000000;
MemoryLayout.SessionSpaceEnd = (PVOID)0xFFFFF98000000000;
MemoryLayout.SystemCacheStart = (PVOID)0xFFFFF98000000000;
MemoryLayout.SystemCacheEnd = (PVOID)0xFFFFFA7FFFFFFFFF;
MemoryLayout.NonPagedPoolStart = (PVOID)0xFFFFFA8000000000;
MemoryLayout.NonPagedPoolEnd = (PVOID)0xFFFFFFFFFFBFFFFF;
MemoryLayout.HardwarePoolStart = (PVOID)0xFFFFFFFFFFC00000;
MemoryLayout.HardwarePoolEnd = (PVOID)0xFFFFFFFFFFFFFFFF;
}
/* Compute allocation size for the PFN database */
MM::Pfn::ComputePfnDatabaseSize(&MemoryLayout.PfnDatabaseSize);
/* Compute boot image size */
ComputeBootImageSize(&MemoryLayout.LoaderMappingsSize);
/* Compute session space size */
ComputeSessionSpaceSize(&MemoryLayout.SessionSpaceSize);
/* Update loader mappings space end address */
MemoryLayout.LoaderMappingsEnd = (PVOID)((ULONGLONG)MemoryLayout.LoaderMappingsStart +
MemoryLayout.LoaderMappingsSize * MM_PAGE_SIZE);
/* Update session space start address */
MemoryLayout.SessionSpaceStart = (PVOID)((ULONGLONG)MemoryLayout.SessionSpaceEnd -
MemoryLayout.SessionSpaceSize * MM_PAGE_SIZE);
/* Compute system PTE size */
ComputeSystemPteSize(&NumberOfSystemPtes);
/* Compute non-paged pool size */
ComputeNonPagedPoolSize(&MemoryLayout.NonPagedPoolSize);
ComputeMaximumNonPagedPoolSize(&MaximumNonPagedPoolSize);
/* Compute paged pool size */
ComputePagedPoolSize(&MemoryLayout.PagedPoolSize);
/* Insert the PFN database at the beginning of the non-paged pool */
MemoryLayout.PfnDatabase = (PMMPFN)MemoryLayout.NonPagedPoolStart;
/* Compute the PFN database page-aligned end address */
PfnDatabaseEnd = (ULONGLONG)MemoryLayout.PfnDatabase + (MemoryLayout.PfnDatabaseSize * MM_PAGE_SIZE);
PfnDatabaseEnd = ROUND_UP(PfnDatabaseEnd, MM_PAGE_SIZE);
/* Shrink the non-paged pool to fit the PFN database */
MemoryLayout.NonPagedPoolStart = (PVOID)PfnDatabaseEnd;
/* Assign the rest of the non-paged pool to the expansion pool */
MemoryLayout.NonPagedExpansionPoolStart = (PVOID)((ULONGLONG)MemoryLayout.NonPagedPoolStart +
MemoryLayout.NonPagedPoolSize * MM_PAGE_SIZE);
MemoryLayout.NonPagedPoolEnd = MemoryLayout.NonPagedExpansionPoolStart;
MemoryLayout.NonPagedExpansionPoolEnd = (PVOID)((ULONGLONG)MemoryLayout.NonPagedPoolStart +
MaximumNonPagedPoolSize * MM_PAGE_SIZE);
MemoryLayout.NonPagedExpansionPoolSize = ((ULONGLONG)MemoryLayout.NonPagedExpansionPoolEnd -
(ULONGLONG)MemoryLayout.NonPagedExpansionPoolStart) / MM_PAGE_SIZE;
/* Update paged pool end address */
MemoryLayout.PagedPoolEnd = (PVOID)(((ULONGLONG)MemoryLayout.PagedPoolStart +
MemoryLayout.PagedPoolSize * MM_PAGE_SIZE) - 1);
}

Voir le fichier

@@ -9,6 +9,51 @@
#include <xtos.hh>
/**
* Advances a PTE pointer by a given number of entries, considering the actual PTE size.
*
* @param Pte
* The PTE pointer to advance.
*
* @param Count
* The number of PTE entries to advance by.
*
* @return The advanced PTE pointer.
*
* @since XT 1.0
*/
XTAPI
PMMPTE
MM::PageMap::AdvancePte(IN PMMPTE Pte,
IN LONG Count)
{
/* Return advanced PTE pointer */
return (PMMPTE)((ULONG_PTR)Pte + (Count * sizeof(MMPTE)));
}
/**
* Checks if the given address is canonical.
*
* @param VirtualAddress
* Specifies the virtual address to check.
*
* @return This routine returns TRUE if the address is canonical, FALSE otherwise.
*
* @since XT 1.0
*/
XTAPI
BOOLEAN
MM::PageMap::CanonicalAddress(IN PVOID VirtualAddress)
{
ULONG Shift;
/* Calculate the number of unused upper bits based on the paging mode */
Shift = 64 - PageMapInfo.VaBits;
/* Sign-extend via arithmetic shifts to verify the canonical form */
return ((((LONGLONG)VirtualAddress << Shift) >> Shift) == (LONGLONG)VirtualAddress);
}
/**
* Clears the contents of a page table entry (PTE).
*
@@ -21,13 +66,64 @@
*/
XTAPI
VOID
MM::PageMap::ClearPte(PHARDWARE_PTE PtePointer)
MM::PageMap::ClearPte(IN PMMPTE PtePointer)
{
PtePointer->CacheDisable = 0;
PtePointer->PageFrameNumber = 0;
PtePointer->Valid = 0;
PtePointer->Writable = 0;
PtePointer->WriteThrough = 0;
/* Clear PTE */
PtePointer->Long = 0;
}
/**
* Gets the next entry in a PTE list.
*
* @param Pte
* The PTE pointer to get the next entry from.
*
* @return This routine returns the next entry in the PTE list.
*
* @since XT 1.0
*/
XTAPI
ULONG_PTR
MM::PageMap::GetNextEntry(IN PMMPTE Pte)
{
/* Return next entry in PTE list */
return Pte->List.NextEntry;
}
/**
* Advances a PTE pointer, considering the actual PTE size.
*
* @param Pte
* The PTE pointer to advance.
*
* @return The advanced PTE pointer.
*
* @since XT 1.0
*/
XTAPI
PMMPTE
MM::PageMap::GetNextPte(IN PMMPTE Pte)
{
/* Return advanced PTE pointer */
return AdvancePte(Pte, 1);
}
/**
* Checks if a PTE list contains only one entry.
*
* @param Pte
* The PTE pointer to check.
*
* @return This routine returns TRUE if the PTE list has only one entry, FALSE otherwise.
*
* @since XT 1.0
*/
XTAPI
BOOLEAN
MM::PageMap::GetOneEntry(IN PMMPTE Pte)
{
/* Return one entry status */
return Pte->List.OneEntry;
}
/**
@@ -42,7 +138,7 @@ MM::PageMap::ClearPte(PHARDWARE_PTE PtePointer)
*/
XTAPI
PMMP5E
MM::PageMap::GetP5eAddress(PVOID Address)
MM::PageMap::GetP5eAddress(IN PVOID Address)
{
ULONGLONG Offset;
@@ -51,6 +147,72 @@ MM::PageMap::GetP5eAddress(PVOID Address)
return (PMMP5E)((PageMapInfo.P5eBase + Offset) * PageMapInfo.Xpa);
}
/**
* Gets the Offset of the P5E (Page Map Level 5 Entry), that maps given address.
*
* @param Address
* Specifies the virtual address for which to retrieve the corresponding P5E.
*
* @return This routine returns the Offset of the P5E, or NULLPTR if LA57 is not enabled.
*
* @since XT 1.0
*/
XTAPI
ULONG
MM::PageMap::GetP5eOffset(IN PVOID Address)
{
/* Return P5E Offset */
return (((((ULONGLONG)Address) >> MM_P5I_SHIFT) & 0x1FF) * PageMapInfo.Xpa);
}
/**
* Gets the virtual address that is mapped by a given Page Map Level 5 Entry.
*
* @param P5ePointer
* Specifies the address of the P5E.
*
* @return This routine returns the virtual address mapped by the P5E, or NULLPTR if LA57 is not enabled.
*
* @since XT 1.0
*/
XTAPI
PVOID
MM::PageMap::GetP5eVirtualAddress(IN PMMP5E P5ePointer)
{
return (PVOID)((((LONGLONG)P5ePointer << 52) >> 7) * PageMapInfo.Xpa);
}
/**
* Gets the page frame number from a corresponding PTE.
*
* @param Pte
* The PTE pointer to get the page frame number from.
*
* @return This routine returns the page frame number.
*
* @since XT 1.0
*/
XTAPI
PFN_NUMBER
MM::PageMap::GetPageFrameNumber(IN PMMPTE Pte)
{
return Pte->Hardware.PageFrameNumber;
}
/**
* Gets Page Map Level (PML) for current paging mode.
*
* @return This routine returns the page map level.
*
* @since XT 1.0
*/
XTAPI
USHORT
MM::PageMap::GetPageMapLevel()
{
return PageMapInfo.Xpa ? 5 : 4;
}
/**
* Gets the address of the PDE (Page Directory Entry), that maps given address.
*
@@ -63,7 +225,7 @@ MM::PageMap::GetP5eAddress(PVOID Address)
*/
XTAPI
PMMPDE
MM::PageMap::GetPdeAddress(PVOID Address)
MM::PageMap::GetPdeAddress(IN PVOID Address)
{
ULONGLONG Offset;
@@ -73,18 +235,36 @@ MM::PageMap::GetPdeAddress(PVOID Address)
}
/**
* Gets the address of the PPE (Page Directory Pointer Table Entry), that maps given address.
* Gets the Offset of the PDE (Page Directory Entry), that maps given address.
*
* @param Address
* Specifies the virtual address for which to retrieve the corresponding PDE.
*
* @return This routine returns the Offset of the PDE.
*
* @since XT 1.0
*/
XTAPI
ULONG
MM::PageMap::GetPdeOffset(IN PVOID Address)
{
/* Return PDE Offset */
return ((((ULONGLONG)Address) >> MM_PDI_SHIFT) & 0x1FF);
}
/**
* Gets the address of the PPE (Page Directory Pointer Table Entry), that maps given address.
*
* @param Address
* Specifies the virtual address for which to retrieve the corresponding PPE.
*
* @return This routine returns the address of the PPE.
*
* @since XT 1.0
*/
XTAPI
PMMPPE
MM::PageMap::GetPpeAddress(PVOID Address)
MM::PageMap::GetPpeAddress(IN PVOID Address)
{
ULONGLONG Offset;
@@ -93,6 +273,42 @@ MM::PageMap::GetPpeAddress(PVOID Address)
return (PMMPPE)(PageMapInfo.PpeBase + Offset);
}
/**
* Gets the Offset of the PPE (Page Directory Pointer Table Entry), that maps given address.
*
* @param Address
* Specifies the virtual address for which to retrieve the corresponding PPE.
*
* @return This routine returns the Offset of the PPE.
*
* @since XT 1.0
*/
XTAPI
ULONG
MM::PageMap::GetPpeOffset(IN PVOID Address)
{
/* Return PPE Offset */
return ((((ULONGLONG)Address) >> MM_PPI_SHIFT) & 0x1FF);
}
/**
* Gets the entire contents of a Page Table Entry (PTE) as a single value.
*
* @param PtePointer
* Pointer to the Page Table Entry (PTE) to read.
*
* @return This routine returns the contents of the PTE as a single value.
*
* @since XT 1.0
*/
XTAPI
ULONGLONG
MM::PageMap::GetPte(IN PMMPTE PtePointer)
{
/* Return PTE value */
return PtePointer->Long;
}
/**
* Gets the address of the PTE (Page Table Entry), that maps given address.
*
@@ -105,7 +321,7 @@ MM::PageMap::GetPpeAddress(PVOID Address)
*/
XTAPI
PMMPTE
MM::PageMap::GetPteAddress(PVOID Address)
MM::PageMap::GetPteAddress(IN PVOID Address)
{
ULONGLONG Offset;
@@ -114,6 +330,115 @@ MM::PageMap::GetPteAddress(PVOID Address)
return (PMMPTE)(PageMapInfo.PteBase + Offset);
}
/**
* Calculates the distance between two PTE pointers.
*
* @param EndPte
* Pointer to the ending Page Table Entry.
*
* @param StartPte
* Pointer to the starting Page Table Entry.
*
* @return This routine returns a signed value representing the number of PTEs between EndPte and StartPte.
*
* @since XT 1.0
*/
XTAPI
LONG
MM::PageMap::GetPteDistance(PMMPTE EndPte,
PMMPTE StartPte)
{
/* Return distance between PTE pointers */
return ((ULONG_PTR)EndPte - (ULONG_PTR)StartPte) / sizeof(MMPTE);
}
/**
* Gets the Offset of the PTE (Page Table Entry), that maps given address.
*
* @param Address
* Specifies the virtual address for which to retrieve the corresponding PTE.
*
* @return This routine returns the Offset of the PTE.
*
* @since XT 1.0
*/
XTAPI
ULONG
MM::PageMap::GetPteOffset(IN PVOID Address)
{
/* Return PTE Offset */
return ((((ULONGLONG)Address) >> MM_PTI_SHIFT) & 0x1FF);
}
/**
* Gets the size of a PTE.
*
* @return This routine returns the size of a PTE.
*
* @since XT 1.0
*/
XTAPI
ULONG
MM::PageMap::GetPteSize(VOID)
{
/* Return the size of MMPTE */
return sizeof(MMPTE);
}
/**
* Gets the software protection value of the corresponding Page Table Entry.
*
* @param PtePointer
* Specifies the address of the PTE.
*
* @return This routine returns the PTE software protection value.
*
* @since XT 1.0
*/
XTAPI
ULONG
MM::PageMap::GetPteSoftwareProtection(IN PMMPTE PtePointer)
{
/* Return PTE software protection value */
return (ULONG)PtePointer->Software.Protection;
}
/**
* Gets the software prototype value of the corresponding Page Table Entry.
*
* @param PtePointer
* Specifies the address of the PTE.
*
* @return This routine returns the PTE software prototype value.
*
* @since XT 1.0
*/
XTAPI
ULONG
MM::PageMap::GetPteSoftwarePrototype(IN PMMPTE PtePointer)
{
/* Return PTE software prototype value */
return (ULONG)PtePointer->Software.Prototype;
}
/**
* Gets the software transition value of the corresponding Page Table Entry.
*
* @param PtePointer
* Specifies the address of the PTE.
*
* @return This routine returns the PTE software transition value.
*
* @since XT 1.0
*/
XTAPI
ULONG
MM::PageMap::GetPteSoftwareTransition(IN PMMPTE PtePointer)
{
/* Return PTE software transition value */
return (ULONG)PtePointer->Software.Transition;
}
/**
* Gets the address of the PXE (Extended Page Entry), that maps given address.
*
@@ -126,14 +451,47 @@ MM::PageMap::GetPteAddress(PVOID Address)
*/
XTAPI
PMMPXE
MM::PageMap::GetPxeAddress(PVOID Address)
MM::PageMap::GetPxeAddress(IN PVOID Address)
{
ULONGLONG Offset;
/* Calculate offset and return PXE address */
Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << PageMapInfo.VaBits) - 1)) >> MM_PXI_SHIFT) << MM_PTE_SHIFT);
return (PMMPXE)(PageMapInfo.PxeBase + Offset);
}
/**
* Gets the Offset of the PXE (Extended Page Entry), that maps given address.
*
* @param Address
* Specifies the virtual address for which to retrieve the corresponding PXE.
*
* @return This routine returns the Offset of the PXE.
*
* @since XT 1.0
*/
XTAPI
ULONG
MM::PageMap::GetPxeOffset(IN PVOID Address)
{
/* Return PXE Offset */
return ((((ULONGLONG)Address) >> MM_PXI_SHIFT) & 0x1FF);
}
/**
* Gets the status of Extended Paging Address (XPA) mode.
*
* @return This routine returns TRUE if XPA is enabled, FALSE otherwise.
*
* @since XT 1.0
*/
XTAPI
BOOLEAN
MM::PageMap::GetXpaStatus()
{
return PageMapInfo.Xpa;
}
/**
* Checks whether the given PML2 page table entry (PTE) is valid.
*
@@ -146,22 +504,20 @@ MM::PageMap::GetPxeAddress(PVOID Address)
*/
XTAPI
BOOLEAN
MM::PageMap::PteValid(PHARDWARE_PTE PtePointer)
MM::PageMap::PteValid(IN PMMPTE PtePointer)
{
return (BOOLEAN)PtePointer->Valid;
/* Check if PTE is valid */
return (BOOLEAN)PtePointer->Hardware.Valid;
}
/**
* Sets a PML2 page table entry (PTE) with the specified physical page and access flags.
* Sets the next entry in a PTE list.
*
* @param PtePointer
* Pointer to the page table entry (PTE) to set.
* @param Pte
* The PTE pointer to modify.
*
* @param PageFrameNumber
* Physical frame number to map.
*
* @param Writable
* Indicates whether the page should be writable.
* @param Value
* The value to set as the next entry.
*
* @return This routine does not return any value.
*
@@ -169,13 +525,82 @@ MM::PageMap::PteValid(PHARDWARE_PTE PtePointer)
*/
XTAPI
VOID
MM::PageMap::SetPte(PHARDWARE_PTE PtePointer,
PFN_NUMBER PageFrameNumber,
BOOLEAN Writable)
MM::PageMap::SetNextEntry(IN PMMPTE Pte,
IN ULONG_PTR Value)
{
PtePointer->PageFrameNumber = PageFrameNumber;
PtePointer->Valid = 1;
PtePointer->Writable = Writable;
/* Set next entry in PTE list */
Pte->List.NextEntry = Value;
}
/**
* Sets the flag indicating whether a PTE list contains only one entry.
*
* @param Pte
* The PTE pointer to modify.
*
* @param Value
* The value to set. TRUE if the list has only one entry, FALSE otherwise.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::PageMap::SetOneEntry(IN PMMPTE Pte,
IN BOOLEAN Value)
{
/* Set one entry status */
Pte->List.OneEntry = Value;
}
/**
* Sets a Page Table Entry (PTE) with the specified physical page and access flags.
*
* @param PtePointer
* Pointer to the page table entry (PTE) to set.
*
* @param PageFrameNumber
* Physical frame number to map.
*
* @param AttributesMask
* Specifies the attributes mask to apply to the PTE.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::PageMap::SetPte(IN PMMPTE PtePointer,
IN PFN_NUMBER PageFrameNumber,
IN ULONGLONG AttributesMask)
{
/* Set PTE */
PtePointer->Hardware.PageFrameNumber = PageFrameNumber;
PtePointer->Hardware.Valid = 1;
PtePointer->Long |= AttributesMask;
}
/**
* Sets a Page Table Entry (PTE) with the specified attributes.
*
* @param PtePointer
* Pointer to the page table entry (PTE) to set.
*
* @param Attributes
* Specifies the attributes to apply to the PTE.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::PageMap::SetPte(IN PMMPTE PtePointer,
IN ULONGLONG Attributes)
{
PtePointer->Long = Attributes;
}
/**
@@ -196,12 +621,138 @@ MM::PageMap::SetPte(PHARDWARE_PTE PtePointer,
*/
XTAPI
VOID
MM::PageMap::SetPteCaching(PHARDWARE_PTE PtePointer,
BOOLEAN CacheDisable,
BOOLEAN WriteThrough)
MM::PageMap::SetPteCaching(IN PMMPTE PtePointer,
IN BOOLEAN CacheDisable,
IN BOOLEAN WriteThrough)
{
PtePointer->CacheDisable = CacheDisable;
PtePointer->WriteThrough = WriteThrough;
/* Set caching attributes */
PtePointer->Hardware.CacheDisable = CacheDisable;
PtePointer->Hardware.WriteThrough = WriteThrough;
}
/**
* Transitions a Page Table Entry (PTE) to invalid state
*
* @param PointerPte
* Pointer to the page table entry (PTE) to transition.
*
* @param Protection
* Specifies the protection attribute to apply to the PTE.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::PageMap::TransitionPte(IN PMMPTE PointerPte,
IN ULONG_PTR Protection)
{
MMPTE TempPte;
/* Set transition PTE */
TempPte = *PointerPte;
TempPte.Software.Protection = Protection;
TempPte.Software.Prototype = 0;
TempPte.Software.Transition = 1;
TempPte.Software.Valid = 0;
/* Write PTE value */
*PointerPte = TempPte;
}
/**
* Writes a Page Table Entry (PTE) with the specified value.
*
* @param Pte
* Pointer to the page table entry (PTE) to write.
*
* @param Value
* The value to write to the PTE.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::PageMap::WritePte(IN PMMPTE Pte,
IN MMPTE Value)
{
/* Write PTE value */
Pte->Long = Value.Long;
}
/**
* Gets the virtual address that is mapped by a given Page Directory Entry (PML4).
*
* @param PdePointer
* Specifies the address of the PDE.
*
* @return This routine returns the virtual address mapped by the PDE.
*
* @since XT 1.0
*/
XTAPI
PVOID
MM::PageMapBasic::GetPdeVirtualAddress(IN PMMPDE PdePointer)
{
/* Return PDE virtual address */
return (PVOID)(((LONGLONG)PdePointer << 34) >> 16);
}
/**
* Gets the virtual address that is mapped by a given Page Directory Pointer Table Entry (PML4).
*
* @param PpePointer
* Specifies the address of the PPE.
*
* @return This routine returns the virtual address mapped by the PPE.
*
* @since XT 1.0
*/
XTAPI
PVOID
MM::PageMapBasic::GetPpeVirtualAddress(IN PMMPPE PpePointer)
{
/* Return PPE virtual address */
return (PVOID)(((LONGLONG)PpePointer << 43) >> 16);
}
/**
* Gets the virtual address that is mapped by a given Page Table Entry (PML4).
*
* @param PtePointer
* Specifies the address of the PTE.
*
* @return This routine returns the virtual address mapped by the PTE.
*
* @since XT 1.0
*/
XTAPI
PVOID
MM::PageMapBasic::GetPteVirtualAddress(IN PMMPTE PtePointer)
{
/* Return PTE virtual address */
return (PVOID)(((LONGLONG)PtePointer << 25) >> 16);
}
/**
* Gets the virtual address that is mapped by a given Extended Page Entry (PML4).
*
* @param PxePointer
* Specifies the address of the PXE.
*
* @return This routine returns the virtual address mapped by the PXE.
*
* @since XT 1.0
*/
XTAPI
PVOID
MM::PageMapBasic::GetPxeVirtualAddress(IN PMMPXE PxePointer)
{
/* Return PXE virtual address */
return (PVOID)(((LONGLONG)PxePointer << 52) >> 16);
}
/**
@@ -229,6 +780,78 @@ MM::PageMapBasic::InitializePageMapInfo(VOID)
PageMapInfo.VaBits = 48;
}
/**
* Gets the virtual address that is mapped by a given Page Directory Entry (PML5).
*
* @param PdePointer
* Specifies the address of the PDE.
*
* @return This routine returns the virtual address mapped by the PDE.
*
* @since XT 1.0
*/
XTAPI
PVOID
MM::PageMapXpa::GetPdeVirtualAddress(IN PMMPDE PdePointer)
{
/* Return PDE virtual address */
return (PVOID)(((LONGLONG)PdePointer << 25) >> 7);
}
/**
* Gets the virtual address that is mapped by a given Page Directory Pointer Table Entry (PML5).
*
* @param PpePointer
* Specifies the address of the PPE.
*
* @return This routine returns the virtual address mapped by the PPE.
*
* @since XT 1.0
*/
XTAPI
PVOID
MM::PageMapXpa::GetPpeVirtualAddress(IN PMMPPE PpePointer)
{
/* Return PPE virtual address */
return (PVOID)(((LONGLONG)PpePointer << 34) >> 7);
}
/**
* Gets the virtual address that is mapped by a given Page Table Entry (PML5).
*
* @param PtePointer
* Specifies the address of the PTE.
*
* @return This routine returns the virtual address mapped by the PTE.
*
* @since XT 1.0
*/
XTAPI
PVOID
MM::PageMapXpa::GetPteVirtualAddress(IN PMMPTE PtePointer)
{
/* Return PTE virtual address */
return (PVOID)(((LONGLONG)PtePointer << 16) >> 7);
}
/**
* Gets the virtual address that is mapped by a given Extended Page Entry (PML5).
*
* @param PxePointer
* Specifies the address of the PXE.
*
* @return This routine returns the virtual address mapped by the PXE.
*
* @since XT 1.0
*/
XTAPI
PVOID
MM::PageMapXpa::GetPxeVirtualAddress(IN PMMPXE PxePointer)
{
/* Return PXE virtual address */
return (PVOID)(((LONGLONG)PxePointer << 43) >> 7);
}
/**
* Initializes page map information for XPA paging (PML5).
*

Voir le fichier

@@ -25,6 +25,78 @@ MM::Paging::GetExtendedPhysicalAddressingStatus(VOID)
return ((AR::CpuFunc::ReadControlRegister(4) & CR4_LA57) != 0) ? TRUE : FALSE;
}
/**
* Gets the address of the P5E (Page Map Level 5 Entry), that maps given address.
*
* @param Address
* Specifies the virtual address for which to retrieve the corresponding P5E.
*
* @return This routine returns the address of the P5E, or NULLPTR if LA57 is not enabled.
*
* @since XT 1.0
*/
XTAPI
PMMP5E
MM::Paging::GetP5eAddress(IN PVOID Address)
{
/* Return PDE address */
return PmlRoutines->GetP5eAddress(Address);
}
/**
* Gets the virtual address that is mapped by a given Page Map Level 5 Entry.
*
* @param P5ePointer
* Specifies the address of the P5E.
*
* @return This routine returns the virtual address mapped by the P5E, or NULLPTR if LA57 is not enabled.
*
* @since XT 1.0
*/
XTAPI
PVOID
MM::Paging::GetP5eVirtualAddress(IN PMMP5E P5ePointer)
{
/* Return PTE virtual address */
return PmlRoutines->GetP5eVirtualAddress(P5ePointer);
}
/**
* Gets the address of the PXE (Extended Page Entry), that maps given address.
*
* @param Address
* Specifies the virtual address for which to retrieve the corresponding PXE.
*
* @return This routine returns the address of the PXE.
*
* @since XT 1.0
*/
XTAPI
PMMPXE
MM::Paging::GetPxeAddress(IN PVOID Address)
{
/* Return PXE address */
return PmlRoutines->GetPxeAddress(Address);
}
/**
* Gets the virtual address that is mapped by a given Extended Page Entry.
*
* @param PxePointer
* Specifies the address of the PXE.
*
* @return This routine returns the virtual address mapped by the PXE.
*
* @since XT 1.0
*/
XTAPI
PVOID
MM::Paging::GetPxeVirtualAddress(IN PMMPXE PxePointer)
{
/* Return PXE virtual address */
return PmlRoutines->GetPxeVirtualAddress(PxePointer);
}
/**
* Fills a section of memory with zeroes like RtlZeroMemory(), but in more efficient way.
*

26
xtoskrnl/mm/amd64/pfault.cc Fichier normal
Voir le fichier

@@ -0,0 +1,26 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/mm/amd64/pfault.cc
* DESCRIPTION: Page fault support for AMD64 architecture
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
/**
* Evaluates the PDE for for paged pool and per-session mappings.
*
* @param VirtualAddress
* Specifies the virtual address to verify.
*
* @return This routine returns ACCESS_VIOLATION regardless PML4 or PML5 is used.
*/
XTFASTCALL
XTSTATUS
MM::PageFault::CheckPdeForPagedPool(IN PVOID VirtualAddress)
{
/* Return access violation */
return STATUS_ACCESS_VIOLATION;
}

345
xtoskrnl/mm/amd64/pfn.cc Fichier normal
Voir le fichier

@@ -0,0 +1,345 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/mm/amd64/pfn.cc
* DESCRIPTION: Physical Frame Number for AMD64 support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
* Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.hh>
/**
* Allocates and initializes page directory structures for a range of PDEs.
*
* @param StartingPde
* Supplies a pointer to the first PDE in the range to initialize.
*
* @param EndingPde
* Supplies a pointer to the last PDE in the range to initialize.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Pfn::InitializePageDirectory(IN PMMPDE StartingPde,
IN PMMPDE EndingPde)
{
PMMPTE ParentPte, ValidPte;
BOOLEAN PteValidated;
/* Get a template PTE for mapping the PFN database pages */
ValidPte = MM::Pte::GetValidPte();
/* Initialize validation flag */
PteValidated = FALSE;
/* Iterate through the range of PDEs to ensure the paging hierarchy is fully mapped */
while(StartingPde <= EndingPde)
{
/* Check if there is a need to validate upper-level page table entries */
if(!PteValidated || ((ULONG_PTR)StartingPde & (MM_PAGE_SIZE - 1)) == 0)
{
/* For LA57, ensure PML5 entry exists */
if(MM::Paging::GetXpaStatus())
{
/* Get the P5E that maps the PXE page containing this hierarchy */
ParentPte = MM::Paging::GetPpeAddress(StartingPde);
/* Check if P5E entry is valid */
if(!MM::Paging::PteValid(ParentPte))
{
/* Allocate a new PML4 page and map P5E to it */
MM::Paging::SetPte(ValidPte, AllocateBootstrapPages(1), 0);
*ParentPte = *ValidPte;
/* Clear the newly created page */
RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(ParentPte), MM_PAGE_SIZE);
}
}
/* Get the PXE that maps the PPE page containing PDE */
ParentPte = MM::Paging::GetPdeAddress(StartingPde);
/* Check if PXE entry is valid */
if(!MM::Paging::PteValid(ParentPte))
{
/* Allocate a new PPE page and map PXE to it */
MM::Paging::SetPte(ValidPte, AllocateBootstrapPages(1), 0);
*ParentPte = *ValidPte;
/* Clear the newly created page */
RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(ParentPte), MM_PAGE_SIZE);
}
/* Get the PPE that maps the PDE page containing PTE */
ParentPte = MM::Paging::GetPteAddress(StartingPde);
/* Check if PPE entry is valid */
if(!MM::Paging::PteValid(ParentPte))
{
/* Allocate a new PDE page and map PPE to it */
MM::Paging::SetPte(ValidPte, AllocateBootstrapPages(1), 0);
*ParentPte = *ValidPte;
/* Clear the newly created page */
RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(ParentPte), MM_PAGE_SIZE);
}
/* Upper levels for this PDE have been validated */
PteValidated = TRUE;
}
/* Ensure the PDE has a PTE page allocated */
if(!MM::Paging::PteValid(StartingPde))
{
/* Allocate a new PTE page and map PDE to it */
MM::Paging::SetPte(ValidPte, AllocateBootstrapPages(1), 0);
*StartingPde = *ValidPte;
/* Clear the newly created page */
RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(StartingPde), MM_PAGE_SIZE);
}
/* Move to the next PDE */
StartingPde = MM::Paging::GetNextPte(StartingPde);
}
}
/**
* Initializes the PFN database by mapping virtual memory and populating entries.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Pfn::InitializePfnDatabase(VOID)
{
PKERNEL_INITIALIZATION_BLOCK InitializationBlock;
PLIST_ENTRY ListEntry;
PLOADER_MEMORY_DESCRIPTOR Descriptor;
PUCHAR PfnDatabaseEnd;
PMMMEMORY_LAYOUT MemoryLayout;
PMMPTE ValidPte;
/* Raise runlevel and acquire the PFN lock */
KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);
KE::QueuedSpinLockGuard SpinLock(SystemSpaceLock);
/* Get the kernel initialization block */
InitializationBlock = KE::BootInformation::GetInitializationBlock();
/* Get the memory layout */
MemoryLayout = MM::Manager::GetMemoryLayout();
/* Get the PFN database size and calculate the end of the PFN database virtual address space */
PfnDatabaseEnd = (PUCHAR)MemoryLayout->PfnDatabase + (MemoryLayout->PfnDatabaseSize * MM_PAGE_SIZE) - 1;
/* Get a template PTE for mapping the PFN database pages */
ValidPte = MM::Pte::GetValidPte();
/* Map the Page Directory and Page Directory Pointer tables for the PFN database */
MM::Pte::MapPPE(MemoryLayout->PfnDatabase, PfnDatabaseEnd, ValidPte);
MM::Pte::MapPDE(MemoryLayout->PfnDatabase, PfnDatabaseEnd, ValidPte);
MM::Pte::MapPTE(MemoryLayout->PfnDatabase, PfnDatabaseEnd, ValidPte);
/* Zero PFN database virtual space */
RTL::Memory::ZeroMemory(MemoryLayout->PfnDatabase, MemoryLayout->PfnDatabaseSize * MM_PAGE_SIZE);
/* Initialize the color tables */
MM::Colors::InitializeColorTables();
/* Iterate over memory descriptors to map the PFN database and initialize entries */
ListEntry = InitializationBlock->MemoryDescriptorListHead.Flink;
while(ListEntry != &InitializationBlock->MemoryDescriptorListHead)
{
/* Get the descriptor */
Descriptor = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_DESCRIPTOR, ListEntry);
/* Skip invisible memory regions */
if(MM::Manager::VerifyMemoryTypeInvisible(Descriptor->MemoryType))
{
/* Move to the next descriptor and continue */
ListEntry = ListEntry->Flink;
continue;
}
/* Check if this is the modified free descriptor */
if(Descriptor == FreeDescriptor)
{
/* Switch to the original descriptor */
Descriptor = &OriginalFreeDescriptor;
}
/* Check if the free memory block that was split is being processed */
if(Descriptor == &OriginalFreeDescriptor)
{
/* Skip loop processing, free memory is initialized separately */
ListEntry = ListEntry->Flink;
continue;
}
/* Initialize PFNs for this memory range */
ProcessMemoryDescriptor(Descriptor->BasePage, Descriptor->PageCount, Descriptor->MemoryType);
/* Move to the next descriptor */
ListEntry = ListEntry->Flink;
}
/* Initialize PFNs for the free memory */
ProcessMemoryDescriptor(FreeDescriptor->BasePage, FreeDescriptor->PageCount, LoaderFree);
/* Initialize PFNs for the physical pages backing the PFN database */
ProcessMemoryDescriptor(OriginalFreeDescriptor.BasePage,
FreeDescriptor->BasePage - OriginalFreeDescriptor.BasePage,
LoaderMemoryData);
/* Restore original free descriptor */
*FreeDescriptor = OriginalFreeDescriptor;
/* Initialize PFNs backing page tables */
InitializePageTablePfns();
}
/**
* Initializes PFN database entries for the system page tables.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Pfn::InitializePageTablePfns(VOID)
{
PFN_NUMBER PageFrameIndex;
PMMPFN Pfn;
ULONG RootLevel;
PMMPTE RootPte;
/* Determine root structure based on paging mode */
if(MM::Paging::GetXpaStatus())
{
/* XPA enabled, 5-level paging (LA57) */
RootLevel = 5;
/* Retrieve the PFN of the PML5 table and its virtual base address */
PageFrameIndex = MM::Paging::GetPageFrameNumber(MM::Paging::GetPteAddress((PVOID)MM_P5E_LA57_BASE));
RootPte = (PMMPTE)MM::Paging::GetP5eAddress(NULLPTR);
}
else
{
/* XPA disabled, 4-level paging */
RootLevel = 4;
/* Retrieve the PFN of the PML4 table and its virtual base address */
PageFrameIndex = MM::Paging::GetPageFrameNumber(MM::Paging::GetPteAddress((PVOID)MM_PXE_BASE));
RootPte = (PMMPTE)MM::Paging::GetPxeAddress(NULLPTR);
}
/* Initialize the PFN entry for the root page table itself */
Pfn = GetPfnEntry(PageFrameIndex);
if(Pfn)
{
/* Initialize the PFN entry */
Pfn->PteAddress = NULLPTR;
Pfn->u1.WsIndex = 0;
Pfn->u2.ShareCount = 1;
Pfn->u3.e1.CacheAttribute = PfnNonCached;
Pfn->u3.e2.ReferenceCount = 1;
Pfn->u4.PteFrame = 0;
}
/* Start recursive scan from the top level */
if(RootPte)
{
/* Scan the root page table */
ScanPageTable(RootPte, RootLevel);
}
}
/**
* Recursively scans a page table to initialize PFN database entries for active pages.
*
* @param PointerPte
* Pointer to the base of the page table to scan.
*
* @param Level
* The paging level of the table being scanned.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Pfn::ScanPageTable(IN PMMPTE PointerPte,
IN ULONG Level)
{
PVOID Address;
ULONG Index;
PMMPTE NextLevelPte;
ULONG PtesPerPage;
/* Get the number of PTEs per page */
PtesPerPage = MM::Pte::GetPtesPerPage();
/* Iterate through all entries in the current page table */
for(Index = 0; Index < PtesPerPage; Index++)
{
/* Check if the page table entry is present */
if(MM::Paging::PteValid(PointerPte))
{
/* Mark the PFN pointed to by this entry as active */
LinkPfnForPageTable(MM::Paging::GetPageFrameNumber(PointerPte), PointerPte);
/* Recurse to the next level, if this is not a leaf node (PTE) */
if(Level > 1)
{
/* Calculate the virtual address mapped by this entry to find the next table */
switch(Level)
{
case 5:
/* Calculate PXE */
Address = MM::Paging::GetP5eVirtualAddress((PMMP5E)PointerPte);
NextLevelPte = (PMMPTE)MM::Paging::GetPxeAddress(Address);
break;
case 4:
/* Calculate PPE */
Address = MM::Paging::GetPxeVirtualAddress((PMMPXE)PointerPte);
NextLevelPte = (PMMPTE)MM::Paging::GetPpeAddress(Address);
break;
case 3:
/* Calculate PDE */
Address = MM::Paging::GetPpeVirtualAddress((PMMPPE)PointerPte);
NextLevelPte = (PMMPTE)MM::Paging::GetPdeAddress(Address);
break;
case 2:
/* Calculate PTE */
Address = MM::Paging::GetPdeVirtualAddress((PMMPDE)PointerPte);
NextLevelPte = MM::Paging::GetPteAddress(Address);
break;
default:
/* Nothing to calculate, return NULLPTR */
NextLevelPte = NULLPTR;
break;
}
/* Recurse deeper if not at the bottom level (PTE) already */
if(NextLevelPte)
{
/* Recursively scan the next level page table */
ScanPageTable(NextLevelPte, Level - 1);
}
}
}
/* Move to the next entry in the current table */
PointerPte = MM::Paging::GetNextPte(PointerPte);
}
}

34
xtoskrnl/mm/amd64/pool.cc Fichier normal
Voir le fichier

@@ -0,0 +1,34 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/mm/amd64/pool.cc
* DESCRIPTION: AMD64 Memory Manager pool manager
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
/**
* Maps the PTE for the base of the non-paged pool.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Pool::MapNonPagedPool(VOID)
{
PMMMEMORY_LAYOUT MemoryLayout;
/* Retrieve memory layout */
MemoryLayout = MM::Manager::GetMemoryLayout();
/* Map PPE and PDE for whole non-paged pool */
MM::Pte::MapPPE(MemoryLayout->NonPagedPoolStart, MemoryLayout->NonPagedExpansionPoolEnd, MM::Pte::GetValidPte());
MM::Pte::MapPDE(MemoryLayout->NonPagedPoolStart, MemoryLayout->NonPagedExpansionPoolEnd, MM::Pte::GetValidPte());
/* Map PTE only for the base of the non-paged pool */
MM::Pte::MapPTE(MemoryLayout->NonPagedPoolStart, (PCHAR)MemoryLayout->NonPagedPoolEnd - 1, MM::Pte::GetValidPte());
}

295
xtoskrnl/mm/amd64/pte.cc Fichier normal
Voir le fichier

@@ -0,0 +1,295 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/mm/amd64/pte.cc
* DESCRIPTION: Page Table Entry (PTE) for AMD64 support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
/**
* Checks if the virtual address is valid and mapped in the page tables.
*
* @param VirtualAddress
* The virtual address to check.
*
* @return This routine returns TRUE if the address is valid, or FALSE otherwise.
*
* @since XT 1.0
*/
XTAPI
BOOLEAN
MM::Pte::AddressValid(IN PVOID VirtualAddress)
{
/* Check XPA status */
if(MM::Paging::GetXpaStatus())
{
/* Check if the P5E is valid */
if(!MM::Paging::PteValid(MM::Paging::GetP5eAddress(VirtualAddress)))
{
/* Invalid P5E, return FALSE */
return FALSE;
}
}
/* Check if PXE, PPE, PDE and PTE are valid */
if(!MM::Paging::PteValid(MM::Paging::GetPxeAddress(VirtualAddress)) ||
!MM::Paging::PteValid(MM::Paging::GetPpeAddress(VirtualAddress)) ||
!MM::Paging::PteValid(MM::Paging::GetPdeAddress(VirtualAddress)) ||
!MM::Paging::PteValid(MM::Paging::GetPteAddress(VirtualAddress)))
{
/* Invalid PXE, PPE, PDE or PTE, return FALSE */
return FALSE;
}
/* Address is valid, return TRUE */
return TRUE;
}
/**
* Retrieves the base virtual address of the system PTEs.
*
* @return This routine returns a pointer to the first PTE in the system PTE space.
*
* @since XT 1.0
*/
XTAPI
PMMPTE
MM::Pte::GetSystemPteBaseAddress(VOID)
{
PMMMEMORY_LAYOUT MemoryLayout;
/* Retrieve the system's memory layout */
MemoryLayout = MM::Manager::GetMemoryLayout();
/* Determine the base address for system PTEs based on the paging mode */
if(MM::Paging::GetXpaStatus())
{
/* For 5-level paging, system PTEs start at the beginning of system space */
return MM::Paging::GetPteAddress((PVOID)MemoryLayout->NonPagedSystemPoolStart);
}
else
{
/* For 4-level paging, system PTEs start at the legacy KSEG0_BASE */
return MM::Paging::GetPteAddress((PVOID)KSEG0_BASE);
}
}
/**
* Performs the initial setup of the system's page table hierarchy.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Pte::InitializePageTable(VOID)
{
PMMPTE EndSpacePte, PointerPte;
PMMMEMORY_LAYOUT MemoryLayout;
PVOID MappingRange;
MMPTE TemplatePte;
BOOLEAN Xpa;
/* Retrieve current paging mode and memory layout */
Xpa = MM::Paging::GetXpaStatus();
MemoryLayout = MM::Manager::GetMemoryLayout();
/* Enable the Global Paging (PGE) feature */
AR::CpuFunc::WriteControlRegister(4, AR::CpuFunc::ReadControlRegister(4) | CR4_PGE);
/* Check XPA status */
if(Xpa)
{
/* Get the PML5 user-space range if 5-level paging is active */
PointerPte = MM::Paging::GetP5eAddress(0);
EndSpacePte = MM::Paging::GetP5eAddress(MemoryLayout->UserSpaceEnd);
}
else
{
/* Otherwise, get the PML4 user-space range for 4-level paging */
PointerPte = MM::Paging::GetPxeAddress(0);
EndSpacePte = MM::Paging::GetPxeAddress(MemoryLayout->UserSpaceEnd);
}
/* Clear all top-level entries mapping the user address space */
while(PointerPte <= EndSpacePte)
{
MM::Paging::ClearPte(PointerPte);
PointerPte = MM::Paging::GetNextPte(PointerPte);
}
/* Flush the TLB to invalidate all non-global entries */
AR::CpuFunc::FlushTlb();
/* Create a template PTE for mapping kernel pages */
MM::Paging::ClearPte(&TemplatePte);
MM::Paging::SetPte(&TemplatePte, 0, MM_PTE_READWRITE | MM_PTE_CACHE_ENABLE);
/* Check XPA status */
if(Xpa)
{
/* Map the kernel's PML5 entries if 5-level paging is active */
MM::Pte::MapP5E(MemoryLayout->HyperSpaceStart, (PVOID)MM_HIGHEST_SYSTEM_ADDRESS, &TemplatePte);
}
/* Map the kernel's PML4 entries */
MM::Pte::MapPXE(MemoryLayout->HyperSpaceStart, (PVOID)MM_HIGHEST_SYSTEM_ADDRESS, &TemplatePte);
/* Calculate the end address of the hyperspace working set mapping */
MappingRange = (PVOID)((ULONG_PTR)MemoryLayout->HyperSpaceStart + MM_HYPERSPACE_PAGE_COUNT * MM_PAGE_SIZE);
/* Map the PDPT entries for paged pool and hyperspace */
MM::Pte::MapPPE(MemoryLayout->PagedPoolStart, MemoryLayout->PagedPoolEnd, &ValidPte);
MM::Pte::MapPPE(MemoryLayout->HyperSpaceStart, MemoryLayout->HyperSpaceEnd, &ValidPte);
/* Map the PDEs for the hyperspace working set */
MM::Pte::MapPDE(MemoryLayout->HyperSpaceStart, MappingRange, &ValidPte);
/* Set the hyperspace working set's PTE with the total PTE count */
MM::Paging::SetPte(MM::Paging::GetPteAddress((PVOID)MemoryLayout->HyperSpaceStart), MM_HYPERSPACE_PAGE_COUNT, 0);
}
/**
* Maps a range of virtual addresses at the P5E (PML5) level.
*
* @param StartAddress
* The beginning of the virtual address range to map.
*
* @param EndAddress
* The end of the virtual address range to map.
*
* @param TemplateP5e
* A template P5E to use for creating new entries.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Pte::MapP5E(IN PVOID StartAddress,
IN PVOID EndAddress,
IN PMMP5E TemplateP5e)
{
PMMP5E EndSpace, PointerP5e;
/* Get P5E addresses */
PointerP5e = MM::Paging::GetP5eAddress(StartAddress);
EndSpace = MM::Paging::GetP5eAddress(EndAddress);
/* Iterate over all P5Es */
while(PointerP5e <= EndSpace)
{
/* Check if P5E is already mapped */
if(!MM::Paging::PteValid(PointerP5e))
{
/* Map P5E */
MM::Paging::SetPte(TemplateP5e, MM::Pfn::AllocateBootstrapPages(1), 0);
*PointerP5e = *TemplateP5e;
/* Clear the page table */
RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(PointerP5e), MM_PAGE_SIZE);
}
/* Get next table entry */
PointerP5e = MM::Paging::GetNextPte(PointerP5e);
}
}
/**
* Maps a range of virtual addresses at the PPE (Page Directory Pointer Entry) level.
*
* @param StartAddress
* The beginning of the virtual address range to map.
*
* @param EndAddress
* The end of the virtual address range to map.
*
* @param TemplatePpe
* A template PPE to use for creating new entries.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Pte::MapPPE(IN PVOID StartAddress,
IN PVOID EndAddress,
IN PMMPPE TemplatePpe)
{
PMMPPE EndSpace, PointerPpe;
/* Get PPE addresses */
PointerPpe = MM::Paging::GetPpeAddress(StartAddress);
EndSpace = MM::Paging::GetPpeAddress(EndAddress);
/* Iterate over all PPEs */
while(PointerPpe <= EndSpace)
{
/* Check if PPE is already mapped */
if(!MM::Paging::PteValid(PointerPpe))
{
/* Map PPE */
MM::Paging::SetPte(TemplatePpe, MM::Pfn::AllocateBootstrapPages(1), 0);
*PointerPpe = *TemplatePpe;
/* Clear the page table */
RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(PointerPpe), MM_PAGE_SIZE);
}
/* Get next table entry */
PointerPpe = MM::Paging::GetNextPte(PointerPpe);
}
}
/**
* Maps a range of virtual addresses at the PXE (PML4) level.
*
* @param StartAddress
* The beginning of the virtual address range to map.
*
* @param EndAddress
* The end of the virtual address range to map.
*
* @param TemplatePxe
* A template PXE to use for creating new entries.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Pte::MapPXE(IN PVOID StartAddress,
IN PVOID EndAddress,
IN PMMPXE TemplatePxe)
{
PMMPXE EndSpace, PointerPxe;
/* Get PXE addresses */
PointerPxe = MM::Paging::GetPxeAddress(StartAddress);
EndSpace = MM::Paging::GetPxeAddress(EndAddress);
/* Iterate over all PTEs */
while(PointerPxe <= EndSpace)
{
/* Check if PTE is already mapped */
if(!MM::Paging::PteValid(PointerPxe))
{
/* Map PTE */
MM::Paging::SetPte(TemplatePxe, MM::Pfn::AllocateBootstrapPages(1), 0);
*PointerPxe = *TemplatePxe;
/* Clear the page table */
RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(PointerPxe), MM_PAGE_SIZE);
}
/* Get next table entry */
PointerPxe = MM::Paging::GetNextPte(PointerPxe);
}
}

178
xtoskrnl/mm/colors.cc Fichier normal
Voir le fichier

@@ -0,0 +1,178 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/mm/colors.cc
* DESCRIPTION: Memory manager page coloring subsystem
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
/**
* Computes & initializes the system's page coloring.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Colors::ComputePageColoring(VOID)
{
UNIMPLEMENTED;
/* Compute L2 paging colors and mask */
PagingColors = MM_PAGING_COLORS;
PagingColorsMask = PagingColors - 1;
}
/**
* Retrieves a pointer to the color table for a specific page list and color.
*
* @param PageList
* The page list type (e.g., FreePageList, ZeroedPageList).
*
* @param Color
* Supplies the specific color index.
*
* @return This routine returns a pointer to the corresponding MMCOLOR_TABLES structure.
*
* @since XT 1.0
*/
XTAPI
PMMCOLOR_TABLES
MM::Colors::GetFreePages(IN MMPAGELISTS PageList,
IN ULONG Color)
{
/* Return a pointer to the requested color table entry */
return &FreePages[PageList][Color];
}
/**
* Retrieves a pointer to the modified pages list for a specific color.
*
* @param Color
* Supplies the specific color index.
*
* @return This routine returns a pointer to the corresponding MMPFNLIST structure.
*
* @since XT 1.0
*/
XTAPI
PMMPFNLIST
MM::Colors::GetModifiedPages(IN ULONG Color)
{
return &ModifiedPages[Color];
}
/**
* Retrieves the next available color for page coloring.
*
* @return This routine returns the next color value, ensuring it stays within the valid color range.
*
* @since XT 1.0
*/
XTAPI
ULONG
MM::Colors::GetNextColor(VOID)
{
/* Increment the color counter and wrap it around using the mask */
return ((++PagingColors) & PagingColorsMask);
}
/**
* Retrieves the total number of page colors configured in the system.
*
* @return This routine returns the number of page colors.
*
* @since XT 1.0
*/
XTAPI
ULONG
MM::Colors::GetPagingColors(VOID)
{
/* Return the total number of page colors */
return PagingColors;
}
/**
* Retrieves the bitmask used for calculating a page's color.
*
* @return This routine returns the page color mask.
*
* @since XT 1.0
*/
XTAPI
ULONG
MM::Colors::GetPagingColorsMask(VOID)
{
/* Return the mask used for page coloring calculations */
return PagingColorsMask;
}
/**
* Initializes the data structures for page coloring.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
MM::Colors::InitializeColorTables(VOID)
{
PMMMEMORY_LAYOUT MemoryLayout;
PMMPTE PointerPte, LastPte;
ULONG Color;
PMMPTE ValidPte;
/* Get the memory layout */
MemoryLayout = MM::Manager::GetMemoryLayout();
/* Set the base address of the color tables to start right after the PFN database */
FreePages[0] = (PMMCOLOR_TABLES)&((PMMPFN)MemoryLayout->PfnDatabase)[MM::Pfn::GetHighestPhysicalPage() + 1];
/* Calculate the virtual address range for both color tables */
PointerPte = MM::Paging::GetPteAddress(&FreePages[0][0]);
LastPte = MM::Paging::GetPteAddress((PVOID)((ULONG_PTR)FreePages[0] +
(2 * PagingColors * sizeof(MMCOLOR_TABLES)) - 1));
/* Get a pointer to a PTE template */
ValidPte = MM::Pte::GetValidPte();
/* Ensure the entire virtual address range for the color tables is mapped */
while(PointerPte <= LastPte)
{
/* Check if a page in the range is not mapped */
if(!MM::Paging::PteValid(PointerPte))
{
/* Use the bootstrap allocator to get a physical page */
MM::Paging::SetPte(ValidPte, MM::Pfn::AllocateBootstrapPages(1), 0);
*PointerPte = *ValidPte;
/* Zero out the newly mapped page */
RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(PointerPte), MM_PAGE_SIZE);
}
/* Move to the next PTE in the range */
PointerPte = MM::Paging::GetNextPte(PointerPte);
}
/* Set the pointer for the second list */
FreePages[1] = &FreePages[0][PagingColors];
/* Initialize all entries in both color tables */
for(Color = 0; Color < PagingColors; Color++)
{
/* Initialize the FreePageList entry for the current color */
FreePages[FreePageList][Color].Flink = MAXULONG_PTR;
FreePages[FreePageList][Color].Blink = (PVOID)MAXULONG_PTR;
FreePages[FreePageList][Color].Count = 0;
/* Initialize the ZeroedPageList entry for the current color */
FreePages[ZeroedPageList][Color].Flink = MAXULONG_PTR;
FreePages[ZeroedPageList][Color].Blink = (PVOID)MAXULONG_PTR;
FreePages[ZeroedPageList][Color].Count = 0;
}
}

Voir le fichier

@@ -9,6 +9,54 @@
#include <xtos.hh>
/* Expansion table used to track pool memory allocations */
PPOOL_TRACKING_TABLE MM::Allocator::AllocationsTrackingExpansionTable;
/* Total number of entries in the expansion allocations tracking table */
SIZE_T MM::Allocator::AllocationsTrackingExpansionTableSize;
/* Global table used to track pool memory allocations */
PPOOL_TRACKING_TABLE MM::Allocator::AllocationsTrackingTable;
/* Spinlock protecting the allocations table */
KSPIN_LOCK MM::Allocator::AllocationsTrackingTableLock;
/* Bitmask used during the hashing process */
SIZE_T MM::Allocator::AllocationsTrackingTableMask;
/* Total number of entries in the global allocations tracking table */
SIZE_T MM::Allocator::AllocationsTrackingTableSize;
/* Active number of big allocations to trigger table expansion */
ULONG MM::Allocator::BigAllocationsInUse;
/* Pointer to the hash table for tracking page-aligned memory */
PPOOL_TRACKING_BIG_ALLOCATIONS MM::Allocator::BigAllocationsTrackingTable;
/* Bitmask used for fast modulo arithmetic during hash bucket lookups */
SIZE_T MM::Allocator::BigAllocationsTrackingTableHash;
/* Spinlock protecting the big allocations table */
KSPIN_LOCK MM::Allocator::BigAllocationsTrackingTableLock;
/* Maximum capacity of the tracking hash table */
SIZE_T MM::Allocator::BigAllocationsTrackingTableSize;
/* Array of CPU-local tracking tables */
PPOOL_TRACKING_TABLE MM::Allocator::TagTables[MM_POOL_TRACKING_TABLES];
/* Array of free page lists segregated by cache color */
PMMCOLOR_TABLES MM::Colors::FreePages[FreePageList + 1];
/* Array of modified pages segregated by cache color */
MMPFNLIST MM::Colors::ModifiedPages[MM_PAGING_COLORS] = {{0, ModifiedPageList, MAXULONG_PTR, MAXULONG_PTR}};
/* Number of supported page colors */
ULONG MM::Colors::PagingColors;
/* Bitmask used to calculate the cache color index */
ULONG MM::Colors::PagingColorsMask;
/* Allocation descriptors dedicated for hardware layer */
LOADER_MEMORY_DESCRIPTOR MM::HardwarePool::HardwareAllocationDescriptors[MM_HARDWARE_ALLOCATION_DESCRIPTORS];
@@ -18,23 +66,102 @@ PVOID MM::HardwarePool::HardwareHeapStart = MM_HARDWARE_HEAP_START_ADDRESS;
/* Number of used hardware allocation descriptors */
ULONG MM::HardwarePool::UsedHardwareAllocationDescriptors = 0;
/* Biggest free memory descriptor */
PLOADER_MEMORY_DESCRIPTOR MM::Init::FreeDescriptor;
/* Global structure describing the virtual memory layout of the system */
MMMEMORY_LAYOUT MM::Manager::MemoryLayout;
/* Highest physical page number */
ULONG_PTR MM::Init::HighestPhysicalPage;
/* Total number of PTEs reserved for system space mapping */
PFN_NUMBER MM::Manager::NumberOfSystemPtes;
/* Lowest physical page number */
ULONG_PTR MM::Init::LowestPhysicalPage = -1;
/* Number of physical pages */
ULONG MM::Init::NumberOfPhysicalPages;
/* Old biggest free memory descriptor */
LOADER_MEMORY_DESCRIPTOR MM::Init::OldFreeDescriptor;
/* Processor structures data (THIS IS A TEMPORARY HACK) */
UCHAR MM::KernelPool::ProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE] = {{0}};
/* Physical memory block descriptor */
PPHYSICAL_MEMORY_DESCRIPTOR MM::Manager::PhysicalMemoryBlock;
/* Instance of the page map routines for the current PML level */
MM::PPAGEMAP MM::Paging::PmlRoutines;
/* Total number of physical pages available for allocation */
PFN_NUMBER MM::Pfn::AvailablePages;
/* Head of the list containing physical pages marked as defective */
MMPFNLIST MM::Pfn::BadPagesList = {0, BadPageList, MAXULONG_PTR, MAXULONG_PTR};
/* Biggest free memory descriptor */
PLOADER_MEMORY_DESCRIPTOR MM::Pfn::FreeDescriptor;
/* List containing free physical pages */
MMPFNLIST MM::Pfn::FreePagesList = {0, FreePageList, MAXULONG_PTR, MAXULONG_PTR};
/* Highest physical page number */
ULONG_PTR MM::Pfn::HighestPhysicalPage;
/* Lowest physical page number */
ULONG_PTR MM::Pfn::LowestPhysicalPage;
/* List containing modified pages */
MMPFNLIST MM::Pfn::ModifiedPagesList = {0, ModifiedPageList, MAXULONG_PTR, MAXULONG_PTR};
/* List containing modified pages mapped as read-only */
MMPFNLIST MM::Pfn::ModifiedReadOnlyPagesList = {0, ModifiedReadOnlyPageList, MAXULONG_PTR, MAXULONG_PTR};
/* Number of physical pages */
ULONGLONG MM::Pfn::NumberOfPhysicalPages;
/* Old biggest free memory descriptor */
LOADER_MEMORY_DESCRIPTOR MM::Pfn::OriginalFreeDescriptor;
/* Array of pointers to PFN lists */
PMMPFNLIST MM::Pfn::PageLocationList[] = {&ZeroedPagesList,
&FreePagesList,
&StandbyPagesList,
&ModifiedPagesList,
&ModifiedReadOnlyPagesList,
&BadPagesList,
NULLPTR,
NULLPTR};
/* Bitmap used to track physical pages */
RTL_BITMAP MM::Pfn::PfnBitMap;
/* List containing pages mapped as Read-Only (ROM) */
MMPFNLIST MM::Pfn::RomPagesList = {0, StandbyPageList, MAXULONG_PTR, MAXULONG_PTR};
/* List containing standby pages (clean, can be reclaimed or repurposed) */
MMPFNLIST MM::Pfn::StandbyPagesList = {0, StandbyPageList, MAXULONG_PTR, MAXULONG_PTR};
/* List containing free physical pages that have been zeroed out */
MMPFNLIST MM::Pfn::ZeroedPagesList = {0, ZeroedPageList, MAXULONG_PTR, MAXULONG_PTR};
/* Non-paged pool descriptor */
POOL_DESCRIPTOR MM::Pool::NonPagedPoolDescriptor;
/* PFN marking the initial non-paged pool end boundary */
PFN_NUMBER MM::Pool::NonPagedPoolFrameEnd;
/* PFN marking the initial non-paged pool start boundary */
PFN_NUMBER MM::Pool::NonPagedPoolFrameStart;
/* Array of non-paged pool free list heads */
LIST_ENTRY MM::Pool::NonPagedPoolFreeList[MM_MAX_FREE_PAGE_LIST_HEADS];
/* Random cookie used to obfuscate pool links */
ULONG MM::Pool::PoolSecureCookie;
/* Array of pool descriptors */
PPOOL_DESCRIPTOR MM::Pool::PoolVector[2];
/* Array of lists for available System PTEs, separated by pool type */
MMPTE MM::Pte::FirstSystemFreePte[MaximumPtePoolTypes];
/* Virtual base address of the System PTE space */
PMMPTE MM::Pte::SystemPteBase;
/* End addresses for the System PTE ranges */
PMMPTE MM::Pte::SystemPtesEnd[MaximumPtePoolTypes];
/* Start addresses for the System PTE ranges */
PMMPTE MM::Pte::SystemPtesStart[MaximumPtePoolTypes];
/* Total count of available System PTEs */
PFN_COUNT MM::Pte::TotalSystemFreePtes[MaximumPtePoolTypes];
/* Template PTE entry containing standard flags for a valid, present kernel page */
MMPTE MM::Pte::ValidPte;

102
xtoskrnl/mm/exports.cc Fichier normal
Voir le fichier

@@ -0,0 +1,102 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/mm/exports.cc
* DESCRIPTION: C-compatible API wrappers for exported kernel functions
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
/**
* Allocates a block of memory from the specified pool type.
*
* @param PoolType
* Specifies the type of pool to allocate from.
*
* @param Bytes
* Specifies the number of bytes to allocate.
*
* @param Memory
* Supplies a pointer to the allocated memory.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
MmAllocatePool(IN MMPOOL_TYPE PoolType,
IN SIZE_T Bytes,
OUT PVOID *Memory)
{
return MM::Allocator::AllocatePool(PoolType, Bytes, Memory);
}
/**
* Allocates a block of memory from the specified pool type.
*
* @param PoolType
* Specifies the type of pool to allocate from.
*
* @param Bytes
* Specifies the number of bytes to allocate.
*
* @param Memory
* Supplies a pointer to the allocated memory.
*
* @param Tag
* Specifies the allocation identifying tag.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
MmAllocatePoolWithTag(IN MMPOOL_TYPE PoolType,
IN SIZE_T Bytes,
OUT PVOID *Memory,
IN ULONG Tag)
{
return MM::Allocator::AllocatePool(PoolType, Bytes, Memory, Tag);
}
/**
* Frees a previously allocated memory pool.
*
* @param VirtualAddress
* Supplies the base virtual address of the pool allocation to free.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
MmFreePool(IN PVOID VirtualAddress)
{
return MM::Allocator::FreePool(VirtualAddress);
}
/**
* Frees a previously allocated memory pool.
*
* @param VirtualAddress
* Supplies the base virtual address of the pool allocation to free.
*
* @param Tag
* Specifies the allocation identifying tag.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
MmFreePoolWithTag(IN PVOID VirtualAddress,
IN ULONG Tag)
{
return MM::Allocator::FreePool(VirtualAddress, Tag);
}

Voir le fichier

@@ -170,7 +170,7 @@ MM::HardwarePool::MapHardwareMemory(IN PHYSICAL_ADDRESS PhysicalAddress,
{
PVOID BaseAddress, ReturnAddress;
PFN_NUMBER MappedPages;
PHARDWARE_PTE PtePointer;
PMMPTE PtePointer;
/* Initialize variables */
BaseAddress = HardwareHeapStart;
@@ -189,7 +189,7 @@ MM::HardwarePool::MapHardwareMemory(IN PHYSICAL_ADDRESS PhysicalAddress,
}
/* Get PTE pointer and advance to next page */
PtePointer = (PHARDWARE_PTE)MM::Paging::GetPteAddress(ReturnAddress);
PtePointer = MM::Paging::GetPteAddress(ReturnAddress);
ReturnAddress = (PVOID)((ULONG_PTR)ReturnAddress + MM_PAGE_SIZE);
/* Check if PTE is valid */
@@ -219,10 +219,10 @@ MM::HardwarePool::MapHardwareMemory(IN PHYSICAL_ADDRESS PhysicalAddress,
while(MappedPages--)
{
/* Get PTE pointer */
PtePointer = (PHARDWARE_PTE)MM::Paging::GetPteAddress(BaseAddress);
PtePointer = MM::Paging::GetPteAddress(BaseAddress);
/* Fill the PTE */
MM::Paging::SetPte(PtePointer, (PFN_NUMBER)(PhysicalAddress.QuadPart >> MM_PAGE_SHIFT), TRUE);
MM::Paging::SetPte(PtePointer, (PFN_NUMBER)(PhysicalAddress.QuadPart >> MM_PAGE_SHIFT), MM_PTE_READWRITE);
/* Advance to the next address */
PhysicalAddress.QuadPart += MM_PAGE_SIZE;
@@ -259,18 +259,18 @@ VOID
MM::HardwarePool::MarkHardwareMemoryWriteThrough(IN PVOID VirtualAddress,
IN PFN_NUMBER PageCount)
{
PHARDWARE_PTE PtePointer;
PMMPTE PtePointer;
PFN_NUMBER Page;
/* Get PTE address from virtual address */
PtePointer = (PHARDWARE_PTE)MM::Paging::GetPteAddress(VirtualAddress);
PtePointer = MM::Paging::GetPteAddress(VirtualAddress);
/* Iterate through mapped pages */
for(Page = 0; Page < PageCount; Page++)
{
/* Mark pages as CD/WT */
MM::Paging::SetPteCaching(PtePointer, TRUE, TRUE);
PtePointer++;
MM::Paging::GetNextEntry(PtePointer);
}
}
@@ -296,13 +296,13 @@ MM::HardwarePool::RemapHardwareMemory(IN PVOID VirtualAddress,
IN PHYSICAL_ADDRESS PhysicalAddress,
IN BOOLEAN FlushTlb)
{
PHARDWARE_PTE PtePointer;
PMMPTE PtePointer;
/* Get PTE address from virtual address */
PtePointer = (PHARDWARE_PTE)MM::Paging::GetPteAddress(VirtualAddress);
PtePointer = MM::Paging::GetPteAddress(VirtualAddress);
/* Remap the PTE */
MM::Paging::SetPte(PtePointer, (PFN_NUMBER)(PhysicalAddress.QuadPart >> MM_PAGE_SHIFT), TRUE);
MM::Paging::SetPte(PtePointer, (PFN_NUMBER)(PhysicalAddress.QuadPart >> MM_PAGE_SHIFT), MM_PTE_READWRITE);
/* Check if TLB needs to be flushed */
if(FlushTlb)
@@ -334,7 +334,7 @@ MM::HardwarePool::UnmapHardwareMemory(IN PVOID VirtualAddress,
IN PFN_NUMBER PageCount,
IN BOOLEAN FlushTlb)
{
PHARDWARE_PTE PtePointer;
PMMPTE PtePointer;
PFN_NUMBER Page;
/* Check if address is valid hardware memory */
@@ -348,7 +348,7 @@ MM::HardwarePool::UnmapHardwareMemory(IN PVOID VirtualAddress,
VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress & ~(MM_PAGE_SIZE - 1));
/* Get PTE address from virtual address */
PtePointer = (PHARDWARE_PTE)MM::Paging::GetPteAddress(VirtualAddress);
PtePointer = MM::Paging::GetPteAddress(VirtualAddress);
/* Iterate through mapped pages */
for(Page = 0; Page < PageCount; Page++)

Certains fichiers ne sont pas affichés car ce diff contient trop de modifications Voir plus