Compare commits

..

211 Commits

Author SHA1 Message Date
1339943473 Implement MM::KernelPool::FreeProcessorStructures
All checks were successful
Builds / ExectOS (amd64, release) (push) Successful in 25s
Builds / ExectOS (i686, debug) (push) Successful in 37s
Builds / ExectOS (i686, release) (push) Successful in 27s
Builds / ExectOS (amd64, debug) (push) Successful in 39s
2026-03-25 15:03:33 +01:00
160222fd3b Implement TLB flushing for cache attribute changes during page removal 2026-03-25 15:03:33 +01:00
7e4b425702 Fix check for PTE removal flag 2026-03-25 15:03:33 +01:00
bbdbdc7bcd Mark PFN as deleted instead of clearing PteAddress when freeing pages 2026-03-25 15:03:33 +01:00
28dd16fb94 Revert 1e01c52c0c 2026-03-25 15:03:33 +01:00
6ac0fd0a1c Clear the internal list links to prevent corruption 2026-03-25 15:03:33 +01:00
202b98a3fd Rephrase comments for consistency 2026-03-25 15:03:33 +01:00
b323956f4b Add bounds checking and implement reclamation for large expansion pool allocations 2026-03-25 15:03:33 +01:00
6e992f3005 Set PTE frame for non-paged pool allocations 2026-03-25 15:03:33 +01:00
d1a4b378b1 Precommit page map to allocate memory 2026-03-25 15:03:33 +01:00
3ca3a86c0f Fix memory map size tracking and memory leak 2026-03-25 15:03:33 +01:00
8ee50255bb Fix memory corruption caused by UEFI memory map size changes during allocation 2026-03-25 15:03:33 +01:00
f1b9d57bf7 Strip MM_POOL_PROTECTED flag to maintain NT compatibility and ensure correct pool tracking hash lookups 2026-03-25 15:03:33 +01:00
f18c9ca5b4 Add expansion table and overflow handling for pool tag tracking 2026-03-25 15:03:33 +01:00
5fa948d57e Update pool tracking statistics when resizing big allocations table 2026-03-25 15:03:33 +01:00
6577876285 Unify naming convention for pool tracking structures 2026-03-25 15:03:33 +01:00
caf0287135 Implement pool allocations and frees tracking 2026-03-25 15:03:33 +01:00
95a3b5d7e2 Refactor big allocation tracker to use Tag 2026-03-25 15:03:33 +01:00
579ac1d90e Remove temporary hack and allocate processor structures from non-paged pool 2026-03-25 15:03:33 +01:00
4015b4b2f3 Implement core pool allocation and deallocation logic 2026-03-25 15:03:33 +01:00
0375a08ca5 Add definitions for pool management structures 2026-03-25 15:03:33 +01:00
d55a8219e3 Revert e2eff2b836 2026-03-25 15:03:33 +01:00
8a35727e43 Fix DebugPrint definition 2026-03-25 15:03:33 +01:00
322fea763b Replace NULL with NULLPTR 2026-03-25 15:03:33 +01:00
77e487495b Implement RAII guard for memory pool synchronization 2026-03-25 15:03:33 +01:00
7b3f4bb35a Decouple pool initialization and validation from allocation logic 2026-03-25 15:03:33 +01:00
427c7ae810 Track valid physical memory pages using a PFN bitmap 2026-03-25 15:03:33 +01:00
c575352f90 Update panic invocations with detailed error context 2026-03-25 15:03:33 +01:00
d8a430ee42 Add runlevel verification to memory pool allocations 2026-03-25 15:03:33 +01:00
2e5c259a5a Introduce pool allocation and free routines 2026-03-25 15:03:33 +01:00
66df8fddda Fix critical memory corruption bug caused by overwriting active page tables marked as free memory 2026-03-25 15:03:33 +01:00
4f16957016 Ensure correct PTE value assignment via accessors 2026-03-25 15:03:33 +01:00
e1b9664ec0 Unify PTE type definitions across architectures 2026-03-25 15:03:33 +01:00
60d8844afe Refactor panic calls in memory manager 2026-03-25 15:03:33 +01:00
d39ddabd04 Calculate virtual address per page when initializing PFN entries 2026-03-25 15:03:33 +01:00
6044dbaac9 Initialize system PTE pool for non-paged expansion pool 2026-03-25 15:03:33 +01:00
3d2be65545 Make MM::Pte::InitializeSystemPtePool public 2026-03-25 15:03:33 +01:00
caff02383c Correct PTE mapping logic during multiple page allocation 2026-03-25 15:03:33 +01:00
58bc1839f5 Implement memory deallocation and coalescing for non-paged pool 2026-03-25 15:03:33 +01:00
72b3fe8209 Set up owner pointers for all pages during pool initialization 2026-03-25 15:03:33 +01:00
a1899fd1fa Implement canonical address validation routine 2026-03-25 15:03:33 +01:00
5748e73853 Remove redundant static initialization of LowestPhysicalPage 2026-03-25 15:03:33 +01:00
792157eab1 Improve type safety of physical page boundaries initialization 2026-03-25 15:03:33 +01:00
14276179a7 Correct physical memory range detection 2026-03-25 15:03:33 +01:00
71684314c7 Fix uninitialized PTE pages causing memory corruption 2026-03-25 15:03:33 +01:00
b959e1908f Add MIN and MAX helper macros 2026-03-25 15:03:33 +01:00
5cca5970b1 Implement basic non-paged pool allocator 2026-03-25 15:03:33 +01:00
6c6b1f6a52 Initialize paged pool after PFN database setup 2026-03-25 15:03:33 +01:00
706aca6e20 Initialize paged pool alongside non-paged pool 2026-03-25 15:03:33 +01:00
cd60cd7b1a Implement page allocation interface 2026-03-25 15:03:33 +01:00
a6b050ddf2 Correct comment phrasing 2026-03-25 15:03:33 +01:00
398de5cb5b Expose the number of available physical pages 2026-03-25 15:03:33 +01:00
37d70c449c Refactor PFN linking logic 2026-03-25 15:03:33 +01:00
50654a28b5 Add definition for guarded PTE flag and remove hardcoded value 2026-03-25 15:03:33 +01:00
1f8d2a0370 Add interface to retrieve page map level (PML) 2026-03-25 15:03:33 +01:00
bd9af3bb5c Fix PFN calculation truncation for memory above 4GB to prevent memory descriptor aliasing on PAE systems 2026-03-25 15:03:33 +01:00
c303694384 Reorder initialization sequence and flush TLB 2026-03-25 15:03:33 +01:00
4de76886ee Map PDE and PTE ranges for i686 non-paged pool 2026-03-25 15:03:33 +01:00
52355698a9 Refactor EFI memory mapping to support distinct mapping strategies 2026-03-25 15:03:33 +01:00
420a66629b Fix boot image size alignment calculation 2026-03-25 15:03:33 +01:00
59f851f22c Minor style fixes 2026-03-25 15:03:33 +01:00
58ed35b0e4 Deduplicate PFN descriptor processing logic across architectures 2026-03-25 15:03:33 +01:00
dc2c24e83e Fix stale comment 2026-03-25 15:03:33 +01:00
932e951d4b Ensure paging hierarchy exists before processing memory descriptors 2026-03-25 15:03:33 +01:00
b7f85909cb Introduce page directory initialization helper 2026-03-25 15:03:33 +01:00
ca661d1201 Remove explicit identity mapping for internal page tables 2026-03-25 15:03:33 +01:00
1be5732789 Fix coding style 2026-03-25 15:03:33 +01:00
e08af6bfd3 Map and zero entire PFN database upfront 2026-03-25 15:03:33 +01:00
78fac504b7 Refactor PFN database initialization loop on i686 2026-03-25 15:03:33 +01:00
157c48ce7f Fix missing assignment of PointerPte 2026-03-25 15:03:33 +01:00
3b397aca92 Refactor PFN initialization to ensure proper page table setup 2026-03-25 15:03:33 +01:00
755c3fe1bf Use 64-bit format specifiers for memory mapping logs 2026-03-25 15:03:33 +01:00
75484e8c58 Fix physical address limit checks 2026-03-25 15:03:33 +01:00
3799dbae65 Fix PFN truncation on i686 with PAE enabled 2026-03-25 15:03:33 +01:00
aa7d9bb417 Centralize memory layout dumping 2026-03-25 15:03:33 +01:00
21fb192790 Handle non-paged pool overflow 2026-03-25 15:03:33 +01:00
a4f5211a96 Remove redundant PFN database alignment 2026-03-25 15:03:33 +01:00
9da11d827e Overhaul kernel memory layout initialization and pool sizing 2026-03-25 15:03:33 +01:00
bcd3032fe3 Enable non-paged pool setup 2026-03-25 15:03:33 +01:00
d8792cc9db Fix PFN database size calculation call sites 2026-03-25 15:03:33 +01:00
a2335900ad Move PFN database size tracking to memory layout 2026-03-25 15:03:33 +01:00
94320928bc Refactor memory layout structure 2026-03-25 15:03:33 +01:00
17e096f18c Add private helper declaration 2026-03-25 15:03:33 +01:00
66300103e1 Calculate aligned boot image size from loader parameters 2026-03-25 15:03:33 +01:00
8d05099d7b Add skeleton for memory pool allocator 2026-03-25 15:03:33 +01:00
488736512f Fix incorrect header guard comment 2026-03-25 15:03:33 +01:00
a326fea9af Limit system PTE space mapping to calculated pool size 2026-03-25 15:03:33 +01:00
bd7129ce13 Calculate total boot image size and pass it to kernel 2026-03-25 15:03:33 +01:00
af9cc43b1d Remove unused kernel base address definition 2026-03-25 15:03:33 +01:00
d272d2cb78 Ensure contiguous virtual memory mapping 2026-03-25 15:03:33 +01:00
b435752cbf Correctly advance virtual address after mapping non-free regions 2026-03-25 15:03:33 +01:00
2e0a32ca1d Rollback bootloader memory management changes 2026-03-25 15:03:33 +01:00
8554c634df Fix broken PPE check on i686 2026-03-25 15:03:33 +01:00
8577d23e47 Add routine to retrieve installed memory size 2026-03-25 15:03:33 +01:00
bc85eb3c12 Add missing annotations 2026-03-25 15:03:33 +01:00
52c119885c Standardize ValidPte setup across architectures 2026-03-25 15:03:33 +01:00
efe7f28675 Correctly initialize PFN entries for pre-mapped KSEG0 based memory 2026-03-25 15:03:33 +01:00
c29afe477c Annotate input parameters 2026-03-25 15:03:33 +01:00
ae43f7c723 Drop obsolete KSEG0_KERNEL_BASE definition 2026-03-25 15:03:33 +01:00
c8792a013a Abstract base mapping address retrieval 2026-03-25 15:03:33 +01:00
edfae7ec6a Extract MapDescriptor logic and simplify memory mapping API 2026-03-25 15:03:33 +01:00
31002b27be Clean up unused physical-to-virtual conversion routines 2026-03-25 15:03:33 +01:00
44a217ea14 Update function documentation and remove debug prints 2026-03-25 15:03:33 +01:00
4a26507228 Remove manual virtual address tracking from boot sequence 2026-03-25 15:03:33 +01:00
33d41a9442 Relocate kernel and modules to KSEG0 memory space 2026-03-25 15:03:33 +01:00
d2374799eb Temporary fix for PAE addressing limits and KSEG0 base mapping 2026-03-25 15:03:33 +01:00
0ee46924a7 Prevent adding referenced pages to the free list 2026-03-25 15:03:33 +01:00
3384556543 Correctly setup PFN database for ROM and in-use pages 2026-03-25 15:03:33 +01:00
3b8359042b Ensure every page in a bad memory region is marked as bad 2026-03-25 15:03:33 +01:00
c8fa998e38 Make memory descriptor processing architecture-dependent 2026-03-25 15:03:33 +01:00
807b0a736f Add logic to insert pages at the head of standby list 2026-03-25 15:03:33 +01:00
cb61566e8b Add temporary fallback for BeginStandbyList insertion 2026-03-25 15:03:33 +01:00
41eed4c7ad Allow PFN insertion at the beginning of standby list 2026-03-25 15:03:33 +01:00
042d0fa03a Optimize system PTE deallocation by avoiding immediate and expensive TLB flush 2026-03-25 15:03:33 +01:00
6accbfd2ae Replace ULONG with PFN_COUNT in system PTE variables 2026-03-25 15:03:33 +01:00
ec27cb7f76 Fix deadlock by reducing lock scope 2026-03-25 15:03:33 +01:00
bfa5cddb57 Add missing semicolon 2026-03-25 15:03:33 +01:00
f8cdcc3f75 Implement kernel stack deallocation and physical page freeing logic 2026-03-25 15:03:33 +01:00
602e837e11 Add mechanism to free system PTEs and merge adjacent clusters 2026-03-25 15:03:33 +01:00
0ca04a7dfe Clean up paging code 2026-03-25 15:03:33 +01:00
3270f920dd Remove dead code from paging and PTE management 2026-03-25 15:03:33 +01:00
4f6e8bc07a Initialize system PTEs with arch-specific list terminator 2026-03-25 15:03:33 +01:00
4aa841650a Abstract PTE list terminator into paging layer 2026-03-25 15:03:33 +01:00
c5ea9e4489 Add support for transitioning PTE to invalid state 2026-03-25 15:03:33 +01:00
c6041b02ae Add explicit default initialization for MM::Colors::ModifiedPages list 2026-03-25 15:03:33 +01:00
0153b2fb33 Properly handle bad physical pages 2026-03-25 15:03:33 +01:00
e0bcac3722 Implement generic PFN list linking function 2026-03-25 15:03:33 +01:00
466b0c8eab Introduce helper functions for querying the software prototype and transition bits of PTE 2026-03-25 15:03:33 +01:00
374f404324 Introduce per-page-color modified page lists 2026-03-25 15:03:33 +01:00
6308fd048b Remove redundant check for invisible memory regions 2026-03-25 15:03:33 +01:00
4963ff5367 Initialize PTE template dynamically to resolve build warnings 2026-03-25 15:03:33 +01:00
e0e3482326 Prevent initialization of invisible memory ranges 2026-03-25 15:03:33 +01:00
896803e248 Improve formatting 2026-03-25 15:03:33 +01:00
b5ebd24f24 Adjust thread initialization to match new stack allocator signature 2026-03-25 15:03:33 +01:00
e1144da195 Simplify stack page count calculation 2026-03-25 15:03:33 +01:00
0c9ea2ed20 Implement kernel stack allocation logic 2026-03-25 15:03:33 +01:00
43d0e8932d Implement logic to link physical pages to PTEs 2026-03-25 15:03:33 +01:00
d88fa93df9 Introduce page fault handling infrastructure 2026-03-25 15:03:33 +01:00
9cfc22e1f3 Reserve space for color tables to fix invalid memory access 2026-03-25 15:03:33 +01:00
d9a95527f3 Ensure page map structures are self-mapped 2026-03-25 15:03:33 +01:00
47606faded Initialize paged pool sizing logic 2026-03-25 15:03:33 +01:00
b6c5bae289 Minor style fixes in MM includes 2026-03-25 15:03:33 +01:00
330c9e3eaf Update PTE support to use safe write accessors 2026-03-25 15:03:33 +01:00
2854f77159 Refactor memory clearing calls and cleanup code style 2026-03-25 15:03:33 +01:00
75dfcec5a6 Implement PFN database initialization and memory descriptor processing 2026-03-25 15:03:33 +01:00
f33fa0fdaf Expose PFN database lookup via GetPfnEntry 2026-03-25 15:03:33 +01:00
cdad8ffe2c Implement tracking of available physical pages 2026-03-25 15:03:33 +01:00
425780de69 Initialize system PTE pools and implement reservation routines 2026-03-25 15:03:33 +01:00
446d9af325 Initialize system page tables and configure kernel mappings 2026-03-25 15:03:33 +01:00
536d59c3a8 Include mm/colors.cc in kernel build configuration 2026-03-25 15:03:33 +01:00
4192e93157 Introduce page coloring support to memory manager 2026-03-25 15:03:33 +01:00
b32c66110b Add storage for PFN database size 2026-03-25 15:03:33 +01:00
cdb3c1a8da Initialize memory manager during kernel startup 2026-03-25 15:03:33 +01:00
5e54aca398 Update modified page list enum terminology 2026-03-25 15:03:33 +01:00
68604e1bc0 Update memory manager type definitions and constants 2026-03-25 15:03:33 +01:00
a4b36827e4 Bring up i686 page table initialization 2026-03-25 15:03:33 +01:00
e8512e9f45 Fix physical page count overflow by using 64-bit type 2026-03-25 15:03:33 +01:00
0448217c06 Fix PTE free list sentinel handling 2026-03-25 15:03:33 +01:00
f9b27b48b0 Select correct self-map base for PAE and non-PAE paging 2026-03-25 15:03:33 +01:00
eb621e0264 Extend PTE helpers with raw read and write support 2026-03-25 15:03:33 +01:00
ed769e023f Respect architecture-specific PTE layouts and write PTEs via PML-aware helpers 2026-03-25 15:03:33 +01:00
08b095d47c Make PPE mapping architecture-specific 2026-03-25 15:03:33 +01:00
87aa3494f9 Add early spin lock initialization 2026-03-25 15:03:33 +01:00
244af13500 Clarify page table entry offset semantics 2026-03-25 15:03:33 +01:00
e6d2574bf9 Fix paging abstraction for PDE/PTE virtual address calculation 2026-03-25 15:03:33 +01:00
6f9e537e86 Implement initial virtual memory layout setup 2026-03-25 15:03:33 +01:00
be6ad1658f Update SelfMapAddress 2026-03-25 15:03:33 +01:00
a45cd95b6f Call page table initialization 2026-03-25 15:03:33 +01:00
3c5bb52152 Add virtual address validation and system PTE helpers 2026-03-25 15:03:33 +01:00
3a311a0497 Move memory layout initialization to architecture-specific code 2026-03-25 15:03:33 +01:00
140b25ff76 Architecture-specific system PTE limits 2026-03-25 15:03:33 +01:00
c760016ee5 Extend memory layout 2026-03-25 15:03:33 +01:00
6a55b1a42c Remove unsupported PML4/PML5 PTE interfaces 2026-03-25 15:03:33 +01:00
d8b2af8f1e Split PTE implementation per architecture 2026-03-25 15:03:33 +01:00
28fc0ab435 Compute PTE count per page from entry size 2026-03-25 15:03:33 +01:00
329c22ae82 Implement early page table mapping routines 2026-03-25 15:03:33 +01:00
d27954091a Add bootstrap physical page allocator 2026-03-25 15:03:33 +01:00
df9028d425 Introduce kernel virtual memory layout 2026-03-25 15:03:33 +01:00
540c4df13e Compute PFN database size during MM initialization 2026-03-25 15:03:33 +01:00
0a2fb7ae38 Tidy up memory type verification helpers 2026-03-25 15:03:33 +01:00
6f824c55bb Harden PFN initialization and expose page count 2026-03-25 15:03:33 +01:00
f371b305ad Make memory type verification helpers accessible to PFN 2026-03-25 15:03:33 +01:00
24e20f3d8f Extract PFN management into separate module 2026-03-25 15:03:33 +01:00
c7bfc028b6 Refactor memory manager initialization into MM::Manager 2026-03-25 15:03:33 +01:00
9492ba09a6 Fix GetP5eAddress return type 2026-03-25 15:03:33 +01:00
4e7ab3585e Add missing virtual GetPteDistance to pagemap interface 2026-03-25 15:03:33 +01:00
9d27778e4c Add architecture-specific GetPteDistance 2026-03-25 15:03:33 +01:00
0796164cf8 Refactor XPA detection API 2026-03-25 15:03:33 +01:00
2f4d26b432 Fix incorrect pointer types 2026-03-25 15:03:33 +01:00
48fafd4a9a Fix incorrect pointer types 2026-03-25 15:03:33 +01:00
1996024e96 Split paging interface into arch-specific code 2026-03-25 15:03:33 +01:00
42a96ae5c3 Implement virtual address resolvers for all page map levels and add XPA status accessor 2026-03-25 15:03:33 +01:00
f9a057db2d Add MM::PageMap::GetXpaStatus() for querying PML level 2026-03-25 15:03:33 +01:00
f210c9e334 Refactor PageMap to enable architecture-specific VA translation 2026-03-25 15:03:33 +01:00
117d174e6e Add PFN_COUNT typedef 2026-03-25 15:03:33 +01:00
8334fe5a48 Correct LA57 paging base addresses, add self-map constants and extend PTE structures 2026-03-25 15:03:33 +01:00
7b7426738a Add kernel parameters section and fix minor formatting issues 2026-03-25 15:03:33 +01:00
8d4455de88 Prevent duplicate object generation by linking xtoskrnl with libxtos 2026-03-25 15:03:33 +01:00
b7f0f07f8b Add page list and PTE pool type enums 2026-03-25 15:03:33 +01:00
e831902363 Fix class name 2026-03-25 15:03:33 +01:00
f247726ee9 Add GetPageFrameNumber() to PTE interfaces 2026-03-25 15:03:33 +01:00
9449ee6eb1 Make MM::Paging::GetExtendedPhysicalAddressingStatus public 2026-03-25 15:03:33 +01:00
34586d8fa1 Replace writable flag with AttributesMask in PTE setup 2026-03-25 15:03:33 +01:00
05b9bb75a7 Add PTE attribute definitions 2026-03-25 15:03:33 +01:00
d752de20f6 Unify PTE pointer types across MM subsystem 2026-03-25 15:03:33 +01:00
fd7cc019ee Unify MMPML2_PTE field naming convention 2026-03-25 15:03:33 +01:00
8e48153852 Add input qualifiers to page map interface definitions 2026-03-25 15:03:33 +01:00
bf98860ff2 Add input qualifiers to paging interface definitions 2026-03-25 15:03:33 +01:00
c2d3f2e6f4 Add PTE management routines 2026-03-25 15:03:33 +01:00
779726c4d6 Add missing EmptyPteList field to MMPAGEMAP_INFO 2026-03-25 15:03:33 +01:00
4cf2c0c9e8 Implement unified PTE accessors and management helpers 2026-03-25 15:03:33 +01:00
173 changed files with 1717 additions and 11045 deletions

View File

@@ -55,9 +55,6 @@ add_definitions(-D__XTOS__)
add_definitions(-DXTOS_SOURCE_DIR="${EXECTOS_SOURCE_DIR}") add_definitions(-DXTOS_SOURCE_DIR="${EXECTOS_SOURCE_DIR}")
add_definitions(-DXTOS_BINARY_DIR="${EXECTOS_BINARY_DIR}") add_definitions(-DXTOS_BINARY_DIR="${EXECTOS_BINARY_DIR}")
# Add assembler flags
add_compiler_asmflags(-D__XTOS_ASSEMBLER__)
# Compute __FILE__ definition # Compute __FILE__ definition
file(RELATIVE_PATH _PATH_PREFIX ${EXECTOS_BINARY_DIR} ${EXECTOS_SOURCE_DIR}) file(RELATIVE_PATH _PATH_PREFIX ${EXECTOS_BINARY_DIR} ${EXECTOS_SOURCE_DIR})
add_compiler_flags(-D__RELFILE__="&__FILE__[__FILE__[0] == '.' ? sizeof \\\"${_PATH_PREFIX}\\\" - 1 : sizeof XTOS_SOURCE_DIR]") add_compiler_flags(-D__RELFILE__="&__FILE__[__FILE__[0] == '.' ? sizeof \\\"${_PATH_PREFIX}\\\" - 1 : sizeof XTOS_SOURCE_DIR]")

View File

@@ -221,15 +221,10 @@ Console::QueryMode(OUT PUINT_PTR ResX,
* @since XT 1.0 * @since XT 1.0
*/ */
XTCDECL XTCDECL
EFI_STATUS VOID
Console::ReadKeyStroke(OUT PEFI_INPUT_KEY Key) Console::ReadKeyStroke(OUT PEFI_INPUT_KEY Key)
{ {
/* Clear the key structure to prevent ghost keystrokes */ XtLoader::GetEfiSystemTable()->ConIn->ReadKeyStroke(XtLoader::GetEfiSystemTable()->ConIn, Key);
Key->ScanCode = 0;
Key->UnicodeChar = 0;
/* Read the keystroke from the EFI input console */
return XtLoader::GetEfiSystemTable()->ConIn->ReadKeyStroke(XtLoader::GetEfiSystemTable()->ConIn, Key);
} }
/** /**

View File

@@ -56,21 +56,6 @@ XTBL_LOADER_PROTOCOL Protocol::LoaderProtocol;
/* XT Boot Loader loaded modules list */ /* XT Boot Loader loaded modules list */
LIST_ENTRY Protocol::LoadedModules; LIST_ENTRY Protocol::LoadedModules;
/* XT Boot Loader shell exit flag */
BOOLEAN Shell::ExitRequest;
/* XT Boot Loader shell history buffer */
WCHAR Shell::History[XTBL_SH_HISTORY_ENTRIES][XTBL_SH_MAX_LINE_LENGTH];
/* XT Boot Loader shell history count */
ULONG Shell::HistoryCount = 0;
/* XT Boot Loader shell history index */
ULONG Shell::HistoryIndex = 0;
/* XT Boot Loader shell commands list */
LIST_ENTRY Shell::ShellCommands;
/* List of available block devices */ /* List of available block devices */
LIST_ENTRY Volume::EfiBlockDevices; LIST_ENTRY Volume::EfiBlockDevices;

View File

@@ -93,7 +93,7 @@ class Console
STATIC XTCDECL XTSTATUS PutChar(IN WCHAR Character); STATIC XTCDECL XTSTATUS PutChar(IN WCHAR Character);
STATIC XTCDECL VOID QueryMode(OUT PUINT_PTR ResX, STATIC XTCDECL VOID QueryMode(OUT PUINT_PTR ResX,
OUT PUINT_PTR ResY); OUT PUINT_PTR ResY);
STATIC XTCDECL EFI_STATUS ReadKeyStroke(OUT PEFI_INPUT_KEY Key); STATIC XTCDECL VOID ReadKeyStroke(OUT PEFI_INPUT_KEY Key);
STATIC XTCDECL VOID ResetInputBuffer(); STATIC XTCDECL VOID ResetInputBuffer();
STATIC XTCDECL VOID SetAttributes(IN ULONGLONG Attributes); STATIC XTCDECL VOID SetAttributes(IN ULONGLONG Attributes);
STATIC XTCDECL VOID SetCursorPosition(IN ULONGLONG PosX, STATIC XTCDECL VOID SetCursorPosition(IN ULONGLONG PosX,
@@ -253,47 +253,11 @@ class Protocol
class Shell class Shell
{ {
private:
STATIC BOOLEAN ExitRequest;
STATIC WCHAR History[XTBL_SH_HISTORY_ENTRIES][XTBL_SH_MAX_LINE_LENGTH];
STATIC ULONG HistoryCount;
STATIC ULONG HistoryIndex;
STATIC LIST_ENTRY ShellCommands;
public: public:
STATIC XTCDECL EFI_STATUS RegisterCommand(IN PCWSTR Command,
IN PCWSTR Description,
IN PBL_SHELL_COMMAND Handler);
STATIC XTCDECL VOID StartLoaderShell(); STATIC XTCDECL VOID StartLoaderShell();
private: private:
STATIC XTCDECL VOID CommandExit(IN ULONG Argc,
IN PWCHAR *Argv);
STATIC XTCDECL VOID CommandHelp(IN ULONG Argc,
IN PWCHAR *Argv);
STATIC XTCDECL VOID CommandInsmod(IN ULONG Argc,
IN PWCHAR *Argv);
STATIC XTCDECL VOID CommandLsmod(IN ULONG Argc,
IN PWCHAR *Argv);
STATIC XTCDECL VOID CommandPoweroff(IN ULONG Argc,
IN PWCHAR *Argv);
STATIC XTCDECL VOID CommandReboot(IN ULONG Argc,
IN PWCHAR *Argv);
STATIC XTCDECL VOID CommandVersion(IN ULONG Argc,
IN PWCHAR *Argv);
STATIC XTCDECL VOID ExecuteCommand(IN ULONG Argc,
IN PWCHAR *Argv);
STATIC XTCDECL EFI_STATUS ParseCommand(IN PWCHAR CommandLine,
OUT PULONG Argc,
OUT PWCHAR **Argv);
STATIC XTCDECL VOID PrintPrompt(); STATIC XTCDECL VOID PrintPrompt();
STATIC XTCDECL VOID PrintPromptLine(IN PWCHAR Buffer,
IN ULONG BufferLength,
IN ULONG CursorPosition,
IN ULONG PreviousBufferLength);
STATIC XTCDECL VOID ReadCommand(OUT PWCHAR Buffer,
IN ULONG BufferSize);
STATIC XTCDECL VOID RegisterBuiltinCommands();
}; };
class TextUi class TextUi

View File

@@ -302,7 +302,6 @@ Protocol::LoadModule(IN PWCHAR ModuleName)
PXTBL_MODULE_DEPS ModuleDependency; PXTBL_MODULE_DEPS ModuleDependency;
PXTBL_MODULE_INFO ModuleInfo; PXTBL_MODULE_INFO ModuleInfo;
WCHAR ModuleFileName[24]; WCHAR ModuleFileName[24];
ULONG ModuleNameLength;
USHORT SectionIndex; USHORT SectionIndex;
PWCHAR SectionData; PWCHAR SectionData;
SIZE_T ModuleSize; SIZE_T ModuleSize;
@@ -329,11 +328,8 @@ Protocol::LoadModule(IN PWCHAR ModuleName)
/* Print debug message */ /* Print debug message */
Debug::Print(L"Loading module '%S' ...\n", ModuleName); Debug::Print(L"Loading module '%S' ...\n", ModuleName);
/* Calculate module name length */
ModuleNameLength = RTL::WideString::WideStringLength(ModuleName, 0) + 1;
/* Set module path */ /* Set module path */
RTL::Memory::CopyMemory(ModuleFileName, ModuleName, ModuleNameLength * sizeof(WCHAR)); RTL::Memory::CopyMemory(ModuleFileName, ModuleName, (RTL::WideString::WideStringLength(ModuleName, 0) + 1) * sizeof(WCHAR));
RTL::WideString::ConcatenateWideString(ModuleFileName, (PWCHAR)L".EFI", 0); RTL::WideString::ConcatenateWideString(ModuleFileName, (PWCHAR)L".EFI", 0);
/* Open EFI volume */ /* Open EFI volume */
@@ -442,8 +438,7 @@ Protocol::LoadModule(IN PWCHAR ModuleName)
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to load module, print error message and return status code */ /* Failed to load module, print error message and return status code */
Debug::Print(L"Failed to load dependency module '%S' (Status Code: 0x%zX)\n", Debug::Print(L"Failed to load dependency module '%S' (Status Code: 0x%zX)\n", ModuleDependency->ModuleName, Status);
ModuleDependency->ModuleName, Status);
return STATUS_EFI_UNSUPPORTED; return STATUS_EFI_UNSUPPORTED;
} }
@@ -506,19 +501,8 @@ Protocol::LoadModule(IN PWCHAR ModuleName)
XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULLPTR); XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULLPTR);
} }
/* Allocate memory for module name */
Status = Memory::AllocatePool(ModuleNameLength * sizeof(WCHAR), (PVOID *)&ModuleInfo->ModuleName);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to allocate memory for module name, return error */
Debug::Print(L"ERROR: Failed to allocate memory (Status Code: 0x%zX)\n", Status);
return Status;
}
/* Copy module name */
RTL::Memory::CopyMemory(ModuleInfo->ModuleName, ModuleName, ModuleNameLength * sizeof(WCHAR));
/* Save additional module information, not found in '.modinfo' section */ /* Save additional module information, not found in '.modinfo' section */
ModuleInfo->ModuleName = ModuleName;
ModuleInfo->ModuleBase = LoadedImage->ImageBase; ModuleInfo->ModuleBase = LoadedImage->ImageBase;
ModuleInfo->ModuleSize = LoadedImage->ImageSize; ModuleInfo->ModuleSize = LoadedImage->ImageSize;
ModuleInfo->Revision = LoadedImage->Revision; ModuleInfo->Revision = LoadedImage->Revision;
@@ -1093,7 +1077,6 @@ Protocol::InstallXtLoaderProtocol()
LoaderProtocol.Protocol.LocateHandles = LocateProtocolHandles; LoaderProtocol.Protocol.LocateHandles = LocateProtocolHandles;
LoaderProtocol.Protocol.Open = OpenProtocol; LoaderProtocol.Protocol.Open = OpenProtocol;
LoaderProtocol.Protocol.OpenHandle = OpenProtocolHandle; LoaderProtocol.Protocol.OpenHandle = OpenProtocolHandle;
LoaderProtocol.Shell.RegisterCommand = Shell::RegisterCommand;
LoaderProtocol.String.Compare = RTL::String::CompareString; LoaderProtocol.String.Compare = RTL::String::CompareString;
LoaderProtocol.String.Length = RTL::String::StringLength; LoaderProtocol.String.Length = RTL::String::StringLength;
LoaderProtocol.String.ToWideString = RTL::String::StringToWideString; LoaderProtocol.String.ToWideString = RTL::String::StringToWideString;

View File

@@ -4,21 +4,13 @@
* FILE: xtldr/shell.cc * FILE: xtldr/shell.cc
* DESCRIPTION: XT Boot Loader shell * DESCRIPTION: XT Boot Loader shell
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/ */
#include <xtldr.hh> #include <xtldr.hh>
/** /**
* Implements the built-in `exit` command. Sets the exit flag to signal the main * Starts XTLDR shell.
* shell loop to terminate and return control to the boot menu.
*
* @param Argc
* Supplies the number of arguments provided by the user.
*
* @param Argv
* Supplies a list of arguments provided by the user.
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
@@ -26,410 +18,14 @@
*/ */
XTCDECL XTCDECL
VOID VOID
Shell::CommandExit(IN ULONG Argc, Shell::StartLoaderShell()
IN PWCHAR *Argv)
{ {
/* Signal the main shell loop to stop and return to the boot menu */ /* Initialize console */
ExitRequest = TRUE; Console::InitializeConsole();
}
/** /* Print prompt */
* Implements the built-in `help` command. Prints a list of available commands alongside their descriptions. PrintPrompt();
* for(;;);
* @param Argc
* Supplies the number of arguments provided by the user.
*
* @param Argv
* Supplies a list of arguments provided by the user.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
Shell::CommandHelp(IN ULONG Argc,
IN PWCHAR *Argv)
{
PXTBL_SHELL_COMMAND CommandEntry;
PLIST_ENTRY ListEntry;
/* Print a header line */
Console::Print(L"Available commands:\n\n");
/* Walk the registered commands list */
ListEntry = ShellCommands.Flink;
while(ListEntry != &ShellCommands)
{
/* Retrieve the current command entry */
CommandEntry = CONTAIN_RECORD(ListEntry, XTBL_SHELL_COMMAND, Flink);
/* Print the command name in a highlighted color */
Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_WHITE);
Console::Print(L" %-12S", CommandEntry->Command);
/* Print the description in the default color */
Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
Console::Print(L" %S\n", CommandEntry->Description);
/* Advance to the next entry */
ListEntry = ListEntry->Flink;
}
}
/**
* Implements the built-in `insmod` command. Loads an XTLDR module by its name.
*
* @param Argc
* Supplies the number of arguments provided by the user.
*
* @param Argv
* Supplies a list of arguments provided by the user.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
Shell::CommandInsmod(IN ULONG Argc,
IN PWCHAR *Argv)
{
EFI_STATUS Status;
/* Check if the module name was provided */
if(Argc != 2)
{
/* Print usage message and return */
Console::Print(L"Usage: insmod <module_name>\n");
return;
}
/* Load the module */
Status = Protocol::LoadModule(Argv[1]);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to load module, print error message */
Console::Print(L"ERROR: Failed to load module '%S' (Status: 0x%llx).\n", Argv[1], Status);
}
}
/**
* Implements the built-in `lsmod` command. Lists all loaded XTLDR modules.
*
* @param Argc
* Supplies the number of arguments provided by the user.
*
* @param Argv
* Supplies a list of arguments provided by the user.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
Shell::CommandLsmod(IN ULONG Argc,
IN PWCHAR *Argv)
{
PXTBL_MODULE_INFO ModuleInfo;
PLIST_ENTRY ModulesList;
PLIST_ENTRY ListEntry;
/* Print header */
Console::Print(L"Module Name Version Base Address Size\n");
Console::Print(L"----------------------------------------------------------------------\n");
/* Get modules list */
ModulesList = Protocol::GetModulesList();
if(ModulesList == NULLPTR)
{
/* No modules loaded */
return;
}
/* Iterate over all loaded modules */
ListEntry = ModulesList->Flink;
while(ListEntry != ModulesList)
{
/* Retrieve the module information */
ModuleInfo = CONTAIN_RECORD(ListEntry, XTBL_MODULE_INFO, Flink);
/* Print module information */
Console::Print(L"%-16S %-16S 0x%016llx %llu\n",
ModuleInfo->ModuleName, ModuleInfo->Version,
(ULONGLONG)ModuleInfo->ModuleBase, ModuleInfo->ModuleSize);
/* Advance to the next entry */
ListEntry = ListEntry->Flink;
}
}
/**
* Implements the built-in `poweroff` command. Shuts down the machine.
*
* @param Argc
* Supplies the number of arguments provided by the user.
*
* @param Argv
* Supplies a list of arguments provided by the user.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
Shell::CommandPoweroff(IN ULONG Argc,
IN PWCHAR *Argv)
{
/* Attempt to power off the machine */
Console::Print(L"Powering off...\n");
EfiUtils::ShutdownSystem();
/* The poweroff call failed, print error message */
Console::Print(L"ERROR: Failed to power off the machine\n");
}
/**
* Implements the built-in `reboot` command. Performs a normal system restart via the EFI runtime services.
* When the '/EFI' parameter is supplied, the routine instead schedules a reboot into the UEFI firmware setup interface.
*
* @param Argc
* Supplies the number of arguments provided by the user.
*
* @param Argv
* Supplies a list of arguments provided by the user.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
Shell::CommandReboot(IN ULONG Argc,
IN PWCHAR *Argv)
{
/* Check if the /EFI flag was specified */
if(Argc > 1 && RTL::WideString::CompareWideStringInsensitive(Argv[1], L"/EFI", 0) == 0)
{
/* Attempt to reboot into firmware setup */
Console::Print(L"Rebooting into UEFI firmware setup...\n");
EfiUtils::EnterFirmwareSetup();
/* The firmware does not support this feature, print error message */
Console::Print(L"ERROR: Reboot into firmware setup interface not supported.\n");
}
else
{
/* Perform a standard system reboot */
Console::Print(L"Rebooting...\n");
EfiUtils::RebootSystem();
/* The reboot call failed, print error message */
Console::Print(L"ERROR: Failed to reboot the machine\n");
}
}
/**
* Implements the built-in `ver` command. Prints the bootloader identification string.
*
* @param Argc
* Supplies the number of arguments provided by the user.
*
* @param Argv
* Supplies a list of arguments provided by the user.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
Shell::CommandVersion(IN ULONG Argc,
IN PWCHAR *Argv)
{
/* Check if debugging enabled */
if(DEBUG)
{
/* Print debug version of XTLDR version string */
Console::Print(L"XTLDR Boot Loader v%d.%d (%s-%s)\n",
XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR, XTOS_VERSION_DATE, XTOS_VERSION_HASH);
}
else
{
/* Print standard XTLDR version string */
Console::Print(L"XTLDR Boot Loader v%d.%d\n", XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR);
}
}
/**
* Looks up the given command name in the registered shell commands list and invokes the corresponding handler.
*
* @param Argc
* Supplies the number of arguments in the argument vector, including the command name itself.
*
* @param Argv
* Supplies a pointer to the argument vector. First argument is the command name.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
Shell::ExecuteCommand(IN ULONG Argc,
IN PWCHAR *Argv)
{
PXTBL_SHELL_COMMAND CommandEntry;
PLIST_ENTRY ListEntry;
/* Walk through the list of registered shell commands */
ListEntry = ShellCommands.Flink;
while(ListEntry != &ShellCommands)
{
/* Retrieve the shell command entry from the list node */
CommandEntry = CONTAIN_RECORD(ListEntry, XTBL_SHELL_COMMAND, Flink);
/* Perform a case-insensitive comparison against the command name */
if(RTL::WideString::CompareWideStringInsensitive(CommandEntry->Command, Argv[0], 0) == 0)
{
/* Command matches, invoke its handler and return */
CommandEntry->Handler(Argc, Argv);
return;
}
/* Advance to the next registered command */
ListEntry = ListEntry->Flink;
}
/* No matching command was found, print error message */
Console::Print(L"ERROR: '%S' is not recognized as a valid command.\n", Argv[0]);
}
/**
* Splits the supplied raw command line string into an argument count and an argument vector suitable
* for command dispatch. The input string is tokenized by whitespace.
*
* @param CommandLine
* Supplies a mutable wide-character string containing the raw command line.
*
* @param Argc
* Receives the number of arguments found in the command line.
*
* @param Argv
* Receives a pointer to an allocated array of wide-character string pointers, one for each argument.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
Shell::ParseCommand(IN PWCHAR CommandLine,
OUT PULONG Argc,
OUT PWCHAR **Argv)
{
PWCHAR *ArgumentVector, TempLine;
ULONG ArgumentCount;
EFI_STATUS Status;
/* Initialize argument count */
ArgumentCount = 0;
/* Count the tokens to determine the size of the argument vector */
TempLine = CommandLine;
while(*TempLine != L'\0')
{
/* Skip leading spaces */
while(*TempLine == L' ')
{
/* Move to the next character */
TempLine++;
}
/* Check if the end of the string was reached */
if(*TempLine == L'\0')
{
/* End of the string, break the loop */
break;
}
/* One more argument found */
ArgumentCount++;
/* Skip the characters of the token */
while(*TempLine != L'\0' && *TempLine != L' ')
{
/* Move to the next character */
TempLine++;
}
}
/* Check if the command line was empty */
if(ArgumentCount == 0)
{
/* Set argument count and vector to zero and NULL */
*Argc = 0;
*Argv = NULLPTR;
/* Return success */
return STATUS_EFI_SUCCESS;
}
/* Allocate memory for the argument vector */
Status = Memory::AllocatePool(ArgumentCount * sizeof(PWCHAR), (PVOID *)&ArgumentVector);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, return status code */
return Status;
}
/* Reset argument count and temp line */
ArgumentCount = 0;
TempLine = CommandLine;
/* Walk through the command line */
while(*TempLine != L'\0')
{
/* Skip leading whitespace */
while(*TempLine == L' ')
{
/* Move to the next character */
TempLine++;
}
/* Check if the end of the string was reached */
if(*TempLine == L'\0')
{
/* End of string reached, break the loop */
break;
}
/* Record token */
ArgumentVector[ArgumentCount] = TempLine;
ArgumentCount++;
/* Advance past the token characters */
while(*TempLine != L'\0' && *TempLine != L' ')
{
/* Move to the next character */
TempLine++;
}
/* Check if token was NULL-terminated */
if(*TempLine != L'\0')
{
/* NULL-terminate the token and move to the next character */
*TempLine = L'\0';
TempLine++;
}
}
/* Return results to the caller */
*Argc = ArgumentCount;
*Argv = ArgumentVector;
return STATUS_EFI_SUCCESS;
} }
/** /**
@@ -446,486 +42,9 @@ Shell::PrintPrompt()
/* Set prompt color */ /* Set prompt color */
Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_YELLOW); Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_YELLOW);
/* Print prompt at the start of the line */ /* Print prompt */
Console::Print(L"\rXTLDR> "); Console::Print(L"XTLDR> ");
/* Reset standard shell colors */ /* Reset standard shell colors */
Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
} }
/**
* Prints the whole prompt line, including the current command line and the cursor position.
*
* @param Buffer
* Supplies a pointer to the buffer containing the command line.
*
* @param BufferLength
* Supplies the buffer text length.
*
* @param CursorPosition
* Supplies the current cursor position.
*
* @param PreviousBufferLength
* Supplies the previous buffer text length to clear artifacts.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
Shell::PrintPromptLine(IN PWCHAR Buffer,
IN ULONG BufferLength,
IN ULONG CursorPosition,
IN ULONG PreviousBufferLength)
{
INT32 TargetX, TargetY;
WCHAR SavedChar;
ULONG Index;
/* Print the prompt */
PrintPrompt();
/* Temporarily truncate the string to capture cursor position */
SavedChar = Buffer[CursorPosition];
Buffer[CursorPosition] = L'\0';
/* Print up to the cursor position */
Console::Print(L"%S", Buffer);
/* Capture target cursor coordinates from the EFI text mode structure */
TargetX = XtLoader::GetEfiSystemTable()->ConOut->Mode->CursorColumn;
TargetY = XtLoader::GetEfiSystemTable()->ConOut->Mode->CursorRow;
/* Restore the character and print the remainder of the buffer */
Buffer[CursorPosition] = SavedChar;
Console::Print(L"%S", Buffer + CursorPosition);
/* Check if the previous buffer was longer than the current one */
if(PreviousBufferLength > BufferLength)
{
/* Clear artifacts from the previous longer line */
for(Index = 0; Index < (PreviousBufferLength - BufferLength); Index++)
{
/* Print a white space */
Console::Print(L" ");
}
}
/* Move the cursor back to the correct target position */
Console::SetCursorPosition(TargetX, TargetY);
}
/**
* Reads a complete line of input from the shell console into the supplied buffer.
*
* @param Buffer
* Supplies a pointer to a wide-character buffer that receives the entered command line.
*
* @param BufferSize
* Supplies the capacity of the buffer, in wide characters.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
Shell::ReadCommand(OUT PWCHAR Buffer,
IN ULONG BufferSize)
{
ULONG BufferLength, CursorPosition, OldBufferLength;
UINT_PTR EventIndex;
EFI_INPUT_KEY Key;
/* Start with an empty buffer */
CursorPosition = 0;
BufferLength = 0;
Buffer[0] = L'\0';
/* Reset history index */
HistoryIndex = HistoryCount;
/* Read characters until the user submits the command line */
while(TRUE)
{
/* Wait until a key event is available */
EfiUtils::WaitForEfiEvent(1, &(XtLoader::GetEfiSystemTable()->ConIn->WaitForKey), &EventIndex);
/* Read the keystroke from the input device */
Console::ReadKeyStroke(&Key);
/* Capture the previous line length to wipe possible artifacts */
OldBufferLength = BufferLength;
/* Check the keystroke */
if(Key.UnicodeChar == 0x0D)
{
/* ENTER key pressed, terminate the buffer and move to a new line */
Buffer[BufferLength] = L'\0';
Console::Print(L"\n");
/* Check if the buffer is not empty */
if(BufferLength > 0)
{
/* Check if the history is not full */
if(HistoryCount < XTBL_SH_HISTORY_ENTRIES)
{
/* Store command in history and increment history count */
RTL::Memory::CopyMemory(History[HistoryCount], Buffer, (BufferLength + 1) * sizeof(WCHAR));
HistoryCount++;
}
else
{
/* Shift history entries to fit new command */
RTL::Memory::MoveMemory(History[0],
History[1],
(XTBL_SH_HISTORY_ENTRIES - 1) * XTBL_SH_MAX_LINE_LENGTH * sizeof(WCHAR));
RTL::Memory::CopyMemory(History[XTBL_SH_HISTORY_ENTRIES - 1],
Buffer,
(BufferLength + 1) * sizeof(WCHAR));
}
}
/* Return the command line to the caller */
return;
}
else if(Key.ScanCode == 0x01)
{
/* UP key pressed, go back in history */
if(HistoryIndex > 0)
{
/* Decrement history index */
HistoryIndex--;
/* Copy history entry to buffer and update cursor position */
BufferLength = RTL::WideString::WideStringLength(History[HistoryIndex], XTBL_SH_MAX_LINE_LENGTH - 1);
RTL::Memory::CopyMemory(Buffer, History[HistoryIndex], (BufferLength + 1) * sizeof(WCHAR));
CursorPosition = BufferLength;
/* Reprint the prompt line */
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
}
/* Continue to the next iteration */
continue;
}
else if(Key.ScanCode == 0x02)
{
/* DOWN key pressed, go forward in history */
if(HistoryIndex < HistoryCount)
{
/* Increment history index */
HistoryIndex++;
/* Check if we are at the end of history */
if(HistoryIndex == HistoryCount)
{
/* End of history, show empty prompt */
Buffer[0] = L'\0';
BufferLength = 0;
CursorPosition = 0;
}
else
{
/* Copy history entry to buffer and update cursor position */
BufferLength = RTL::WideString::WideStringLength(History[HistoryIndex],
XTBL_SH_MAX_LINE_LENGTH - 1);
RTL::Memory::CopyMemory(Buffer, History[HistoryIndex], (BufferLength + 1) * sizeof(WCHAR));
CursorPosition = BufferLength;
}
/* Reprint the prompt line */
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
}
/* Continue to the next iteration */
continue;
}
else if(Key.ScanCode == 0x03)
{
/* RIGHT key pressed, move cursor right */
if(CursorPosition < BufferLength)
{
/* Increment cursor position */
CursorPosition++;
/* Reprint the prompt line */
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
}
/* Continue to the next iteration */
continue;
}
else if(Key.ScanCode == 0x04)
{
/* LEFT key pressed, move cursor left */
if(CursorPosition > 0)
{
/* Decrement cursor position */
CursorPosition--;
/* Reprint the prompt line */
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
}
/* Continue to the next iteration */
continue;
}
else if(Key.ScanCode == 0x05)
{
/* HOME key pressed, move cursor to beginning */
if (CursorPosition > 0)
{
/* Set cursor position to beginning of the line and reprint the prompt line */
CursorPosition = 0;
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
}
/* Continue to the next iteration */
continue;
}
else if(Key.ScanCode == 0x06)
{
/* END key pressed, move cursor to end */
if (CursorPosition < BufferLength)
{
/* Set cursor position to end of the line and reprint the prompt line */
CursorPosition = BufferLength;
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
}
/* Continue to the next iteration */
continue;
}
else if(Key.ScanCode == 0x17)
{
/* ESC key pressed, discard the current input, move to a new line and reprint the prompt */
Buffer[0] = L'\0';
Console::Print(L"\n");
PrintPrompt();
/* Reset cursor position, buffer length and history index */
CursorPosition = 0;
BufferLength = 0;
HistoryIndex = HistoryCount;
/* Continue reading the command line */
continue;
}
else if(Key.ScanCode == 0x08)
{
/* DELETE key pressed, remove character at cursor */
if(CursorPosition < BufferLength)
{
/* Move memory to remove the character at cursor */
RTL::Memory::MoveMemory(Buffer + CursorPosition,
Buffer + CursorPosition + 1,
(BufferLength - CursorPosition) * sizeof(WCHAR));
/* Decrement buffer length and reprint the prompt line */
BufferLength--;
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
}
/* Continue to the next iteration */
continue;
}
else if(Key.UnicodeChar == 0x08)
{
/* BACKSPACE key pressed, delete character before cursor */
if(CursorPosition > 0)
{
/* Move memory to remove the character before cursor */
RTL::Memory::MoveMemory(Buffer + CursorPosition - 1,
Buffer + CursorPosition,
(BufferLength - CursorPosition + 1) * sizeof(WCHAR));
/* Decrement cursor position and buffer length */
CursorPosition--;
BufferLength--;
/* Reprint the prompt line */
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
}
/* Continue reading the command line */
continue;
}
else if(Key.UnicodeChar == 0)
{
/* Ignore non-printable characters */
continue;
}
/* Make sure there is room in the buffer (reserve one slot for NULL terminator) */
if(BufferLength < BufferSize - 1)
{
/* Insert character in the middle or end of the buffer */
RTL::Memory::MoveMemory(Buffer + CursorPosition + 1,
Buffer + CursorPosition,
(BufferLength - CursorPosition + 1) * sizeof(WCHAR));
Buffer[CursorPosition] = Key.UnicodeChar;
/* Increment cursor position and buffer length */
CursorPosition++;
BufferLength++;
/* Reprint the prompt line */
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
}
}
}
/**
* Registers a new command in the XTLDR shell.
*
* @param Command
* Supplies the command keyword that the user types at the shell prompt.
*
* @param Description
* Supplies a short help string displayed by the 'help' command.
*
* @param Handler
* Supplies a pointer to the function that implements the command.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
Shell::RegisterCommand(IN PCWSTR Command,
IN PCWSTR Description,
IN PBL_SHELL_COMMAND Handler)
{
PXTBL_SHELL_COMMAND CommandEntry;
PLIST_ENTRY ListEntry;
EFI_STATUS Status;
/* Verify that a command with this name has not already been registered */
ListEntry = ShellCommands.Flink;
while(ListEntry != &ShellCommands)
{
/* Retrieve the existing shell command entry */
CommandEntry = CONTAIN_RECORD(ListEntry, XTBL_SHELL_COMMAND, Flink);
/* Compare command names case-insensitively */
if(RTL::WideString::CompareWideStringInsensitive(CommandEntry->Command, Command, 0) == 0)
{
/* Duplicate command name, return error */
return STATUS_EFI_INVALID_PARAMETER;
}
/* Advance to the next entry */
ListEntry = ListEntry->Flink;
}
/* Allocate memory for the new command entry */
Status = Memory::AllocatePool(sizeof(XTBL_SHELL_COMMAND), (PVOID *)&CommandEntry);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, return error */
return STATUS_EFI_OUT_OF_RESOURCES;
}
/* Populate the new command entry */
CommandEntry->Command = (PWCHAR)Command;
CommandEntry->Description = (PWCHAR)Description;
CommandEntry->Handler = Handler;
/* Append the command to the global shell commands list */
RTL::LinkedList::InsertTailList(&ShellCommands, &CommandEntry->Flink);
/* Return success */
return STATUS_EFI_SUCCESS;
}
/**
* Registers all built-in shell commands that are provided by the XTLDR.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
Shell::RegisterBuiltinCommands()
{
/* Register all built-in shell commands */
RegisterCommand(L"exit", L"Exits the shell and returns to the boot menu", CommandExit);
RegisterCommand(L"help", L"Displays a list of all available shell commands", CommandHelp);
RegisterCommand(L"insmod", L"Loads a specific XTLDR module", CommandInsmod);
RegisterCommand(L"lsmod", L"Displays a list of loaded modules", CommandLsmod);
RegisterCommand(L"poweroff", L"Shuts down the machine", CommandPoweroff);
RegisterCommand(L"reboot", L"Reboots the machine (/EFI to enter firmware setup)", CommandReboot);
RegisterCommand(L"ver", L"Displays the boot loader version information", CommandVersion);
}
/**
* Initializes the command list, registers the built-in commands and enters an interactive XTLDR shell loop.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
Shell::StartLoaderShell()
{
WCHAR CommandLine[XTBL_SH_MAX_LINE_LENGTH];
PWCHAR *ArgumentVector;
ULONG ArgumentCount;
EFI_STATUS Status;
/* Initialize console */
Console::InitializeConsole();
/* Initialize the shell commands list */
RTL::LinkedList::InitializeListHead(&ShellCommands);
/* Register all built-in commands */
RegisterBuiltinCommands();
/* Clear the shell exit request flag */
ExitRequest = FALSE;
/* Main XTLDR shell loop */
while(!ExitRequest)
{
/* Display the shell prompt */
PrintPrompt();
/* Read a command line */
ReadCommand(CommandLine, XTBL_SH_MAX_LINE_LENGTH);
/* Parse the command line into a list of arguments */
Status = ParseCommand(CommandLine, &ArgumentCount, &ArgumentVector);
if(Status != STATUS_EFI_SUCCESS)
{
/* Parsing failed, print error and continue */
Console::Print(L"ERROR: Failed to parse command line (Status: 0x%llx).\n\n", Status);
continue;
}
/* Check if command line is empty */
if(ArgumentCount == 0)
{
/* Skip empty command line */
continue;
}
/* Check if command line starts with a comment symbol (#) */
if(ArgumentVector[0][0] != L'#')
{
/* Dispatch the command */
ExecuteCommand(ArgumentCount, ArgumentVector);
}
/* Free the argument vector */
Memory::FreePool(ArgumentVector);
/* Print a trailing blank line for visual separation */
Console::Print(L"\n");
}
}

View File

@@ -717,9 +717,9 @@ TextUi::DisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry)
RedrawEntries = TRUE; RedrawEntries = TRUE;
} }
} }
else if(Key.ScanCode == 0x14) else if(Key.UnicodeChar == 0x02)
{ {
/* F10 key pressed, boot the OS */ /* CTRL-B key pressed, boot the OS */
Console::SetAttributes(Handle.DialogColor | Handle.TextColor); Console::SetAttributes(Handle.DialogColor | Handle.TextColor);
Console::ClearLine(Handle.PosY + Handle.Height + 4); Console::ClearLine(Handle.PosY + Handle.Height + 4);
Console::SetCursorPosition(4, Handle.PosY + Handle.Height + 4); Console::SetCursorPosition(4, Handle.PosY + Handle.Height + 4);
@@ -1673,7 +1673,7 @@ TextUi::DrawEditMenu(OUT PXTBL_DIALOG_HANDLE Handle)
Console::SetCursorPosition(0, Handle->PosY + Handle->Height); Console::SetCursorPosition(0, Handle->PosY + Handle->Height);
Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
Console::Print(L" Use cursors to change the selection. Press ENTER key to edit the chosen\n" Console::Print(L" Use cursors to change the selection. Press ENTER key to edit the chosen\n"
L" option, ESC to return to the main boot menu or F10 to boot.\n"); L" option, ESC to return to the main boot menu or CTRL-B to boot.\n");
} }
/** /**

View File

@@ -1,3 +1 @@
add_subdirectory("xtadk")
set_sdk_target("xtdk/" "include") set_sdk_target("xtdk/" "include")

View File

@@ -59,86 +59,6 @@ function(add_module_linker_flags MODULE FLAGS)
set_module_property(${MODULE} LINK_FLAGS ${FLAGS}) set_module_property(${MODULE} LINK_FLAGS ${FLAGS})
endfunction() endfunction()
# This function compiles XT Assembly Development Kit
function(generate_xtadk TARGET_NAME SOURCE_FILES)
# Define the absolute destination path for the generated header file
set(HEADER_OUTPUT "${EXECTOS_BINARY_DIR}/sdk/includes/${TARGET_NAME}.h")
get_filename_component(HEADER_OUTPUT_DIRECTORY "${HEADER_OUTPUT}" DIRECTORY)
# Tokenize global CXX flags into a list to ensure correct argument expansion
separate_arguments(COMPILER_FLAGS NATIVE_COMMAND "${CMAKE_CXX_FLAGS}")
# Resolve and tokenize build-configuration specific flags
string(TOUPPER "${CMAKE_BUILD_TYPE}" BUILD_TYPE)
if(BUILD_TYPE)
separate_arguments(BUILD_TYPE_SPECIFIC_FLAGS NATIVE_COMMAND "${CMAKE_CXX_FLAGS_${BUILD_TYPE}}")
endif()
# Retrieve compiler definitions, include paths, and options
get_directory_property(COMPILE_DEFINITIONS COMPILE_DEFINITIONS)
get_directory_property(INCLUDE_DIRECTORIES INCLUDE_DIRECTORIES)
get_directory_property(COMPILE_OPTIONS COMPILE_OPTIONS)
# Initialize the final compiler argument list
set(COMPILER_ARGUMENTS "")
list(APPEND COMPILER_ARGUMENTS ${COMPILER_FLAGS} ${BUILD_TYPE_SPECIFIC_FLAGS})
# Transform definitions into MSVC-style
foreach(DEFINITION ${COMPILE_DEFINITIONS})
list(APPEND COMPILER_ARGUMENTS "/D${DEFINITION}")
endforeach()
# Transform include paths into MSVC-style
foreach(INCLUDE_PATH ${INCLUDE_DIRECTORIES})
list(APPEND COMPILER_ARGUMENTS "/I${INCLUDE_PATH}")
endforeach()
# Append all supplemental compiler options
list(APPEND COMPILER_ARGUMENTS ${COMPILE_OPTIONS})
set(COLLECTED_ASSEMBLY_OUTPUTS "")
# Iterate through each source file to create individual assembly generation rules
foreach(SOURCE_FILE_PATH ${SOURCE_FILES})
# Extract the base filename
get_filename_component(FILENAME_WITHOUT_EXTENSION "${SOURCE_FILE_PATH}" NAME_WE)
# Define the unique output path for the intermediate assembly file
set(CURRENT_ASSEMBLY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FILENAME_WITHOUT_EXTENSION}.S")
list(APPEND COLLECTED_ASSEMBLY_OUTPUTS "${CURRENT_ASSEMBLY_OUTPUT}")
get_filename_component(CURRENT_ASSEMBLY_DIRECTORY "${CURRENT_ASSEMBLY_OUTPUT}" DIRECTORY)
# Execute the compiler to generate assembly code
add_custom_command(
OUTPUT "${CURRENT_ASSEMBLY_OUTPUT}"
COMMAND ${CMAKE_COMMAND} -E make_directory "${CURRENT_ASSEMBLY_DIRECTORY}"
COMMAND ${CMAKE_CXX_COMPILER}
${COMPILER_ARGUMENTS}
/c /FAs /Fa${CURRENT_ASSEMBLY_OUTPUT}
-- ${SOURCE_FILE_PATH}
DEPENDS "${SOURCE_FILE_PATH}"
COMMENT "Generating XTADK Assembly: ${FILENAME_WITHOUT_EXTENSION}"
VERBATIM
COMMAND_EXPAND_LISTS
)
endforeach()
# Aggregate all generated assembly units into a single consolidated XTADK header
add_custom_command(
OUTPUT "${HEADER_OUTPUT}"
COMMAND ${CMAKE_COMMAND} -E make_directory "${HEADER_OUTPUT_DIRECTORY}"
COMMAND xtadkgen ${COLLECTED_ASSEMBLY_OUTPUTS} -O "${HEADER_OUTPUT}"
DEPENDS ${COLLECTED_ASSEMBLY_OUTPUTS}
COMMENT "Generating XTADK header: ${TARGET_NAME}"
VERBATIM
)
# Establish the generation target and expose the header directory via an interface library
add_custom_target(${TARGET_NAME}_gen DEPENDS "${HEADER_OUTPUT}")
add_library(${TARGET_NAME} INTERFACE)
add_dependencies(${TARGET_NAME} ${TARGET_NAME}_gen)
target_include_directories(${TARGET_NAME} INTERFACE "${EXECTOS_BINARY_DIR}/sdk/includes")
endfunction()
# This function compiles an assembly bootsector file into a flat binary # This function compiles an assembly bootsector file into a flat binary
function(compile_bootsector NAME SOURCE BASEADDR ENTRYPOINT) function(compile_bootsector NAME SOURCE BASEADDR ENTRYPOINT)
set(BINARY_NAME "${NAME}.bin") set(BINARY_NAME "${NAME}.bin")

View File

@@ -13,10 +13,6 @@ The ovmf_vars files, store UEFI variables, which are used to store and retrieve
boot options, device settings, and system preferences. The ovmf_vars file contains the persistent variables specific to boot options, device settings, and system preferences. The ovmf_vars file contains the persistent variables specific to
a virtual machine, allowing it to maintain its configuration across multiple boot sessions. a virtual machine, allowing it to maintain its configuration across multiple boot sessions.
## BOCHS ROM BIOS
The rombios.bin file contains the ROM BIOS image for Bochs. This image is distributed under the GNU Lesser General Public
License (LGPL).
## Video BIOS (LGPL'd VGABios) ## Video BIOS (LGPL'd VGABios)
The vgabios.bin file contains the Video Bios for Bochs and QEMU. This VGA Bios is very specific to the emulated VGA card. The vgabios.bin file contains the Video Bios for Bochs and QEMU. This VGA Bios is very specific to the emulated VGA card.
It is NOT meant to drive a physical vga card. It also implements support for VBE version 2.0. It is NOT meant to drive a physical vga card. It also implements support for VBE version 2.0.

View File

@@ -1,14 +0,0 @@
# XT Assembly Development Kit
PROJECT(XTADK)
# Specify include directories
include_directories(
${EXECTOS_SOURCE_DIR}/sdk/xtdk
${XTADK_SOURCE_DIR}/includes)
# Specify list of XTADK source code files
list(APPEND XTADK_SOURCE
${XTADK_SOURCE_DIR}/${ARCH}/ke.cc)
# Generate assembly header from XTADK sources
generate_xtadk(xtadk "${XTADK_SOURCE}")

View File

@@ -1,91 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: sdk/xtadk/amd64/ke.cc
* DESCRIPTION: ADK generator for AMD64 version of Kernel Library
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtkmapi.h>
#include <adkdefs.h>
/**
* Generates a definitions file for the Kernel Library used by the XTOS kernel assembly code
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCLINK
XTAPI
VOID
GenerateAssemblyDefinitions(VOID)
{
/* Generate KTRAP_FRAME offsets */
ADK_OFFSET(KTRAP_FRAME, Xmm0);
ADK_OFFSET(KTRAP_FRAME, Xmm1);
ADK_OFFSET(KTRAP_FRAME, Xmm2);
ADK_OFFSET(KTRAP_FRAME, Xmm3);
ADK_OFFSET(KTRAP_FRAME, Xmm4);
ADK_OFFSET(KTRAP_FRAME, Xmm5);
ADK_OFFSET(KTRAP_FRAME, Xmm6);
ADK_OFFSET(KTRAP_FRAME, Xmm7);
ADK_OFFSET(KTRAP_FRAME, Xmm8);
ADK_OFFSET(KTRAP_FRAME, Xmm9);
ADK_OFFSET(KTRAP_FRAME, Xmm10);
ADK_OFFSET(KTRAP_FRAME, Xmm11);
ADK_OFFSET(KTRAP_FRAME, Xmm12);
ADK_OFFSET(KTRAP_FRAME, Xmm13);
ADK_OFFSET(KTRAP_FRAME, Xmm14);
ADK_OFFSET(KTRAP_FRAME, Xmm15);
ADK_OFFSET(KTRAP_FRAME, MxCsr);
ADK_OFFSET(KTRAP_FRAME, PreviousMode);
ADK_OFFSET(KTRAP_FRAME, Cr2);
ADK_OFFSET(KTRAP_FRAME, Cr3);
ADK_OFFSET(KTRAP_FRAME, Dr0);
ADK_OFFSET(KTRAP_FRAME, Dr1);
ADK_OFFSET(KTRAP_FRAME, Dr2);
ADK_OFFSET(KTRAP_FRAME, Dr3);
ADK_OFFSET(KTRAP_FRAME, Dr6);
ADK_OFFSET(KTRAP_FRAME, Dr7);
ADK_OFFSET(KTRAP_FRAME, SegDs);
ADK_OFFSET(KTRAP_FRAME, SegEs);
ADK_OFFSET(KTRAP_FRAME, SegFs);
ADK_OFFSET(KTRAP_FRAME, SegGs);
ADK_OFFSET(KTRAP_FRAME, Rax);
ADK_OFFSET(KTRAP_FRAME, Rbx);
ADK_OFFSET(KTRAP_FRAME, Rcx);
ADK_OFFSET(KTRAP_FRAME, Rdx);
ADK_OFFSET(KTRAP_FRAME, R8);
ADK_OFFSET(KTRAP_FRAME, R9);
ADK_OFFSET(KTRAP_FRAME, R10);
ADK_OFFSET(KTRAP_FRAME, R11);
ADK_OFFSET(KTRAP_FRAME, R12);
ADK_OFFSET(KTRAP_FRAME, R13);
ADK_OFFSET(KTRAP_FRAME, R14);
ADK_OFFSET(KTRAP_FRAME, R15);
ADK_OFFSET(KTRAP_FRAME, Rsi);
ADK_OFFSET(KTRAP_FRAME, Rdi);
ADK_OFFSET(KTRAP_FRAME, Rbp);
ADK_OFFSET(KTRAP_FRAME, Vector);
ADK_OFFSET(KTRAP_FRAME, ErrorCode);
ADK_OFFSET(KTRAP_FRAME, ExceptionFrame);
ADK_OFFSET(KTRAP_FRAME, Rip);
ADK_OFFSET(KTRAP_FRAME, SegCs);
ADK_OFFSET(KTRAP_FRAME, Flags);
ADK_OFFSET(KTRAP_FRAME, Rsp);
ADK_OFFSET(KTRAP_FRAME, SegSs);
/* Generate KTRAP_FRAME size and REGISTERS_SIZE */
ADK_SIZE(KTRAP_FRAME);
ADK_SIZE_FROM(REGISTERS_SIZE, KTRAP_FRAME, Rax);
/* Generate PROCESSOR_START_BLOCK offsets */
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr3);
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr4);
ADK_OFFSET(PROCESSOR_START_BLOCK, EntryPoint);
ADK_OFFSET(PROCESSOR_START_BLOCK, ProcessorStructures);
ADK_OFFSET(PROCESSOR_START_BLOCK, Stack);
ADK_OFFSET(PROCESSOR_START_BLOCK, Started);
}

View File

@@ -1,65 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: sdk/xtadk/i686/ke.cc
* DESCRIPTION: ADK generator for i686 version of Kernel Library
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtkmapi.h>
#include <adkdefs.h>
/**
* Generates a definitions file for the Kernel Library used by the XTOS kernel assembly code
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCLINK
XTAPI
VOID
GenerateAssemblyDefinitions(VOID)
{
/* Generate KTRAP_FRAME offsets */
ADK_OFFSET(KTRAP_FRAME, PreviousMode);
ADK_OFFSET(KTRAP_FRAME, Cr2);
ADK_OFFSET(KTRAP_FRAME, Cr3);
ADK_OFFSET(KTRAP_FRAME, Dr0);
ADK_OFFSET(KTRAP_FRAME, Dr1);
ADK_OFFSET(KTRAP_FRAME, Dr2);
ADK_OFFSET(KTRAP_FRAME, Dr3);
ADK_OFFSET(KTRAP_FRAME, Dr6);
ADK_OFFSET(KTRAP_FRAME, Dr7);
ADK_OFFSET(KTRAP_FRAME, SegDs);
ADK_OFFSET(KTRAP_FRAME, SegEs);
ADK_OFFSET(KTRAP_FRAME, SegFs);
ADK_OFFSET(KTRAP_FRAME, SegGs);
ADK_OFFSET(KTRAP_FRAME, Eax);
ADK_OFFSET(KTRAP_FRAME, Ebx);
ADK_OFFSET(KTRAP_FRAME, Ecx);
ADK_OFFSET(KTRAP_FRAME, Edx);
ADK_OFFSET(KTRAP_FRAME, Esi);
ADK_OFFSET(KTRAP_FRAME, Edi);
ADK_OFFSET(KTRAP_FRAME, Ebp);
ADK_OFFSET(KTRAP_FRAME, Vector);
ADK_OFFSET(KTRAP_FRAME, ErrorCode);
ADK_OFFSET(KTRAP_FRAME, Eip);
ADK_OFFSET(KTRAP_FRAME, SegCs);
ADK_OFFSET(KTRAP_FRAME, Flags);
ADK_OFFSET(KTRAP_FRAME, Esp);
ADK_OFFSET(KTRAP_FRAME, SegSs);
/* Generate KTRAP_FRAME size and REGISTERS_SIZE */
ADK_SIZE(KTRAP_FRAME);
ADK_SIZE_FROM(REGISTERS_SIZE, KTRAP_FRAME, Eax);
/* Generate PROCESSOR_START_BLOCK offsets */
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr3);
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr4);
ADK_OFFSET(PROCESSOR_START_BLOCK, EntryPoint);
ADK_OFFSET(PROCESSOR_START_BLOCK, ProcessorStructures);
ADK_OFFSET(PROCESSOR_START_BLOCK, Stack);
ADK_OFFSET(PROCESSOR_START_BLOCK, Started);
}

View File

@@ -1,19 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: sdk/xtadk/adkdefs.h
* DESCRIPTION: Definitions for XTADK
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTADK_ADKDEFS_H
#define __XTADK_ADKDEFS_H
/* Macros for calculating structure size and offsets for assembler code */
#define ADK_DEFINE(Symbol, Value) __asm__ volatile("\n\t# ==> " #Symbol " %c0" : : "i" ((SIZE_T)(Value)))
#define ADK_OFFSET(Structure, Member) ADK_DEFINE(Structure ## _ ## Member, FIELD_OFFSET(Structure, Member))
#define ADK_SIZE(Structure) ADK_DEFINE(Structure ## _SIZE, sizeof(Structure))
#define ADK_SIZE_FROM(Name, Structure, Member) ADK_DEFINE(Structure ## _ ## Name, sizeof(Structure) - FIELD_OFFSET(Structure, Member))
#endif /* __XTADK_ADKDEFS_H */

View File

@@ -12,7 +12,6 @@
#include <xtdefs.h> #include <xtdefs.h>
#include <xtstruct.h> #include <xtstruct.h>
#include <xttypes.h> #include <xttypes.h>
#include ARCH_HEADER(xtstruct.h)
/* Control Register 0 constants */ /* Control Register 0 constants */
@@ -128,10 +127,6 @@
#define X86_EFLAGS_VIP_MASK 0x00100000 /* Virtual Interrupt Pending */ #define X86_EFLAGS_VIP_MASK 0x00100000 /* Virtual Interrupt Pending */
#define X86_EFLAGS_ID_MASK 0x00200000 /* Identification */ #define X86_EFLAGS_ID_MASK 0x00200000 /* Identification */
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* CPU vendor enumeration list */ /* CPU vendor enumeration list */
typedef enum _CPU_VENDOR typedef enum _CPU_VENDOR
{ {
@@ -140,18 +135,6 @@ typedef enum _CPU_VENDOR
CPU_VENDOR_UNKNOWN = 0xFFFFFFFF CPU_VENDOR_UNKNOWN = 0xFFFFFFFF
} CPU_VENDOR, *PCPU_VENDOR; } CPU_VENDOR, *PCPU_VENDOR;
/* CPUID advanced power management features (0x80000007) enumeration list */
typedef enum _CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT
{
CPUID_FEATURES_EDX_TS = 1 << 0, /* Temperature Sensor */
CPUID_FEATURES_EDX_FIS = 1 << 1, /* Frequency ID Selection */
CPUID_FEATURES_EDX_VIS = 1 << 2, /* Voltage ID Selection */
CPUID_FEATURES_EDX_TTS = 1 << 3, /* ThermaTrip Support */
CPUID_FEATURES_EDX_HTC = 1 << 4, /* Hardware Thermal Throttling */
CPUID_FEATURES_EDX_STC = 1 << 5, /* Software Thermal Throttling */
CPUID_FEATURES_EDX_TSCI = 1 << 8 /* TSC Invariant */
} CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT, *PCPUID_FEATURES_ADVANCED_POWER_MANAGEMENT;
/* CPUID extended features (0x80000001) enumeration list */ /* CPUID extended features (0x80000001) enumeration list */
typedef enum _CPUID_FEATURES_EXTENDED typedef enum _CPUID_FEATURES_EXTENDED
{ {
@@ -193,23 +176,6 @@ typedef enum _CPUID_FEATURES_EXTENDED
CPUID_FEATURES_EDX_3DNOW = 1 << 31 CPUID_FEATURES_EDX_3DNOW = 1 << 31
} CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED; } CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
/* CPUID Thermal and Power Management features (0x00000006) enumeration list */
typedef enum _CPUID_FEATURES_POWER_MANAGEMENT
{
CPUID_FEATURES_EAX_DTHERM = 1 << 0,
CPUID_FEATURES_EAX_IDA = 1 << 1,
CPUID_FEATURES_EAX_ARAT = 1 << 2,
CPUID_FEATURES_EAX_PLN = 1 << 4,
CPUID_FEATURES_EAX_PTS = 1 << 6,
CPUID_FEATURES_EAX_HWP = 1 << 7,
CPUID_FEATURES_EAX_HWP_NOTIFY = 1 << 8,
CPUID_FEATURES_EAX_HWP_ACT_WINDOW = 1 << 9,
CPUID_FEATURES_EAX_HWP_EPP = 1 << 10,
CPUID_FEATURES_EAX_HWP_PKG_REQ = 1 << 11,
CPUID_FEATURES_EAX_HWP_HIGHEST_PERF_CHANGE = 1 << 15,
CPUID_FEATURES_EAX_HFI = 1 << 19
} CPUID_FEATURES_LEAF6, *PCPUID_FEATURES_LEAF6;
/* CPUID STD1 features (0x00000001) enumeration list */ /* CPUID STD1 features (0x00000001) enumeration list */
typedef enum _CPUID_FEATURES_STANDARD1 typedef enum _CPUID_FEATURES_STANDARD1
{ {
@@ -236,7 +202,7 @@ typedef enum _CPUID_FEATURES_STANDARD1
CPUID_FEATURES_ECX_X2APIC = 1 << 21, CPUID_FEATURES_ECX_X2APIC = 1 << 21,
CPUID_FEATURES_ECX_MOVBE = 1 << 22, CPUID_FEATURES_ECX_MOVBE = 1 << 22,
CPUID_FEATURES_ECX_POPCNT = 1 << 23, CPUID_FEATURES_ECX_POPCNT = 1 << 23,
CPUID_FEATURES_ECX_TSC_DEADLINE = 1 << 24, CPUID_FEATURES_ECX_TSC = 1 << 24,
CPUID_FEATURES_ECX_AES = 1 << 25, CPUID_FEATURES_ECX_AES = 1 << 25,
CPUID_FEATURES_ECX_XSAVE = 1 << 26, CPUID_FEATURES_ECX_XSAVE = 1 << 26,
CPUID_FEATURES_ECX_OSXSAVE = 1 << 27, CPUID_FEATURES_ECX_OSXSAVE = 1 << 27,
@@ -410,29 +376,20 @@ typedef enum _CPUID_FEATURES_STANDARD7_LEAF1
/* CPUID requests */ /* CPUID requests */
typedef enum _CPUID_REQUESTS typedef enum _CPUID_REQUESTS
{ {
CPUID_GET_VENDOR_STRING = 0x00000000, CPUID_GET_VENDOR_STRING,
CPUID_GET_STANDARD1_FEATURES = 0x00000001, CPUID_GET_STANDARD1_FEATURES,
CPUID_GET_TLB_CACHE = 0x00000002, CPUID_GET_TLB_CACHE,
CPUID_GET_SERIAL = 0x00000003, CPUID_GET_SERIAL,
CPUID_GET_CACHE_TOPOLOGY = 0x00000004, CPUID_GET_CACHE_TOPOLOGY,
CPUID_GET_MONITOR_MWAIT = 0x00000005, CPUID_GET_MONITOR_MWAIT,
CPUID_GET_POWER_MANAGEMENT = 0x00000006, CPUID_GET_POWER_MANAGEMENT,
CPUID_GET_STANDARD7_FEATURES = 0x00000007, CPUID_GET_STANDARD7_FEATURES
CPUID_GET_TSC_CRYSTAL_CLOCK = 0x00000015,
CPUID_GET_EXTENDED_MAX = 0x80000000,
CPUID_GET_EXTENDED_FEATURES = 0x80000001,
CPUID_GET_ADVANCED_POWER_MANAGEMENT = 0x80000007
} CPUID_REQUESTS, *PCPUID_REQUESTS; } CPUID_REQUESTS, *PCPUID_REQUESTS;
/* Interrupt handler */
typedef VOID (*PINTERRUPT_HANDLER)(PKTRAP_FRAME TrapFrame);
/* Processor identification information */ /* Processor identification information */
typedef struct _CPU_IDENTIFICATION typedef struct _CPU_IDENTIFICATION
{ {
ULONGLONG ExtendedFeatureBits;
USHORT Family; USHORT Family;
ULONGLONG FeatureBits;
USHORT Model; USHORT Model;
USHORT Stepping; USHORT Stepping;
CPU_VENDOR Vendor; CPU_VENDOR Vendor;
@@ -469,5 +426,4 @@ typedef enum _TRAMPOLINE_TYPE
TrampolineEnableXpa TrampolineEnableXpa
} TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE; } TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_AMD64_ARTYPES_H */ #endif /* __XTDK_AMD64_ARTYPES_H */

View File

@@ -15,9 +15,6 @@
#include <amd64/xtstruct.h> #include <amd64/xtstruct.h>
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Hardware layer routines forward references */ /* Hardware layer routines forward references */
XTCLINK XTCLINK
XTCDECL XTCDECL
@@ -52,5 +49,4 @@ VOID
HlWritePort32(IN USHORT Port, HlWritePort32(IN USHORT Port,
IN ULONG Value); IN ULONG Value);
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_AMD64_HLFUNCS_H */ #endif /* __XTDK_AMD64_HLFUNCS_H */

View File

@@ -9,7 +9,6 @@
#ifndef __XTDK_AMD64_HLTYPES_H #ifndef __XTDK_AMD64_HLTYPES_H
#define __XTDK_AMD64_HLTYPES_H #define __XTDK_AMD64_HLTYPES_H
#include <xtbase.h>
#include <xtdefs.h> #include <xtdefs.h>
#include <xtstruct.h> #include <xtstruct.h>
#include <xttypes.h> #include <xttypes.h>
@@ -54,27 +53,6 @@
/* Maximum number of I/O APICs */ /* Maximum number of I/O APICs */
#define APIC_MAX_IOAPICS 64 #define APIC_MAX_IOAPICS 64
/* I/O APIC base address */
#define IOAPIC_DEFAULT_BASE 0xFEC00000
/* I/O APIC definitions */
#define IOAPIC_MAX_CONTROLLERS 128
#define IOAPIC_MAX_OVERRIDES 16
#define IOAPIC_RTE_MASKED 0x100FF
#define IOAPIC_RTE_SIZE 2
#define IOAPIC_VECTOR_FREE 0xFF
#define IOAPIC_VECTOR_RESERVED 0xFE
/* IOAPIC offsets */
#define IOAPIC_IOREGSEL 0x00
#define IOAPIC_IOWIN 0x10
/* IOAPIC registers */
#define IOAPIC_ID 0x00
#define IOAPIC_VER 0x01
#define IOAPIC_ARB 0x02
#define IOAPIC_REDTBL 0x10
/* 8259/ISP PIC ports definitions */ /* 8259/ISP PIC ports definitions */
#define PIC1_CONTROL_PORT 0x20 #define PIC1_CONTROL_PORT 0x20
#define PIC1_DATA_PORT 0x21 #define PIC1_DATA_PORT 0x21
@@ -84,87 +62,6 @@
/* PIC vector definitions */ /* PIC vector definitions */
#define PIC1_VECTOR_SPURIOUS 0x37 #define PIC1_VECTOR_SPURIOUS 0x37
/* HPET General Capabilities definitions */
#define HPET_CAPABILITY_64BIT 0x2000ULL
#define HPET_CAPABILITY_LEGACY_REPLACEMENT 0x8000ULL
/* HPET General Configuration definitions */
#define HPET_CONFIG_ENABLE 0x0001ULL
#define HPET_CONFIG_LEGACY_REPLACEMENT 0x0002ULL
/* HPET Timer Configuration definitions */
#define HPET_TIMER_CONFIG_LEVEL_TRIGGERED 0x0002ULL
#define HPET_TIMER_CONFIG_ENABLED 0x0004ULL
#define HPET_TIMER_CONFIG_PERIODIC 0x0008ULL
#define HPET_TIMER_CONFIG_SUPPORTS_PERIODIC 0x0010ULL
#define HPET_TIMER_CONFIG_SUPPORTS_64BIT 0x0020ULL
#define HPET_TIMER_CONFIG_VALUE_ACCUMULATOR 0x0040ULL
#define HPET_TIMER_CONFIG_FORCE_32BIT 0x0100ULL
#define HPET_TIMER_CONFIG_FSB_ENABLED 0x4000ULL
#define HPET_TIMER_CONFIG_SUPPORTS_FSB 0x8000ULL
/* PIT ports definitions */
#define PIT_COMMAND_PORT 0x43
#define PIT_DATA_PORT0 0x40
#define PIT_DATA_PORT1 0x41
#define PIT_DATA_PORT2 0x42
/* PIT related definitions */
#define PIT_BASE_FREQUENCY 1193182
/* PIT Access Mode: Defines how the CPU reads or writes the counter value */
#define PIT_CMD_ACCESS_LATCH 0x00
#define PIT_CMD_ACCESS_LOWBYTE_ONLY 0x10
#define PIT_CMD_ACCESS_HIGHBYTE_ONLY 0x20
#define PIT_CMD_ACCESS_LOWBYTE_HIGHBYTE 0x30
/* PIT Channel Selection: Specifies the physical timer channel to configure */
#define PIT_CMD_CHANNEL0 0x00
#define PIT_CMD_CHANNEL1 0x40
#define PIT_CMD_CHANNEL2 0x80
/* PIT Operating Mode: Defines the hardware behavior and the generated waveform */
#define PIT_MODE0_INT_ON_TERMINAL_COUNT 0x00
#define PIT_MODE1_ONESHOT 0x02
#define PIT_MODE2_RATE_GENERATOR 0x04
#define PIT_MODE3_SQUARE_WAVE_GEN 0x06
#define PIT_MODE4_SOFTWARE_STROBE 0x08
#define PIT_MODE5_HARDWARE_STROBE 0x0A
/* CMOS controller access ports */
#define CMOS_SELECT_PORT 0x70
#define CMOS_DATA_PORT 0x71
/* CMOD Select port definitions */
#define CMOS_NMI_SELECT 0x80
#define CMOS_REGISTER_SECOND 0x00
#define CMOS_REGISTER_MINUTE 0x02
#define CMOS_REGISTER_HOUR 0x04
#define CMOS_REGISTER_WEEKDAY 0x06
#define CMOS_REGISTER_DAY 0x07
#define CMOS_REGISTER_MONTH 0x08
#define CMOS_REGISTER_YEAR 0x09
#define CMOS_REGISTER_A 0x0A
#define CMOS_REGISTER_B 0x0B
#define CMOS_REGISTER_C 0x0C
/* CMOS Register A definitions */
#define CMOS_REGISTER_A_RATE_MASK 0x0F
#define CMOS_REGISTER_A_UPDATE_IN_PROGRESS 0x80
/* CMOS Register B definitions */
#define CMOS_REGISTER_B_24_HOUR 0x02
#define CMOS_REGISTER_B_BINARY 0x04
#define CMOS_REGISTER_B_PERIODIC 0x40
#define CMOS_REGISTER_B_SET_CLOCK 0x80
/* CMOS Register C definitions */
#define CMOS_REGISTER_C_PERIODIC 0x40
#define CMOS_REGISTER_C_INTERRUPT 0x80
/* CMOS RTC 24-hour mode */
#define CMOS_RTC_POST_MERIDIEM 0x80
/* Serial ports information */ /* Serial ports information */
#define COMPORT_ADDRESS {0x3F8, 0x2F8, 0x3E8, 0x2E8, 0x5F8, 0x4F8, 0x5E8, 0x4E8} #define COMPORT_ADDRESS {0x3F8, 0x2F8, 0x3E8, 0x2E8, 0x5F8, 0x4F8, 0x5E8, 0x4E8}
#define COMPORT_COUNT 8 #define COMPORT_COUNT 8
@@ -172,17 +69,6 @@
/* Initial stall factor */ /* Initial stall factor */
#define INITIAL_STALL_FACTOR 100 #define INITIAL_STALL_FACTOR 100
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* APIC destination mode enumeration list */
typedef enum _APIC_DEST_MODE
{
APIC_DM_Physical,
APIC_DM_Logical
} APIC_DEST_MODE, *PAPIC_DEST_MODE;
/* APIC delivery mode enumeration list */ /* APIC delivery mode enumeration list */
typedef enum _APIC_DM typedef enum _APIC_DM
{ {
@@ -240,7 +126,6 @@ typedef enum _APIC_REGISTER
APIC_TICR = 0x38, /* Initial Count Register for Timer */ APIC_TICR = 0x38, /* Initial Count Register for Timer */
APIC_TCCR = 0x39, /* Current Count Register for Timer */ APIC_TCCR = 0x39, /* Current Count Register for Timer */
APIC_TDCR = 0x3E, /* Timer Divide Configuration Register */ APIC_TDCR = 0x3E, /* Timer Divide Configuration Register */
APIC_SIPI = 0x3F, /* Self-IPI Register */
APIC_EAFR = 0x40, /* extended APIC Feature register */ APIC_EAFR = 0x40, /* extended APIC Feature register */
APIC_EACR = 0x41, /* Extended APIC Control Register */ APIC_EACR = 0x41, /* Extended APIC Control Register */
APIC_SEOI = 0x42, /* Specific End Of Interrupt Register */ APIC_SEOI = 0x42, /* Specific End Of Interrupt Register */
@@ -250,19 +135,6 @@ typedef enum _APIC_REGISTER
APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */ APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */
} APIC_REGISTER, *PAPIC_REGISTER; } APIC_REGISTER, *PAPIC_REGISTER;
/* APIC Timer Divide enumeration list */
typedef enum _APIC_TIMER_DIVISOR
{
TIMER_DivideBy2 = 0,
TIMER_DivideBy4 = 1,
TIMER_DivideBy8 = 2,
TIMER_DivideBy16 = 3,
TIMER_DivideBy32 = 8,
TIMER_DivideBy64 = 9,
TIMER_DivideBy128 = 10,
TIMER_DivideBy1 = 11,
} APIC_TIMER_DIVISOR, *PAPIC_TIMER_DIVISOR;
/* I8259 PIC interrupt mode enumeration list */ /* I8259 PIC interrupt mode enumeration list */
typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE
{ {
@@ -307,17 +179,6 @@ typedef enum _PIC_I8259_ICW4_SYSTEM_MODE
New8086Mode New8086Mode
} PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE; } PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;
/* Supported hardware timer backends */
typedef enum _TIMER_TYPE
{
TimerNone,
TimerAcpiPm,
TimerHpet,
TimerLapic,
TimerPit,
TimerTsc
} TIMER_TYPE, *PTIMER_TYPE;
/* APIC Base Register */ /* APIC Base Register */
typedef union _APIC_BASE_REGISTER typedef union _APIC_BASE_REGISTER
{ {
@@ -391,40 +252,6 @@ typedef union _APIC_SPURIOUS_REGISTER
}; };
} APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER; } APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
/* I/O APIC Controller information */
typedef struct _IOAPIC_DATA
{
ULONG GsiBase;
ULONG Identifier;
ULONG LineCount;
PHYSICAL_ADDRESS PhysicalAddress;
ULONG_PTR VirtualAddress;
} IOAPIC_DATA, *PIOAPIC_DATA;
/* I/O APIC Redirection Register */
typedef union _IOAPIC_REDIRECTION_REGISTER
{
ULONGLONG LongLong;
struct
{
UINT Base;
UINT Extended;
};
struct
{
ULONGLONG Vector:8;
ULONGLONG DeliveryMode:3;
ULONGLONG DestinationMode:1;
ULONGLONG DeliveryStatus:1;
ULONGLONG PinPolarity:1;
ULONGLONG RemoteIRR:1;
ULONGLONG TriggerMode:1;
ULONGLONG Mask:1;
ULONGLONG Reserved:39;
ULONGLONG Destination:8;
};
} IOAPIC_REDIRECTION_REGISTER, *PIOAPIC_REDIRECTION_REGISTER;
/* I8259 PIC register structure */ /* I8259 PIC register structure */
typedef union _PIC_I8259_ICW1 typedef union _PIC_I8259_ICW1
{ {
@@ -490,39 +317,4 @@ typedef union _PIC_I8259_ICW4
UCHAR Bits; UCHAR Bits;
} PIC_I8259_ICW4, *PPIC_I8259_ICW4; } PIC_I8259_ICW4, *PPIC_I8259_ICW4;
/* HPET Registers structure definition */
typedef struct _HPET_REGISTERS
{
VOLATILE ULONGLONG GeneralCapabilities;
VOLATILE ULONGLONG Reserved0;
VOLATILE ULONGLONG GeneralConfiguration;
VOLATILE ULONGLONG Reserved1;
VOLATILE ULONGLONG GeneralInterruptStatus;
VOLATILE ULONGLONG Reserved2;
VOLATILE ULONGLONG Reserved3[2][12];
VOLATILE ULONGLONG MainCounterValue;
VOLATILE ULONGLONG Reserved4;
struct
{
VOLATILE ULONGLONG Configuration;
VOLATILE ULONGLONG Comparator;
VOLATILE ULONGLONG FsbInterruptRoute;
VOLATILE ULONGLONG Reserved;
} Timers[];
} HPET_REGISTERS, *PHPET_REGISTERS;
/* Hardware timer capabilities and CPU clock features */
typedef struct _TIMER_CAPABILITIES
{
BOOLEAN Arat;
BOOLEAN Art;
BOOLEAN InvariantTsc;
BOOLEAN RDTSCP;
ULONG TimerFrequency;
BOOLEAN TscDeadline;
ULONG TscDenominator;
ULONG TscNumerator;
} TIMER_CAPABILITIES, *PTIMER_CAPABILITIES;
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_AMD64_HLTYPES_H */ #endif /* __XTDK_AMD64_HLTYPES_H */

View File

@@ -23,7 +23,6 @@
/* GDT selector names */ /* GDT selector names */
#define KGDT_NULL 0x0000 #define KGDT_NULL 0x0000
#define KGDT_R0_CMCODE 0x0008
#define KGDT_R0_CODE 0x0010 #define KGDT_R0_CODE 0x0010
#define KGDT_R0_DATA 0x0018 #define KGDT_R0_DATA 0x0018
#define KGDT_R3_CMCODE 0x0020 #define KGDT_R3_CMCODE 0x0020
@@ -47,7 +46,7 @@
#define KGDT_DESCRIPTOR_CODE 0x08 #define KGDT_DESCRIPTOR_CODE 0x08
/* GDT descriptor type codes */ /* GDT descriptor type codes */
#define KGDT_TYPE_NONE 0x00 #define KGDT_TYPE_NONE 0x0
#define KGDT_TYPE_CODE (0x10 | KGDT_DESCRIPTOR_CODE | KGDT_DESCRIPTOR_EXECUTE_READ) #define KGDT_TYPE_CODE (0x10 | KGDT_DESCRIPTOR_CODE | KGDT_DESCRIPTOR_EXECUTE_READ)
#define KGDT_TYPE_DATA (0x10 | KGDT_DESCRIPTOR_READ_WRITE) #define KGDT_TYPE_DATA (0x10 | KGDT_DESCRIPTOR_READ_WRITE)
@@ -59,7 +58,6 @@
#define KIDT_IST_RESERVED 0 #define KIDT_IST_RESERVED 0
#define KIDT_IST_PANIC 1 #define KIDT_IST_PANIC 1
#define KIDT_IST_MCA 2 #define KIDT_IST_MCA 2
#define KIDT_IST_NMI 3
/* AMD64 Segment Types */ /* AMD64 Segment Types */
#define AMD64_TASK_GATE 0x5 #define AMD64_TASK_GATE 0x5
@@ -69,62 +67,6 @@
#define AMD64_INTERRUPT_GATE 0xE #define AMD64_INTERRUPT_GATE 0xE
#define AMD64_TRAP_GATE 0xF #define AMD64_TRAP_GATE 0xF
/* Kernel CPU Standard Features */
#define KCF_VME (1ULL << 0) /* Virtual 8086 Mode Enhancements */
#define KCF_LARGE_PAGE (1ULL << 1) /* Page Size Extensions */
#define KCF_RDTSC (1ULL << 2) /* Time Stamp Counter */
#define KCF_PAE (1ULL << 3) /* Physical Address Extension */
#define KCF_MCE (1ULL << 4) /* Machine Check Exception */
#define KCF_CMPXCHG8B (1ULL << 5) /* CMPXCHG8B Instruction */
#define KCF_APIC (1ULL << 6) /* APIC On-Chip */
#define KCF_FAST_SYSCALL (1ULL << 7) /* SYSENTER/SYSEXIT Instructions */
#define KCF_MTRR (1ULL << 8) /* Memory Type Range Registers */
#define KCF_GLOBAL_PAGE (1ULL << 9) /* Page Global Enable */
#define KCF_MCA (1ULL << 10) /* Machine Check Architecture */
#define KCF_CMOV (1ULL << 11) /* Conditional Move Instructions */
#define KCF_PAT (1ULL << 12) /* Page Attribute Table */
#define KCF_PSE36 (1ULL << 13) /* 36-bit Page Size Extension */
#define KCF_CLFLUSH (1ULL << 14) /* CLFLUSH Instruction */
#define KCF_FXSR (1ULL << 15) /* FXSAVE/FXRSTOR Instructions */
#define KCF_ACPI (1ULL << 16) /* Thermal Monitor and Software Controlled Clock */
#define KCF_MMX (1ULL << 17) /* MMX Technology */
#define KCF_SSE (1ULL << 18) /* Streaming SIMD Extensions */
#define KCF_SSE2 (1ULL << 19) /* Streaming SIMD Extensions 2 */
#define KCF_SMT (1ULL << 20) /* Hyper-Threading Technology */
#define KCF_SSE3 (1ULL << 21) /* Streaming SIMD Extensions 3 */
#define KCF_VMX (1ULL << 22) /* Intel Virtual Machine Extensions */
#define KCF_SSSE3 (1ULL << 23) /* Supplemental SSE3 Instructions */
#define KCF_SSE41 (1ULL << 24) /* SSE4.1 Instructions */
#define KCF_SSE42 (1ULL << 25) /* SSE4.2 Instructions */
#define KCF_X2APIC (1ULL << 26) /* x2APIC Support */
#define KCF_POPCNT (1ULL << 27) /* POPCNT Instruction */
#define KCF_TSC_DEADLINE (1ULL << 28) /* TSC Deadline Timer */
#define KCF_AES (1ULL << 29) /* AES-NI Instruction Set */
#define KCF_XSAVE (1ULL << 30) /* XSAVE/XRSTOR Instructions */
#define KCF_AVX (1ULL << 31) /* Advanced Vector Extensions */
#define KCF_RDRAND (1ULL << 32) /* RDRAND Instruction */
#define KCF_FSGSBASE (1ULL << 33) /* RDFSBASE/WRFSBASE Instructions */
#define KCF_AVX2 (1ULL << 34) /* AVX2 Instructions */
#define KCF_SMEP (1ULL << 35) /* Supervisor Mode Execution Prevention */
#define KCF_RDSEED (1ULL << 36) /* RDSEED Instruction */
#define KCF_SMAP (1ULL << 37) /* Supervisor Mode Access Prevention */
#define KCF_SHA (1ULL << 38) /* SHA Extensions */
#define KCF_LA57 (1ULL << 39) /* 57-bit Linear Addresses */
#define KCF_ARAT (1ULL << 40) /* Always Running APIC Timer */
/* Kernel CPU Extended Features */
#define KCF_SVM (1ULL << 0) /* AMD Secure Virtual Machine */
#define KCF_SSE4A (1ULL << 1) /* SSE4A Instructions */
#define KCF_FMA4 (1ULL << 2) /* FMA4 Instructions */
#define KCF_TOPOEXT (1ULL << 3) /* AMD Topology Extensions */
#define KCF_SYSCALL (1ULL << 4) /* SYSCALL/SYSRET Instructions */
#define KCF_NX_BIT (1ULL << 5) /* No-Execute Page Protection */
#define KCF_RDTSCP (1ULL << 6) /* RDTSCP Instruction */
#define KCF_64BIT (1ULL << 7) /* Long Mode Support */
#define KCF_3DNOW_EXT (1ULL << 8) /* 3DNow! Extensions */
#define KCF_3DNOW (1ULL << 9) /* 3DNow! Instructions */
#define KCF_INVARIANT_TSC (1ULL << 10) /* Invariant Time Stamp Counter */
/* Context control flags */ /* Context control flags */
#define CONTEXT_ARCHITECTURE 0x00100000 #define CONTEXT_ARCHITECTURE 0x00100000
#define CONTEXT_CONTROL (CONTEXT_ARCHITECTURE | 0x01) #define CONTEXT_CONTROL (CONTEXT_ARCHITECTURE | 0x01)
@@ -168,14 +110,13 @@
/* XTOS Kernel stack size */ /* XTOS Kernel stack size */
#define KERNEL_STACK_SIZE 0x8000 #define KERNEL_STACK_SIZE 0x8000
#define KERNEL_STACKS 3
/* XTOS Kernel stack guard pages */ /* XTOS Kernel stack guard pages */
#define KERNEL_STACK_GUARD_PAGES 1 #define KERNEL_STACK_GUARD_PAGES 1
/* Processor structures size */ /* Processor structures size */
#define KPROCESSOR_STRUCTURES_SIZE ((KERNEL_STACKS * KERNEL_STACK_SIZE) + (GDT_ENTRIES * sizeof(KGDTENTRY)) + \ #define KPROCESSOR_STRUCTURES_SIZE ((2 * KERNEL_STACK_SIZE) + (GDT_ENTRIES * sizeof(KGDTENTRY)) + sizeof(KTSS) + \
sizeof(KTSS) + sizeof(KPROCESSOR_BLOCK) + MM_PAGE_SIZE) sizeof(KPROCESSOR_BLOCK) + MM_PAGE_SIZE)
/* Kernel frames */ /* Kernel frames */
#define KEXCEPTION_FRAME_SIZE sizeof(KEXCEPTION_FRAME) #define KEXCEPTION_FRAME_SIZE sizeof(KEXCEPTION_FRAME)
@@ -194,10 +135,6 @@
#define NPX_STATE_SCRUB 0x1 #define NPX_STATE_SCRUB 0x1
#define NPX_STATE_SWITCH 0x2 #define NPX_STATE_SWITCH 0x2
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Floating point state storing structure */ /* Floating point state storing structure */
typedef struct _FLOATING_SAVE_AREA typedef struct _FLOATING_SAVE_AREA
{ {
@@ -526,22 +463,11 @@ typedef struct _KSPECIAL_REGISTERS
ULONG64 MsrSyscallMask; ULONG64 MsrSyscallMask;
} KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS; } KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS;
/* Processor start block structure definition */
typedef struct _PROCESSOR_START_BLOCK
{
ULONG_PTR Cr3;
ULONG_PTR Cr4;
PVOID EntryPoint;
PVOID ProcessorStructures;
PVOID Stack;
BOOLEAN Started;
} PROCESSOR_START_BLOCK, *PPROCESSOR_START_BLOCK;
/* Processor state frame structure definition */ /* Processor state frame structure definition */
typedef struct _KPROCESSOR_STATE typedef struct _KPROCESSOR_STATE
{ {
CONTEXT ContextFrame;
KSPECIAL_REGISTERS SpecialRegisters; KSPECIAL_REGISTERS SpecialRegisters;
CONTEXT ContextFrame;
} KPROCESSOR_STATE, *PKPROCESSOR_STATE; } KPROCESSOR_STATE, *PKPROCESSOR_STATE;
/* Processor Control Block (PRCB) structure definition */ /* Processor Control Block (PRCB) structure definition */
@@ -564,7 +490,6 @@ typedef struct _KPROCESSOR_CONTROL_BLOCK
ULONG_PTR MultiThreadProcessorSet; ULONG_PTR MultiThreadProcessorSet;
SINGLE_LIST_ENTRY DeferredReadyListHead; SINGLE_LIST_ENTRY DeferredReadyListHead;
PROCESSOR_POWER_STATE PowerState; PROCESSOR_POWER_STATE PowerState;
ULONG ProfilingCountdown;
} KPROCESSOR_CONTROL_BLOCK, *PKPROCESSOR_CONTROL_BLOCK; } KPROCESSOR_CONTROL_BLOCK, *PKPROCESSOR_CONTROL_BLOCK;
/* Processor Block structure definition */ /* Processor Block structure definition */
@@ -591,9 +516,6 @@ typedef struct _KPROCESSOR_BLOCK
KAFFINITY SetMember; KAFFINITY SetMember;
ULONG StallScaleFactor; ULONG StallScaleFactor;
UCHAR CpuNumber; UCHAR CpuNumber;
ULONG HardwareId;
VOLATILE BOOLEAN Started;
PINTERRUPT_HANDLER InterruptDispatchTable[256];
} KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK; } KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK;
/* Thread Environment Block (TEB) structure definition */ /* Thread Environment Block (TEB) structure definition */
@@ -602,5 +524,4 @@ typedef struct _THREAD_ENVIRONMENT_BLOCK
THREAD_INFORMATION_BLOCK InformationBlock; THREAD_INFORMATION_BLOCK InformationBlock;
} THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK; } THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_AMD64_KETYPES_H */ #endif /* __XTDK_AMD64_KETYPES_H */

View File

@@ -101,9 +101,6 @@
/* HAL memory pool virtual address start */ /* HAL memory pool virtual address start */
#define MM_HARDWARE_VA_START 0xFFFFFFFFFFC00000ULL #define MM_HARDWARE_VA_START 0xFFFFFFFFFFC00000ULL
/* Kernel shared data address */
#define MM_KERNEL_SHARED_DATA_ADDRESS 0xFFFFFFFFFFDF0000ULL
/* Maximum physical address used by HAL allocations */ /* Maximum physical address used by HAL allocations */
#define MM_MAXIMUM_PHYSICAL_ADDRESS 0x00000000FFFFFFFFULL #define MM_MAXIMUM_PHYSICAL_ADDRESS 0x00000000FFFFFFFFULL
@@ -122,10 +119,6 @@
/* Number of pool tracking tables */ /* Number of pool tracking tables */
#define MM_POOL_TRACKING_TABLES 64 #define MM_POOL_TRACKING_TABLES 64
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Page size enumeration list */ /* Page size enumeration list */
typedef enum _PAGE_SIZE typedef enum _PAGE_SIZE
{ {
@@ -351,5 +344,4 @@ typedef struct _POOL_DESCRIPTOR
SIZE_T Reserved; SIZE_T Reserved;
} POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR; } POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_AMD64_MMTYPES_H */ #endif /* __XTDK_AMD64_MMTYPES_H */

View File

@@ -12,20 +12,13 @@
#include <xtdefs.h> #include <xtdefs.h>
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Architecture-specific enumeration lists forward references */ /* Architecture-specific enumeration lists forward references */
typedef enum _APIC_DEST_MODE APIC_DEST_MODE, *PAPIC_DEST_MODE;
typedef enum _APIC_DM APIC_DM, *PAPIC_DM; typedef enum _APIC_DM APIC_DM, *PAPIC_DM;
typedef enum _APIC_DSH APIC_DSH, *PAPIC_DSH; typedef enum _APIC_DSH APIC_DSH, *PAPIC_DSH;
typedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE; typedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE;
typedef enum _APIC_REGISTER APIC_REGISTER, *PAPIC_REGISTER; typedef enum _APIC_REGISTER APIC_REGISTER, *PAPIC_REGISTER;
typedef enum _APIC_TIMER_DIVISOR APIC_TIMER_DIVISOR, *PAPIC_TIMER_DIVISOR;
typedef enum _CPU_VENDOR CPU_VENDOR, *PCPU_VENDOR; typedef enum _CPU_VENDOR CPU_VENDOR, *PCPU_VENDOR;
typedef enum _CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT, *PCPUID_FEATURES_ADVANCED_POWER_MANAGEMENT;
typedef enum _CPUID_FEATURES_EXTENDED CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED; typedef enum _CPUID_FEATURES_EXTENDED CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
typedef enum _CPUID_FEATURES_POWER_MANAGEMENT CPUID_FEATURES_POWER_MANAGEMENT, *PCPUID_FEATURES_POWER_MANAGEMENT;
typedef enum _CPUID_FEATURES_STANDARD1 CPUID_FEATURES_STANDARD1, *PCPUID_FEATURES_STANDARD1; typedef enum _CPUID_FEATURES_STANDARD1 CPUID_FEATURES_STANDARD1, *PCPUID_FEATURES_STANDARD1;
typedef enum _CPUID_FEATURES_STANDARD7_LEAF0 CPUID_FEATURES_STANDARD7_LEAF0, *PCPUID_FEATURES_STANDARD7_LEAF0; typedef enum _CPUID_FEATURES_STANDARD7_LEAF0 CPUID_FEATURES_STANDARD7_LEAF0, *PCPUID_FEATURES_STANDARD7_LEAF0;
typedef enum _CPUID_FEATURES_STANDARD7_LEAF1 CPUID_FEATURES_STANDARD7_LEAF1, *PCPUID_FEATURES_STANDARD7_LEAF1; typedef enum _CPUID_FEATURES_STANDARD7_LEAF1 CPUID_FEATURES_STANDARD7_LEAF1, *PCPUID_FEATURES_STANDARD7_LEAF1;
@@ -37,7 +30,6 @@ typedef enum _PIC_I8259_ICW1_OPERATING_MODE PIC_I8259_ICW1_OPERATING_MODE, *PPIC
typedef enum _PIC_I8259_ICW4_BUFFERED_MODE PIC_I8259_ICW4_BUFFERED_MODE, *PPIC_I8259_ICW4_BUFFERED_MODE; typedef enum _PIC_I8259_ICW4_BUFFERED_MODE PIC_I8259_ICW4_BUFFERED_MODE, *PPIC_I8259_ICW4_BUFFERED_MODE;
typedef enum _PIC_I8259_ICW4_EOI_MODE PIC_I8259_ICW4_EOI_MODE, *PPIC_I8259_ICW4_EOI_MODE; typedef enum _PIC_I8259_ICW4_EOI_MODE PIC_I8259_ICW4_EOI_MODE, *PPIC_I8259_ICW4_EOI_MODE;
typedef enum _PIC_I8259_ICW4_SYSTEM_MODE PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE; typedef enum _PIC_I8259_ICW4_SYSTEM_MODE PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;
typedef enum _TIMER_TYPE TIMER_TYPE, *PTIMER_TYPE;
typedef enum _TRAMPOLINE_TYPE TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE; typedef enum _TRAMPOLINE_TYPE TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;
/* Architecture-specific structures forward references */ /* Architecture-specific structures forward references */
@@ -47,8 +39,6 @@ typedef struct _CPUID_REGISTERS CPUID_REGISTERS, *PCPUID_REGISTERS;
typedef struct _CPUID_SIGNATURE CPUID_SIGNATURE, *PCPUID_SIGNATURE; typedef struct _CPUID_SIGNATURE CPUID_SIGNATURE, *PCPUID_SIGNATURE;
typedef struct _FLOATING_SAVE_AREA FLOATING_SAVE_AREA, *PFLOATING_SAVE_AREA; typedef struct _FLOATING_SAVE_AREA FLOATING_SAVE_AREA, *PFLOATING_SAVE_AREA;
typedef struct _HARDWARE_PTE HARDWARE_PTE, *PHARDWARE_PTE; typedef struct _HARDWARE_PTE HARDWARE_PTE, *PHARDWARE_PTE;
typedef struct _HPET_REGISTERS HPET_REGISTERS, *PHPET_REGISTERS;
typedef struct _IOAPIC_DATA IOAPIC_DATA, *PIOAPIC_DATA;
typedef struct _KDESCRIPTOR KDESCRIPTOR, *PKDESCRIPTOR; typedef struct _KDESCRIPTOR KDESCRIPTOR, *PKDESCRIPTOR;
typedef struct _KEXCEPTION_FRAME KEXCEPTION_FRAME, *PKEXCEPTION_FRAME; typedef struct _KEXCEPTION_FRAME KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;
typedef struct _KGDTENTRY KGDTENTRY, *PKGDTENTRY; typedef struct _KGDTENTRY KGDTENTRY, *PKGDTENTRY;
@@ -73,14 +63,12 @@ typedef struct _MMPTE_SUBSECTION MMPTE_SUBSECTION, *PMMPTE_SUBSECTION;
typedef struct _MMPTE_TRANSITION MMPTE_TRANSITION, *PMMPTE_TRANSITION; typedef struct _MMPTE_TRANSITION MMPTE_TRANSITION, *PMMPTE_TRANSITION;
typedef struct _POOL_DESCRIPTOR POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR; typedef struct _POOL_DESCRIPTOR POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK; typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
typedef struct _TIMER_CAPABILITIES TIMER_CAPABILITIES, *PTIMER_CAPABILITIES;
/* Unions forward references */ /* Unions forward references */
typedef union _APIC_BASE_REGISTER APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER; typedef union _APIC_BASE_REGISTER APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER;
typedef union _APIC_COMMAND_REGISTER APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGISTER; typedef union _APIC_COMMAND_REGISTER APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGISTER;
typedef union _APIC_LVT_REGISTER APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER; typedef union _APIC_LVT_REGISTER APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER;
typedef union _APIC_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER; typedef union _APIC_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
typedef union _IOAPIC_REDIRECTION_REGISTER IOAPIC_REDIRECTION_REGISTER, *PIOAPIC_REDIRECTION_REGISTER;
typedef union _MMPTE MMP5E, *PMMP5E; typedef union _MMPTE MMP5E, *PMMP5E;
typedef union _MMPTE MMPDE, *PMMPDE; typedef union _MMPTE MMPDE, *PMMPDE;
typedef union _MMPTE MMPPE, *PMMPPE; typedef union _MMPTE MMPPE, *PMMPPE;
@@ -91,5 +79,4 @@ typedef union _PIC_I8259_ICW2 PIC_I8259_ICW2, *PPIC_I8259_ICW2;
typedef union _PIC_I8259_ICW3 PIC_I8259_ICW3, *PPIC_I8259_ICW3; typedef union _PIC_I8259_ICW3 PIC_I8259_ICW3, *PPIC_I8259_ICW3;
typedef union _PIC_I8259_ICW4 PIC_I8259_ICW4, *PPIC_I8259_ICW4; typedef union _PIC_I8259_ICW4 PIC_I8259_ICW4, *PPIC_I8259_ICW4;
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_AMD64_XTSTRUCT_H */ #endif /* __XTDK_AMD64_XTSTRUCT_H */

View File

@@ -13,9 +13,6 @@
#include <xtuefi.h> #include <xtuefi.h>
/* C/C++ specific code */
#ifndef D__XTOS_ASSEMBLER__
/* XT BootLoader routines forward references */ /* XT BootLoader routines forward references */
XTCLINK XTCLINK
XTCDECL XTCDECL
@@ -24,5 +21,4 @@ BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable,
IN EFI_HANDLE ImageHandle, IN EFI_HANDLE ImageHandle,
OUT PXTBL_LOADER_PROTOCOL *ProtocolHandler); OUT PXTBL_LOADER_PROTOCOL *ProtocolHandler);
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_BLFUNCS_H */ #endif /* __XTDK_BLFUNCS_H */

View File

@@ -29,10 +29,6 @@
#define XTBL_DEBUGPORT_SCREEN 1 #define XTBL_DEBUGPORT_SCREEN 1
#define XTBL_DEBUGPORT_SERIAL 2 #define XTBL_DEBUGPORT_SERIAL 2
/* XTLDR Shell definitions */
#define XTBL_SH_MAX_LINE_LENGTH 256
#define XTBL_SH_HISTORY_ENTRIES 20
/* TUI dialog box attributes */ /* TUI dialog box attributes */
#define XTBL_TUI_DIALOG_GENERIC_BOX 1 #define XTBL_TUI_DIALOG_GENERIC_BOX 1
#define XTBL_TUI_DIALOG_ERROR_BOX 2 #define XTBL_TUI_DIALOG_ERROR_BOX 2
@@ -45,10 +41,6 @@
/* TUI dialog box maximum width */ /* TUI dialog box maximum width */
#define XTBL_TUI_MAX_DIALOG_WIDTH 100 #define XTBL_TUI_MAX_DIALOG_WIDTH 100
/* C/C++ specific code */
#ifndef D__XTOS_ASSEMBLER__
/* XTLDR Routine pointers */ /* XTLDR Routine pointers */
typedef LOADER_MEMORY_TYPE (XTCDECL *PBL_GET_MEMTYPE_ROUTINE)(IN EFI_MEMORY_TYPE EfiMemoryType); typedef LOADER_MEMORY_TYPE (XTCDECL *PBL_GET_MEMTYPE_ROUTINE)(IN EFI_MEMORY_TYPE EfiMemoryType);
@@ -77,7 +69,7 @@ typedef VOID (XTCDECL *PBL_CONSOLE_DISABLE_CURSOR)();
typedef VOID (XTCDECL *PBL_CONSOLE_ENABLE_CURSOR)(); typedef VOID (XTCDECL *PBL_CONSOLE_ENABLE_CURSOR)();
typedef VOID (XTCDECL *PBL_CONSOLE_PRINT)(IN PCWSTR Format, IN ...); typedef VOID (XTCDECL *PBL_CONSOLE_PRINT)(IN PCWSTR Format, IN ...);
typedef VOID (XTCDECL *PBL_CONSOLE_QUERY_MODE)(OUT PUINT_PTR ResX, OUT PUINT_PTR ResY); typedef VOID (XTCDECL *PBL_CONSOLE_QUERY_MODE)(OUT PUINT_PTR ResX, OUT PUINT_PTR ResY);
typedef EFI_STATUS (XTCDECL *PBL_CONSOLE_READ_KEY_STROKE)(OUT PEFI_INPUT_KEY Key); typedef VOID (XTCDECL *PBL_CONSOLE_READ_KEY_STROKE)(OUT PEFI_INPUT_KEY Key);
typedef VOID (XTCDECL *PBL_CONSOLE_RESET_INPUT_BUFFER)(); typedef VOID (XTCDECL *PBL_CONSOLE_RESET_INPUT_BUFFER)();
typedef VOID (XTCDECL *PBL_CONSOLE_SET_ATTRIBUTES)(IN ULONGLONG Attributes); typedef VOID (XTCDECL *PBL_CONSOLE_SET_ATTRIBUTES)(IN ULONGLONG Attributes);
typedef VOID (XTCDECL *PBL_CONSOLE_SET_CURSOR_POSITION)(IN ULONGLONG PosX, IN ULONGLONG PosY); typedef VOID (XTCDECL *PBL_CONSOLE_SET_CURSOR_POSITION)(IN ULONGLONG PosX, IN ULONGLONG PosY);
@@ -147,8 +139,6 @@ typedef XTSTATUS (XTAPI *PBL_WIDESTRING_FORMAT)(IN PRTL_PRINT_CONTEXT Context, I
typedef SIZE_T (XTAPI *PBL_WIDESTRING_LENGTH)(IN PCWSTR String, IN SIZE_T MaxLength); typedef SIZE_T (XTAPI *PBL_WIDESTRING_LENGTH)(IN PCWSTR String, IN SIZE_T MaxLength);
typedef PWCHAR (XTAPI *PBL_WIDESTRING_TOKENIZE)(IN PWCHAR String, IN PCWSTR Delimiter, IN OUT PWCHAR *SavePtr); typedef PWCHAR (XTAPI *PBL_WIDESTRING_TOKENIZE)(IN PWCHAR String, IN PCWSTR Delimiter, IN OUT PWCHAR *SavePtr);
typedef EFI_STATUS (XTCDECL *PBL_WAIT_FOR_EFI_EVENT)(IN UINT_PTR NumberOfEvents, IN PEFI_EVENT Event, OUT PUINT_PTR Index); typedef EFI_STATUS (XTCDECL *PBL_WAIT_FOR_EFI_EVENT)(IN UINT_PTR NumberOfEvents, IN PEFI_EVENT Event, OUT PUINT_PTR Index);
typedef VOID (XTCDECL *PBL_SHELL_COMMAND)(IN ULONG Argc, IN PWCHAR *Argv);
typedef EFI_STATUS (XTCDECL *PBL_REGISTER_SHELL_COMMAND)(IN PCWSTR Command, IN PCWSTR Description, IN PBL_SHELL_COMMAND Handler);
typedef VOID (XTCDECL *PBL_XT_BOOT_MENU)(); typedef VOID (XTCDECL *PBL_XT_BOOT_MENU)();
typedef VOID (XTAPI *PBL_ZERO_MEMORY)(OUT PVOID Destination, IN SIZE_T Length); typedef VOID (XTAPI *PBL_ZERO_MEMORY)(OUT PVOID Destination, IN SIZE_T Length);
@@ -239,15 +229,6 @@ typedef struct _XTBL_KNOWN_BOOT_PROTOCOL
EFI_GUID Guid; EFI_GUID Guid;
} XTBL_KNOWN_BOOT_PROTOCOL, *PXTBL_KNOWN_BOOT_PROTOCOL; } XTBL_KNOWN_BOOT_PROTOCOL, *PXTBL_KNOWN_BOOT_PROTOCOL;
/* XTLDR Shell command entry */
typedef struct _XTBL_SHELL_COMMAND
{
LIST_ENTRY Flink;
PWCHAR Command;
PWCHAR Description;
PBL_SHELL_COMMAND Handler;
} XTBL_SHELL_COMMAND, *PXTBL_SHELL_COMMAND;
/* Boot Loader memory mapping information */ /* Boot Loader memory mapping information */
typedef struct _XTBL_MEMORY_MAPPING typedef struct _XTBL_MEMORY_MAPPING
{ {
@@ -497,10 +478,6 @@ typedef struct _XTBL_LOADER_PROTOCOL
PBL_OPEN_PROTOCOL_HANDLE OpenHandle; PBL_OPEN_PROTOCOL_HANDLE OpenHandle;
} Protocol; } Protocol;
struct struct
{
PBL_REGISTER_SHELL_COMMAND RegisterCommand;
} Shell;
struct
{ {
PBL_STRING_COMPARE Compare; PBL_STRING_COMPARE Compare;
PBL_STRING_LENGTH Length; PBL_STRING_LENGTH Length;
@@ -543,5 +520,4 @@ typedef struct _XTBL_LOADER_PROTOCOL
} WideString; } WideString;
} XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL; } XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL;
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_BLTYPES_H */ #endif /* __XTDK_BLTYPES_H */

View File

@@ -13,9 +13,6 @@
#include <xttypes.h> #include <xttypes.h>
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Kernel Executive routines forward references */ /* Kernel Executive routines forward references */
XTCLINK XTCLINK
XTFASTCALL XTFASTCALL
@@ -47,5 +44,4 @@ XTFASTCALL
VOID VOID
ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor); ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor);
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_EXFUNCS_H */ #endif /* __XTDK_EXFUNCS_H */

View File

@@ -17,10 +17,6 @@
/* Rundown protection flags */ /* Rundown protection flags */
#define EX_RUNDOWN_ACTIVE 0x1 #define EX_RUNDOWN_ACTIVE 0x1
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Executive rundown protection structure definition */ /* Executive rundown protection structure definition */
typedef struct _EX_RUNDOWN_REFERENCE typedef struct _EX_RUNDOWN_REFERENCE
{ {
@@ -38,5 +34,4 @@ typedef struct _EX_RUNDOWN_WAIT_BLOCK
KEVENT WakeEvent; KEVENT WakeEvent;
} EX_RUNDOWN_WAIT_BLOCK, *PEX_RUNDOWN_WAIT_BLOCK; } EX_RUNDOWN_WAIT_BLOCK, *PEX_RUNDOWN_WAIT_BLOCK;
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_EXTYPES_H */ #endif /* __XTDK_EXTYPES_H */

View File

@@ -14,15 +14,7 @@
#include <xttypes.h> #include <xttypes.h>
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Hardware layer routines forward references */ /* Hardware layer routines forward references */
XTCLINK
XTAPI
LARGE_INTEGER
HlQueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceFrequency);
XTCLINK XTCLINK
XTAPI XTAPI
UCHAR UCHAR
@@ -38,11 +30,6 @@ XTAPI
ULONG ULONG
HlReadRegister32(IN PVOID Register); HlReadRegister32(IN PVOID Register);
XTCLINK
XTAPI
ULONG
HlSetClockRate(IN ULONG Rate);
XTCLINK XTCLINK
XTAPI XTAPI
VOID VOID
@@ -61,5 +48,4 @@ VOID
HlWriteRegister32(IN PVOID Register, HlWriteRegister32(IN PVOID Register,
IN ULONG Value); IN ULONG Value);
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_HLFUNCS_H */ #endif /* __XTDK_HLFUNCS_H */

View File

@@ -64,8 +64,8 @@
#define ACPI_FADT_32BIT_TIMER (1<<8) #define ACPI_FADT_32BIT_TIMER (1<<8)
/* ACPI Timer bit masks */ /* ACPI Timer bit masks */
#define ACPI_FADT_TIMER_32BIT 0xFFFFFFFF #define ACPI_FADT_TIMER_32BIT 0x80000000
#define ACPI_FADT_TIMER_24BIT 0x00FFFFFF #define ACPI_FADT_TIMER_24BIT 0x00800000
/* ACPI MADT subtable type definitions */ /* ACPI MADT subtable type definitions */
#define ACPI_MADT_TYPE_LOCAL_APIC 0 #define ACPI_MADT_TYPE_LOCAL_APIC 0
@@ -101,15 +101,6 @@
#define ACPI_MADT_PLACE_ENABLED 0 /* Processor Local APIC CPU Enabled */ #define ACPI_MADT_PLACE_ENABLED 0 /* Processor Local APIC CPU Enabled */
#define ACPI_MADT_PLAOC_ENABLED 1 /* Processor Local APIC Online Capable */ #define ACPI_MADT_PLAOC_ENABLED 1 /* Processor Local APIC Online Capable */
/* ACPI Timer frequency */
#define ACPI_PM_TIMER_FREQUENCY 3579545
/* ACPI address space definitions */
#define ACPI_ADDRESS_SPACE_MEMORY 0x00
/* Maximum number of cached ACPI tables */
#define ACPI_MAX_CACHED_TABLES 32
/* Default serial port settings */ /* Default serial port settings */
#define COMPORT_CLOCK_RATE 0x1C200 #define COMPORT_CLOCK_RATE 0x1C200
#define COMPORT_WAIT_TIMEOUT 204800 #define COMPORT_WAIT_TIMEOUT 204800
@@ -188,33 +179,6 @@
#define COMPORT_REG_MSR 0x06 /* Modem Status Register */ #define COMPORT_REG_MSR 0x06 /* Modem Status Register */
#define COMPORT_REG_SR 0x07 /* Scratch Register */ #define COMPORT_REG_SR 0x07 /* Scratch Register */
/* Standard system clock rates (in 100-nanosecond units)*/
#define HL_CLOCK_RATE_1000HZ 10000 /* 1 ms (1000 Hz) - Best Performance */
#define HL_CLOCK_RATE_500HZ 20000 /* 2 ms (500 Hz) - High Responsiveness */
#define HL_CLOCK_RATE_300HZ 33333 /* 3.33ms (300 Hz) - Multimedia Sync */
#define HL_CLOCK_RATE_250HZ 40000 /* 4 ms (250 Hz) - Optimal Balance */
#define HL_CLOCK_RATE_100HZ 100000 /* 10 ms (100 Hz) - Power Saving */
#define HL_CLOCK_RATE_50HZ 200000 /* 20 ms (50 Hz) - Deep Power Saving */
/* Minimum and maximum system clock rate definitions */
#define HL_MINIMUM_CLOCK_RATE HL_CLOCK_RATE_1000HZ
#define HL_MAXIMUM_CLOCK_RATE HL_CLOCK_RATE_50HZ
/* Minimum and maximum profile intervals */
#define MIN_PROFILE_INTERVAL 10000
#define MAX_PROFILE_INTERVAL 10000000
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Hardware Layer routine callbacks */
typedef XTSTATUS (XTAPI *PHALP_INITIALIZE_CLOCK)(VOID);
typedef ULONGLONG (XTAPI *PHALP_QUERY_PERF_COUNTER)(VOID);
typedef ULONG (XTAPI *PHALP_QUERY_TIME_DELTA)(VOID);
typedef ULONG (XTAPI *PHALP_SET_CLOCK_RATE)(IN ULONG Increment);
typedef VOID (XTAPI *PHALP_STALL_EXECUTION)(IN ULONG MicroSeconds);
/* Generic Address structure */ /* Generic Address structure */
typedef struct _GENERIC_ADDRESS typedef struct _GENERIC_ADDRESS
{ {
@@ -250,7 +214,7 @@ typedef struct _ACPI_SUBTABLE_HEADER
typedef struct _ACPI_CACHE_LIST typedef struct _ACPI_CACHE_LIST
{ {
LIST_ENTRY ListEntry; LIST_ENTRY ListEntry;
PACPI_DESCRIPTION_HEADER Table; ACPI_DESCRIPTION_HEADER Header;
} ACPI_CACHE_LIST, *PACPI_CACHE_LIST; } ACPI_CACHE_LIST, *PACPI_CACHE_LIST;
/* ACPI Root System Description Table Pointer (RSDP) structure */ /* ACPI Root System Description Table Pointer (RSDP) structure */
@@ -341,17 +305,6 @@ typedef struct _ACPI_FADT
GENERIC_ADDRESS SleepStatusReg; GENERIC_ADDRESS SleepStatusReg;
} PACKED ACPI_FADT, *PACPI_FADT; } PACKED ACPI_FADT, *PACPI_FADT;
/* ACPI High Precision Event Timer (HPET) table structure */
typedef struct _ACPI_HPET
{
ACPI_DESCRIPTION_HEADER Header;
ULONG EventTimerBlockId;
GENERIC_ADDRESS BaseAddress;
UCHAR HpetNumber;
USHORT MinimumTick;
UCHAR PageProtectionAndOem;
} PACKED ACPI_HPET, *PACPI_HPET;
/* ACPI Multiple APIC Description Table (MADT) structure */ /* ACPI Multiple APIC Description Table (MADT) structure */
typedef struct _ACPI_MADT typedef struct _ACPI_MADT
{ {
@@ -361,26 +314,6 @@ typedef struct _ACPI_MADT
ULONG ApicTables[]; ULONG ApicTables[];
} PACKED ACPI_MADT, *PACPI_MADT; } PACKED ACPI_MADT, *PACPI_MADT;
/* ACPI Interrupt Override MADT subtable structure */
typedef struct _ACPI_MADT_INTERRUPT_OVERRIDE
{
ACPI_SUBTABLE_HEADER Header;
UCHAR Bus;
UCHAR SourceIrq;
ULONG GlobalSystemInterrupt;
USHORT Flags;
} PACKED ACPI_MADT_INTERRUPT_OVERRIDE, *PACPI_MADT_INTERRUPT_OVERRIDE;
/* ACPI IO APIC MADT subtable structure */
typedef struct _ACPI_MADT_IOAPIC
{
ACPI_SUBTABLE_HEADER Header;
UCHAR IoApicId;
UCHAR Reserved;
ULONG IoApicAddress;
ULONG GlobalIrqBase;
} PACKED ACPI_MADT_IOAPIC, *PACPI_MADT_IOAPIC;
/* ACPI Local APIC MADT subtable structure */ /* ACPI Local APIC MADT subtable structure */
typedef struct _ACPI_MADT_LOCAL_APIC typedef struct _ACPI_MADT_LOCAL_APIC
{ {
@@ -517,15 +450,4 @@ typedef struct _SMBIOS3_TABLE_HEADER
ULONGLONG TableAddress; ULONGLONG TableAddress;
} SMBIOS3_TABLE_HEADER, *PSMBIOS3_TABLE_HEADER; } SMBIOS3_TABLE_HEADER, *PSMBIOS3_TABLE_HEADER;
/* Timer dispatch table */
typedef struct _TIMER_ROUTINES
{
PHALP_INITIALIZE_CLOCK InitializeClock;
PHALP_QUERY_PERF_COUNTER QueryPerformanceCounter;
PHALP_QUERY_TIME_DELTA QueryTimeDelta;
PHALP_SET_CLOCK_RATE SetClockRate;
PHALP_STALL_EXECUTION StallExecution;
} TIMER_ROUTINES, *PTIMER_ROUTINES;
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_HLTYPES_H */ #endif /* __XTDK_HLTYPES_H */

View File

@@ -12,7 +12,6 @@
#include <xtdefs.h> #include <xtdefs.h>
#include <xtstruct.h> #include <xtstruct.h>
#include <xttypes.h> #include <xttypes.h>
#include ARCH_HEADER(xtstruct.h)
/* Control Register 0 constants */ /* Control Register 0 constants */
@@ -93,10 +92,6 @@
#define X86_EFLAGS_VIP_MASK 0x00100000 /* Virtual Interrupt Pending */ #define X86_EFLAGS_VIP_MASK 0x00100000 /* Virtual Interrupt Pending */
#define X86_EFLAGS_ID_MASK 0x00200000 /* Identification */ #define X86_EFLAGS_ID_MASK 0x00200000 /* Identification */
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* CPU vendor enumeration list */ /* CPU vendor enumeration list */
typedef enum _CPU_VENDOR typedef enum _CPU_VENDOR
{ {
@@ -105,18 +100,6 @@ typedef enum _CPU_VENDOR
CPU_VENDOR_UNKNOWN = 0xFFFFFFFF CPU_VENDOR_UNKNOWN = 0xFFFFFFFF
} CPU_VENDOR, *PCPU_VENDOR; } CPU_VENDOR, *PCPU_VENDOR;
/* CPUID advanced power management features (0x80000007) enumeration list */
typedef enum _CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT
{
CPUID_FEATURES_EDX_TS = 1 << 0, /* Temperature Sensor */
CPUID_FEATURES_EDX_FIS = 1 << 1, /* Frequency ID Selection */
CPUID_FEATURES_EDX_VIS = 1 << 2, /* Voltage ID Selection */
CPUID_FEATURES_EDX_TTS = 1 << 3, /* ThermaTrip Support */
CPUID_FEATURES_EDX_HTC = 1 << 4, /* Hardware Thermal Throttling */
CPUID_FEATURES_EDX_STC = 1 << 5, /* Software Thermal Throttling */
CPUID_FEATURES_EDX_TSCI = 1 << 8 /* TSC Invariant */
} CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT, *PCPUID_FEATURES_ADVANCED_POWER_MANAGEMENT;
/* CPUID extended features (0x80000001) enumeration list */ /* CPUID extended features (0x80000001) enumeration list */
typedef enum _CPUID_FEATURES_EXTENDED typedef enum _CPUID_FEATURES_EXTENDED
{ {
@@ -158,23 +141,6 @@ typedef enum _CPUID_FEATURES_EXTENDED
CPUID_FEATURES_EDX_3DNOW = 1 << 31 CPUID_FEATURES_EDX_3DNOW = 1 << 31
} CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED; } CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
/* CPUID Thermal and Power Management features (0x00000006) enumeration list */
typedef enum _CPUID_FEATURES_POWER_MANAGEMENT
{
CPUID_FEATURES_EAX_DTHERM = 1 << 0,
CPUID_FEATURES_EAX_IDA = 1 << 1,
CPUID_FEATURES_EAX_ARAT = 1 << 2,
CPUID_FEATURES_EAX_PLN = 1 << 4,
CPUID_FEATURES_EAX_PTS = 1 << 6,
CPUID_FEATURES_EAX_HWP = 1 << 7,
CPUID_FEATURES_EAX_HWP_NOTIFY = 1 << 8,
CPUID_FEATURES_EAX_HWP_ACT_WINDOW = 1 << 9,
CPUID_FEATURES_EAX_HWP_EPP = 1 << 10,
CPUID_FEATURES_EAX_HWP_PKG_REQ = 1 << 11,
CPUID_FEATURES_EAX_HWP_HIGHEST_PERF_CHANGE = 1 << 15,
CPUID_FEATURES_EAX_HFI = 1 << 19
} CPUID_FEATURES_LEAF6, *PCPUID_FEATURES_LEAF6;
/* CPUID STD1 features (0x00000001) enumeration list */ /* CPUID STD1 features (0x00000001) enumeration list */
typedef enum _CPUID_FEATURES_STANDARD1 typedef enum _CPUID_FEATURES_STANDARD1
{ {
@@ -201,7 +167,7 @@ typedef enum _CPUID_FEATURES_STANDARD1
CPUID_FEATURES_ECX_X2APIC = 1 << 21, CPUID_FEATURES_ECX_X2APIC = 1 << 21,
CPUID_FEATURES_ECX_MOVBE = 1 << 22, CPUID_FEATURES_ECX_MOVBE = 1 << 22,
CPUID_FEATURES_ECX_POPCNT = 1 << 23, CPUID_FEATURES_ECX_POPCNT = 1 << 23,
CPUID_FEATURES_ECX_TSC_DEADLINE = 1 << 24, CPUID_FEATURES_ECX_TSC = 1 << 24,
CPUID_FEATURES_ECX_AES = 1 << 25, CPUID_FEATURES_ECX_AES = 1 << 25,
CPUID_FEATURES_ECX_XSAVE = 1 << 26, CPUID_FEATURES_ECX_XSAVE = 1 << 26,
CPUID_FEATURES_ECX_OSXSAVE = 1 << 27, CPUID_FEATURES_ECX_OSXSAVE = 1 << 27,
@@ -375,29 +341,20 @@ typedef enum _CPUID_FEATURES_STANDARD7_LEAF1
/* CPUID requests */ /* CPUID requests */
typedef enum _CPUID_REQUESTS typedef enum _CPUID_REQUESTS
{ {
CPUID_GET_VENDOR_STRING = 0x00000000, CPUID_GET_VENDOR_STRING,
CPUID_GET_STANDARD1_FEATURES = 0x00000001, CPUID_GET_STANDARD1_FEATURES,
CPUID_GET_TLB_CACHE = 0x00000002, CPUID_GET_TLB_CACHE,
CPUID_GET_SERIAL = 0x00000003, CPUID_GET_SERIAL,
CPUID_GET_CACHE_TOPOLOGY = 0x00000004, CPUID_GET_CACHE_TOPOLOGY,
CPUID_GET_MONITOR_MWAIT = 0x00000005, CPUID_GET_MONITOR_MWAIT,
CPUID_GET_POWER_MANAGEMENT = 0x00000006, CPUID_GET_POWER_MANAGEMENT,
CPUID_GET_STANDARD7_FEATURES = 0x00000007, CPUID_GET_STANDARD7_FEATURES
CPUID_GET_TSC_CRYSTAL_CLOCK = 0x00000015,
CPUID_GET_EXTENDED_MAX = 0x80000000,
CPUID_GET_EXTENDED_FEATURES = 0x80000001,
CPUID_GET_ADVANCED_POWER_MANAGEMENT = 0x80000007
} CPUID_REQUESTS, *PCPUID_REQUESTS; } CPUID_REQUESTS, *PCPUID_REQUESTS;
/* Interrupt handler */
typedef VOID (*PINTERRUPT_HANDLER)(PKTRAP_FRAME TrapFrame);
/* Processor identification information */ /* Processor identification information */
typedef struct _CPU_IDENTIFICATION typedef struct _CPU_IDENTIFICATION
{ {
ULONGLONG ExtendedFeatureBits;
USHORT Family; USHORT Family;
ULONGLONG FeatureBits;
USHORT Model; USHORT Model;
USHORT Stepping; USHORT Stepping;
CPU_VENDOR Vendor; CPU_VENDOR Vendor;
@@ -433,5 +390,4 @@ typedef enum _TRAMPOLINE_TYPE
TrampolineApStartup TrampolineApStartup
} TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE; } TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_I686_ARTYPES_H */ #endif /* __XTDK_I686_ARTYPES_H */

View File

@@ -15,9 +15,6 @@
#include <i686/xtstruct.h> #include <i686/xtstruct.h>
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Hardware layer routines forward references */ /* Hardware layer routines forward references */
XTCLINK XTCLINK
XTCDECL XTCDECL
@@ -52,5 +49,4 @@ VOID
HlWritePort32(IN USHORT Port, HlWritePort32(IN USHORT Port,
IN ULONG Value); IN ULONG Value);
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_I686_HLFUNCS_H */ #endif /* __XTDK_I686_HLFUNCS_H */

View File

@@ -9,7 +9,6 @@
#ifndef __XTDK_I686_HLTYPES_H #ifndef __XTDK_I686_HLTYPES_H
#define __XTDK_I686_HLTYPES_H #define __XTDK_I686_HLTYPES_H
#include <xtbase.h>
#include <xtdefs.h> #include <xtdefs.h>
#include <xtstruct.h> #include <xtstruct.h>
#include <xttypes.h> #include <xttypes.h>
@@ -37,7 +36,6 @@
#define APIC_VECTOR_GENERIC 0xC1 #define APIC_VECTOR_GENERIC 0xC1
#define APIC_VECTOR_SYNC 0xC1 #define APIC_VECTOR_SYNC 0xC1
#define APIC_VECTOR_CLOCK 0xD1 #define APIC_VECTOR_CLOCK 0xD1
#define APIC_VECTOR_CLOCK_IPI 0xD2
#define APIC_VECTOR_IPI 0xE1 #define APIC_VECTOR_IPI 0xE1
#define APIC_VECTOR_ERROR 0xE3 #define APIC_VECTOR_ERROR 0xE3
#define APIC_VECTOR_POWERFAIL 0xEF #define APIC_VECTOR_POWERFAIL 0xEF
@@ -60,27 +58,6 @@
/* Maximum number of I/O APICs */ /* Maximum number of I/O APICs */
#define APIC_MAX_IOAPICS 64 #define APIC_MAX_IOAPICS 64
/* I/O APIC base address */
#define IOAPIC_DEFAULT_BASE 0xFEC00000
/* I/O APIC definitions */
#define IOAPIC_MAX_CONTROLLERS 64
#define IOAPIC_MAX_OVERRIDES 16
#define IOAPIC_RTE_MASKED 0x100FF
#define IOAPIC_RTE_SIZE 2
#define IOAPIC_VECTOR_FREE 0xFF
#define IOAPIC_VECTOR_RESERVED 0xFE
/* IOAPIC offsets */
#define IOAPIC_IOREGSEL 0x00
#define IOAPIC_IOWIN 0x10
/* IOAPIC registers */
#define IOAPIC_ID 0x00
#define IOAPIC_VER 0x01
#define IOAPIC_ARB 0x02
#define IOAPIC_REDTBL 0x10
/* 8259/ISP PIC ports definitions */ /* 8259/ISP PIC ports definitions */
#define PIC1_CONTROL_PORT 0x20 #define PIC1_CONTROL_PORT 0x20
#define PIC1_DATA_PORT 0x21 #define PIC1_DATA_PORT 0x21
@@ -92,87 +69,6 @@
/* PIC vector definitions */ /* PIC vector definitions */
#define PIC1_VECTOR_SPURIOUS 0x37 #define PIC1_VECTOR_SPURIOUS 0x37
/* HPET General Capabilities definitions */
#define HPET_CAPABILITY_64BIT 0x2000ULL
#define HPET_CAPABILITY_LEGACY_REPLACEMENT 0x8000ULL
/* HPET General Configuration definitions */
#define HPET_CONFIG_ENABLE 0x0001ULL
#define HPET_CONFIG_LEGACY_REPLACEMENT 0x0002ULL
/* HPET Timer Configuration definitions */
#define HPET_TIMER_CONFIG_LEVEL_TRIGGERED 0x0002ULL
#define HPET_TIMER_CONFIG_ENABLED 0x0004ULL
#define HPET_TIMER_CONFIG_PERIODIC 0x0008ULL
#define HPET_TIMER_CONFIG_SUPPORTS_PERIODIC 0x0010ULL
#define HPET_TIMER_CONFIG_SUPPORTS_64BIT 0x0020ULL
#define HPET_TIMER_CONFIG_VALUE_ACCUMULATOR 0x0040ULL
#define HPET_TIMER_CONFIG_FORCE_32BIT 0x0100ULL
#define HPET_TIMER_CONFIG_FSB_ENABLED 0x4000ULL
#define HPET_TIMER_CONFIG_SUPPORTS_FSB 0x8000ULL
/* PIT ports definitions */
#define PIT_COMMAND_PORT 0x43
#define PIT_DATA_PORT0 0x40
#define PIT_DATA_PORT1 0x41
#define PIT_DATA_PORT2 0x42
/* PIT related definitions */
#define PIT_BASE_FREQUENCY 1193182
/* PIT Access Mode: Defines how the CPU reads or writes the counter value */
#define PIT_CMD_ACCESS_LATCH 0x00
#define PIT_CMD_ACCESS_LOWBYTE_ONLY 0x10
#define PIT_CMD_ACCESS_HIGHBYTE_ONLY 0x20
#define PIT_CMD_ACCESS_LOWBYTE_HIGHBYTE 0x30
/* PIT Channel Selection: Specifies the physical timer channel to configure */
#define PIT_CMD_CHANNEL0 0x00
#define PIT_CMD_CHANNEL1 0x40
#define PIT_CMD_CHANNEL2 0x80
/* PIT Operating Mode: Defines the hardware behavior and the generated waveform */
#define PIT_MODE0_INT_ON_TERMINAL_COUNT 0x00
#define PIT_MODE1_ONESHOT 0x02
#define PIT_MODE2_RATE_GENERATOR 0x04
#define PIT_MODE3_SQUARE_WAVE_GEN 0x06
#define PIT_MODE4_SOFTWARE_STROBE 0x08
#define PIT_MODE5_HARDWARE_STROBE 0x0A
/* CMOS controller access ports */
#define CMOS_SELECT_PORT 0x70
#define CMOS_DATA_PORT 0x71
/* CMOD Select port definitions */
#define CMOS_NMI_SELECT 0x80
#define CMOS_REGISTER_SECOND 0x00
#define CMOS_REGISTER_MINUTE 0x02
#define CMOS_REGISTER_HOUR 0x04
#define CMOS_REGISTER_WEEKDAY 0x06
#define CMOS_REGISTER_DAY 0x07
#define CMOS_REGISTER_MONTH 0x08
#define CMOS_REGISTER_YEAR 0x09
#define CMOS_REGISTER_A 0x0A
#define CMOS_REGISTER_B 0x0B
#define CMOS_REGISTER_C 0x0C
/* CMOS Register A definitions */
#define CMOS_REGISTER_A_RATE_MASK 0x0F
#define CMOS_REGISTER_A_UPDATE_IN_PROGRESS 0x80
/* CMOS Register B definitions */
#define CMOS_REGISTER_B_24_HOUR 0x02
#define CMOS_REGISTER_B_BINARY 0x04
#define CMOS_REGISTER_B_PERIODIC 0x40
#define CMOS_REGISTER_B_SET_CLOCK 0x80
/* CMOS Register C definitions */
#define CMOS_REGISTER_C_PERIODIC 0x40
#define CMOS_REGISTER_C_INTERRUPT 0x80
/* CMOS RTC 24-hour mode */
#define CMOS_RTC_POST_MERIDIEM 0x80
/* Serial ports information */ /* Serial ports information */
#define COMPORT_ADDRESS {0x3F8, 0x2F8, 0x3E8, 0x2E8, 0x5F8, 0x4F8, 0x5E8, 0x4E8} #define COMPORT_ADDRESS {0x3F8, 0x2F8, 0x3E8, 0x2E8, 0x5F8, 0x4F8, 0x5E8, 0x4E8}
#define COMPORT_COUNT 8 #define COMPORT_COUNT 8
@@ -180,17 +76,6 @@
/* Initial stall factor */ /* Initial stall factor */
#define INITIAL_STALL_FACTOR 100 #define INITIAL_STALL_FACTOR 100
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* APIC destination mode enumeration list */
typedef enum _APIC_DEST_MODE
{
APIC_DM_Physical,
APIC_DM_Logical
} APIC_DEST_MODE, *PAPIC_DEST_MODE;
/* APIC delivery mode enumeration list */ /* APIC delivery mode enumeration list */
typedef enum _APIC_DM typedef enum _APIC_DM
{ {
@@ -248,7 +133,6 @@ typedef enum _APIC_REGISTER
APIC_TICR = 0x38, /* Initial Count Register for Timer */ APIC_TICR = 0x38, /* Initial Count Register for Timer */
APIC_TCCR = 0x39, /* Current Count Register for Timer */ APIC_TCCR = 0x39, /* Current Count Register for Timer */
APIC_TDCR = 0x3E, /* Timer Divide Configuration Register */ APIC_TDCR = 0x3E, /* Timer Divide Configuration Register */
APIC_SIPI = 0x3F, /* Self-IPI Register */
APIC_EAFR = 0x40, /* extended APIC Feature register */ APIC_EAFR = 0x40, /* extended APIC Feature register */
APIC_EACR = 0x41, /* Extended APIC Control Register */ APIC_EACR = 0x41, /* Extended APIC Control Register */
APIC_SEOI = 0x42, /* Specific End Of Interrupt Register */ APIC_SEOI = 0x42, /* Specific End Of Interrupt Register */
@@ -258,19 +142,6 @@ typedef enum _APIC_REGISTER
APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */ APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */
} APIC_REGISTER, *PAPIC_REGISTER; } APIC_REGISTER, *PAPIC_REGISTER;
/* APIC Timer Divide enumeration list */
typedef enum _APIC_TIMER_DIVISOR
{
TIMER_DivideBy2 = 0,
TIMER_DivideBy4 = 1,
TIMER_DivideBy8 = 2,
TIMER_DivideBy16 = 3,
TIMER_DivideBy32 = 8,
TIMER_DivideBy64 = 9,
TIMER_DivideBy128 = 10,
TIMER_DivideBy1 = 11,
} APIC_TIMER_DIVISOR, *PAPIC_TIMER_DIVISOR;
/* I8259 PIC interrupt mode enumeration list */ /* I8259 PIC interrupt mode enumeration list */
typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE
{ {
@@ -315,17 +186,6 @@ typedef enum _PIC_I8259_ICW4_SYSTEM_MODE
New8086Mode New8086Mode
} PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE; } PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;
/* Supported hardware timer backends */
typedef enum _TIMER_TYPE
{
TimerNone,
TimerAcpiPm,
TimerHpet,
TimerLapic,
TimerPit,
TimerTsc
} TIMER_TYPE, *PTIMER_TYPE;
/* APIC Base Register */ /* APIC Base Register */
typedef union _APIC_BASE_REGISTER typedef union _APIC_BASE_REGISTER
{ {
@@ -399,40 +259,6 @@ typedef union _APIC_SPURIOUS_REGISTER
}; };
} APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER; } APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
/* I/O APIC Controller information */
typedef struct _IOAPIC_DATA
{
ULONG GsiBase;
ULONG Identifier;
ULONG LineCount;
PHYSICAL_ADDRESS PhysicalAddress;
ULONG_PTR VirtualAddress;
} IOAPIC_DATA, *PIOAPIC_DATA;
/* I/O APIC Redirection Register */
typedef union _IOAPIC_REDIRECTION_REGISTER
{
ULONGLONG LongLong;
struct
{
UINT Base;
UINT Extended;
};
struct
{
ULONGLONG Vector:8;
ULONGLONG DeliveryMode:3;
ULONGLONG DestinationMode:1;
ULONGLONG DeliveryStatus:1;
ULONGLONG PinPolarity:1;
ULONGLONG RemoteIRR:1;
ULONGLONG TriggerMode:1;
ULONGLONG Mask:1;
ULONGLONG Reserved:39;
ULONGLONG Destination:8;
};
} IOAPIC_REDIRECTION_REGISTER, *PIOAPIC_REDIRECTION_REGISTER;
/* I8259 PIC register structure */ /* I8259 PIC register structure */
typedef union _PIC_I8259_ICW1 typedef union _PIC_I8259_ICW1
{ {
@@ -498,39 +324,4 @@ typedef union _PIC_I8259_ICW4
UCHAR Bits; UCHAR Bits;
} PIC_I8259_ICW4, *PPIC_I8259_ICW4; } PIC_I8259_ICW4, *PPIC_I8259_ICW4;
/* HPET Registers structure definition */
typedef struct _HPET_REGISTERS
{
VOLATILE ULONGLONG GeneralCapabilities;
VOLATILE ULONGLONG Reserved0;
VOLATILE ULONGLONG GeneralConfiguration;
VOLATILE ULONGLONG Reserved1;
VOLATILE ULONGLONG GeneralInterruptStatus;
VOLATILE ULONGLONG Reserved2;
VOLATILE ULONGLONG Reserved3[2][12];
VOLATILE ULONGLONG MainCounterValue;
VOLATILE ULONGLONG Reserved4;
struct
{
VOLATILE ULONGLONG Configuration;
VOLATILE ULONGLONG Comparator;
VOLATILE ULONGLONG FsbInterruptRoute;
VOLATILE ULONGLONG Reserved;
} Timers[];
} HPET_REGISTERS, *PHPET_REGISTERS;
/* Hardware timer capabilities and CPU clock features */
typedef struct _TIMER_CAPABILITIES
{
BOOLEAN Arat;
BOOLEAN Art;
BOOLEAN InvariantTsc;
BOOLEAN RDTSCP;
ULONG TimerFrequency;
BOOLEAN TscDeadline;
ULONG TscDenominator;
ULONG TscNumerator;
} TIMER_CAPABILITIES, *PTIMER_CAPABILITIES;
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_I686_HLTYPES_H */ #endif /* __XTDK_I686_HLTYPES_H */

View File

@@ -50,7 +50,7 @@
#define KGDT_DESCRIPTOR_CODE 0x08 #define KGDT_DESCRIPTOR_CODE 0x08
/* GDT descriptor type codes */ /* GDT descriptor type codes */
#define KGDT_TYPE_NONE 0x00 #define KGDT_TYPE_NONE 0x0
#define KGDT_TYPE_CODE (0x10 | KGDT_DESCRIPTOR_CODE | KGDT_DESCRIPTOR_EXECUTE_READ) #define KGDT_TYPE_CODE (0x10 | KGDT_DESCRIPTOR_CODE | KGDT_DESCRIPTOR_EXECUTE_READ)
#define KGDT_TYPE_DATA (0x10 | KGDT_DESCRIPTOR_READ_WRITE) #define KGDT_TYPE_DATA (0x10 | KGDT_DESCRIPTOR_READ_WRITE)
@@ -82,7 +82,6 @@
#define KTSS_IO_MAPS 0x68 #define KTSS_IO_MAPS 0x68
/* I686 Segment Types */ /* I686 Segment Types */
#define I686_LDT 0x2
#define I686_TASK_GATE 0x5 #define I686_TASK_GATE 0x5
#define I686_TSS 0x9 #define I686_TSS 0x9
#define I686_ACTIVE_TSS 0xB #define I686_ACTIVE_TSS 0xB
@@ -90,62 +89,6 @@
#define I686_INTERRUPT_GATE 0xE #define I686_INTERRUPT_GATE 0xE
#define I686_TRAP_GATE 0xF #define I686_TRAP_GATE 0xF
/* Kernel CPU Standard Features */
#define KCF_VME (1ULL << 0) /* Virtual 8086 Mode Enhancements */
#define KCF_LARGE_PAGE (1ULL << 1) /* Page Size Extensions */
#define KCF_RDTSC (1ULL << 2) /* Time Stamp Counter */
#define KCF_PAE (1ULL << 3) /* Physical Address Extension */
#define KCF_MCE (1ULL << 4) /* Machine Check Exception */
#define KCF_CMPXCHG8B (1ULL << 5) /* CMPXCHG8B Instruction */
#define KCF_APIC (1ULL << 6) /* APIC On-Chip */
#define KCF_FAST_SYSCALL (1ULL << 7) /* SYSENTER/SYSEXIT Instructions */
#define KCF_MTRR (1ULL << 8) /* Memory Type Range Registers */
#define KCF_GLOBAL_PAGE (1ULL << 9) /* Page Global Enable */
#define KCF_MCA (1ULL << 10) /* Machine Check Architecture */
#define KCF_CMOV (1ULL << 11) /* Conditional Move Instructions */
#define KCF_PAT (1ULL << 12) /* Page Attribute Table */
#define KCF_PSE36 (1ULL << 13) /* 36-bit Page Size Extension */
#define KCF_CLFLUSH (1ULL << 14) /* CLFLUSH Instruction */
#define KCF_FXSR (1ULL << 15) /* FXSAVE/FXRSTOR Instructions */
#define KCF_ACPI (1ULL << 16) /* Thermal Monitor and Software Controlled Clock */
#define KCF_MMX (1ULL << 17) /* MMX Technology */
#define KCF_SSE (1ULL << 18) /* Streaming SIMD Extensions */
#define KCF_SSE2 (1ULL << 19) /* Streaming SIMD Extensions 2 */
#define KCF_SMT (1ULL << 20) /* Hyper-Threading Technology */
#define KCF_SSE3 (1ULL << 21) /* Streaming SIMD Extensions 3 */
#define KCF_VMX (1ULL << 22) /* Intel Virtual Machine Extensions */
#define KCF_SSSE3 (1ULL << 23) /* Supplemental SSE3 Instructions */
#define KCF_SSE41 (1ULL << 24) /* SSE4.1 Instructions */
#define KCF_SSE42 (1ULL << 25) /* SSE4.2 Instructions */
#define KCF_X2APIC (1ULL << 26) /* x2APIC Support */
#define KCF_POPCNT (1ULL << 27) /* POPCNT Instruction */
#define KCF_TSC_DEADLINE (1ULL << 28) /* TSC Deadline Timer */
#define KCF_AES (1ULL << 29) /* AES-NI Instruction Set */
#define KCF_XSAVE (1ULL << 30) /* XSAVE/XRSTOR Instructions */
#define KCF_AVX (1ULL << 31) /* Advanced Vector Extensions */
#define KCF_RDRAND (1ULL << 32) /* RDRAND Instruction */
#define KCF_FSGSBASE (1ULL << 33) /* RDFSBASE/WRFSBASE Instructions */
#define KCF_AVX2 (1ULL << 34) /* AVX2 Instructions */
#define KCF_SMEP (1ULL << 35) /* Supervisor Mode Execution Prevention */
#define KCF_RDSEED (1ULL << 36) /* RDSEED Instruction */
#define KCF_SMAP (1ULL << 37) /* Supervisor Mode Access Prevention */
#define KCF_SHA (1ULL << 38) /* SHA Extensions */
#define KCF_LA57 (1ULL << 39) /* 57-bit Linear Addresses */
#define KCF_ARAT (1ULL << 40) /* Always Running APIC Timer */
/* Kernel CPU Extended Features */
#define KCF_SVM (1ULL << 0) /* AMD Secure Virtual Machine */
#define KCF_SSE4A (1ULL << 1) /* SSE4A Instructions */
#define KCF_FMA4 (1ULL << 2) /* FMA4 Instructions */
#define KCF_TOPOEXT (1ULL << 3) /* AMD Topology Extensions */
#define KCF_SYSCALL (1ULL << 4) /* SYSCALL/SYSRET Instructions */
#define KCF_NX_BIT (1ULL << 5) /* No-Execute Page Protection */
#define KCF_RDTSCP (1ULL << 6) /* RDTSCP Instruction */
#define KCF_64BIT (1ULL << 7) /* Long Mode Support */
#define KCF_3DNOW_EXT (1ULL << 8) /* 3DNow! Extensions */
#define KCF_3DNOW (1ULL << 9) /* 3DNow! Instructions */
#define KCF_INVARIANT_TSC (1ULL << 10) /* Invariant Time Stamp Counter */
/* Context control flags */ /* Context control flags */
#define CONTEXT_ARCHITECTURE 0x00010000 #define CONTEXT_ARCHITECTURE 0x00010000
#define CONTEXT_CONTROL (CONTEXT_ARCHITECTURE | 0x01) #define CONTEXT_CONTROL (CONTEXT_ARCHITECTURE | 0x01)
@@ -187,14 +130,13 @@
/* XTOS Kernel stack size */ /* XTOS Kernel stack size */
#define KERNEL_STACK_SIZE 0x4000 #define KERNEL_STACK_SIZE 0x4000
#define KERNEL_STACKS 3
/* XTOS Kernel stack guard pages */ /* XTOS Kernel stack guard pages */
#define KERNEL_STACK_GUARD_PAGES 1 #define KERNEL_STACK_GUARD_PAGES 1
/* Processor structures size */ /* Processor structures size */
#define KPROCESSOR_STRUCTURES_SIZE ((KERNEL_STACKS * KERNEL_STACK_SIZE) + (GDT_ENTRIES * sizeof(KGDTENTRY)) + \ #define KPROCESSOR_STRUCTURES_SIZE ((2 * KERNEL_STACK_SIZE) + (GDT_ENTRIES * sizeof(KGDTENTRY)) + sizeof(KTSS) + \
sizeof(KTSS) + sizeof(KPROCESSOR_BLOCK) + MM_PAGE_SIZE) sizeof(KPROCESSOR_BLOCK) + MM_PAGE_SIZE)
/* Kernel frames */ /* Kernel frames */
#define KTRAP_FRAME_ALIGN 0x08 #define KTRAP_FRAME_ALIGN 0x08
@@ -215,10 +157,6 @@
#define NPX_STATE_LOADED 0x0 #define NPX_STATE_LOADED 0x0
#define NPX_STATE_UNLOADED 0xA #define NPX_STATE_UNLOADED 0xA
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Floating point state storing structure */ /* Floating point state storing structure */
typedef struct _FN_SAVE_FORMAT typedef struct _FN_SAVE_FORMAT
{ {
@@ -399,14 +337,10 @@ typedef struct _KTSS
UCHAR IntDirectionMap[IOPM_DIRECTION_MAP_SIZE]; UCHAR IntDirectionMap[IOPM_DIRECTION_MAP_SIZE];
} KTSS, *PKTSS; } KTSS, *PKTSS;
/* Exception frame definition (not available on i686) */ /* Exception frame definition (not available on ia32) */
typedef struct _KEXCEPTION_FRAME typedef struct _KEXCEPTION_FRAME
{ {
ULONG Ebp; ULONG PlaceHolder;
ULONG Ebx;
ULONG Edi;
ULONG Esi;
ULONG Return;
} KEXCEPTION_FRAME, *PKEXCEPTION_FRAME; } KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;
/* Thread start frame definition */ /* Thread start frame definition */
@@ -487,17 +421,6 @@ typedef struct _KSPECIAL_REGISTERS
ULONG Reserved[6]; ULONG Reserved[6];
} KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS; } KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS;
/* Processor start block structure definition */
typedef struct _PROCESSOR_START_BLOCK
{
ULONG_PTR Cr3;
ULONG_PTR Cr4;
PVOID EntryPoint;
PVOID ProcessorStructures;
PVOID Stack;
BOOLEAN Started;
} PROCESSOR_START_BLOCK, *PPROCESSOR_START_BLOCK;
/* Processor state frame structure definition */ /* Processor state frame structure definition */
typedef struct _KPROCESSOR_STATE typedef struct _KPROCESSOR_STATE
{ {
@@ -523,7 +446,6 @@ typedef struct _KPROCESSOR_CONTROL_BLOCK
VOLATILE ULONG_PTR TimerRequest; VOLATILE ULONG_PTR TimerRequest;
SINGLE_LIST_ENTRY DeferredReadyListHead; SINGLE_LIST_ENTRY DeferredReadyListHead;
PROCESSOR_POWER_STATE PowerState; PROCESSOR_POWER_STATE PowerState;
ULONG ProfilingCountdown;
} KPROCESSOR_CONTROL_BLOCK, *PKPROCESSOR_CONTROL_BLOCK; } KPROCESSOR_CONTROL_BLOCK, *PKPROCESSOR_CONTROL_BLOCK;
/* Processor Block structure definition */ /* Processor Block structure definition */
@@ -550,9 +472,6 @@ typedef struct _KPROCESSOR_BLOCK
KAFFINITY SetMember; KAFFINITY SetMember;
ULONG StallScaleFactor; ULONG StallScaleFactor;
UCHAR CpuNumber; UCHAR CpuNumber;
ULONG HardwareId;
VOLATILE BOOLEAN Started;
PINTERRUPT_HANDLER InterruptDispatchTable[256];
} KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK; } KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK;
/* Thread Environment Block (TEB) structure definition */ /* Thread Environment Block (TEB) structure definition */
@@ -561,5 +480,4 @@ typedef struct _THREAD_ENVIRONMENT_BLOCK
THREAD_INFORMATION_BLOCK InformationBlock; THREAD_INFORMATION_BLOCK InformationBlock;
} THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK; } THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_I686_KETYPES_H */ #endif /* __XTDK_I686_KETYPES_H */

View File

@@ -99,9 +99,6 @@
/* HAL memory pool virtual address start */ /* HAL memory pool virtual address start */
#define MM_HARDWARE_VA_START 0xFFC00000 #define MM_HARDWARE_VA_START 0xFFC00000
/* Kernel shared data address */
#define MM_KERNEL_SHARED_DATA_ADDRESS 0xFFDF0000
/* Maximum physical address used by HAL allocations */ /* Maximum physical address used by HAL allocations */
#define MM_MAXIMUM_PHYSICAL_ADDRESS 0xFFFFFFFF #define MM_MAXIMUM_PHYSICAL_ADDRESS 0xFFFFFFFF
@@ -120,10 +117,6 @@
/* Number of pool tracking tables */ /* Number of pool tracking tables */
#define MM_POOL_TRACKING_TABLES 32 #define MM_POOL_TRACKING_TABLES 32
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Page size enumeration list */ /* Page size enumeration list */
typedef enum _PAGE_SIZE typedef enum _PAGE_SIZE
{ {
@@ -444,5 +437,4 @@ typedef struct _POOL_DESCRIPTOR
SIZE_T Reserved; SIZE_T Reserved;
} POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR; } POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_I686_MMTYPES_H */ #endif /* __XTDK_I686_MMTYPES_H */

View File

@@ -12,20 +12,13 @@
#include <xtdefs.h> #include <xtdefs.h>
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Architecture-specific enumeration lists forward references */ /* Architecture-specific enumeration lists forward references */
typedef enum _APIC_DEST_MODE APIC_DEST_MODE, *PAPIC_DEST_MODE;
typedef enum _APIC_DM APIC_DM, *PAPIC_DM; typedef enum _APIC_DM APIC_DM, *PAPIC_DM;
typedef enum _APIC_DSH APIC_DSH, *PAPIC_DSH; typedef enum _APIC_DSH APIC_DSH, *PAPIC_DSH;
typedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE; typedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE;
typedef enum _APIC_REGISTER APIC_REGISTER, *PAPIC_REGISTER; typedef enum _APIC_REGISTER APIC_REGISTER, *PAPIC_REGISTER;
typedef enum _APIC_TIMER_DIVISOR APIC_TIMER_DIVISOR, *PAPIC_TIMER_DIVISOR;
typedef enum _CPU_VENDOR CPU_VENDOR, *PCPU_VENDOR; typedef enum _CPU_VENDOR CPU_VENDOR, *PCPU_VENDOR;
typedef enum _CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT, *PCPUID_FEATURES_ADVANCED_POWER_MANAGEMENT;
typedef enum _CPUID_FEATURES_EXTENDED CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED; typedef enum _CPUID_FEATURES_EXTENDED CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
typedef enum _CPUID_FEATURES_POWER_MANAGEMENT CPUID_FEATURES_POWER_MANAGEMENT, *PCPUID_FEATURES_POWER_MANAGEMENT;
typedef enum _CPUID_FEATURES_STANDARD1 CPUID_FEATURES_STANDARD1, *PCPUID_FEATURES_STANDARD1; typedef enum _CPUID_FEATURES_STANDARD1 CPUID_FEATURES_STANDARD1, *PCPUID_FEATURES_STANDARD1;
typedef enum _CPUID_FEATURES_STANDARD7_LEAF0 CPUID_FEATURES_STANDARD7_LEAF0, *PCPUID_FEATURES_STANDARD7_LEAF0; typedef enum _CPUID_FEATURES_STANDARD7_LEAF0 CPUID_FEATURES_STANDARD7_LEAF0, *PCPUID_FEATURES_STANDARD7_LEAF0;
typedef enum _CPUID_FEATURES_STANDARD7_LEAF1 CPUID_FEATURES_STANDARD7_LEAF1, *PCPUID_FEATURES_STANDARD7_LEAF1; typedef enum _CPUID_FEATURES_STANDARD7_LEAF1 CPUID_FEATURES_STANDARD7_LEAF1, *PCPUID_FEATURES_STANDARD7_LEAF1;
@@ -37,7 +30,6 @@ typedef enum _PIC_I8259_ICW1_OPERATING_MODE PIC_I8259_ICW1_OPERATING_MODE, *PPIC
typedef enum _PIC_I8259_ICW4_BUFFERED_MODE PIC_I8259_ICW4_BUFFERED_MODE, *PPIC_I8259_ICW4_BUFFERED_MODE; typedef enum _PIC_I8259_ICW4_BUFFERED_MODE PIC_I8259_ICW4_BUFFERED_MODE, *PPIC_I8259_ICW4_BUFFERED_MODE;
typedef enum _PIC_I8259_ICW4_EOI_MODE PIC_I8259_ICW4_EOI_MODE, *PPIC_I8259_ICW4_EOI_MODE; typedef enum _PIC_I8259_ICW4_EOI_MODE PIC_I8259_ICW4_EOI_MODE, *PPIC_I8259_ICW4_EOI_MODE;
typedef enum _PIC_I8259_ICW4_SYSTEM_MODE PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE; typedef enum _PIC_I8259_ICW4_SYSTEM_MODE PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;
typedef enum _TIMER_TYPE TIMER_TYPE, *PTIMER_TYPE;
typedef enum _TRAMPOLINE_TYPE TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE; typedef enum _TRAMPOLINE_TYPE TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;
/* Architecture-specific structures forward references */ /* Architecture-specific structures forward references */
@@ -50,8 +42,6 @@ typedef struct _FX_SAVE_AREA FX_SAVE_AREA, *PFX_SAVE_AREA;
typedef struct _FX_SAVE_FORMAT FX_SAVE_FORMAT, *PFX_SAVE_FORMAT; typedef struct _FX_SAVE_FORMAT FX_SAVE_FORMAT, *PFX_SAVE_FORMAT;
typedef struct _HARDWARE_LEGACY_PTE HARDWARE_LEGACY_PTE, *PHARDWARE_LEGACY_PTE; typedef struct _HARDWARE_LEGACY_PTE HARDWARE_LEGACY_PTE, *PHARDWARE_LEGACY_PTE;
typedef struct _HARDWARE_MODERN_PTE HARDWARE_MODERN_PTE, *PHARDWARE_MODERN_PTE; typedef struct _HARDWARE_MODERN_PTE HARDWARE_MODERN_PTE, *PHARDWARE_MODERN_PTE;
typedef struct _HPET_REGISTERS HPET_REGISTERS, *PHPET_REGISTERS;
typedef struct _IOAPIC_DATA IOAPIC_DATA, *PIOAPIC_DATA;
typedef struct _KDESCRIPTOR KDESCRIPTOR, *PKDESCRIPTOR; typedef struct _KDESCRIPTOR KDESCRIPTOR, *PKDESCRIPTOR;
typedef struct _KEXCEPTION_FRAME KEXCEPTION_FRAME, *PKEXCEPTION_FRAME; typedef struct _KEXCEPTION_FRAME KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;
typedef struct _KGDTENTRY KGDTENTRY, *PKGDTENTRY; typedef struct _KGDTENTRY KGDTENTRY, *PKGDTENTRY;
@@ -82,7 +72,6 @@ typedef struct _MMPML3_PTE_SUBSECTION MMPML3_PTE_SUBSECTION, *PMMPML3_PTE_SUBSEC
typedef struct _MMPML3_PTE_TRANSITION MMPML3_PTE_TRANSITION, *PMMPML3_PTE_TRANSITION; typedef struct _MMPML3_PTE_TRANSITION MMPML3_PTE_TRANSITION, *PMMPML3_PTE_TRANSITION;
typedef struct _POOL_DESCRIPTOR POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR; typedef struct _POOL_DESCRIPTOR POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK; typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
typedef struct _TIMER_CAPABILITIES TIMER_CAPABILITIES, *PTIMER_CAPABILITIES;
/* Unions forward references */ /* Unions forward references */
typedef union _APIC_BASE_REGISTER APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER; typedef union _APIC_BASE_REGISTER APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER;
@@ -90,7 +79,6 @@ typedef union _APIC_COMMAND_REGISTER APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGIS
typedef union _APIC_LVT_REGISTER APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER; typedef union _APIC_LVT_REGISTER APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER;
typedef union _APIC_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER; typedef union _APIC_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
typedef union _HARDWARE_PTE HARDWARE_PTE, *PHARDWARE_PTE; typedef union _HARDWARE_PTE HARDWARE_PTE, *PHARDWARE_PTE;
typedef union _IOAPIC_REDIRECTION_REGISTER IOAPIC_REDIRECTION_REGISTER, *PIOAPIC_REDIRECTION_REGISTER;
typedef union _MMPML2_PTE MMPML2_PTE, *PMMPML2_PTE; typedef union _MMPML2_PTE MMPML2_PTE, *PMMPML2_PTE;
typedef union _MMPML3_PTE MMPML3_PTE, *PMMPML3_PTE; typedef union _MMPML3_PTE MMPML3_PTE, *PMMPML3_PTE;
typedef union _MMPTE MMPDE, *PMMPDE; typedef union _MMPTE MMPDE, *PMMPDE;
@@ -101,5 +89,4 @@ typedef union _PIC_I8259_ICW2 PIC_I8259_ICW2, *PPIC_I8259_ICW2;
typedef union _PIC_I8259_ICW3 PIC_I8259_ICW3, *PPIC_I8259_ICW3; typedef union _PIC_I8259_ICW3 PIC_I8259_ICW3, *PPIC_I8259_ICW3;
typedef union _PIC_I8259_ICW4 PIC_I8259_ICW4, *PPIC_I8259_ICW4; typedef union _PIC_I8259_ICW4 PIC_I8259_ICW4, *PPIC_I8259_ICW4;
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_I686_XTSTRUCT_H */ #endif /* __XTDK_I686_XTSTRUCT_H */

View File

@@ -58,10 +58,6 @@
#define PCI_STATUS_SIGNALED_SYSTEM_ERROR 0x4000 #define PCI_STATUS_SIGNALED_SYSTEM_ERROR 0x4000
#define PCI_STATUS_DETECTED_PARITY_ERROR 0x8000 #define PCI_STATUS_DETECTED_PARITY_ERROR 0x8000
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* PCI bridge control registers */ /* PCI bridge control registers */
typedef struct _PCI_BRIDGE_CONTROL_REGISTER typedef struct _PCI_BRIDGE_CONTROL_REGISTER
{ {
@@ -218,5 +214,4 @@ typedef struct _PCI_TYPE1_DEVICE
PCI_BRIDGE_CONTROL_REGISTER Bridge; PCI_BRIDGE_CONTROL_REGISTER Bridge;
} PCI_TYPE1_DEVICE, *PPCI_TYPE1_DEVICE; } PCI_TYPE1_DEVICE, *PPCI_TYPE1_DEVICE;
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_IOTYPES_H */ #endif /* __XTDK_IOTYPES_H */

View File

@@ -13,9 +13,6 @@
#include <xttypes.h> #include <xttypes.h>
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Kernel debugger routines forward references */ /* Kernel debugger routines forward references */
XTCLINK XTCLINK
XTCDECL XTCDECL
@@ -23,5 +20,4 @@ VOID
DbgPrint(PCWSTR Format, DbgPrint(PCWSTR Format,
...); ...);
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_KDFUNCS_H */ #endif /* __XTDK_KDFUNCS_H */

View File

@@ -21,10 +21,6 @@
#define DEBUG_PROVIDER_COMPORT 0x00000001 #define DEBUG_PROVIDER_COMPORT 0x00000001
#define DEBUG_PROVIDER_FRAMEBUFFER 0x00000002 #define DEBUG_PROVIDER_FRAMEBUFFER 0x00000002
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Kernel routine callbacks */ /* Kernel routine callbacks */
typedef XTSTATUS (XTAPI *PKD_INIT_ROUTINE)(); typedef XTSTATUS (XTAPI *PKD_INIT_ROUTINE)();
typedef VOID (*PKD_PRINT_ROUTINE)(IN PCWSTR Format, IN ...); typedef VOID (*PKD_PRINT_ROUTINE)(IN PCWSTR Format, IN ...);
@@ -46,5 +42,4 @@ typedef struct _KD_DISPATCH_TABLE
RTL_PRINT_CONTEXT PrintContext; RTL_PRINT_CONTEXT PrintContext;
} KD_DISPATCH_TABLE, *PKD_DISPATCH_TABLE; } KD_DISPATCH_TABLE, *PKD_DISPATCH_TABLE;
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_KDTYPES_H */ #endif /* __XTDK_KDTYPES_H */

View File

@@ -15,9 +15,6 @@
#include <ketypes.h> #include <ketypes.h>
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Kernel services routines forward references */ /* Kernel services routines forward references */
XTCLINK XTCLINK
XTFASTCALL XTFASTCALL
@@ -144,12 +141,6 @@ VOID
KeSetTargetProcessorDpc(IN PKDPC Dpc, KeSetTargetProcessorDpc(IN PKDPC Dpc,
IN CCHAR Number); IN CCHAR Number);
XTCLINK
XTAPI
VOID
KeSetTimeIncrement(IN ULONG MaxIncrement,
IN ULONG MinIncrement);
XTCLINK XTCLINK
XTAPI XTAPI
VOID VOID
@@ -168,5 +159,4 @@ XTAPI
BOOLEAN BOOLEAN
KeSignalCallDpcSynchronize(IN PVOID SystemArgument); KeSignalCallDpcSynchronize(IN PVOID SystemArgument);
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_KEFUNCS_H */ #endif /* __XTDK_KEFUNCS_H */

View File

@@ -49,10 +49,6 @@
#define THREAD_HIGH_PRIORITY 31 #define THREAD_HIGH_PRIORITY 31
#define THREAD_MAXIMUM_PRIORITY 32 #define THREAD_MAXIMUM_PRIORITY 32
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Adjust reason */ /* Adjust reason */
typedef enum _ADJUST_REASON typedef enum _ADJUST_REASON
{ {
@@ -137,37 +133,6 @@ typedef enum _KPROCESS_STATE
ProcessOutSwap ProcessOutSwap
} KPROCESS_STATE, *PKPROCESS_STATE; } KPROCESS_STATE, *PKPROCESS_STATE;
/* Kernel profiling sources */
typedef enum _KPROFILE_SOURCE
{
ProfileTime,
ProfileAlignmentFixup,
ProfileTotalIssues,
ProfilePipelineDry,
ProfileLoadInstructions,
ProfilePipelineFrozen,
ProfileBranchInstructions,
ProfileTotalNonissues,
ProfileDcacheMisses,
ProfileIcacheMisses,
ProfileCacheMisses,
ProfileBranchMispredictions,
ProfileStoreInstructions,
ProfileFpInstructions,
ProfileIntegerInstructions,
Profile2Issue,
Profile3Issue,
Profile4Issue,
ProfileSpecialInstructions,
ProfileTotalCycles,
ProfileIcacheIssues,
ProfileDcacheAccesses,
ProfileMemoryBarrierCycles,
ProfileLoadLinkedIssues,
ProfileXtKernel,
ProfileMaximum
} KPROFILE_SOURCE, *PKPROFILE_SOURCE;
/* Thread state */ /* Thread state */
typedef enum _KTHREAD_STATE typedef enum _KTHREAD_STATE
{ {
@@ -449,29 +414,6 @@ typedef struct _KPROCESS
UCHAR Spare; UCHAR Spare;
} KPROCESS, *PKPROCESS; } KPROCESS, *PKPROCESS;
/* System Time structure definition */
typedef struct _KSYSTEM_TIME
{
ULONG LowPart;
LONG High1Part;
LONG High2Part;
} KSYSTEM_TIME, *PKSYSTEM_TIME;
/* Kernel Shared Data (KSD) structure definition */
typedef struct _KSHARED_DATA
{
VOLATILE KSYSTEM_TIME InterruptTime;
VOLATILE KSYSTEM_TIME SystemTime;
VOLATILE KSYSTEM_TIME TickCount;
ULONG XtMajorVersion;
ULONG XtMinorVersion;
WCHAR XtBuild[8];
WCHAR XtBuildHash[11];
WCHAR XtArchitecture[8];
WCHAR XtDate[9];
WCHAR XtFullDate[25];
} KSHARED_DATA, *PKSHARED_DATA;
/* Thread control block structure definition */ /* Thread control block structure definition */
typedef struct _KTHREAD typedef struct _KTHREAD
{ {
@@ -705,5 +647,4 @@ typedef struct _KUBSAN_TYPE_MISMATCH_DATA_V1
UCHAR TypeCheckKind; UCHAR TypeCheckKind;
} KUBSAN_TYPE_MISMATCH_DATA_V1, *PKUBSAN_TYPE_MISMATCH_DATA_V1; } KUBSAN_TYPE_MISMATCH_DATA_V1, *PKUBSAN_TYPE_MISMATCH_DATA_V1;
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_KEFUNCS_H */ #endif /* __XTDK_KEFUNCS_H */

View File

@@ -38,10 +38,6 @@
#define LDR_DTE_MM_LOADED 0x40000000 #define LDR_DTE_MM_LOADED 0x40000000
#define LDR_DTE_COMPAT_DATABASE_PROCESSED 0x80000000 #define LDR_DTE_COMPAT_DATABASE_PROCESSED 0x80000000
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Loader data table entry */ /* Loader data table entry */
typedef struct _LDR_DATA_TABLE_ENTRY typedef struct _LDR_DATA_TABLE_ENTRY
{ {
@@ -74,5 +70,4 @@ typedef struct _LDR_DATA_TABLE_ENTRY
PVOID PatchInformation; PVOID PatchInformation;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY; } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_LDRTYPES_H */ #endif /* __XTDK_LDRTYPES_H */

View File

@@ -1,44 +0,0 @@
/**
* 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>
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* 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 /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_MMFUNCS_H */

View File

@@ -55,10 +55,6 @@
/* Protection field shift */ /* Protection field shift */
#define MM_PROTECT_FIELD_SHIFT 5 #define MM_PROTECT_FIELD_SHIFT 5
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Memory manager page lists */ /* Memory manager page lists */
typedef enum _MMPAGELISTS typedef enum _MMPAGELISTS
{ {
@@ -262,5 +258,4 @@ typedef struct _POOL_TRACKING_TABLE
ULONG Tag; ULONG Tag;
} POOL_TRACKING_TABLE, *PPOOL_TRACKING_TABLE; } POOL_TRACKING_TABLE, *PPOOL_TRACKING_TABLE;
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_MMTYPES_H */ #endif /* __XTDK_MMTYPES_H */

View File

@@ -14,9 +14,6 @@
#include <ketypes.h> #include <ketypes.h>
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Power Manager routine callbacks */ /* Power Manager routine callbacks */
typedef VOID (XTFASTCALL *PPROCESSOR_IDLE_FUNCTION)(IN PPROCESSOR_POWER_STATE PowerState); typedef VOID (XTFASTCALL *PPROCESSOR_IDLE_FUNCTION)(IN PPROCESSOR_POWER_STATE PowerState);
typedef XTSTATUS (XTFASTCALL *PSET_PROCESSOR_THROTTLE)(IN UCHAR Throttle); typedef XTSTATUS (XTFASTCALL *PSET_PROCESSOR_THROTTLE)(IN UCHAR Throttle);
@@ -91,5 +88,4 @@ typedef struct _PROCESSOR_POWER_STATE
ULONG LastC3UserTime; ULONG LastC3UserTime;
} PROCESSOR_POWER_STATE, *PPROCESSOR_POWER_STATE; } PROCESSOR_POWER_STATE, *PPROCESSOR_POWER_STATE;
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_POTYPES_H */ #endif /* __XTDK_POTYPES_H */

View File

@@ -13,9 +13,6 @@
#include <ketypes.h> #include <ketypes.h>
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Kernel's representation of a process object */ /* Kernel's representation of a process object */
typedef struct _EPROCESS typedef struct _EPROCESS
{ {
@@ -30,5 +27,4 @@ typedef struct _ETHREAD
UINT Reserved0; UINT Reserved0;
} ETHREAD, *PETHREAD; } ETHREAD, *PETHREAD;
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_PSTYPES_H */ #endif /* __XTDK_PSTYPES_H */

View File

@@ -15,9 +15,6 @@
#include <rtltypes.h> #include <rtltypes.h>
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Runtime Library routines forward references */ /* Runtime Library routines forward references */
XTCLINK XTCLINK
XTAPI XTAPI
@@ -297,18 +294,6 @@ BOOLEAN
RtlTestBit(IN PRTL_BITMAP BitMap, RtlTestBit(IN PRTL_BITMAP BitMap,
IN ULONG_PTR Bit); IN ULONG_PTR Bit);
XTCLINK
XTAPI
XTSTATUS
RtlTimeFieldsToUnixEpoch(IN PTIME_FIELDS TimeFields,
OUT PLONGLONG UnixTime);
XTCLINK
XTAPI
XTSTATUS
RtlTimeFieldsToXtEpoch(IN PTIME_FIELDS TimeFields,
OUT PLARGE_INTEGER XtTime);
XTCLINK XTCLINK
XTAPI XTAPI
PCHAR PCHAR
@@ -385,5 +370,4 @@ VOID
RtlZeroMemory(OUT PVOID Destination, RtlZeroMemory(OUT PVOID Destination,
IN SIZE_T Length); IN SIZE_T Length);
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_RTLFUNCS_H */ #endif /* __XTDK_RTLFUNCS_H */

View File

@@ -53,17 +53,6 @@
#define SHA1_BLOCK_SIZE 64 #define SHA1_BLOCK_SIZE 64
#define SHA1_DIGEST_SIZE 20 #define SHA1_DIGEST_SIZE 20
/* Time related definitions */
#define TIME_SECONDS_PER_MINUTE 60
#define TIME_SECONDS_PER_HOUR 3600
#define TIME_SECONDS_PER_DAY 86400
#define TIME_TICKS_PER_SECOND 10000000
#define TIME_TICKS_PER_MILLISECOND 10000
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Runtime Library routine callbacks */ /* Runtime Library routine callbacks */
typedef XTSTATUS (*PWRITE_CHARACTER)(IN CHAR Character); typedef XTSTATUS (*PWRITE_CHARACTER)(IN CHAR Character);
typedef XTSTATUS (*PWRITE_WIDE_CHARACTER)(IN WCHAR Character); typedef XTSTATUS (*PWRITE_WIDE_CHARACTER)(IN WCHAR Character);
@@ -118,18 +107,4 @@ typedef struct _RTL_SHA1_CONTEXT
UCHAR Buffer[SHA1_BLOCK_SIZE]; UCHAR Buffer[SHA1_BLOCK_SIZE];
} RTL_SHA1_CONTEXT, *PRTL_SHA1_CONTEXT; } RTL_SHA1_CONTEXT, *PRTL_SHA1_CONTEXT;
/* Runtime time fields structure definition */
typedef struct _TIME_FIELDS
{
SHORT Year;
SHORT Month;
SHORT Day;
SHORT Hour;
SHORT Minute;
SHORT Second;
SHORT Milliseconds;
SHORT Weekday;
} TIME_FIELDS, *PTIME_FIELDS;
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_RTLTYPES_H */ #endif /* __XTDK_RTLTYPES_H */

View File

@@ -14,9 +14,6 @@
#include <xttypes.h> #include <xttypes.h>
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Kernel affinity */ /* Kernel affinity */
typedef ULONG_PTR KAFFINITY, *PKAFFINITY; typedef ULONG_PTR KAFFINITY, *PKAFFINITY;
@@ -111,5 +108,4 @@ typedef struct _DISPATCHER_HEADER
LIST_ENTRY WaitListHead; LIST_ENTRY WaitListHead;
} DISPATCHER_HEADER, *PDISPATCHER_HEADER; } DISPATCHER_HEADER, *PDISPATCHER_HEADER;
#endif /* __XTOS_ASSEMBLER_ */
#endif /* __XTDK_XTBASE_H */ #endif /* __XTDK_XTBASE_H */

View File

@@ -10,15 +10,11 @@
#define __XTDK_XTCOMPAT_H #define __XTDK_XTCOMPAT_H
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
#ifdef __cplusplus #ifdef __cplusplus
/* C++ definitions */ /* C++ definitions */
#define NULLPTR nullptr #define NULLPTR nullptr
#define VIRTUAL virtual #define VIRTUAL virtual
#define XTCLINK extern "C" #define XTCLINK extern "C"
#define XTSYMBOL(Name) __asm__(Name)
/* C++ boolean type */ /* C++ boolean type */
typedef bool BOOLEAN, *PBOOLEAN; typedef bool BOOLEAN, *PBOOLEAN;
@@ -32,7 +28,6 @@
#define NULLPTR ((void *)0) #define NULLPTR ((void *)0)
#define VIRTUAL #define VIRTUAL
#define XTCLINK #define XTCLINK
#define XTSYMBOL(Name)
/* C boolean type */ /* C boolean type */
typedef enum _BOOLEAN typedef enum _BOOLEAN
@@ -45,5 +40,4 @@
typedef unsigned short wchar; typedef unsigned short wchar;
#endif #endif
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_XTCOMPAT_H */ #endif /* __XTDK_XTCOMPAT_H */

View File

@@ -58,10 +58,6 @@
/* Macro for calculating size of an array */ /* Macro for calculating size of an array */
#define ARRAY_SIZE(Array) (sizeof(Array) / sizeof(*Array)) #define ARRAY_SIZE(Array) (sizeof(Array) / sizeof(*Array))
/* Macros for converting Binary Coded Decimal (BCD) into decimal and vice versa */
#define BCD_TO_DECIMAL(Value) (((Value) & 0x0F) + (((Value) >> 4) * 10))
#define DECIMAL_TO_BCD(Value) ((((Value) / 10) << 4) | ((Value) % 10))
/* Macros for concatenating two strings */ /* Macros for concatenating two strings */
#define CONCAT_STRING(Str1, Str2) Str1##Str2 #define CONCAT_STRING(Str1, Str2) Str1##Str2
#define CONCATENATE(Str1, Str2) CONCAT_STRING(Str1, Str2) #define CONCATENATE(Str1, Str2) CONCAT_STRING(Str1, Str2)
@@ -115,6 +111,7 @@
#define UNIQUE(Prefix) CONCATENATE(CONCATENATE(__UNIQUE_ID_, Prefix), __COUNTER__) #define UNIQUE(Prefix) CONCATENATE(CONCATENATE(__UNIQUE_ID_, Prefix), __COUNTER__)
/* Variadic ABI functions */ /* 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, UINT_PTR)) : \
(Type)(__builtin_va_arg(Marker, Type))) (Type)(__builtin_va_arg(Marker, Type)))

View File

@@ -13,9 +13,6 @@
#include <xtdefs.h> #include <xtdefs.h>
/* C/C++ specific code */
#ifndef D__XTOS_ASSEMBLER__
/* SSF2 font header */ /* SSF2 font header */
typedef struct _SSFN_FONT_HEADER typedef struct _SSFN_FONT_HEADER
{ {
@@ -3983,5 +3980,4 @@ UCHAR XtFbDefaultFont[] = {0x78, 0x74, 0x66, 0x6E, 0x3B, 0xE7, 0x00, 0x00, 0x03,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x82, 0x32, 0x4E, 0x46, 0x53}; 0x82, 0x32, 0x4E, 0x46, 0x53};
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_XTFONT_H */ #endif /* __XTDK_XTFONT_H */

View File

@@ -19,10 +19,6 @@
/* Version number of the current XTOS loader protocol */ /* Version number of the current XTOS loader protocol */
#define BOOT_PROTOCOL_VERSION 1 #define BOOT_PROTOCOL_VERSION 1
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Memory allocation structures */ /* Memory allocation structures */
typedef enum _LOADER_MEMORY_TYPE typedef enum _LOADER_MEMORY_TYPE
{ {
@@ -120,5 +116,4 @@ typedef struct _KERNEL_INITIALIZATION_BLOCK
FIRMWARE_INFORMATION_BLOCK FirmwareInformation; FIRMWARE_INFORMATION_BLOCK FirmwareInformation;
} KERNEL_INITIALIZATION_BLOCK, *PKERNEL_INITIALIZATION_BLOCK; } KERNEL_INITIALIZATION_BLOCK, *PKERNEL_INITIALIZATION_BLOCK;
#endif /* __XTOS_ASSEMBLER_ */
#endif /* __XTDK_XTFW_H */ #endif /* __XTDK_XTFW_H */

View File

@@ -12,9 +12,6 @@
#include <xttypes.h> #include <xttypes.h>
/* C/C++ specific code */
#ifndef D__XTOS_ASSEMBLER__
CHAR XTGLYPH_EXECTOS_LOGO[] = CHAR XTGLYPH_EXECTOS_LOGO[] =
{ {
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x25, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x25, 0x23,
@@ -64,5 +61,4 @@ CHAR XTGLYPH_EXECTOS_LOGO[] =
0x28, 0x0d, 0x0a 0x28, 0x0d, 0x0a
}; };
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_XTGLYPH_H */ #endif /* __XTDK_XTGLYPH_H */

View File

@@ -202,10 +202,6 @@
#define PECOFF_IMAGE_SCN_MEM_READ 0x40000000 #define PECOFF_IMAGE_SCN_MEM_READ 0x40000000
#define PECOFF_IMAGE_SCN_MEM_WRITE 0x80000000 #define PECOFF_IMAGE_SCN_MEM_WRITE 0x80000000
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* PE/COFF image representation structure */ /* PE/COFF image representation structure */
typedef struct _PECOFF_IMAGE_CONTEXT typedef struct _PECOFF_IMAGE_CONTEXT
{ {
@@ -642,5 +638,4 @@ typedef struct _PECOFF_IMAGE_RESOURCE_DATA_ENTRY
ULONG Reserved; ULONG Reserved;
} PECOFF_IMAGE_RESOURCE_DATA_ENTRY, *PPECOFF_IMAGE_RESOURCE_DATA_ENTRY; } PECOFF_IMAGE_RESOURCE_DATA_ENTRY, *PPECOFF_IMAGE_RESOURCE_DATA_ENTRY;
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_XTIMAGE_H */ #endif /* __XTDK_XTIMAGE_H */

View File

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

View File

@@ -61,8 +61,6 @@
#define STATUS_NO_MEMORY ((XTSTATUS) 0xC0000017L) #define STATUS_NO_MEMORY ((XTSTATUS) 0xC0000017L)
#define STATUS_PORT_DISCONNECTED ((XTSTATUS) 0xC0000037L) #define STATUS_PORT_DISCONNECTED ((XTSTATUS) 0xC0000037L)
#define STATUS_CRC_ERROR ((XTSTATUS) 0xC000003FL) #define STATUS_CRC_ERROR ((XTSTATUS) 0xC000003FL)
#define STATUS_FLOAT_OVERFLOW ((XTSTATUS) 0xC0000091L)
#define STATUS_INTEGER_OVERFLOW ((XTSTATUS) 0xC0000095L)
#define STATUS_INSUFFICIENT_RESOURCES ((XTSTATUS) 0xC000009AL) #define STATUS_INSUFFICIENT_RESOURCES ((XTSTATUS) 0xC000009AL)
#define STATUS_DEVICE_NOT_READY ((XTSTATUS) 0xC00000A3L) #define STATUS_DEVICE_NOT_READY ((XTSTATUS) 0xC00000A3L)
#define STATUS_NOT_SUPPORTED ((XTSTATUS) 0xC00000BBL) #define STATUS_NOT_SUPPORTED ((XTSTATUS) 0xC00000BBL)

View File

@@ -12,9 +12,6 @@
#include <xtdefs.h> #include <xtdefs.h>
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Enumeration lists forward references */ /* Enumeration lists forward references */
typedef enum _ADJUST_REASON ADJUST_REASON, *PADJUST_REASON; typedef enum _ADJUST_REASON ADJUST_REASON, *PADJUST_REASON;
typedef enum _EXCEPTION_DISPOSITION EXCEPTION_DISPOSITION, *PEXCEPTION_DISPOSITION; typedef enum _EXCEPTION_DISPOSITION EXCEPTION_DISPOSITION, *PEXCEPTION_DISPOSITION;
@@ -47,7 +44,6 @@ typedef enum _KDPC_IMPORTANCE KDPC_IMPORTANCE, *PKDPC_IMPORTANCE;
typedef enum _KEVENT_TYPE KEVENT_TYPE, *PKEVENT_TYPE; typedef enum _KEVENT_TYPE KEVENT_TYPE, *PKEVENT_TYPE;
typedef enum _KOBJECTS KOBJECTS, *PKOBJECTS; typedef enum _KOBJECTS KOBJECTS, *PKOBJECTS;
typedef enum _KPROCESS_STATE KPROCESS_STATE, *PKPROCESS_STATE; typedef enum _KPROCESS_STATE KPROCESS_STATE, *PKPROCESS_STATE;
typedef enum _KPROFILE_SOURCE KPROFILE_SOURCE, *PKPROFILE_SOURCE;
typedef enum _KTHREAD_STATE KTHREAD_STATE, *PKTHREAD_STATE; typedef enum _KTHREAD_STATE KTHREAD_STATE, *PKTHREAD_STATE;
typedef enum _KTIMER_TYPE KTIMER_TYPE, *PKTIMER_TYPE; typedef enum _KTIMER_TYPE KTIMER_TYPE, *PKTIMER_TYPE;
typedef enum _KUBSAN_DATA_TYPE KUBSAN_DATA_TYPE, *PKUBSAN_DATA_TYPE; typedef enum _KUBSAN_DATA_TYPE KUBSAN_DATA_TYPE, *PKUBSAN_DATA_TYPE;
@@ -66,12 +62,8 @@ typedef enum _WAIT_TYPE WAIT_TYPE, *PWAIT_TYPE;
typedef struct _ACPI_CACHE_LIST ACPI_CACHE_LIST, *PACPI_CACHE_LIST; typedef struct _ACPI_CACHE_LIST ACPI_CACHE_LIST, *PACPI_CACHE_LIST;
typedef struct _ACPI_DESCRIPTION_HEADER ACPI_DESCRIPTION_HEADER, *PACPI_DESCRIPTION_HEADER; typedef struct _ACPI_DESCRIPTION_HEADER ACPI_DESCRIPTION_HEADER, *PACPI_DESCRIPTION_HEADER;
typedef struct _ACPI_FADT ACPI_FADT, *PACPI_FADT; typedef struct _ACPI_FADT ACPI_FADT, *PACPI_FADT;
typedef struct _ACPI_HPET ACPI_HPET, *PACPI_HPET;
typedef struct _ACPI_MADT ACPI_MADT, *PACPI_MADT; typedef struct _ACPI_MADT ACPI_MADT, *PACPI_MADT;
typedef struct _ACPI_MADT_INTERRUPT_OVERRIDE ACPI_MADT_INTERRUPT_OVERRIDE, *PACPI_MADT_INTERRUPT_OVERRIDE; typedef struct _ACPI_MADT_TABLE_LOCAL_APIC ACPI_MADT_TABLE_LOCAL_APIC, *PACPI_MADT_TABLE_LOCAL_APIC;
typedef struct _ACPI_MADT_IOAPIC ACPI_MADT_IOAPIC, *PACPI_MADT_IOAPIC;
typedef struct _ACPI_MADT_LOCAL_APIC ACPI_MADT_LOCAL_APIC, *PACPI_MADT_LOCAL_APIC;
typedef struct _ACPI_MADT_LOCAL_X2APIC ACPI_MADT_LOCAL_X2APIC, *PACPI_MADT_LOCAL_X2APIC;
typedef struct _ACPI_RSDP ACPI_RSDP, *PACPI_RSDP; typedef struct _ACPI_RSDP ACPI_RSDP, *PACPI_RSDP;
typedef struct _ACPI_RSDT ACPI_RSDT, *PACPI_RSDT; typedef struct _ACPI_RSDT ACPI_RSDT, *PACPI_RSDT;
typedef struct _ACPI_SUBTABLE_HEADER ACPI_SUBTABLE_HEADER, *PACPI_SUBTABLE_HEADER; typedef struct _ACPI_SUBTABLE_HEADER ACPI_SUBTABLE_HEADER, *PACPI_SUBTABLE_HEADER;
@@ -263,9 +255,7 @@ typedef struct _KPROCESS KPROCESS, *PKPROCESS;
typedef struct _KQUEUE KQUEUE, *PKQUEUE; typedef struct _KQUEUE KQUEUE, *PKQUEUE;
typedef struct _KSEMAPHORE KSEMAPHORE, *PKSEMAPHORE; typedef struct _KSEMAPHORE KSEMAPHORE, *PKSEMAPHORE;
typedef struct _KSERVICE_DESCRIPTOR_TABLE KSERVICE_DESCRIPTOR_TABLE, *PKSERVICE_DESCRIPTOR_TABLE; typedef struct _KSERVICE_DESCRIPTOR_TABLE KSERVICE_DESCRIPTOR_TABLE, *PKSERVICE_DESCRIPTOR_TABLE;
typedef struct _KSHARED_DATA KSHARED_DATA, *PKSHARED_DATA;
typedef struct _KSPIN_LOCK_QUEUE KSPIN_LOCK_QUEUE, *PKSPIN_LOCK_QUEUE; typedef struct _KSPIN_LOCK_QUEUE KSPIN_LOCK_QUEUE, *PKSPIN_LOCK_QUEUE;
typedef struct _KSYSTEM_TIME KSYSTEM_TIME, *PKSYSTEM_TIME;
typedef struct _KTHREAD KTHREAD, *PKTHREAD; typedef struct _KTHREAD KTHREAD, *PKTHREAD;
typedef struct _KTIMER KTIMER, *PKTIMER; typedef struct _KTIMER KTIMER, *PKTIMER;
typedef struct _KUBSAN_FLOAT_CAST_OVERFLOW_DATA KUBSAN_FLOAT_CAST_OVERFLOW_DATA, *PKUBSAN_FLOAT_CAST_OVERFLOW_DATA; typedef struct _KUBSAN_FLOAT_CAST_OVERFLOW_DATA KUBSAN_FLOAT_CAST_OVERFLOW_DATA, *PKUBSAN_FLOAT_CAST_OVERFLOW_DATA;
@@ -337,8 +327,6 @@ typedef struct _STRING STRING, *PSTRING;
typedef struct _STRING32 STRING32, *PSTRING32; typedef struct _STRING32 STRING32, *PSTRING32;
typedef struct _STRING64 STRING64, *PSTRING64; typedef struct _STRING64 STRING64, *PSTRING64;
typedef struct _THREAD_INFORMATION_BLOCK THREAD_INFORMATION_BLOCK, *PTHREAD_INFORMATION_BLOCK; typedef struct _THREAD_INFORMATION_BLOCK THREAD_INFORMATION_BLOCK, *PTHREAD_INFORMATION_BLOCK;
typedef struct _TIME_FIELDS TIME_FIELDS, *PTIME_FIELDS;
typedef struct _TIMER_ROUTINES TIMER_ROUTINES, *PTIMER_ROUTINES;
typedef struct _UEFI_FIRMWARE_INFORMATION UEFI_FIRMWARE_INFORMATION, *PUEFI_FIRMWARE_INFORMATION; typedef struct _UEFI_FIRMWARE_INFORMATION UEFI_FIRMWARE_INFORMATION, *PUEFI_FIRMWARE_INFORMATION;
typedef struct _UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING; typedef struct _UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING;
typedef struct _UNICODE_STRING32 UNICODE_STRING32, *PUNICODE_STRING32; typedef struct _UNICODE_STRING32 UNICODE_STRING32, *PUNICODE_STRING32;
@@ -375,5 +363,4 @@ typedef union _LARGE_INTEGER LARGE_INTEGER, *PLARGE_INTEGER;
typedef union _SINGLE_LIST_HEADER SINGLE_LIST_HEADER, *PSINGLE_LIST_HEADER; typedef union _SINGLE_LIST_HEADER SINGLE_LIST_HEADER, *PSINGLE_LIST_HEADER;
typedef union _ULARGE_INTEGER ULARGE_INTEGER, *PULARGE_INTEGER; typedef union _ULARGE_INTEGER ULARGE_INTEGER, *PULARGE_INTEGER;
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_XTSTRUCT_H */ #endif /* __XTDK_XTSTRUCT_H */

View File

@@ -13,9 +13,6 @@
#include <xtcompat.h> #include <xtcompat.h>
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Standard C types */ /* Standard C types */
typedef unsigned char BYTE, *PBYTE, *LPBYTE; typedef unsigned char BYTE, *PBYTE, *LPBYTE;
typedef char CHAR, *PCHAR, *LPCHAR; typedef char CHAR, *PCHAR, *LPCHAR;
@@ -153,9 +150,6 @@ typedef LPCWSTR PCTSTR, LPCTSTR;
typedef LPUWSTR PUTSTR, LPUTSTR; typedef LPUWSTR PUTSTR, LPUTSTR;
typedef LPCUWSTR PCUTSTR, LPCUTSTR; typedef LPCUWSTR PCUTSTR, LPCUTSTR;
/* Variadic ABI types */
typedef __builtin_va_list VA_LIST, *PVA_LIST;
/* 128-bit floats structure */ /* 128-bit floats structure */
typedef struct _FLOAT128 typedef struct _FLOAT128
{ {
@@ -293,5 +287,4 @@ typedef struct _UNICODE_STRING64
} UNICODE_STRING64, *PUNICODE_STRING64; } UNICODE_STRING64, *PUNICODE_STRING64;
typedef const UNICODE_STRING64 *PCUNICODE_STRING64; typedef const UNICODE_STRING64 *PCUNICODE_STRING64;
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_XTTYPES_H */ #endif /* __XTDK_XTTYPES_H */

View File

@@ -373,10 +373,6 @@
#define EFI_CONFIG_TABLE_SMBIOS_TABLE_GUID {0xEB9D2D31, 0x2D88, 0x11D3, {0x9A, 0x16, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}} #define EFI_CONFIG_TABLE_SMBIOS_TABLE_GUID {0xEB9D2D31, 0x2D88, 0x11D3, {0x9A, 0x16, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}}
#define EFI_CONFIG_TABLE_SMBIOS3_TABLE_GUID {0xF2FD1544, 0x9794, 0x4A2C, {0x99, 0x2E, 0xE5, 0xBB, 0xCf, 0x20, 0xE3, 0x94}} #define EFI_CONFIG_TABLE_SMBIOS3_TABLE_GUID {0xF2FD1544, 0x9794, 0x4A2C, {0x99, 0x2E, 0xE5, 0xBB, 0xCf, 0x20, 0xE3, 0x94}}
/* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__
/* Basic UEFI types */ /* Basic UEFI types */
typedef PVOID EFI_EVENT, *PEFI_EVENT; typedef PVOID EFI_EVENT, *PEFI_EVENT;
typedef PVOID EFI_HANDLE, *PEFI_HANDLE; typedef PVOID EFI_HANDLE, *PEFI_HANDLE;
@@ -2727,5 +2723,4 @@ typedef struct _EFI_PROCESSOR_INFORMATION
EFI_PROCESSOR_PHYSICAL_LOCATION Location; EFI_PROCESSOR_PHYSICAL_LOCATION Location;
} EFI_PROCESSOR_INFORMATION, *PEFI_PROCESSOR_INFORMATION; } EFI_PROCESSOR_INFORMATION, *PEFI_PROCESSOR_INFORMATION;
#endif /* __XTOS_ASSEMBLER__ */
#endif /* __XTDK_XTUEFI_H */ #endif /* __XTDK_XTUEFI_H */

View File

@@ -10,6 +10,7 @@ include_directories(
# Specify list of kernel source code files # Specify list of kernel source code files
list(APPEND XTOSKRNL_SOURCE list(APPEND XTOSKRNL_SOURCE
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/archsup.S ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/archsup.S
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/boot.S
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.cc ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.cc
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/data.cc ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/data.cc
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/procsup.cc ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/procsup.cc
@@ -17,13 +18,9 @@ list(APPEND XTOSKRNL_SOURCE
${XTOSKRNL_SOURCE_DIR}/ex/exports.cc ${XTOSKRNL_SOURCE_DIR}/ex/exports.cc
${XTOSKRNL_SOURCE_DIR}/ex/rundown.cc ${XTOSKRNL_SOURCE_DIR}/ex/rundown.cc
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/cpu.cc ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/cpu.cc
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/firmware.cc
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.cc
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/irq.cc
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/pic.cc ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/pic.cc
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/rtc.cc ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.cc
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/runlevel.cc ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/runlevel.cc
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/timer.cc
${XTOSKRNL_SOURCE_DIR}/hl/acpi.cc ${XTOSKRNL_SOURCE_DIR}/hl/acpi.cc
${XTOSKRNL_SOURCE_DIR}/hl/cport.cc ${XTOSKRNL_SOURCE_DIR}/hl/cport.cc
${XTOSKRNL_SOURCE_DIR}/hl/data.cc ${XTOSKRNL_SOURCE_DIR}/hl/data.cc
@@ -34,7 +31,7 @@ list(APPEND XTOSKRNL_SOURCE
${XTOSKRNL_SOURCE_DIR}/kd/data.cc ${XTOSKRNL_SOURCE_DIR}/kd/data.cc
${XTOSKRNL_SOURCE_DIR}/kd/dbgio.cc ${XTOSKRNL_SOURCE_DIR}/kd/dbgio.cc
${XTOSKRNL_SOURCE_DIR}/kd/exports.cc ${XTOSKRNL_SOURCE_DIR}/kd/exports.cc
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/dispatch.cc ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/irq.cc
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/krnlinit.cc ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/krnlinit.cc
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/kthread.cc ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/kthread.cc
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/proc.cc ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/proc.cc
@@ -42,7 +39,6 @@ list(APPEND XTOSKRNL_SOURCE
${XTOSKRNL_SOURCE_DIR}/ke/bootinfo.cc ${XTOSKRNL_SOURCE_DIR}/ke/bootinfo.cc
${XTOSKRNL_SOURCE_DIR}/ke/crash.cc ${XTOSKRNL_SOURCE_DIR}/ke/crash.cc
${XTOSKRNL_SOURCE_DIR}/ke/data.cc ${XTOSKRNL_SOURCE_DIR}/ke/data.cc
${XTOSKRNL_SOURCE_DIR}/ke/dispatch.cc
${XTOSKRNL_SOURCE_DIR}/ke/dpc.cc ${XTOSKRNL_SOURCE_DIR}/ke/dpc.cc
${XTOSKRNL_SOURCE_DIR}/ke/event.cc ${XTOSKRNL_SOURCE_DIR}/ke/event.cc
${XTOSKRNL_SOURCE_DIR}/ke/exports.cc ${XTOSKRNL_SOURCE_DIR}/ke/exports.cc
@@ -52,10 +48,8 @@ list(APPEND XTOSKRNL_SOURCE
${XTOSKRNL_SOURCE_DIR}/ke/kubsan.cc ${XTOSKRNL_SOURCE_DIR}/ke/kubsan.cc
${XTOSKRNL_SOURCE_DIR}/ke/runlevel.cc ${XTOSKRNL_SOURCE_DIR}/ke/runlevel.cc
${XTOSKRNL_SOURCE_DIR}/ke/semphore.cc ${XTOSKRNL_SOURCE_DIR}/ke/semphore.cc
${XTOSKRNL_SOURCE_DIR}/ke/shdata.cc
${XTOSKRNL_SOURCE_DIR}/ke/spinlock.cc ${XTOSKRNL_SOURCE_DIR}/ke/spinlock.cc
${XTOSKRNL_SOURCE_DIR}/ke/sysres.cc ${XTOSKRNL_SOURCE_DIR}/ke/sysres.cc
${XTOSKRNL_SOURCE_DIR}/ke/systime.cc
${XTOSKRNL_SOURCE_DIR}/ke/timer.cc ${XTOSKRNL_SOURCE_DIR}/ke/timer.cc
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/mmgr.cc ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/mmgr.cc
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pagemap.cc ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pagemap.cc
@@ -67,7 +61,6 @@ list(APPEND XTOSKRNL_SOURCE
${XTOSKRNL_SOURCE_DIR}/mm/alloc.cc ${XTOSKRNL_SOURCE_DIR}/mm/alloc.cc
${XTOSKRNL_SOURCE_DIR}/mm/colors.cc ${XTOSKRNL_SOURCE_DIR}/mm/colors.cc
${XTOSKRNL_SOURCE_DIR}/mm/data.cc ${XTOSKRNL_SOURCE_DIR}/mm/data.cc
${XTOSKRNL_SOURCE_DIR}/mm/exports.cc
${XTOSKRNL_SOURCE_DIR}/mm/hlpool.cc ${XTOSKRNL_SOURCE_DIR}/mm/hlpool.cc
${XTOSKRNL_SOURCE_DIR}/mm/kpool.cc ${XTOSKRNL_SOURCE_DIR}/mm/kpool.cc
${XTOSKRNL_SOURCE_DIR}/mm/mmgr.cc ${XTOSKRNL_SOURCE_DIR}/mm/mmgr.cc
@@ -78,7 +71,6 @@ list(APPEND XTOSKRNL_SOURCE
${XTOSKRNL_SOURCE_DIR}/po/idle.cc ${XTOSKRNL_SOURCE_DIR}/po/idle.cc
${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/dispatch.cc ${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/dispatch.cc
${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/exsup.cc ${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/exsup.cc
${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/intrin.cc
${XTOSKRNL_SOURCE_DIR}/rtl/atomic.cc ${XTOSKRNL_SOURCE_DIR}/rtl/atomic.cc
${XTOSKRNL_SOURCE_DIR}/rtl/bitmap.cc ${XTOSKRNL_SOURCE_DIR}/rtl/bitmap.cc
${XTOSKRNL_SOURCE_DIR}/rtl/data.cc ${XTOSKRNL_SOURCE_DIR}/rtl/data.cc
@@ -91,7 +83,6 @@ list(APPEND XTOSKRNL_SOURCE
${XTOSKRNL_SOURCE_DIR}/rtl/sha1.cc ${XTOSKRNL_SOURCE_DIR}/rtl/sha1.cc
${XTOSKRNL_SOURCE_DIR}/rtl/slist.cc ${XTOSKRNL_SOURCE_DIR}/rtl/slist.cc
${XTOSKRNL_SOURCE_DIR}/rtl/string.cc ${XTOSKRNL_SOURCE_DIR}/rtl/string.cc
${XTOSKRNL_SOURCE_DIR}/rtl/time.cc
${XTOSKRNL_SOURCE_DIR}/rtl/widestr.cc) ${XTOSKRNL_SOURCE_DIR}/rtl/widestr.cc)
# Set module definition SPEC file # Set module definition SPEC file
@@ -99,13 +90,15 @@ set_specfile(xtoskrnl.spec xtoskrnl.exe)
# Link static XTOS library # Link static XTOS library
add_library(libxtos ${XTOSKRNL_SOURCE}) add_library(libxtos ${XTOSKRNL_SOURCE})
target_link_libraries(libxtos PRIVATE xtadk)
# Link kernel executable # Link kernel executable
add_executable(xtoskrnl ${CMAKE_CURRENT_BINARY_DIR}/xtoskrnl.def) add_executable(xtoskrnl
${CMAKE_CURRENT_BINARY_DIR}/xtoskrnl.def)
# Add linker libraries # Add linker libraries
target_link_libraries(xtoskrnl PRIVATE libxtos) target_link_libraries(xtoskrnl
PRIVATE
libxtos)
# Set proper binary name and install target # Set proper binary name and install target
set_target_properties(xtoskrnl PROPERTIES SUFFIX .exe) set_target_properties(xtoskrnl PROPERTIES SUFFIX .exe)

View File

@@ -11,23 +11,9 @@ These parameters can be configured either temporarily by editing the boot entry
permanently by modifying the XTLDR configuration file. permanently by modifying the XTLDR configuration file.
The following is a consolidated list of available kernel parameters: The following is a consolidated list of available kernel parameters:
* **CLOCK**: Specifies the primary hardware source used to drive the periodic system clock interrupts and the thread
scheduler tick. Valid values include `LAPIC` (Local APIC Timer), `HPET` (High Precision Event Timer), and `PIT`
(Legacy Programmable Interval Timer). If this parameter is omitted, the kernel will autonomously probe the hardware
and select the most optimal clock source for the current CPU topology, (defaulting to the Local APIC on modern systems.
* **MAXCPUS**: Specifies the maximum number of logical processors the kernel is allowed to initialize and schedule.
Setting `MAXCPUS=1` explicitly disables Symmetric Multiprocessing (SMP), restricting execution exclusively to the Boot
Strap Processor (BSP) and ignoring all Application Processors (APs).
* **NOX2APIC**: Explicitly disables x2APIC support. When specified, the kernel bypasses hardware feature detection for
x2APIC and forces the use of the classic, memory-mapped (MMIO) xAPIC mode. This parameter is particularly useful for
troubleshooting interrupt routing issues or ensuring compatibility with specific hypervisors and legacy emulators.
* **NOXPA**: Disables PAE or LA57 support, depending on the CPU architecture. This parameter is handled by the * **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 bootloader, which configures paging and selects the appropriate Page Map Level (PML) before transferring control to
the kernel. the kernel.
* **TIMER**: Designates the hardware counter used for high-resolution performance tracking (Query Performance Counter)
and microsecond execution stalls. Valid values include `TSC` (Invariant Time Stamp Counter), `HPET`, `ACPI` (or `PM`)
for the ACPI Power Management Timer, and `PIT`. If not specified, the kernel evaluates hardware capabilities and
defaults to the most precise and reliable counter available (e.g., Invariant TSC).
## Source Code ## Source Code
The source code of the kernel is organized into subsystem-specific directories. Each directory name also defines the The source code of the kernel is organized into subsystem-specific directories. Each directory name also defines the

View File

@@ -4,42 +4,31 @@
* FILE: xtoskrnl/ar/amd64/archsup.S * FILE: xtoskrnl/ar/amd64/archsup.S
* DESCRIPTION: Provides AMD64 architecture features not implementable in C * DESCRIPTION: Provides AMD64 architecture features not implementable in C
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/ */
#include <xtkmapi.h> #include <ar/amd64/asmsup.h>
#include <xtadk.h>
.altmacro .altmacro
.text .text
/** /**
* Creates a trap or interrupt handler for the specified vector. * Creates a trap handler for the specified vector.
* *
* @param Vector * @param Vector
* Supplies a trap/interrupt vector number. * Supplies a trap vector number.
*
* @param Type
* Specifies whether the handler is designed to handle an interrupt or a trap.
* *
* @return This macro does not return any value. * @return This macro does not return any value.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
.macro ArCreateHandler Vector Type .macro ArCreateTrapHandler Vector
.global Ar\Type\Vector .global ArTrap\Vector
Ar\Type\Vector: ArTrap\Vector:
/* Check handler type */ /* Push fake error code for non-error vectors */
.ifc \Type,Trap
/* Push fake error code for non-error vector traps */
.if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30 .if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
push $0 push $0
.endif .endif
.else
/* Push fake error code for interrupts */
push $0
.endif
/* Push vector number */ /* Push vector number */
push $\Vector push $\Vector
@@ -62,122 +51,113 @@ Ar\Type\Vector:
push %rax push %rax
/* Reserve space for other registers and point RBP to the trap frame */ /* Reserve space for other registers and point RBP to the trap frame */
sub $(KTRAP_FRAME_SIZE - KTRAP_FRAME_REGISTERS_SIZE), %rsp sub $(TRAP_FRAME_SIZE - TRAP_REGISTERS_SIZE), %rsp
lea (%rsp), %rbp lea (%rsp), %rbp
/* Store segment selectors */ /* Store segment selectors */
mov %gs, KTRAP_FRAME_SegGs(%rbp) mov %gs, TrapSegGs(%rbp)
mov %fs, KTRAP_FRAME_SegFs(%rbp) mov %fs, TrapSegFs(%rbp)
mov %es, KTRAP_FRAME_SegEs(%rbp) mov %es, TrapSegEs(%rbp)
mov %ds, KTRAP_FRAME_SegDs(%rbp) mov %ds, TrapSegDs(%rbp)
/* Store debug registers */ /* Store debug registers */
mov %dr7, %rax mov %dr7, %rax
mov %rax, KTRAP_FRAME_Dr7(%rbp) mov %rax, TrapDr7(%rbp)
mov %dr6, %rax mov %dr6, %rax
mov %rax, KTRAP_FRAME_Dr6(%rbp) mov %rax, TrapDr6(%rbp)
mov %dr3, %rax mov %dr3, %rax
mov %rax, KTRAP_FRAME_Dr3(%rbp) mov %rax, TrapDr3(%rbp)
mov %dr2, %rax mov %dr2, %rax
mov %rax, KTRAP_FRAME_Dr2(%rbp) mov %rax, TrapDr2(%rbp)
mov %dr1, %rax mov %dr1, %rax
mov %rax, KTRAP_FRAME_Dr1(%rbp) mov %rax, TrapDr1(%rbp)
mov %dr0, %rax mov %dr0, %rax
mov %rax, KTRAP_FRAME_Dr0(%rbp) mov %rax, TrapDr0(%rbp)
/* Store CR2 and CR3 */ /* Store CR2 and CR3 */
mov %cr3, %rax mov %cr3, %rax
mov %rax, KTRAP_FRAME_Cr3(%rbp) mov %rax, TrapCr3(%rbp)
mov %cr2, %rax mov %cr2, %rax
mov %rax, KTRAP_FRAME_Cr2(%rbp) mov %rax, TrapCr2(%rbp)
/* Store MxCsr register */ /* Store MxCsr register */
stmxcsr KTRAP_FRAME_MxCsr(%rbp) stmxcsr TrapMxCsr(%rbp)
/* Store XMM registers */ /* Store XMM registers */
movdqa %xmm15, KTRAP_FRAME_Xmm15(%rbp) movdqa %xmm15, TrapXmm15(%rbp)
movdqa %xmm14, KTRAP_FRAME_Xmm14(%rbp) movdqa %xmm14, TrapXmm14(%rbp)
movdqa %xmm13, KTRAP_FRAME_Xmm13(%rbp) movdqa %xmm13, TrapXmm13(%rbp)
movdqa %xmm12, KTRAP_FRAME_Xmm12(%rbp) movdqa %xmm12, TrapXmm12(%rbp)
movdqa %xmm11, KTRAP_FRAME_Xmm11(%rbp) movdqa %xmm11, TrapXmm11(%rbp)
movdqa %xmm10, KTRAP_FRAME_Xmm10(%rbp) movdqa %xmm10, TrapXmm10(%rbp)
movdqa %xmm9, KTRAP_FRAME_Xmm9(%rbp) movdqa %xmm9, TrapXmm9(%rbp)
movdqa %xmm8, KTRAP_FRAME_Xmm8(%rbp) movdqa %xmm8, TrapXmm8(%rbp)
movdqa %xmm7, KTRAP_FRAME_Xmm7(%rbp) movdqa %xmm7, TrapXmm7(%rbp)
movdqa %xmm6, KTRAP_FRAME_Xmm6(%rbp) movdqa %xmm6, TrapXmm6(%rbp)
movdqa %xmm5, KTRAP_FRAME_Xmm5(%rbp) movdqa %xmm5, TrapXmm5(%rbp)
movdqa %xmm4, KTRAP_FRAME_Xmm4(%rbp) movdqa %xmm4, TrapXmm4(%rbp)
movdqa %xmm3, KTRAP_FRAME_Xmm3(%rbp) movdqa %xmm3, TrapXmm3(%rbp)
movdqa %xmm2, KTRAP_FRAME_Xmm2(%rbp) movdqa %xmm2, TrapXmm2(%rbp)
movdqa %xmm1, KTRAP_FRAME_Xmm1(%rbp) movdqa %xmm1, TrapXmm1(%rbp)
movdqa %xmm0, KTRAP_FRAME_Xmm0(%rbp) movdqa %xmm0, TrapXmm0(%rbp)
/* Test previous mode and swap GS if needed */ /* Test previous mode and swap GS if needed */
movl $0, KTRAP_FRAME_PreviousMode(%rbp) movl $0, TrapPreviousMode(%rbp)
mov KTRAP_FRAME_SegCs(%rbp), %ax mov %cs, %ax
and $3, %al and $3, %al
mov %al, KTRAP_FRAME_PreviousMode(%rbp) mov %al, TrapPreviousMode(%rbp)
jz KernelMode$\Vector
/* Skip swapgs as the interrupt originated from kernel mode */
jz Dispatch\Type\Vector
swapgs swapgs
jmp UserMode$\Vector
Dispatch\Type\Vector: KernelMode$\Vector:
/* Set up trap frame pointer for the dispatcher and clear the direction flag */ /* 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 mov %rsp, %rcx
cld cld
/* Preserve the original stack pointer */
mov %rsp, %rbx
/* Force stack alignment */
and $-16, %rsp
/* Allocate 32 bytes of shadow space */
sub $32, %rsp
.ifc \Type,Trap
/* Pass to the trap dispatcher */
call ArDispatchTrap call ArDispatchTrap
.else
/* Pass to the interrupt dispatcher */
call ArDispatchInterrupt
.endif
/* Restore the original trap frame stack pointer */
mov %rbx, %rsp
/* Test previous mode and swapgs if needed */ /* Test previous mode and swapgs if needed */
testb $1, KTRAP_FRAME_PreviousMode(%rbp) testb $1, TrapPreviousMode(%rbp)
jz RestoreState\Type\Vector jz KernelModeReturn$\Vector
cli cli
swapgs swapgs
RestoreState\Type\Vector: KernelModeReturn$\Vector:
/* Restore XMM registers */ /* Restore XMM registers */
movdqa KTRAP_FRAME_Xmm0(%rbp), %xmm0 movdqa TrapXmm0(%rbp), %xmm0
movdqa KTRAP_FRAME_Xmm1(%rbp), %xmm1 movdqa TrapXmm1(%rbp), %xmm1
movdqa KTRAP_FRAME_Xmm2(%rbp), %xmm2 movdqa TrapXmm2(%rbp), %xmm2
movdqa KTRAP_FRAME_Xmm3(%rbp), %xmm3 movdqa TrapXmm3(%rbp), %xmm3
movdqa KTRAP_FRAME_Xmm4(%rbp), %xmm4 movdqa TrapXmm4(%rbp), %xmm4
movdqa KTRAP_FRAME_Xmm5(%rbp), %xmm5 movdqa TrapXmm5(%rbp), %xmm5
movdqa KTRAP_FRAME_Xmm6(%rbp), %xmm6 movdqa TrapXmm6(%rbp), %xmm6
movdqa KTRAP_FRAME_Xmm7(%rbp), %xmm7 movdqa TrapXmm7(%rbp), %xmm7
movdqa KTRAP_FRAME_Xmm8(%rbp), %xmm8 movdqa TrapXmm8(%rbp), %xmm8
movdqa KTRAP_FRAME_Xmm9(%rbp), %xmm9 movdqa TrapXmm9(%rbp), %xmm9
movdqa KTRAP_FRAME_Xmm10(%rbp), %xmm10 movdqa TrapXmm10(%rbp), %xmm10
movdqa KTRAP_FRAME_Xmm11(%rbp), %xmm11 movdqa TrapXmm11(%rbp), %xmm11
movdqa KTRAP_FRAME_Xmm12(%rbp), %xmm12 movdqa TrapXmm12(%rbp), %xmm12
movdqa KTRAP_FRAME_Xmm13(%rbp), %xmm13 movdqa TrapXmm13(%rbp), %xmm13
movdqa KTRAP_FRAME_Xmm14(%rbp), %xmm14 movdqa TrapXmm14(%rbp), %xmm14
movdqa KTRAP_FRAME_Xmm15(%rbp), %xmm15 movdqa TrapXmm15(%rbp), %xmm15
/* Load MxCsr register */ /* Load MxCsr register */
ldmxcsr KTRAP_FRAME_MxCsr(%rbp) ldmxcsr TrapMxCsr(%rbp)
/* Restore segment selectors */
mov TrapSegDs(%rbp), %ds
mov TrapSegEs(%rbp), %es
mov TrapSegFs(%rbp), %fs
/* Free stack space */ /* Free stack space */
add $(KTRAP_FRAME_SIZE - KTRAP_FRAME_REGISTERS_SIZE), %rsp add $(TRAP_FRAME_SIZE - TRAP_REGISTERS_SIZE), %rsp
/* Pop General Purpose Registers */ /* Pop General Purpose Registers */
pop %rax pop %rax
@@ -201,289 +181,9 @@ RestoreState\Type\Vector:
iretq iretq
.endm .endm
/* Populate common interrupt and trap handlers */ /* Populate common trap handlers */
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F .irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F .irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
ArCreateHandler 0x\i\j Interrupt ArCreateTrapHandler 0x\i\j
ArCreateHandler 0x\i\j Trap
.endr .endr
.endr .endr
/* Define array of pointers to the interrupt handlers */
.global ArInterruptEntry
ArInterruptEntry:
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
.quad ArInterrupt0x\i\j
.endr
.endr
/* Define array of pointers to the trap handlers */
.global ArTrapEntry
ArTrapEntry:
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
.quad ArTrap0x\i\j
.endr
.endr
/**
* Enables eXtended Physical Addressing (XPA).
*
* @param PageMap
* Supplies a pointer to the page map to be used.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
.global ArEnableExtendedPhysicalAddressing
ArEnableExtendedPhysicalAddressing:
/* Save the original CR4 register */
movq %cr4, %rax
/* Save the state of stack pointer and non-volatile registers */
movq %rsp, XpaRegisterSaveArea(%rip)
movq %rbp, XpaRegisterSaveArea+0x08(%rip)
movq %rax, XpaRegisterSaveArea+0x10(%rip)
movq %rbx, XpaRegisterSaveArea+0x18(%rip)
/* Save the original CR0 register */
movq %cr0, %rbp
/* Load temporary GDT required for mode transitions */
leaq XpaTemporaryGdtDesc(%rip), %rax
movq %rax, XpaTemporaryGdtBase(%rip)
lgdtq XpaTemporaryGdtSize(%rip)
/* Load addresses for entering compatibility mode and re-entering long mode */
leaq XpaEnterCompatMode(%rip), %rax
leaq XpaEnterLongMode(%rip), %rbx
/* Push the 32-bit code segment selector and the target address for a far jump */
pushq $KGDT_R0_CMCODE
pushq %rax
/* Perform a far return to switch to 32-bit compatibility mode */
lretq
XpaEnterCompatMode:
/* Enter 32-bit compatibility mode */
.code32
/* Store the PageMap pointer on the stack for future use */
pushl %ecx
/* Set the stack segment to the 32-bit data segment selector */
movl $KGDT_R0_DATA, %eax
movl %eax, %ss
/* Disable PGE and PCIDE to ensure all TLB entries will be flushed */
movl %cr4, %eax
andl $~(CR4_PGE | CR4_PCIDE), %eax
movl %eax, %cr4
/* Temporarily disable paging */
movl %ebp, %eax
andl $~CR0_PG, %eax
movl %eax, %cr0
/* Disable Long Mode as prerequisite for enabling 5-level paging */
movl $X86_MSR_EFER, %ecx
rdmsr
andl $~X86_MSR_EFER_LME, %eax
wrmsr
/* Transition to 5-level paging (PML5/LA57) */
movl %cr4, %eax
orl $CR4_LA57, %eax
movl %eax, %cr4
/* Restore the PageMap pointer from the stack and load it into CR3 */
popl %ecx
movl %ecx, %cr3
/* Re-enable Long Mode */
movl $X86_MSR_EFER, %ecx
rdmsr
orl $X86_MSR_EFER_LME, %eax
wrmsr
/* Restore CR0 with paging enabled and flush the instruction pipeline */
movl %ebp, %cr0
call XpaFlushInstructions
XpaFlushInstructions:
/* Push the 64-bit code segment selector and the target address for a far jump */
pushl $KGDT_R0_CODE
pushl %ebx
/* Perform a far return to switch to 64-bit long mode */
lretl
XpaEnterLongMode:
/* Enter 64-bit long mode */
.code64
/* Restore the stack pointer and non-volatile registers */
movq XpaRegisterSaveArea(%rip), %rsp
movq XpaRegisterSaveArea+8(%rip), %rbp
movq XpaRegisterSaveArea+0x10(%rip), %rax
movq XpaRegisterSaveArea+0x18(%rip), %rbx
/* Restore the original CR4 register with LA57 bit set */
orq $CR4_LA57, %rax
movq %rax, %cr4
/* Return to the caller */
retq
/* Data section for saving registers and temporary GDT */
XpaRegisterSaveArea: .quad 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000
XpaTemporaryGdtSize: .short ArEnableExtendedPhysicalAddressingEnd - XpaTemporaryGdtDesc - 1
XpaTemporaryGdtBase: .quad 0x0000000000000000
XpaTemporaryGdtDesc: .quad 0x0000000000000000, 0x00CF9A000000FFFF, 0x00AF9A000000FFFF, 0x00CF92000000FFFF
.global ArEnableExtendedPhysicalAddressingEnd
ArEnableExtendedPhysicalAddressingEnd:
/**
* Handles a spurious interrupt allowing it to end up.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
.global ArHandleSpuriousInterrupt
ArHandleSpuriousInterrupt:
iretq
/**
* Starts an application processor (AP).
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
.global ArStartApplicationProcessor
ArStartApplicationProcessor:
/* Enter 16-bit real mode */
.code16
/* Disable interrupts and clear direction flag */
cli
cld
/* Establish a flat addressing baseline */
movw %cs, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
/* Calculate absolute physical base address */
xorl %ebx, %ebx
movw %cs, %bx
shll $4, %ebx
/* Set up a temporary stack for the AP initialization */
movl %ebx, %esp
addl $0x1000, %esp
/* Load the temporary Global Descriptor Table */
leal (ApTemporaryGdtDesc - ArStartApplicationProcessor)(%ebx), %eax
movl %eax, (ApTemporaryGdtBase - ArStartApplicationProcessor)
lgdtl (ApTemporaryGdtSize - ArStartApplicationProcessor)
/* Enable Protected Mode */
movl %cr0, %eax
orl $0x01, %eax
movl %eax, %cr0
/* Far return to enter 32-bit protected mode */
leal (ApEnterProtectedMode - ArStartApplicationProcessor)(%ebx), %eax
pushl $KGDT_R0_CMCODE
pushl %eax
lretl
ApEnterProtectedMode:
/* Enter 32-bit protected mode */
.code32
/* Setup all data segment registers */
movw $KGDT_R0_DATA, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
xorw %ax, %ax
movw %ax, %fs
movw %ax, %gs
/* Locate PROCESSOR_START_BLOCK structure */
leal (ArStartApplicationProcessorEnd - ArStartApplicationProcessor)(%ebx), %edi
/* Load CR4 from BSP, but mask PCIDE and PGE */
movl PROCESSOR_START_BLOCK_Cr4(%edi), %eax
andl $~(CR4_PGE | CR4_PCIDE), %eax
movl %eax, %cr4
/* Load the Kernel Page Directory Base from BSP */
movl PROCESSOR_START_BLOCK_Cr3(%edi), %eax
movl %eax, %cr3
/* Enable Long Mode and No-Execute */
movl $X86_MSR_EFER, %ecx
rdmsr
orl $(X86_MSR_EFER_LME | X86_MSR_EFER_NXE), %eax
wrmsr
/* Enable Paging */
movl %cr0, %eax
orl $CR0_PG, %eax
movl %eax, %cr0
/* Far return to enter 64-bit long mode */
leal (ApEnterLongMode - ArStartApplicationProcessor)(%ebx), %eax
pushl $KGDT_R0_CODE
pushl %eax
lretl
ApEnterLongMode:
/* Enter 64-bit long mode */
.code64
/* Clear all segment registers */
xorw %ax, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
movw %ax, %fs
movw %ax, %gs
/* Zero-extend EDI into RDI to ensure safe 64-bit pointer usage */
movl %edi, %edi
/* Load dedicated Stack for AP */
movq PROCESSOR_START_BLOCK_Stack(%rdi), %rsp
/* Save the pointer to PROCESSOR_START_BLOCK */
movq %rdi, %rcx
pushq %rdi
/* Call the EntryPoint routine */
movq PROCESSOR_START_BLOCK_EntryPoint(%rdi), %rax
call *%rax
/* Fire the breakpoint and halt if the entry point returns */
.ApNoReturnPoint:
int $0x03
hlt
jmp .ApNoReturnPoint
/* Data section for temporary GDT */
.align 8
ApTemporaryGdtSize: .short ArStartApplicationProcessorEnd - ApTemporaryGdtDesc - 1
ApTemporaryGdtBase: .quad 0x0000000000000000
ApTemporaryGdtDesc: .quad 0x0000000000000000, 0x00CF9A000000FFFF, 0x00AF9A000000FFFF, 0x00CF92000000FFFF
.global ArStartApplicationProcessorEnd
ArStartApplicationProcessorEnd:

147
xtoskrnl/ar/amd64/boot.S Normal file
View File

@@ -0,0 +1,147 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/amd64/boot.S
* DESCRIPTION: AMD64-specific boot code for setting up the low-level CPU environment
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <ar/amd64/asmsup.h>
.altmacro
.text
/**
* Enables eXtended Physical Addressing (XPA).
*
* @param PageMap
* Supplies a pointer to the page map to be used.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
.global ArEnableExtendedPhysicalAddressing
ArEnableExtendedPhysicalAddressing:
/* Save the original CR4 register */
movq %cr4, %rax
/* Save the state of stack pointer and non-volatile registers */
movq %rsp, XpaRegisterSaveArea(%rip)
movq %rbp, XpaRegisterSaveArea+0x08(%rip)
movq %rax, XpaRegisterSaveArea+0x10(%rip)
movq %rbx, XpaRegisterSaveArea+0x18(%rip)
/* Save the original CR0 register */
movq %cr0, %rbp
/* Load temporary GDT required for mode transitions */
leaq XpaTemporaryGdtDesc(%rip), %rax
movq %rax, XpaTemporaryGdtBase(%rip)
lgdtq XpaTemporaryGdtSize(%rip)
/* Load addresses for entering compatibility mode and re-entering long mode */
leaq XpaEnterCompatMode(%rip), %rax
leaq XpaEnterLongMode(%rip), %rbx
/* Push the 32-bit code segment selector and the target address for a far jump */
pushq $GDT_R0_CMCODE
pushq %rax
/* Perform a far return to switch to 32-bit compatibility mode */
lretq
XpaEnterCompatMode:
/* Enter 32-bit compatibility mode */
.code32
/* Store the PageMap pointer on the stack for future use */
pushl %ecx
/* Set the stack segment to the 32-bit data segment selector */
movl $GDT_R0_DATA, %eax
movl %eax, %ss
/* Disable PGE and PCIDE to ensure all TLB entries will be flushed */
movl %cr4, %eax
andl $~(CR4_PGE | CR4_PCIDE), %eax
movl %eax, %cr4
/* Temporarily disable paging */
movl %ebp, %eax
andl $~CR0_PG, %eax
movl %eax, %cr0
/* Disable Long Mode as prerequisite for enabling 5-level paging */
movl $X86_MSR_EFER, %ecx
rdmsr
andl $~X86_MSR_EFER_LME, %eax
wrmsr
/* Transition to 5-level paging (PML5/LA57) */
movl %cr4, %eax
orl $CR4_LA57, %eax
movl %eax, %cr4
/* Restore the PageMap pointer from the stack and load it into CR3 */
popl %ecx
movl %ecx, %cr3
/* Re-enable Long Mode */
movl $X86_MSR_EFER, %ecx
rdmsr
orl $X86_MSR_EFER_LME, %eax
wrmsr
/* Restore CR0 with paging enabled and flush the instruction pipeline */
movl %ebp, %cr0
call XpaFlushInstructions
XpaFlushInstructions:
/* Push the 64-bit code segment selector and the target address for a far jump */
pushl $GDT_R0_CODE
pushl %ebx
/* Perform a far return to switch to 64-bit long mode */
lretl
XpaEnterLongMode:
/* Enter 64-bit long mode */
.code64
/* Restore the stack pointer and non-volatile registers */
movq XpaRegisterSaveArea(%rip), %rsp
movq XpaRegisterSaveArea+8(%rip), %rbp
movq XpaRegisterSaveArea+0x10(%rip), %rax
movq XpaRegisterSaveArea+0x18(%rip), %rbx
/* Restore the original CR4 register with LA57 bit set */
orq $CR4_LA57, %rax
movq %rax, %cr4
/* Return to the caller */
retq
/* Data section for saving registers and temporary GDT */
XpaRegisterSaveArea: .quad 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000
XpaTemporaryGdtSize: .short ArEnableExtendedPhysicalAddressingEnd - XpaTemporaryGdtDesc - 1
XpaTemporaryGdtBase: .quad 0x0000000000000000
XpaTemporaryGdtDesc: .quad 0x0000000000000000, 0x00CF9A000000FFFF, 0x00AF9A000000FFFF, 0x00CF92000000FFFF
.global ArEnableExtendedPhysicalAddressingEnd
ArEnableExtendedPhysicalAddressingEnd:
/**
* Starts an application processor (AP). This is just a stub.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
.global ArStartApplicationProcessor
ArStartApplicationProcessor:
.global ArStartApplicationProcessorEnd
ArStartApplicationProcessorEnd:

View File

@@ -573,33 +573,6 @@ AR::CpuFunc::ReadTimeStampCounter(VOID)
return ((ULONGLONG)High << 32) | Low; return ((ULONGLONG)High << 32) | Low;
} }
/**
* Reads the current value of the CPU's time-stamp counter and processor ID.
*
* @param TscAux
* Supplies a pointer to a variable that receives the auxiliary TSC information (IA32_TSC_AUX).
*
* @return This routine returns the current instruction cycle count since the processor was last reset.
*
* @since XT 1.0
*/
XTCDECL
ULONGLONG
AR::CpuFunc::ReadTimeStampCounterProcessor(OUT PULONG TscAux)
{
ULONG Low, High;
/* Execute the RDTSCP instruction */
__asm__ volatile("rdtscp"
: "=a" (Low),
"=d" (High),
"=c" (*TscAux)
);
/* Combine the two 32-bit registers into a single 64-bit unsigned integer and return the value */
return ((ULONGLONG)High << 32) | Low;
}
/** /**
* Orders memory accesses as seen by other processors, without fence. * Orders memory accesses as seen by other processors, without fence.
* *

View File

@@ -26,9 +26,3 @@ KPROCESSOR_BLOCK AR::ProcSup::InitialProcessorBlock;
/* Initial TSS */ /* Initial TSS */
KTSS AR::ProcSup::InitialTss; KTSS AR::ProcSup::InitialTss;
/* Initial kernel NMI stack */
UCHAR AR::ProcSup::NmiStack[KERNEL_STACK_SIZE] = {};
/* Unhandled interrupt routine */
PINTERRUPT_HANDLER AR::Traps::UnhandledInterruptRoutine = NULLPTR;

View File

@@ -20,8 +20,7 @@ XTAPI
PVOID PVOID
AR::ProcSup::GetBootStack(VOID) AR::ProcSup::GetBootStack(VOID)
{ {
/* Return base address of kernel boot stack */ return (PVOID)BootStack;
return (PVOID)((ULONG_PTR)BootStack + KERNEL_STACK_SIZE);
} }
XTAPI XTAPI
@@ -30,23 +29,19 @@ AR::ProcSup::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
OUT PVOID *TrampolineCode, OUT PVOID *TrampolineCode,
OUT PULONG_PTR TrampolineSize) OUT PULONG_PTR TrampolineSize)
{ {
/* Get trampoline information */
switch(TrampolineType) switch(TrampolineType)
{ {
case TrampolineApStartup: case TrampolineApStartup:
/* Get AP startup trampoline information */
*TrampolineCode = (PVOID)ArStartApplicationProcessor; *TrampolineCode = (PVOID)ArStartApplicationProcessor;
*TrampolineSize = (ULONG_PTR)ArStartApplicationProcessorEnd - *TrampolineSize = (ULONG_PTR)ArStartApplicationProcessorEnd -
(ULONG_PTR)ArStartApplicationProcessor; (ULONG_PTR)ArStartApplicationProcessor;
break; break;
case TrampolineEnableXpa: case TrampolineEnableXpa:
/* Get Enable XPA trampoline information */
*TrampolineCode = (PVOID)ArEnableExtendedPhysicalAddressing; *TrampolineCode = (PVOID)ArEnableExtendedPhysicalAddressing;
*TrampolineSize = (ULONG_PTR)ArEnableExtendedPhysicalAddressingEnd - *TrampolineSize = (ULONG_PTR)ArEnableExtendedPhysicalAddressingEnd -
(ULONG_PTR)ArEnableExtendedPhysicalAddressing; (ULONG_PTR)ArEnableExtendedPhysicalAddressing;
break; break;
default: default:
/* Unknown trampoline type */
*TrampolineCode = NULLPTR; *TrampolineCode = NULLPTR;
*TrampolineSize = 0; *TrampolineSize = 0;
break; break;
@@ -69,13 +64,16 @@ AR::ProcSup::IdentifyProcessor(VOID)
CPUID_REGISTERS CpuRegisters; CPUID_REGISTERS CpuRegisters;
CPUID_SIGNATURE CpuSignature; CPUID_SIGNATURE CpuSignature;
/* Not fully implemented yet */
UNIMPLEMENTED;
/* Get current processor control block */ /* Get current processor control block */
Prcb = KE::Processor::GetCurrentProcessorControlBlock(); Prcb = KE::Processor::GetCurrentProcessorControlBlock();
/* Get CPU vendor by issueing CPUID instruction */ /* Get CPU vendor by issueing CPUID instruction */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING; CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
AR::CpuFunc::CpuId(&CpuRegisters); CpuFunc::CpuId(&CpuRegisters);
/* Store CPU vendor in processor control block */ /* Store CPU vendor in processor control block */
Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx; Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx;
@@ -87,7 +85,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
/* Get CPU standard features */ /* Get CPU standard features */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES; CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
AR::CpuFunc::CpuId(&CpuRegisters); CpuFunc::CpuId(&CpuRegisters);
/* Store CPU signature in processor control block */ /* Store CPU signature in processor control block */
CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax; CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax;
@@ -99,23 +97,23 @@ AR::ProcSup::IdentifyProcessor(VOID)
if(Prcb->CpuId.Vendor == CPU_VENDOR_AMD) if(Prcb->CpuId.Vendor == CPU_VENDOR_AMD)
{ {
/* AMD CPU */ /* AMD CPU */
if(CpuSignature.Family == 0xF) if(Prcb->CpuId.Family >= 0xF)
{ {
Prcb->CpuId.Family += CpuSignature.ExtendedFamily; Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
Prcb->CpuId.Model += (CpuSignature.ExtendedModel << 4); Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
} }
} }
else if(Prcb->CpuId.Vendor == CPU_VENDOR_INTEL) else if(Prcb->CpuId.Vendor == CPU_VENDOR_INTEL)
{ {
/* Intel CPU */ /* Intel CPU */
if(CpuSignature.Family == 0xF) if(Prcb->CpuId.Family == 0xF)
{ {
Prcb->CpuId.Family += CpuSignature.ExtendedFamily; Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
} }
if((CpuSignature.Family == 0x6) || (CpuSignature.Family == 0xF)) if((Prcb->CpuId.Family == 0x6) || (Prcb->CpuId.Family == 0xF))
{ {
Prcb->CpuId.Model += (CpuSignature.ExtendedModel << 4); Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
} }
} }
else else
@@ -124,12 +122,11 @@ AR::ProcSup::IdentifyProcessor(VOID)
Prcb->CpuId.Vendor = CPU_VENDOR_UNKNOWN; Prcb->CpuId.Vendor = CPU_VENDOR_UNKNOWN;
} }
/* Identify processor features */ /* TODO: Store a list of CPU features in processor control block */
IdentifyProcessorFeatures();
} }
/** /**
* Identifies processor features and stores them in Processor Control Block (PRCB). * Initializes AMD64 processor specific structures.
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
@@ -137,133 +134,70 @@ AR::ProcSup::IdentifyProcessor(VOID)
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::IdentifyProcessorFeatures(VOID) AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
{ {
ULONG MaxExtendedLeaf, MaxStandardLeaf; KDESCRIPTOR GdtDescriptor, IdtDescriptor;
PKPROCESSOR_CONTROL_BLOCK Prcb; PVOID KernelBootStack, KernelFaultStack;
CPUID_REGISTERS CpuRegisters; PKPROCESSOR_BLOCK ProcessorBlock;
PKGDTENTRY Gdt;
PKIDTENTRY Idt;
PKTSS Tss;
/* Get current processor control block */ /* Check if processor structures buffer provided */
Prcb = KE::Processor::GetCurrentProcessorControlBlock(); if(ProcessorStructures)
/* Get maximum CPUID standard leaf */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
AR::CpuFunc::CpuId(&CpuRegisters);
MaxStandardLeaf = CpuRegisters.Eax;
/* Get maximum CPUID extended leaf */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_EXTENDED_MAX;
AR::CpuFunc::CpuId(&CpuRegisters);
MaxExtendedLeaf = CpuRegisters.Eax;
/* Check if CPU supports standard features leaf */
if(MaxStandardLeaf >= CPUID_GET_STANDARD1_FEATURES)
{ {
/* Get CPU standard features */ /* Assign CPU structures from provided buffer */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES; &KernelBootStack, &KernelFaultStack);
AR::CpuFunc::CpuId(&CpuRegisters);
/* Store CPU standard features in processor control block */ /* Use global IDT */
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE3) Prcb->CpuId.FeatureBits |= KCF_SSE3; Idt = InitialIdt;
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_VMX) Prcb->CpuId.FeatureBits |= KCF_VMX; }
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSSE3) Prcb->CpuId.FeatureBits |= KCF_SSSE3; else
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4_1) Prcb->CpuId.FeatureBits |= KCF_SSE41; {
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4_2) Prcb->CpuId.FeatureBits |= KCF_SSE42; /* Use initial structures */
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_X2APIC) Prcb->CpuId.FeatureBits |= KCF_X2APIC; Gdt = InitialGdt;
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_POPCNT) Prcb->CpuId.FeatureBits |= KCF_POPCNT; Idt = InitialIdt;
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_TSC_DEADLINE) Prcb->CpuId.FeatureBits |= KCF_TSC_DEADLINE; Tss = &InitialTss;
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_AES) Prcb->CpuId.FeatureBits |= KCF_AES; KernelBootStack = &BootStack;
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_XSAVE) Prcb->CpuId.FeatureBits |= KCF_XSAVE; KernelFaultStack = &FaultStack;
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_AVX) Prcb->CpuId.FeatureBits |= KCF_AVX; ProcessorBlock = &InitialProcessorBlock;
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_RDRAND) Prcb->CpuId.FeatureBits |= KCF_RDRAND;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_VME) Prcb->CpuId.FeatureBits |= KCF_VME;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PSE) Prcb->CpuId.FeatureBits |= KCF_LARGE_PAGE;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSC) Prcb->CpuId.FeatureBits |= KCF_RDTSC;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PAE) Prcb->CpuId.FeatureBits |= KCF_PAE;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MCE) Prcb->CpuId.FeatureBits |= KCF_MCE;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CX8) Prcb->CpuId.FeatureBits |= KCF_CMPXCHG8B;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_APIC) Prcb->CpuId.FeatureBits |= KCF_APIC;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SEP) Prcb->CpuId.FeatureBits |= KCF_FAST_SYSCALL;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MTRR) Prcb->CpuId.FeatureBits |= KCF_MTRR;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PGE) Prcb->CpuId.FeatureBits |= KCF_GLOBAL_PAGE;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MCA) Prcb->CpuId.FeatureBits |= KCF_MCA;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CMOV) Prcb->CpuId.FeatureBits |= KCF_CMOV;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PAT) Prcb->CpuId.FeatureBits |= KCF_PAT;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PSE36) Prcb->CpuId.FeatureBits |= KCF_PSE36;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CLFLUSH) Prcb->CpuId.FeatureBits |= KCF_CLFLUSH;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_FXSR) Prcb->CpuId.FeatureBits |= KCF_FXSR;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_ACPI) Prcb->CpuId.FeatureBits |= KCF_ACPI;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MMX) Prcb->CpuId.FeatureBits |= KCF_MMX;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SSE) Prcb->CpuId.FeatureBits |= KCF_SSE;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SSE2) Prcb->CpuId.FeatureBits |= KCF_SSE2;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_HTT) Prcb->CpuId.FeatureBits |= KCF_SMT;
} }
/* Check if CPU supports standard7 features leaf */ /* Initialize processor block */
if(MaxStandardLeaf >= CPUID_GET_STANDARD7_FEATURES) InitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);
{
/* Get CPU standard features */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_STANDARD7_FEATURES;
AR::CpuFunc::CpuId(&CpuRegisters);
/* Store CPU standard7 features in processor control block */ /* Initialize GDT, IDT and TSS */
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_FSGSBASE) Prcb->CpuId.FeatureBits |= KCF_FSGSBASE; InitializeGdt(ProcessorBlock);
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_AVX2) Prcb->CpuId.FeatureBits |= KCF_AVX2; InitializeIdt(ProcessorBlock);
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SMEP) Prcb->CpuId.FeatureBits |= KCF_SMEP; InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack);
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_RDSEED) Prcb->CpuId.FeatureBits |= KCF_RDSEED;
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SMAP) Prcb->CpuId.FeatureBits |= KCF_SMAP;
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SHA) Prcb->CpuId.FeatureBits |= KCF_SHA;
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_LA57) Prcb->CpuId.FeatureBits |= KCF_LA57;
}
/* Check if CPU supports power management leaf */ /* Set GDT and IDT descriptors */
if(MaxStandardLeaf >= CPUID_GET_POWER_MANAGEMENT) GdtDescriptor.Base = Gdt;
{ GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1;
/* Get CPU power management features */ IdtDescriptor.Base = Idt;
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;
CpuRegisters.Leaf = CPUID_GET_POWER_MANAGEMENT;
AR::CpuFunc::CpuId(&CpuRegisters);
/* Store CPU power management features in processor control block */ /* Load GDT, IDT and TSS */
if(CpuRegisters.Eax & CPUID_FEATURES_EAX_ARAT) Prcb->CpuId.FeatureBits |= KCF_ARAT; CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
} CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS);
/* Check if CPU supports extended features leaf */ /* Enter passive IRQ level */
if(MaxExtendedLeaf >= CPUID_GET_EXTENDED_FEATURES) HL::RunLevel::SetRunLevel(PASSIVE_LEVEL);
{
/* Get CPU extended features */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_EXTENDED_FEATURES;
AR::CpuFunc::CpuId(&CpuRegisters);
/* Store CPU extended features in processor control block */ /* Initialize segment registers */
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SVM) Prcb->CpuId.ExtendedFeatureBits |= KCF_SVM; InitializeSegments();
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4A) Prcb->CpuId.ExtendedFeatureBits |= KCF_SSE4A;
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_FMA4) Prcb->CpuId.ExtendedFeatureBits |= KCF_FMA4;
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_TOPOLOGY_EXTENSIONS) Prcb->CpuId.ExtendedFeatureBits |= KCF_TOPOEXT;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SYSCALL_SYSRET) Prcb->CpuId.ExtendedFeatureBits |= KCF_SYSCALL;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_NX) Prcb->CpuId.ExtendedFeatureBits |= KCF_NX_BIT;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_RDTSCP) Prcb->CpuId.ExtendedFeatureBits |= KCF_RDTSCP;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_LONG_MODE) Prcb->CpuId.ExtendedFeatureBits |= KCF_64BIT;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_3DNOW_EXT) Prcb->CpuId.ExtendedFeatureBits |= KCF_3DNOW_EXT;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_3DNOW) Prcb->CpuId.ExtendedFeatureBits |= KCF_3DNOW;
}
/* Check if CPU supports advanced power management leaf */ /* Set GS base */
if(MaxExtendedLeaf >= CPUID_GET_ADVANCED_POWER_MANAGEMENT) CpuFunc::WriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock);
{ CpuFunc::WriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock);
/* Get CPU advanced power management features */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_ADVANCED_POWER_MANAGEMENT;
AR::CpuFunc::CpuId(&CpuRegisters);
/* Store CPU advanced power management features in processor control block */ /* Initialize processor registers */
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSCI) Prcb->CpuId.ExtendedFeatureBits |= KCF_INVARIANT_TSC; InitializeProcessorRegisters();
}
/* Identify processor */
IdentifyProcessor();
} }
/** /**
@@ -315,108 +249,34 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
for(Vector = 0; Vector < IDT_ENTRIES; Vector++) for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
{ {
/* Set the IDT to handle unexpected interrupts */ /* Set the IDT to handle unexpected interrupts */
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArInterruptEntry[Vector], KGDT_R0_CODE, SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
} }
/* Setup IDT handlers for known interrupts and traps */ /* Setup IDT handlers for known interrupts and traps */
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrapEntry[0x00], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrapEntry[0x01], 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)ArTrapEntry[0x02], KGDT_R0_CODE, KIDT_IST_NMI, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrapEntry[0x03], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrapEntry[0x04], 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)ArTrapEntry[0x05], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, 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)ArTrapEntry[0x06], 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)ArTrapEntry[0x07], 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)ArTrapEntry[0x08], KGDT_R0_CODE, KIDT_IST_PANIC, 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)ArTrapEntry[0x09], KGDT_R0_CODE, KIDT_IST_RESERVED, 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)ArTrapEntry[0x0A], 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)ArTrapEntry[0x0B], 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)ArTrapEntry[0x0C], 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)ArTrapEntry[0x0D], 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)ArTrapEntry[0x0E], 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)ArTrapEntry[0x10], 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)ArTrapEntry[0x11], 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)ArTrapEntry[0x12], KGDT_R0_CODE, KIDT_IST_MCA, 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)ArTrapEntry[0x13], KGDT_R0_CODE, KIDT_IST_RESERVED, 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)ArTrapEntry[0x1F], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x1F, (PVOID)ArTrap0x1F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrapEntry[0x2C], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrapEntry[0x2D], 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)ArTrapEntry[0x2F], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrap0x2F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArInterruptEntry[0xE1], 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);
}
/**
* Initializes AMD64 processor specific structures.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
{
PVOID KernelBootStack, KernelFaultStack, KernelNmiStack;
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
PKPROCESSOR_BLOCK ProcessorBlock;
PKGDTENTRY Gdt;
PKIDTENTRY Idt;
PKTSS Tss;
/* Check if processor structures buffer provided */
if(ProcessorStructures)
{
/* Assign CPU structures from provided buffer */
InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
&KernelBootStack, &KernelFaultStack, &KernelNmiStack);
/* Use global IDT */
Idt = InitialIdt;
}
else
{
/* Use initial structures */
Gdt = InitialGdt;
Idt = InitialIdt;
Tss = &InitialTss;
KernelBootStack = (PVOID)((ULONG_PTR)&BootStack + KERNEL_STACK_SIZE);
KernelFaultStack = (PVOID)((ULONG_PTR)&FaultStack + KERNEL_STACK_SIZE);
KernelNmiStack = (PVOID)((ULONG_PTR)&NmiStack + KERNEL_STACK_SIZE);
ProcessorBlock = &InitialProcessorBlock;
}
/* Initialize processor block */
InitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);
/* Initialize GDT, IDT and TSS */
InitializeGdt(ProcessorBlock);
InitializeIdt(ProcessorBlock);
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack, KernelNmiStack);
/* Set GDT and IDT descriptors */
GdtDescriptor.Base = Gdt;
GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1;
IdtDescriptor.Base = Idt;
IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;
/* Load GDT, IDT and TSS */
AR::CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
AR::CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
AR::CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS);
/* Initialize segment registers */
InitializeSegments();
/* Set GS base */
AR::CpuFunc::WriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock);
AR::CpuFunc::WriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock);
/* Initialize processor registers */
InitializeProcessorRegisters();
/* Identify processor */
IdentifyProcessor();
} }
/** /**
@@ -495,45 +355,45 @@ AR::ProcSup::InitializeProcessorRegisters(VOID)
ULONGLONG PatAttributes; ULONGLONG PatAttributes;
/* Enable FXSAVE restore */ /* Enable FXSAVE restore */
AR::CpuFunc::WriteControlRegister(4, AR::CpuFunc::ReadControlRegister(4) | CR4_FXSR); CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_FXSR);
/* Enable XMMI exceptions */ /* Enable XMMI exceptions */
AR::CpuFunc::WriteControlRegister(4, AR::CpuFunc::ReadControlRegister(4) | CR4_XMMEXCPT); CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_XMMEXCPT);
/* Set debugger extension */ /* Set debugger extension */
AR::CpuFunc::WriteControlRegister(4, AR::CpuFunc::ReadControlRegister(4) | CR4_DE); CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_DE);
/* Enable large pages */ /* Enable large pages */
AR::CpuFunc::WriteControlRegister(4, AR::CpuFunc::ReadControlRegister(4) | CR4_PSE); CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_PSE);
/* Enable write-protection */ /* Enable write-protection */
AR::CpuFunc::WriteControlRegister(0, AR::CpuFunc::ReadControlRegister(0) | CR0_WP); CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_WP);
/* Set alignment mask */ /* Set alignment mask */
AR::CpuFunc::WriteControlRegister(0, AR::CpuFunc::ReadControlRegister(0) | CR0_AM); CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_AM);
/* Disable FPU monitoring */ /* Disable FPU monitoring */
AR::CpuFunc::WriteControlRegister(0, AR::CpuFunc::ReadControlRegister(0) & ~CR0_MP); CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) & ~CR0_MP);
/* Disable x87 FPU exceptions */ /* Disable x87 FPU exceptions */
AR::CpuFunc::WriteControlRegister(0, AR::CpuFunc::ReadControlRegister(0) & ~CR0_NE); CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) & ~CR0_NE);
/* Flush the TLB */ /* Flush the TLB */
AR::CpuFunc::FlushTlb(); CpuFunc::FlushTlb();
/* Initialize system call MSRs */ /* Initialize system call MSRs */
AR::Traps::InitializeSystemCallMsrs(); Traps::InitializeSystemCallMsrs();
/* Enable No-Execute (NXE) in EFER MSR */ /* Enable No-Execute (NXE) in EFER MSR */
AR::CpuFunc::WriteModelSpecificRegister(X86_MSR_EFER, CpuFunc::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_NXE); CpuFunc::WriteModelSpecificRegister(X86_MSR_EFER, CpuFunc::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_NXE);
/* Initialize Page Attribute Table */ /* Initialize Page Attribute Table */
PatAttributes = (PAT_TYPE_WB << 0) | (PAT_TYPE_USWC << 8) | (PAT_TYPE_WEAK_UC << 16) | (PAT_TYPE_STRONG_UC << 24) | PatAttributes = (PAT_TYPE_WB << 0) | (PAT_TYPE_USWC << 8) | (PAT_TYPE_WEAK_UC << 16) | (PAT_TYPE_STRONG_UC << 24) |
(PAT_TYPE_WB << 32) | (PAT_TYPE_USWC << 40) | (PAT_TYPE_WEAK_UC << 48) | (PAT_TYPE_STRONG_UC << 56); (PAT_TYPE_WB << 32) | (PAT_TYPE_USWC << 40) | (PAT_TYPE_WEAK_UC << 48) | (PAT_TYPE_STRONG_UC << 56);
AR::CpuFunc::WriteModelSpecificRegister(X86_MSR_PAT, PatAttributes); CpuFunc::WriteModelSpecificRegister(X86_MSR_PAT, PatAttributes);
/* Initialize MXCSR register */ /* Initialize MXCSR register */
AR::CpuFunc::LoadMxcsrRegister(INITIAL_MXCSR); CpuFunc::LoadMxcsrRegister(INITIAL_MXCSR);
} }
/** /**
@@ -568,8 +428,7 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
OUT PKTSS *Tss, OUT PKTSS *Tss,
OUT PKPROCESSOR_BLOCK *ProcessorBlock, OUT PKPROCESSOR_BLOCK *ProcessorBlock,
OUT PVOID *KernelBootStack, OUT PVOID *KernelBootStack,
OUT PVOID *KernelFaultStack, OUT PVOID *KernelFaultStack)
OUT PVOID *KernelNmiStack)
{ {
UINT_PTR Address; UINT_PTR Address;
@@ -577,49 +436,22 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
Address = ROUND_UP((UINT_PTR)ProcessorStructures, MM_PAGE_SIZE) + KERNEL_STACK_SIZE; Address = ROUND_UP((UINT_PTR)ProcessorStructures, MM_PAGE_SIZE) + KERNEL_STACK_SIZE;
/* Assign a space for kernel boot stack and advance */ /* Assign a space for kernel boot stack and advance */
if(KernelBootStack != NULLPTR)
{
/* Return kernel boot stack address */
*KernelBootStack = (PVOID)Address; *KernelBootStack = (PVOID)Address;
}
Address += KERNEL_STACK_SIZE; Address += KERNEL_STACK_SIZE;
/* Assign a space for kernel fault stack and advance */ /* Assign a space for kernel fault stack, no advance needed as stack grows down */
if(KernelFaultStack != NULLPTR)
{
/* Return kernel fault stack address */
*KernelFaultStack = (PVOID)Address; *KernelFaultStack = (PVOID)Address;
}
Address += KERNEL_STACK_SIZE;
/* Assign a space for kernel NMI stack, no advance needed as stack grows down */
if(KernelNmiStack != NULLPTR)
{
/* Return kernel NMI stack address */
*KernelNmiStack = (PVOID)Address;
}
/* Assign a space for GDT and advance */ /* Assign a space for GDT and advance */
if(Gdt != NULLPTR)
{
/* Return GDT base address */
*Gdt = (PKGDTENTRY)(PVOID)Address; *Gdt = (PKGDTENTRY)(PVOID)Address;
} Address += sizeof(InitialGdt);
Address += (GDT_ENTRIES * sizeof(KGDTENTRY));
/* Assign a space for TSS and advance */
if(Tss != NULLPTR)
{
*Tss = (PKTSS)(PVOID)Address;
}
Address += sizeof(KTSS);
/* Assign a space for Processor Block and advance */ /* Assign a space for Processor Block and advance */
if(ProcessorBlock != NULLPTR)
{
/* Return processor block address */
*ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address; *ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address;
} Address += sizeof(InitialProcessorBlock);
/* Assign a space for TSS */
*Tss = (PKTSS)(PVOID)Address;
} }
/** /**
@@ -634,12 +466,12 @@ VOID
AR::ProcSup::InitializeSegments(VOID) AR::ProcSup::InitializeSegments(VOID)
{ {
/* Initialize segments */ /* Initialize segments */
AR::CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE); CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
AR::CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK); CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
AR::CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK); CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
AR::CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK); CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK);
AR::CpuFunc::LoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK); CpuFunc::LoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK);
AR::CpuFunc::LoadSegment(SEGMENT_SS, KGDT_R0_DATA); CpuFunc::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);
} }
/** /**
@@ -659,8 +491,7 @@ XTAPI
VOID VOID
AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelBootStack, IN PVOID KernelBootStack,
IN PVOID KernelFaultStack, IN PVOID KernelFaultStack)
IN PVOID KernelNmiStack)
{ {
/* Fill TSS with zeroes */ /* Fill TSS with zeroes */
RtlZeroMemory(ProcessorBlock->TssBase, sizeof(KTSS)); RtlZeroMemory(ProcessorBlock->TssBase, sizeof(KTSS));
@@ -670,7 +501,6 @@ AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
ProcessorBlock->TssBase->Rsp0 = (ULONG_PTR)KernelBootStack; ProcessorBlock->TssBase->Rsp0 = (ULONG_PTR)KernelBootStack;
ProcessorBlock->TssBase->Ist[KIDT_IST_PANIC] = (ULONG_PTR)KernelFaultStack; ProcessorBlock->TssBase->Ist[KIDT_IST_PANIC] = (ULONG_PTR)KernelFaultStack;
ProcessorBlock->TssBase->Ist[KIDT_IST_MCA] = (ULONG_PTR)KernelFaultStack; ProcessorBlock->TssBase->Ist[KIDT_IST_MCA] = (ULONG_PTR)KernelFaultStack;
ProcessorBlock->TssBase->Ist[KIDT_IST_NMI] = (ULONG_PTR)KernelNmiStack;
} }
/** /**

View File

@@ -9,44 +9,6 @@
#include <xtos.hh> #include <xtos.hh>
/**
* Dispatches the interrupt provided by common interrupt handler.
*
* @param TrapFrame
* Supplies a kernel trap frame pushed by common interrupt handler on the stack.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
AR::Traps::DispatchInterrupt(IN PKTRAP_FRAME TrapFrame)
{
PINTERRUPT_HANDLER Handler;
/* Read the handler pointer from the CPU's interrupt dispatch table */
Handler = (PINTERRUPT_HANDLER)AR::CpuFunc::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, InterruptDispatchTable) +
(TrapFrame->Vector * sizeof(PINTERRUPT_HANDLER)));
/* Check if the interrupt has a handler registered */
if(Handler != NULLPTR)
{
/* Call the handler */
Handler(TrapFrame);
}
else if(UnhandledInterruptRoutine != NULLPTR)
{
/* Call the unhandled interrupt routine */
UnhandledInterruptRoutine(TrapFrame);
}
else
{
/* Dispatcher not initialized, print a debug message */
DebugPrint(L"ERROR: Caught unhandled interrupt: 0x%.2llX\n", TrapFrame->Vector);
}
}
/** /**
* Dispatches the trap provided by common trap handler. * Dispatches the trap provided by common trap handler.
* *
@@ -265,6 +227,7 @@ VOID
AR::Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame) AR::Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n"); DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n");
KE::Crash::Panic(0x02);
} }
/** /**
@@ -682,19 +645,19 @@ AR::Traps::InitializeSystemCallMsrs(VOID)
} }
/** /**
* Sets the unhandled interrupt routine used for vectors that have no handler registered. * C-linkage wrapper for dispatching the trap provided by common trap handler.
* *
* @param Handler * @param TrapFrame
* Supplies the pointer to the interrupt handler routine. * Supplies a kernel trap frame pushed by common trap handler on the stack.
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
XTAPI XTCLINK
XTCDECL
VOID VOID
AR::Traps::SetUnhandledInterruptRoutine(PINTERRUPT_HANDLER Handler) ArDispatchTrap(IN PKTRAP_FRAME TrapFrame)
{ {
/* Set the unhandled interrupt routine */ AR::Traps::DispatchTrap(TrapFrame);
UnhandledInterruptRoutine = Handler;
} }

View File

@@ -4,69 +4,31 @@
* FILE: xtoskrnl/ar/i686/archsup.S * FILE: xtoskrnl/ar/i686/archsup.S
* DESCRIPTION: Provides i686 architecture features not implementable in C. * DESCRIPTION: Provides i686 architecture features not implementable in C.
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/ */
#include <xtkmapi.h> #include <ar/i686/asmsup.h>
#include <xtadk.h>
.altmacro .altmacro
.text .text
/** /**
* Creates a task, trap or interrupt handler for the specified vector. * This macro creates a trap handler for the specified vector.
* *
* @param Vector * @param Vector
* Supplies a vector number. * Supplies a trap vector number.
*
* @param Type
* Specifies whether the handler is designed to handle an interrupt, a task or a trap.
* *
* @return This macro does not return any value. * @return This macro does not return any value.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
.macro ArCreateHandler Vector Type .macro ArCreateTrapHandler Vector
.global _Ar\Type\Vector .global _ArTrap\Vector
_Ar\Type\Vector: _ArTrap\Vector:
/* Check handler type */ /* Push fake error code for non-error vectors */
.ifc \Type,Task
_Ar\Type\Vector\()Start:
/* Clear the Task Switch flag */
clts
/* Allocate the trap frame and inject the hardware vector for the dispatcher */
sub $KTRAP_FRAME_SIZE, %esp
movl $\Vector, KTRAP_FRAME_Vector(%esp)
/* Pass the trap frame pointer as an argument and clear the direction flag */
push %esp
cld
/* Pass control to the trap dispatcher */
call _ArDispatchTrap
/* Discard the argument and deallocate the trap frame */
add $4, %esp
add $KTRAP_FRAME_SIZE, %esp
/* Hardware task return */
iretl
/* Spin back to the entry point to rearm the task gate */
jmp _Ar\Type\Vector\()Start
.else
/* Check handler type */
.ifc \Type,Trap
/* Push fake error code for non-error vector traps */
.if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30 .if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
push $0 push $0
.endif .endif
.else
/* Push fake error code for interrupts */
push $0
.endif
/* Push vector number */ /* Push vector number */
push $\Vector push $\Vector
@@ -81,81 +43,75 @@ _Ar\Type\Vector\()Start:
push %eax push %eax
/* Reserve space for other registers and point RBP to the trap frame */ /* Reserve space for other registers and point RBP to the trap frame */
sub $(KTRAP_FRAME_SIZE - KTRAP_FRAME_REGISTERS_SIZE), %esp sub $(TRAP_FRAME_SIZE - TRAP_REGISTERS_SIZE), %esp
lea (%esp), %ebp lea (%esp), %ebp
/* Store segment selectors */ /* Store segment selectors */
mov %gs, KTRAP_FRAME_SegGs(%ebp) mov %gs, TrapSegGs(%ebp)
mov %fs, KTRAP_FRAME_SegFs(%ebp) mov %fs, TrapSegFs(%ebp)
mov %es, KTRAP_FRAME_SegEs(%ebp) mov %es, TrapSegEs(%ebp)
mov %ds, KTRAP_FRAME_SegDs(%ebp) mov %ds, TrapSegDs(%ebp)
/* Store debug registers */ /* Store debug registers */
mov %dr7, %eax mov %dr7, %eax
mov %eax, KTRAP_FRAME_Dr7(%ebp) mov %eax, TrapDr7(%ebp)
mov %dr6, %eax mov %dr6, %eax
mov %eax, KTRAP_FRAME_Dr6(%ebp) mov %eax, TrapDr6(%ebp)
mov %dr3, %eax mov %dr3, %eax
mov %eax, KTRAP_FRAME_Dr3(%ebp) mov %eax, TrapDr3(%ebp)
mov %dr2, %eax mov %dr2, %eax
mov %eax, KTRAP_FRAME_Dr2(%ebp) mov %eax, TrapDr2(%ebp)
mov %dr1, %eax mov %dr1, %eax
mov %eax, KTRAP_FRAME_Dr1(%ebp) mov %eax, TrapDr1(%ebp)
mov %dr0, %eax mov %dr0, %eax
mov %eax, KTRAP_FRAME_Dr0(%ebp) mov %eax, TrapDr0(%ebp)
/* Store CR2 and CR3 */ /* Store CR2 and CR3 */
mov %cr3, %eax mov %cr3, %eax
mov %eax, KTRAP_FRAME_Cr3(%ebp) mov %eax, TrapCr3(%ebp)
mov %cr2, %eax mov %cr2, %eax
mov %eax, KTRAP_FRAME_Cr2(%ebp) mov %eax, TrapCr2(%ebp)
/* Test previous mode */ /* Test previous mode and swap GS if needed */
movl $0, KTRAP_FRAME_PreviousMode(%ebp) movl $0, TrapPreviousMode(%ebp)
mov KTRAP_FRAME_SegCs(%ebp), %ax mov %cs, %ax
and $3, %al and $3, %al
mov %al, KTRAP_FRAME_PreviousMode(%ebp) mov %al, TrapPreviousMode(%ebp)
jz Dispatch\Type\Vector jz KernelMode$\Vector
swapgs
jmp UserMode$\Vector
/* Load Kernel PB selector into FS */ KernelMode$\Vector:
mov $KGDT_R0_PB, %ax /* Save kernel stack pointer (SS:ESP) as CPU did not push them */
mov %ax, %fs movl %ss, %eax
mov %eax, TrapSegSs(%ebp)
lea TrapEsp(%ebp), %eax
mov %eax, TrapEsp(%ebp)
/* Set sane data segment selectors */ UserMode$\Vector:
mov $(KGDT_R3_DATA | RPL_MASK), %ax /* Push Frame Pointer, clear direction flag and pass to trap dispatcher */
mov %ax, %ds
mov %ax, %es
Dispatch\Type\Vector:
/* Push Frame Pointer and clear direction flag */
push %esp push %esp
cld cld
.ifc \Type,Trap
/* Pass to the trap dispatcher */
call _ArDispatchTrap call _ArDispatchTrap
.else
/* Pass to the interrupt dispatcher */
call _ArDispatchInterrupt
.endif
/* Clean up the stack */ /* Clean up the stack */
add $4, %esp add $4, %esp
/* Test previous mode and disable interrupts before user mode return */ /* Test previous mode and swapgs if needed */
testb $1, KTRAP_FRAME_PreviousMode(%ebp) testb $1, TrapPreviousMode(%ebp)
jz RestoreState\Type\Vector jz KernelModeReturn$\Vector
cli cli
swapgs
RestoreState\Type\Vector: KernelModeReturn$\Vector:
/* Restore segment selectors */ /* Restore segment selectors */
mov KTRAP_FRAME_SegDs(%ebp), %ds mov TrapSegDs(%ebp), %ds
mov KTRAP_FRAME_SegEs(%ebp), %es mov TrapSegEs(%ebp), %es
mov KTRAP_FRAME_SegFs(%ebp), %fs mov TrapSegFs(%ebp), %fs
mov KTRAP_FRAME_SegGs(%ebp), %gs mov TrapSegGs(%ebp), %gs
/* Free stack space */ /* Free stack space */
add $(KTRAP_FRAME_SIZE - KTRAP_FRAME_REGISTERS_SIZE), %esp add $(TRAP_FRAME_SIZE - TRAP_REGISTERS_SIZE), %esp
/* Pop General Purpose Registers */ /* Pop General Purpose Registers */
pop %eax pop %eax
@@ -169,169 +125,11 @@ RestoreState\Type\Vector:
/* Skip error code and vector number, then return */ /* Skip error code and vector number, then return */
add $(2 * 4), %esp add $(2 * 4), %esp
iretl iretl
.endif
.endm .endm
/* Populate common interrupt, task and trap handlers */ /* Populate common trap handlers */
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F .irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F .irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
ArCreateHandler 0x\i\j Interrupt ArCreateTrapHandler 0x\i\j
.if 0x\i\j == 0x02 || 0x\i\j == 0x08
ArCreateHandler 0x\i\j Task
.else
ArCreateHandler 0x\i\j Trap
.endif
.endr .endr
.endr .endr
/* Define array of pointers to the interrupt handlers */
.global _ArInterruptEntry
_ArInterruptEntry:
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
.long _ArInterrupt0x\i\j
.endr
.endr
/* Define array of pointers to the trap handlers */
.global _ArTrapEntry
_ArTrapEntry:
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
.if 0x\i\j == 0x02 || 0x\i\j == 0x08
.long _ArTask0x\i\j
.else
.long _ArTrap0x\i\j
.endif
.endr
.endr
/**
* Enables eXtended Physical Addressing (XPA). On i386, this is just a stub.
*
* @param PageMap
* Supplies a pointer to the page map to be used.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
.global ArEnableExtendedPhysicalAddressing
ArEnableExtendedPhysicalAddressing:
.global ArEnableExtendedPhysicalAddressingEnd
ArEnableExtendedPhysicalAddressingEnd:
/**
* Handles a spurious interrupt allowing it to end up.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
.global _ArHandleSpuriousInterrupt
_ArHandleSpuriousInterrupt:
iret
/**
* Starts an application processor (AP).
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
.global _ArStartApplicationProcessor
_ArStartApplicationProcessor:
/* Enter 16-bit real mode */
.code16
/* Disable interrupts and clear direction flag */
cli
cld
/* Establish a flat addressing baseline */
movw %cs, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
/* Calculate absolute physical base address */
xorl %ebx, %ebx
movw %cs, %bx
shll $4, %ebx
/* Set up a temporary stack for the AP initialization */
movl %ebx, %esp
addl $0x1000, %esp
/* Load the temporary Global Descriptor Table */
leal (ApTemporaryGdtDesc - _ArStartApplicationProcessor)(%ebx), %eax
movl %eax, (ApTemporaryGdtBase - _ArStartApplicationProcessor)
lgdtl (ApTemporaryGdtSize - _ArStartApplicationProcessor)
/* Enable Protected Mode */
movl %cr0, %eax
orl $0x01, %eax
movl %eax, %cr0
/* Far return to enter 32-bit protected mode */
leal (ApEnterProtectedMode - _ArStartApplicationProcessor)(%ebx), %eax
pushl $KGDT_R0_CODE
pushl %eax
lretl
ApEnterProtectedMode:
/* Enter 32-bit protected mode */
.code32
/* Setup all data segment registers */
movw $KGDT_R0_DATA, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
xorw %ax, %ax
movw %ax, %fs
movw %ax, %gs
/* Locate PROCESSOR_START_BLOCK structure */
leal (_ArStartApplicationProcessorEnd - _ArStartApplicationProcessor)(%ebx), %edi
/* Load CR4 from BSP, but mask PCIDE and PGE */
movl PROCESSOR_START_BLOCK_Cr4(%edi), %eax
andl $~(CR4_PGE | CR4_PCIDE), %eax
movl %eax, %cr4
/* Load the Kernel Page Directory Base from BSP */
movl PROCESSOR_START_BLOCK_Cr3(%edi), %eax
movl %eax, %cr3
/* Enable Paging */
movl %cr0, %eax
orl $CR0_PG, %eax
movl %eax, %cr0
/* Load dedicated Stack for AP */
movl PROCESSOR_START_BLOCK_Stack(%edi), %esp
/* Save the pointer to PROCESSOR_START_BLOCK */
movl %edi, %ecx
pushl %edi
/* Call the EntryPoint routine */
movl PROCESSOR_START_BLOCK_EntryPoint(%edi), %eax
call *%eax
/* Fire the breakpoint and halt if the entry point returns */
.ApNoReturnPoint:
int $0x03
hlt
jmp .ApNoReturnPoint
/* Data section for temporary GDT */
.align 8
ApTemporaryGdtSize: .short _ArStartApplicationProcessorEnd - ApTemporaryGdtDesc - 1
ApTemporaryGdtBase: .long 0x00000000
ApTemporaryGdtDesc: .quad 0x0000000000000000, 0x00CF9A000000FFFF, 0x00CF92000000FFFF
.global _ArStartApplicationProcessorEnd
_ArStartApplicationProcessorEnd:

26
xtoskrnl/ar/i686/boot.S Normal file
View File

@@ -0,0 +1,26 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/i686/boot.S
* DESCRIPTION: i686-specific boot code for setting up the low-level CPU environment
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <ar/amd64/asmsup.h>
.altmacro
.text
/**
* Starts an application processor (AP). This is just a stub.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
.global _ArStartApplicationProcessor
_ArStartApplicationProcessor:
.global _ArStartApplicationProcessorEnd
_ArStartApplicationProcessorEnd:

View File

@@ -543,33 +543,6 @@ AR::CpuFunc::ReadTimeStampCounter(VOID)
return Value; return Value;
} }
/**
* Reads the current value of the CPU's time-stamp counter and processor ID.
*
* @param TscAux
* Supplies a pointer to a variable that receives the auxiliary TSC information (IA32_TSC_AUX).
*
* @return This routine returns the current instruction cycle count since the processor was last reset.
*
* @since XT 1.0
*/
XTCDECL
ULONGLONG
AR::CpuFunc::ReadTimeStampCounterProcessor(OUT PULONG TscAux)
{
ULONG Low, High;
/* Execute the RDTSCP instruction */
__asm__ volatile("rdtscp"
: "=a" (Low),
"=d" (High),
"=c" (*TscAux)
);
/* Combine the two 32-bit registers into a single 64-bit unsigned integer and return the value */
return ((ULONGLONG)High << 32) | Low;
}
/** /**
* Orders memory accesses as seen by other processors, without fence. * Orders memory accesses as seen by other processors, without fence.
* *

View File

@@ -30,11 +30,5 @@ KPROCESSOR_BLOCK AR::ProcSup::InitialProcessorBlock;
/* Initial TSS */ /* Initial TSS */
KTSS AR::ProcSup::InitialTss; KTSS AR::ProcSup::InitialTss;
/* Initial kernel NMI stack */
UCHAR AR::ProcSup::NmiStack[KERNEL_STACK_SIZE] = {};
/* NMI task gate */ /* NMI task gate */
UCHAR AR::ProcSup::NonMaskableInterruptTss[KTSS_IO_MAPS]; UCHAR AR::ProcSup::NonMaskableInterruptTss[KTSS_IO_MAPS];
/* Unhandled interrupt routine */
PINTERRUPT_HANDLER AR::Traps::UnhandledInterruptRoutine = NULLPTR;

View File

@@ -20,8 +20,7 @@ XTAPI
PVOID PVOID
AR::ProcSup::GetBootStack(VOID) AR::ProcSup::GetBootStack(VOID)
{ {
/* Return base address of kernel boot stack */ return (PVOID)BootStack;
return (PVOID)((ULONG_PTR)BootStack + KERNEL_STACK_SIZE);
} }
XTAPI XTAPI
@@ -30,17 +29,14 @@ AR::ProcSup::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
OUT PVOID *TrampolineCode, OUT PVOID *TrampolineCode,
OUT PULONG_PTR TrampolineSize) OUT PULONG_PTR TrampolineSize)
{ {
/* Get trampoline information */
switch(TrampolineType) switch(TrampolineType)
{ {
case TrampolineApStartup: case TrampolineApStartup:
/* Get AP startup trampoline information */
*TrampolineCode = (PVOID)ArStartApplicationProcessor; *TrampolineCode = (PVOID)ArStartApplicationProcessor;
*TrampolineSize = (ULONG_PTR)ArStartApplicationProcessorEnd - *TrampolineSize = (ULONG_PTR)ArStartApplicationProcessorEnd -
(ULONG_PTR)ArStartApplicationProcessor; (ULONG_PTR)ArStartApplicationProcessor;
break; break;
default: default:
/* Unknown trampoline type */
*TrampolineCode = NULLPTR; *TrampolineCode = NULLPTR;
*TrampolineSize = 0; *TrampolineSize = 0;
break; break;
@@ -48,7 +44,8 @@ AR::ProcSup::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
} }
/** /**
* Identifies processor type (vendor, model, stepping) and stores them in Processor Control Block (PRCB). * Identifies processor type (vendor, model, stepping) as well as looks for available CPU features and stores them
* in Processor Control Block (PRCB).
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
@@ -62,13 +59,16 @@ AR::ProcSup::IdentifyProcessor(VOID)
CPUID_REGISTERS CpuRegisters; CPUID_REGISTERS CpuRegisters;
CPUID_SIGNATURE CpuSignature; CPUID_SIGNATURE CpuSignature;
/* Not fully implemented yet */
UNIMPLEMENTED;
/* Get current processor control block */ /* Get current processor control block */
Prcb = KE::Processor::GetCurrentProcessorControlBlock(); Prcb = KE::Processor::GetCurrentProcessorControlBlock();
/* Get CPU vendor by issueing CPUID instruction */ /* Get CPU vendor by issueing CPUID instruction */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING; CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
AR::CpuFunc::CpuId(&CpuRegisters); CpuFunc::CpuId(&CpuRegisters);
/* Store CPU vendor in processor control block */ /* Store CPU vendor in processor control block */
Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx; Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx;
@@ -80,7 +80,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
/* Get CPU standard features */ /* Get CPU standard features */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES; CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
AR::CpuFunc::CpuId(&CpuRegisters); CpuFunc::CpuId(&CpuRegisters);
/* Store CPU signature in processor control block */ /* Store CPU signature in processor control block */
CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax; CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax;
@@ -92,23 +92,23 @@ AR::ProcSup::IdentifyProcessor(VOID)
if(Prcb->CpuId.Vendor == CPU_VENDOR_AMD) if(Prcb->CpuId.Vendor == CPU_VENDOR_AMD)
{ {
/* AMD CPU */ /* AMD CPU */
if(CpuSignature.Family == 0xF) if(Prcb->CpuId.Family >= 0xF)
{ {
Prcb->CpuId.Family += CpuSignature.ExtendedFamily; Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
Prcb->CpuId.Model += (CpuSignature.ExtendedModel << 4); Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
} }
} }
else if(Prcb->CpuId.Vendor == CPU_VENDOR_INTEL) else if(Prcb->CpuId.Vendor == CPU_VENDOR_INTEL)
{ {
/* Intel CPU */ /* Intel CPU */
if(CpuSignature.Family == 0xF) if(Prcb->CpuId.Family == 0xF)
{ {
Prcb->CpuId.Family += CpuSignature.ExtendedFamily; Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
} }
if((CpuSignature.Family == 0x6) || (CpuSignature.Family == 0xF)) if((Prcb->CpuId.Family == 0x6) || (Prcb->CpuId.Family == 0xF))
{ {
Prcb->CpuId.Model += (CpuSignature.ExtendedModel << 4); Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
} }
} }
else else
@@ -117,12 +117,11 @@ AR::ProcSup::IdentifyProcessor(VOID)
Prcb->CpuId.Vendor = CPU_VENDOR_UNKNOWN; Prcb->CpuId.Vendor = CPU_VENDOR_UNKNOWN;
} }
/* Identify processor features */ /* TODO: Store a list of CPU features in processor control block */
IdentifyProcessorFeatures();
} }
/** /**
* Identifies processor features and stores them in Processor Control Block (PRCB). * Initializes i686 processor specific structures.
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
@@ -130,133 +129,66 @@ AR::ProcSup::IdentifyProcessor(VOID)
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::IdentifyProcessorFeatures(VOID) AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
{ {
ULONG MaxExtendedLeaf, MaxStandardLeaf; KDESCRIPTOR GdtDescriptor, IdtDescriptor;
PKPROCESSOR_CONTROL_BLOCK Prcb; PVOID KernelBootStack, KernelFaultStack;
CPUID_REGISTERS CpuRegisters; PKPROCESSOR_BLOCK ProcessorBlock;
PKGDTENTRY Gdt;
PKIDTENTRY Idt;
PKTSS Tss;
/* Get current processor control block */ /* Check if processor structures buffer provided */
Prcb = KE::Processor::GetCurrentProcessorControlBlock(); if(ProcessorStructures)
/* Get maximum CPUID standard leaf */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
AR::CpuFunc::CpuId(&CpuRegisters);
MaxStandardLeaf = CpuRegisters.Eax;
/* Get maximum CPUID extended leaf */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_EXTENDED_MAX;
AR::CpuFunc::CpuId(&CpuRegisters);
MaxExtendedLeaf = CpuRegisters.Eax;
/* Check if CPU supports standard features leaf */
if(MaxStandardLeaf >= CPUID_GET_STANDARD1_FEATURES)
{ {
/* Get CPU standard features */ /* Assign CPU structures from provided buffer */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES; &KernelBootStack, &KernelFaultStack);
AR::CpuFunc::CpuId(&CpuRegisters);
/* Store CPU standard features in processor control block */ /* Use global IDT */
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE3) Prcb->CpuId.FeatureBits |= KCF_SSE3; Idt = InitialIdt;
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_VMX) Prcb->CpuId.FeatureBits |= KCF_VMX; }
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSSE3) Prcb->CpuId.FeatureBits |= KCF_SSSE3; else
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4_1) Prcb->CpuId.FeatureBits |= KCF_SSE41; {
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4_2) Prcb->CpuId.FeatureBits |= KCF_SSE42; /* Use initial structures */
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_X2APIC) Prcb->CpuId.FeatureBits |= KCF_X2APIC; Gdt = InitialGdt;
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_POPCNT) Prcb->CpuId.FeatureBits |= KCF_POPCNT; Idt = InitialIdt;
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_TSC_DEADLINE) Prcb->CpuId.FeatureBits |= KCF_TSC_DEADLINE; Tss = &InitialTss;
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_AES) Prcb->CpuId.FeatureBits |= KCF_AES; KernelBootStack = &BootStack;
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_XSAVE) Prcb->CpuId.FeatureBits |= KCF_XSAVE; KernelFaultStack = &FaultStack;
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_AVX) Prcb->CpuId.FeatureBits |= KCF_AVX; ProcessorBlock = &InitialProcessorBlock;
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_RDRAND) Prcb->CpuId.FeatureBits |= KCF_RDRAND;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_VME) Prcb->CpuId.FeatureBits |= KCF_VME;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PSE) Prcb->CpuId.FeatureBits |= KCF_LARGE_PAGE;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSC) Prcb->CpuId.FeatureBits |= KCF_RDTSC;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PAE) Prcb->CpuId.FeatureBits |= KCF_PAE;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MCE) Prcb->CpuId.FeatureBits |= KCF_MCE;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CX8) Prcb->CpuId.FeatureBits |= KCF_CMPXCHG8B;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_APIC) Prcb->CpuId.FeatureBits |= KCF_APIC;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SEP) Prcb->CpuId.FeatureBits |= KCF_FAST_SYSCALL;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MTRR) Prcb->CpuId.FeatureBits |= KCF_MTRR;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PGE) Prcb->CpuId.FeatureBits |= KCF_GLOBAL_PAGE;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MCA) Prcb->CpuId.FeatureBits |= KCF_MCA;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CMOV) Prcb->CpuId.FeatureBits |= KCF_CMOV;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PAT) Prcb->CpuId.FeatureBits |= KCF_PAT;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PSE36) Prcb->CpuId.FeatureBits |= KCF_PSE36;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CLFLUSH) Prcb->CpuId.FeatureBits |= KCF_CLFLUSH;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_FXSR) Prcb->CpuId.FeatureBits |= KCF_FXSR;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_ACPI) Prcb->CpuId.FeatureBits |= KCF_ACPI;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MMX) Prcb->CpuId.FeatureBits |= KCF_MMX;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SSE) Prcb->CpuId.FeatureBits |= KCF_SSE;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SSE2) Prcb->CpuId.FeatureBits |= KCF_SSE2;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_HTT) Prcb->CpuId.FeatureBits |= KCF_SMT;
} }
/* Check if CPU supports standard7 features leaf */ /* Initialize processor block */
if(MaxStandardLeaf >= CPUID_GET_STANDARD7_FEATURES) InitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);
{
/* Get CPU standard features */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_STANDARD7_FEATURES;
AR::CpuFunc::CpuId(&CpuRegisters);
/* Store CPU standard7 features in processor control block */ /* Initialize GDT, IDT and TSS */
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_FSGSBASE) Prcb->CpuId.FeatureBits |= KCF_FSGSBASE; InitializeGdt(ProcessorBlock);
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_AVX2) Prcb->CpuId.FeatureBits |= KCF_AVX2; InitializeIdt(ProcessorBlock);
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SMEP) Prcb->CpuId.FeatureBits |= KCF_SMEP; InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack);
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_RDSEED) Prcb->CpuId.FeatureBits |= KCF_RDSEED;
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SMAP) Prcb->CpuId.FeatureBits |= KCF_SMAP;
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SHA) Prcb->CpuId.FeatureBits |= KCF_SHA;
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_LA57) Prcb->CpuId.FeatureBits |= KCF_LA57;
}
/* Check if CPU supports power management leaf */ /* Set GDT and IDT descriptors */
if(MaxStandardLeaf >= CPUID_GET_POWER_MANAGEMENT) GdtDescriptor.Base = Gdt;
{ GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1;
/* Get CPU power management features */ IdtDescriptor.Base = Idt;
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;
CpuRegisters.Leaf = CPUID_GET_POWER_MANAGEMENT;
AR::CpuFunc::CpuId(&CpuRegisters);
/* Store CPU power management features in processor control block */ /* Load GDT, IDT and TSS */
if(CpuRegisters.Eax & CPUID_FEATURES_EAX_ARAT) Prcb->CpuId.FeatureBits |= KCF_ARAT; CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
} CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS);
/* Check if CPU supports extended features leaf */ /* Enter passive IRQ level */
if(MaxExtendedLeaf >= CPUID_GET_EXTENDED_FEATURES) HL::RunLevel::SetRunLevel(PASSIVE_LEVEL);
{
/* Get CPU extended features */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_EXTENDED_FEATURES;
AR::CpuFunc::CpuId(&CpuRegisters);
/* Store CPU extended features in processor control block */ /* Initialize segment registers */
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SVM) Prcb->CpuId.ExtendedFeatureBits |= KCF_SVM; InitializeSegments();
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4A) Prcb->CpuId.ExtendedFeatureBits |= KCF_SSE4A;
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_FMA4) Prcb->CpuId.ExtendedFeatureBits |= KCF_FMA4;
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_TOPOLOGY_EXTENSIONS) Prcb->CpuId.ExtendedFeatureBits |= KCF_TOPOEXT;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SYSCALL_SYSRET) Prcb->CpuId.ExtendedFeatureBits |= KCF_SYSCALL;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_NX) Prcb->CpuId.ExtendedFeatureBits |= KCF_NX_BIT;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_RDTSCP) Prcb->CpuId.ExtendedFeatureBits |= KCF_RDTSCP;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_LONG_MODE) Prcb->CpuId.ExtendedFeatureBits |= KCF_64BIT;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_3DNOW_EXT) Prcb->CpuId.ExtendedFeatureBits |= KCF_3DNOW_EXT;
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_3DNOW) Prcb->CpuId.ExtendedFeatureBits |= KCF_3DNOW;
}
/* Check if CPU supports advanced power management leaf */ /* Initialize processor registers */
if(MaxExtendedLeaf >= CPUID_GET_ADVANCED_POWER_MANAGEMENT) InitializeProcessorRegisters();
{
/* Get CPU advanced power management features */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_ADVANCED_POWER_MANAGEMENT;
AR::CpuFunc::CpuId(&CpuRegisters);
/* Store CPU advanced power management features in processor control block */ /* Identify processor */
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSCI) Prcb->CpuId.ExtendedFeatureBits |= KCF_INVARIANT_TSC; IdentifyProcessor();
}
} }
/** /**
@@ -283,9 +215,9 @@ AR::ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_PB, (ULONG_PTR)ProcessorBlock, sizeof(KPROCESSOR_BLOCK), KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_PB, (ULONG_PTR)ProcessorBlock, sizeof(KPROCESSOR_BLOCK), KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_TEB, 0x0, 0xFFF, KGDT_TYPE_DATA | KGDT_DESCRIPTOR_ACCESSED, KGDT_DPL_USER, 2); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_TEB, 0x0, 0xFFF, KGDT_TYPE_DATA | KGDT_DESCRIPTOR_ACCESSED, KGDT_DPL_USER, 2);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDM_TILE, 0x0400, 0xFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 0); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDM_TILE, 0x0400, 0xFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 0);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0x0, I686_LDT, KGDT_DPL_SYSTEM, 0); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_DF_TSS, 0x20000, 0xFFFF, I686_TSS, KGDT_DPL_SYSTEM, 0); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_DF_TSS, 0x20000, 0xFFFF, I686_TSS, KGDT_DPL_SYSTEM, 0);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NMI_TSS, 0x20000, 0xFFFF, I686_TSS, KGDT_DPL_SYSTEM, 0); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NMI_TSS, 0x20000, 0xFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDBS, 0xB8000, 0x3FFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDBS, 0xB8000, 0x3FFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_ALIAS, (ULONG_PTR)ProcessorBlock->GdtBase, (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_ALIAS, (ULONG_PTR)ProcessorBlock->GdtBase, (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0);
} }
@@ -310,105 +242,34 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
for(Vector = 0; Vector < IDT_ENTRIES; Vector++) for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
{ {
/* Set the IDT to handle unexpected interrupts */ /* Set the IDT to handle unexpected interrupts */
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArInterruptEntry[Vector], SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
} }
/* Setup IDT handlers for known interrupts and traps */ /* Setup IDT handlers for known interrupts and traps */
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrapEntry[0x00], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrapEntry[0x01], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrapEntry[0x02], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TASK_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrapEntry[0x03], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrapEntry[0x04], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrapEntry[0x05], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrapEntry[0x06], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrapEntry[0x07], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrapEntry[0x08], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TASK_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrapEntry[0x09], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrapEntry[0x0A], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrapEntry[0x0B], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrapEntry[0x0C], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrapEntry[0x0D], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrapEntry[0x0E], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrapEntry[0x10], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrapEntry[0x11], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrapEntry[0x12], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrapEntry[0x13], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrapEntry[0x2A], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrap0x2A, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrapEntry[0x2B], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrap0x2B, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrapEntry[0x2C], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrapEntry[0x2D], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrapEntry[0x2E], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE); SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrap0x2E, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
}
/**
* Initializes i686 processor specific structures.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
{
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
PVOID KernelBootStack, KernelFaultStack, KernelNmiStack;
PKPROCESSOR_BLOCK ProcessorBlock;
PKGDTENTRY Gdt;
PKIDTENTRY Idt;
PKTSS Tss;
/* Check if processor structures buffer provided */
if(ProcessorStructures)
{
/* Assign CPU structures from provided buffer */
InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
&KernelBootStack, &KernelFaultStack, &KernelNmiStack);
/* Use global IDT */
Idt = InitialIdt;
}
else
{
/* Use initial structures */
Gdt = InitialGdt;
Idt = InitialIdt;
Tss = &InitialTss;
KernelBootStack = (PVOID)((ULONG_PTR)&BootStack + KERNEL_STACK_SIZE);
KernelFaultStack = (PVOID)((ULONG_PTR)&FaultStack + KERNEL_STACK_SIZE);
KernelNmiStack = (PVOID)((ULONG_PTR)&NmiStack + KERNEL_STACK_SIZE);
ProcessorBlock = &InitialProcessorBlock;
}
/* Initialize processor block */
InitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);
/* Initialize GDT, IDT and TSS */
InitializeGdt(ProcessorBlock);
InitializeIdt(ProcessorBlock);
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack, KernelNmiStack);
/* Set GDT and IDT descriptors */
GdtDescriptor.Base = Gdt;
GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1;
IdtDescriptor.Base = Idt;
IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;
/* Load GDT, IDT and TSS */
AR::CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
AR::CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
AR::CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS);
/* Initialize segment registers */
InitializeSegments();
/* Initialize processor registers */
InitializeProcessorRegisters();
/* Identify processor */
IdentifyProcessor();
} }
/** /**
@@ -481,10 +342,10 @@ VOID
AR::ProcSup::InitializeProcessorRegisters(VOID) AR::ProcSup::InitializeProcessorRegisters(VOID)
{ {
/* Clear EFLAGS register */ /* Clear EFLAGS register */
AR::CpuFunc::WriteEflagsRegister(0); CpuFunc::WriteEflagsRegister(0);
/* Enable write-protection */ /* Enable write-protection */
AR::CpuFunc::WriteControlRegister(0, AR::CpuFunc::ReadControlRegister(0) | CR0_WP); CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_WP);
} }
/** /**
@@ -519,8 +380,7 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
OUT PKTSS *Tss, OUT PKTSS *Tss,
OUT PKPROCESSOR_BLOCK *ProcessorBlock, OUT PKPROCESSOR_BLOCK *ProcessorBlock,
OUT PVOID *KernelBootStack, OUT PVOID *KernelBootStack,
OUT PVOID *KernelFaultStack, OUT PVOID *KernelFaultStack)
OUT PVOID *KernelNmiStack)
{ {
UINT_PTR Address; UINT_PTR Address;
@@ -528,49 +388,22 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
Address = ROUND_UP((UINT_PTR)ProcessorStructures, MM_PAGE_SIZE) + KERNEL_STACK_SIZE; Address = ROUND_UP((UINT_PTR)ProcessorStructures, MM_PAGE_SIZE) + KERNEL_STACK_SIZE;
/* Assign a space for kernel boot stack and advance */ /* Assign a space for kernel boot stack and advance */
if(KernelBootStack != NULLPTR)
{
/* Return kernel boot stack address */
*KernelBootStack = (PVOID)Address; *KernelBootStack = (PVOID)Address;
}
Address += KERNEL_STACK_SIZE; Address += KERNEL_STACK_SIZE;
/* Assign a space for kernel fault stack and advance */ /* Assign a space for kernel fault stack, no advance needed as stack grows down */
if(KernelFaultStack != NULLPTR)
{
/* Return kernel fault stack address */
*KernelFaultStack = (PVOID)Address; *KernelFaultStack = (PVOID)Address;
}
Address += KERNEL_STACK_SIZE;
/* Assign a space for kernel NMI stack, no advance needed as stack grows down */
if(KernelNmiStack != NULLPTR)
{
/* Return kernel NMI stack address */
*KernelNmiStack = (PVOID)Address;
}
/* Assign a space for GDT and advance */ /* Assign a space for GDT and advance */
if(Gdt != NULLPTR)
{
/* Return GDT base address */
*Gdt = (PKGDTENTRY)(PVOID)Address; *Gdt = (PKGDTENTRY)(PVOID)Address;
} Address += sizeof(InitialGdt);
Address += (GDT_ENTRIES * sizeof(KGDTENTRY));
/* Assign a space for TSS and advance */
if(Tss != NULLPTR)
{
*Tss = (PKTSS)(PVOID)Address;
}
Address += sizeof(KTSS);
/* Assign a space for Processor Block and advance */ /* Assign a space for Processor Block and advance */
if(ProcessorBlock != NULLPTR)
{
/* Return processor block address */
*ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address; *ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address;
} Address += sizeof(InitialProcessorBlock);
/* Assign a space for TSS */
*Tss = (PKTSS)(PVOID)Address;
} }
/** /**
@@ -585,12 +418,10 @@ VOID
AR::ProcSup::InitializeSegments(VOID) AR::ProcSup::InitializeSegments(VOID)
{ {
/* Initialize segments */ /* Initialize segments */
AR::CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE); CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
AR::CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK); CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
AR::CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK); CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
AR::CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R0_PB); CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R0_PB);
AR::CpuFunc::LoadSegment(SEGMENT_GS, 0);
AR::CpuFunc::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);
} }
/** /**
@@ -607,19 +438,8 @@ XTAPI
VOID VOID
AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelBootStack, IN PVOID KernelBootStack,
IN PVOID KernelFaultStack, IN PVOID KernelFaultStack)
IN PVOID KernelNmiStack)
{ {
PKGDTENTRY TssEntry;
/* Setup System TSS entry in Global Descriptor Table */
TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_SYS_TSS / sizeof(KGDTENTRY)]));
TssEntry->LimitLow = sizeof(KTSS) - 1;
TssEntry->Bits.LimitHigh = 0;
TssEntry->Bits.Dpl = 0;
TssEntry->Bits.Present = 1;
TssEntry->Bits.Type = I686_TSS;
/* Clear I/O map */ /* Clear I/O map */
RtlSetMemory(ProcessorBlock->TssBase->IoMaps[0].IoMap, 0xFF, IOPM_FULL_SIZE); RtlSetMemory(ProcessorBlock->TssBase->IoMaps[0].IoMap, 0xFF, IOPM_FULL_SIZE);
@@ -641,16 +461,16 @@ AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
/* Set I/O map base and disable traps */ /* Set I/O map base and disable traps */
ProcessorBlock->TssBase->IoMapBase = sizeof(KTSS); ProcessorBlock->TssBase->IoMapBase = sizeof(KTSS);
ProcessorBlock->TssBase->Esp0 = (ULONG_PTR)KernelBootStack;
ProcessorBlock->TssBase->Flags = 0; ProcessorBlock->TssBase->Flags = 0;
/* Set CR3, LDT and SS */ /* Set LDT and SS */
ProcessorBlock->TssBase->CR3 = AR::CpuFunc::ReadControlRegister(3); ProcessorBlock->TssBase->LDT = KGDT_R0_LDT;
ProcessorBlock->TssBase->LDT = 0;
ProcessorBlock->TssBase->Ss0 = KGDT_R0_DATA; ProcessorBlock->TssBase->Ss0 = KGDT_R0_DATA;
/* Initialize task gates for DoubleFault and NMI traps */ /* Initialize task gates for DoubleFault and NMI traps */
SetDoubleFaultTssEntry(ProcessorBlock, KernelFaultStack); SetDoubleFaultTssEntry(ProcessorBlock, KernelFaultStack);
SetNonMaskableInterruptTssEntry(ProcessorBlock, KernelNmiStack); SetNonMaskableInterruptTssEntry(ProcessorBlock, KernelFaultStack);
} }
/** /**
@@ -682,24 +502,24 @@ AR::ProcSup::SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
Tss = (PKTSS)DoubleFaultTss; Tss = (PKTSS)DoubleFaultTss;
Tss->IoMapBase = sizeof(KTSS); Tss->IoMapBase = sizeof(KTSS);
Tss->Flags = 0; Tss->Flags = 0;
Tss->LDT = 0; Tss->LDT = KGDT_R0_LDT;
Tss->CR3 = AR::CpuFunc::ReadControlRegister(3); Tss->CR3 = CpuFunc::ReadControlRegister(3);
Tss->Esp = (ULONG_PTR)KernelFaultStack; Tss->Esp = (ULONG_PTR)KernelFaultStack;
Tss->Esp0 = (ULONG_PTR)KernelFaultStack; Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
Tss->Eip = (ULONG)(ULONG_PTR)ArTrapEntry[0x08]; Tss->Eip = PtrToUlong(ArTrap0x08);
Tss->Cs = KGDT_R0_CODE; Tss->Cs = KGDT_R0_CODE;
Tss->Ds = KGDT_R3_DATA | RPL_MASK; Tss->Ds = KGDT_R3_DATA | RPL_MASK;
Tss->Es = KGDT_R3_DATA | RPL_MASK; Tss->Es = KGDT_R3_DATA | RPL_MASK;
Tss->Fs = KGDT_R0_PB; Tss->Fs = KGDT_R0_PB;
Tss->Ss = KGDT_R0_DATA;
Tss->Ss0 = KGDT_R0_DATA; Tss->Ss0 = KGDT_R0_DATA;
CpuFunc::StoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss);
/* Setup DoubleFault TSS entry in Global Descriptor Table */ /* Setup DoubleFault TSS entry in Global Descriptor Table */
TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_DF_TSS / sizeof(KGDTENTRY)])); TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_DF_TSS / sizeof(KGDTENTRY)]));
TssEntry->BaseLow = ((ULONG_PTR)Tss & 0xFFFF); TssEntry->BaseLow = ((ULONG_PTR)Tss & 0xFFFF);
TssEntry->Bytes.BaseMiddle = ((ULONG_PTR)Tss >> 16); TssEntry->Bytes.BaseMiddle = ((ULONG_PTR)Tss >> 16);
TssEntry->Bytes.BaseHigh = ((ULONG_PTR)Tss >> 24); TssEntry->Bytes.BaseHigh = ((ULONG_PTR)Tss >> 24);
TssEntry->LimitLow = 0x68; TssEntry->LimitLow = sizeof(KTSS) - 1;
TssEntry->Bits.LimitHigh = 0; TssEntry->Bits.LimitHigh = 0;
TssEntry->Bits.Dpl = 0; TssEntry->Bits.Dpl = 0;
TssEntry->Bits.Present = 1; TssEntry->Bits.Present = 1;
@@ -880,7 +700,7 @@ AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
XTAPI XTAPI
VOID VOID
AR::ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, AR::ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelNmiStack) IN PVOID KernelFaultStack)
{ {
PKGDTENTRY TaskGateEntry, TssEntry; PKGDTENTRY TaskGateEntry, TssEntry;
PKTSS Tss; PKTSS Tss;
@@ -896,24 +716,23 @@ AR::ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock
Tss = (PKTSS)NonMaskableInterruptTss; Tss = (PKTSS)NonMaskableInterruptTss;
Tss->IoMapBase = sizeof(KTSS); Tss->IoMapBase = sizeof(KTSS);
Tss->Flags = 0; Tss->Flags = 0;
Tss->LDT = 0; Tss->LDT = KGDT_R0_LDT;
Tss->CR3 = AR::CpuFunc::ReadControlRegister(3); Tss->CR3 = CpuFunc::ReadControlRegister(3);
Tss->Esp = (ULONG_PTR)KernelNmiStack; Tss->Esp = (ULONG_PTR)KernelFaultStack;
Tss->Esp0 = (ULONG_PTR)KernelNmiStack; Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
Tss->Eip = (ULONG)(ULONG_PTR)ArTrapEntry[0x02]; Tss->Eip = PtrToUlong(ArTrap0x02);
Tss->Cs = KGDT_R0_CODE; Tss->Cs = KGDT_R0_CODE;
Tss->Ds = KGDT_R3_DATA | RPL_MASK; Tss->Ds = KGDT_R3_DATA | RPL_MASK;
Tss->Es = KGDT_R3_DATA | RPL_MASK; Tss->Es = KGDT_R3_DATA | RPL_MASK;
Tss->Fs = KGDT_R0_PB; Tss->Fs = KGDT_R0_PB;
Tss->Ss = KGDT_R0_DATA; CpuFunc::StoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss);
Tss->Ss0 = KGDT_R0_DATA;
/* Setup NMI TSS entry in Global Descriptor Table */ /* Setup NMI TSS entry in Global Descriptor Table */
TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_NMI_TSS / sizeof(KGDTENTRY)])); TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_NMI_TSS / sizeof(KGDTENTRY)]));
TssEntry->BaseLow = ((ULONG_PTR)Tss & 0xFFFF); TssEntry->BaseLow = ((ULONG_PTR)Tss & 0xFFFF);
TssEntry->Bytes.BaseMiddle = ((ULONG_PTR)Tss >> 16); TssEntry->Bytes.BaseMiddle = ((ULONG_PTR)Tss >> 16);
TssEntry->Bytes.BaseHigh = ((ULONG_PTR)Tss >> 24); TssEntry->Bytes.BaseHigh = ((ULONG_PTR)Tss >> 24);
TssEntry->LimitLow = 0x68; TssEntry->LimitLow = sizeof(KTSS) - 1;
TssEntry->Bits.LimitHigh = 0; TssEntry->Bits.LimitHigh = 0;
TssEntry->Bits.Dpl = 0; TssEntry->Bits.Dpl = 0;
TssEntry->Bits.Present = 1; TssEntry->Bits.Present = 1;

View File

@@ -9,44 +9,6 @@
#include <xtos.hh> #include <xtos.hh>
/**
* Dispatches the interrupt provided by common interrupt handler.
*
* @param TrapFrame
* Supplies a kernel trap frame pushed by common interrupt handler on the stack.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
AR::Traps::DispatchInterrupt(IN PKTRAP_FRAME TrapFrame)
{
PINTERRUPT_HANDLER Handler;
/* Read the handler pointer from the CPU's interrupt dispatch table */
Handler = (PINTERRUPT_HANDLER)AR::CpuFunc::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, InterruptDispatchTable) +
(TrapFrame->Vector * sizeof(PINTERRUPT_HANDLER)));
/* Check if the interrupt has a handler registered */
if(Handler != NULLPTR)
{
/* Call the handler */
Handler(TrapFrame);
}
else if(UnhandledInterruptRoutine != NULLPTR)
{
/* Call the unhandled interrupt routine */
UnhandledInterruptRoutine(TrapFrame);
}
else
{
/* Dispatcher not initialized, print a debug message */
DebugPrint(L"ERROR: Caught unhandled interrupt: 0x%.2lX\n", TrapFrame->Vector);
}
}
/** /**
* Dispatches the trap provided by common trap handler. * Dispatches the trap provided by common trap handler.
* *
@@ -233,6 +195,7 @@ VOID
AR::Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame) AR::Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n"); DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n");
KE::Crash::Panic(0x02);
} }
/** /**
@@ -629,19 +592,19 @@ AR::Traps::HandleTrapFF(IN PKTRAP_FRAME TrapFrame)
} }
/** /**
* Sets the unhandled interrupt routine used for vectors that have no handler registered. * C-linkage wrapper for dispatching the trap provided by common trap handler.
* *
* @param Handler * @param TrapFrame
* Supplies the pointer to the interrupt handler routine. * Supplies a kernel trap frame pushed by common trap handler on the stack.
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
XTCLINK
XTCDECL XTCDECL
VOID VOID
AR::Traps::SetUnhandledInterruptRoutine(PINTERRUPT_HANDLER Handler) ArDispatchTrap(IN PKTRAP_FRAME TrapFrame)
{ {
/* Set the unhandled interrupt routine */ AR::Traps::DispatchTrap(TrapFrame);
UnhandledInterruptRoutine = Handler;
} }

View File

@@ -4,7 +4,6 @@
* FILE: xtoskrnl/hl/x86/acpi.cc * FILE: xtoskrnl/hl/x86/acpi.cc
* DESCRIPTION: Advanced Configuration and Power Interface (ACPI) support * DESCRIPTION: Advanced Configuration and Power Interface (ACPI) support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/ */
#include <xtos.hh> #include <xtos.hh>
@@ -26,21 +25,8 @@ HL::Acpi::CacheAcpiTable(IN PACPI_DESCRIPTION_HEADER AcpiTable)
{ {
PACPI_CACHE_LIST AcpiCache; PACPI_CACHE_LIST AcpiCache;
/* Check if there are free slots in static early-boot cache array */ /* Create new ACPI table cache entry */
if(CacheCount >= ACPI_MAX_CACHED_TABLES) AcpiCache = CONTAIN_RECORD(AcpiTable, ACPI_CACHE_LIST, Header);
{
/* Cache is full, the table is mapped but not cached */
return;
}
/* Get the next available static cache entry */
AcpiCache = &CacheEntries[CacheCount];
CacheCount++;
/* Store the pointer to the mapped ACPI table */
AcpiCache->Table = AcpiTable;
/* Insert entry into the global ACPI cache list */
RTL::LinkedList::InsertTailList(&CacheList, &AcpiCache->ListEntry); RTL::LinkedList::InsertTailList(&CacheList, &AcpiCache->ListEntry);
} }
@@ -105,46 +91,6 @@ HL::Acpi::GetAcpiTable(IN ULONG Signature,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
/**
* Retrieves the ACPI timer information.
*
* @param AcpiTimerInfo
* Supplies a pointer to memory area, where ACPI timer information will be stored.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HL::Acpi::GetAcpiTimerInfo(OUT PACPI_TIMER_INFO *AcpiTimerInfo)
{
/* Check if ACPI timer info is available */
if(AcpiTimerInfo)
{
/* Return ACPI timer info */
*AcpiTimerInfo = &TimerInfo;
}
}
/**
* Gets the ACPI system information structure containing processor and topology data.
*
* @param SystemInfo
* Supplies a pointer to the memory area where the pointer to the system information structure will be stored.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HL::Acpi::GetSystemInformation(OUT PACPI_SYSTEM_INFO *SystemInfo)
{
/* Return a pointer to the ACPI system information */
*SystemInfo = &HL::Acpi::SystemInfo;
}
/** /**
* Performs an initialization of the ACPI subsystem. * Performs an initialization of the ACPI subsystem.
* *
@@ -250,23 +196,14 @@ HL::Acpi::InitializeAcpiSystemDescriptionTable(OUT PACPI_DESCRIPTION_HEADER *Acp
AcpiResource = (PSYSTEM_RESOURCE_ACPI)ResourceHeader; AcpiResource = (PSYSTEM_RESOURCE_ACPI)ResourceHeader;
RsdpAddress.QuadPart = (LONGLONG)AcpiResource->Header.PhysicalAddress; RsdpAddress.QuadPart = (LONGLONG)AcpiResource->Header.PhysicalAddress;
/* Map RSDP using hardware memory pool */ /* Map RSDP and mark it as CD/WT to avoid delays in write-back cache */
Status = MM::HardwarePool::MapHardwareMemory(RsdpAddress, 1, TRUE, (PVOID *)&RsdpStructure); Status = MM::HardwarePool::MapHardwareMemory(RsdpAddress, 1, TRUE, (PVOID *)&RsdpStructure);
if(Status != STATUS_SUCCESS)
{
/* Failed to map RSDP, return error */
return Status;
}
/* Mark RSDP as CD/WT to avoid delays in write-back cache */
MM::HardwarePool::MarkHardwareMemoryWriteThrough(RsdpStructure, 1); MM::HardwarePool::MarkHardwareMemoryWriteThrough(RsdpStructure, 1);
/* Validate RSDP signature */ /* Validate RSDP signature */
if(RsdpStructure->Signature != ACPI_RSDP_SIGNATURE) if(Status != STATUS_SUCCESS || RsdpStructure->Signature != ACPI_RSDP_SIGNATURE)
{ {
/* Invalid RSDP signature, unmap and return error */ /* Not mapped correctly or invalid RSDP signature, return error */
MM::HardwarePool::UnmapHardwareMemory(RsdpStructure, 1, TRUE);
RsdpStructure = NULLPTR;
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
@@ -282,40 +219,34 @@ HL::Acpi::InitializeAcpiSystemDescriptionTable(OUT PACPI_DESCRIPTION_HEADER *Acp
RsdtAddress.QuadPart = (LONGLONG)RsdpStructure->RsdtAddress; RsdtAddress.QuadPart = (LONGLONG)RsdpStructure->RsdtAddress;
} }
/* Map RSDT/XSDT using hardware memory pool */ /* Map RSDT/XSDT as CD/WT */
Status = MM::HardwarePool::MapHardwareMemory(RsdtAddress, 2, TRUE, (PVOID *)&Rsdt); Status = MM::HardwarePool::MapHardwareMemory(RsdtAddress, 2, TRUE, (PVOID *)&Rsdt);
if(Status != STATUS_SUCCESS)
{
/* Failed to map RSDT/XSDT, return error */
return Status;
}
/* Mark RSDT/XSDT as CD/WT */
MM::HardwarePool::MarkHardwareMemoryWriteThrough(Rsdt, 2); MM::HardwarePool::MarkHardwareMemoryWriteThrough(Rsdt, 2);
/* Validate RSDT/XSDT signature */ /* Validate RSDT/XSDT signature */
if(Rsdt->Header.Signature != ACPI_RSDT_SIGNATURE && Rsdt->Header.Signature != ACPI_XSDT_SIGNATURE) if((Status != STATUS_SUCCESS) ||
(Rsdt->Header.Signature != ACPI_RSDT_SIGNATURE &&
Rsdt->Header.Signature != ACPI_XSDT_SIGNATURE))
{ {
/* Not mapped correctly or invalid RSDT/XSDT signature, unmap and return error */ /* Not mapped correctly or invalid RSDT/XSDT signature, return error */
MM::HardwarePool::UnmapHardwareMemory(Rsdt, 2, TRUE);
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
/* Calculate the length of all available ACPI tables and remap it if needed */ /* Calculate the length of all available ACPI tables and remap it if needed */
RsdtPages = (((RsdtAddress.LowPart & (MM_PAGE_SIZE - 1)) + Rsdt->Header.Length + (MM_PAGE_SIZE - 1)) >> MM_PAGE_SHIFT); RsdtPages = ((RsdtAddress.LowPart & (MM_PAGE_SIZE - 1)) + Rsdt->Header.Length + (MM_PAGE_SIZE - 1)) >> MM_PAGE_SHIFT;
if(RsdtPages != 2) if(RsdtPages != 2)
{ {
/* RSDT/XSDT needs less or more than 2 pages, remap it */ /* RSDT/XSDT needs less or more than 2 pages, remap it */
MM::HardwarePool::UnmapHardwareMemory(Rsdt, 2, TRUE); MM::HardwarePool::UnmapHardwareMemory(Rsdt, 2, TRUE);
Status = MM::HardwarePool::MapHardwareMemory(RsdtAddress, RsdtPages, TRUE, (PVOID *)&Rsdt); Status = MM::HardwarePool::MapHardwareMemory(RsdtAddress, RsdtPages, TRUE, (PVOID *)&Rsdt);
MM::HardwarePool::MarkHardwareMemoryWriteThrough(Rsdt, RsdtPages);
/* Make sure remapping was successful */
if(Status != STATUS_SUCCESS) if(Status != STATUS_SUCCESS)
{ {
/* Remapping failed, return error */ /* Remapping failed, return error */
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
/* Mark remapped RSDT/XSDT as CD/WT */
MM::HardwarePool::MarkHardwareMemoryWriteThrough(Rsdt, RsdtPages);
} }
/* Get ACPI table header and return success */ /* Get ACPI table header and return success */
@@ -336,7 +267,6 @@ HL::Acpi::InitializeAcpiSystemInformation(VOID)
{ {
PACPI_MADT_LOCAL_X2APIC LocalX2Apic; PACPI_MADT_LOCAL_X2APIC LocalX2Apic;
PACPI_MADT_LOCAL_APIC LocalApic; PACPI_MADT_LOCAL_APIC LocalApic;
PACPI_SUBTABLE_HEADER SubTable;
ULONG_PTR MadtTable; ULONG_PTR MadtTable;
PACPI_MADT Madt; PACPI_MADT Madt;
XTSTATUS Status; XTSTATUS Status;
@@ -363,20 +293,11 @@ HL::Acpi::InitializeAcpiSystemInformation(VOID)
CpuCount = 0; CpuCount = 0;
/* Traverse all MADT tables to get system information */ /* Traverse all MADT tables to get system information */
while(MadtTable < ((ULONG_PTR)Madt + Madt->Header.Length)) while(MadtTable <= ((ULONG_PTR)Madt + Madt->Header.Length))
{ {
/* Get current MADT subtable header */
SubTable = (PACPI_SUBTABLE_HEADER)MadtTable;
/* Prevent infinite loops if BIOS provides 0 length */
if(SubTable->Length == 0)
{
/* Broken ACPI table, abort traversal */
break;
}
/* Check if this is a local APIC subtable */ /* Check if this is a local APIC subtable */
if(SubTable->Type == ACPI_MADT_TYPE_LOCAL_APIC && SubTable->Length >= sizeof(ACPI_MADT_LOCAL_APIC)) if((((PACPI_SUBTABLE_HEADER)MadtTable)->Type == ACPI_MADT_TYPE_LOCAL_APIC) &&
(((PACPI_SUBTABLE_HEADER)MadtTable)->Length == sizeof(ACPI_MADT_LOCAL_APIC)))
{ {
/* Get local APIC subtable */ /* Get local APIC subtable */
LocalApic = (PACPI_MADT_LOCAL_APIC)MadtTable; LocalApic = (PACPI_MADT_LOCAL_APIC)MadtTable;
@@ -392,8 +313,12 @@ HL::Acpi::InitializeAcpiSystemInformation(VOID)
/* Increment number of CPUs */ /* Increment number of CPUs */
CpuCount++; CpuCount++;
} }
/* Go to the next MADT table */
MadtTable += ((PACPI_SUBTABLE_HEADER)MadtTable)->Length;
} }
else if(SubTable->Type == ACPI_MADT_TYPE_LOCAL_X2APIC && SubTable->Length >= sizeof(ACPI_MADT_LOCAL_X2APIC)) else if((((PACPI_SUBTABLE_HEADER)MadtTable)->Type == ACPI_MADT_TYPE_LOCAL_X2APIC) &&
(((PACPI_SUBTABLE_HEADER)MadtTable)->Length == sizeof(ACPI_MADT_LOCAL_X2APIC)))
{ {
/* Get local X2APIC subtable */ /* Get local X2APIC subtable */
LocalX2Apic = (PACPI_MADT_LOCAL_X2APIC)MadtTable; LocalX2Apic = (PACPI_MADT_LOCAL_X2APIC)MadtTable;
@@ -409,10 +334,15 @@ HL::Acpi::InitializeAcpiSystemInformation(VOID)
/* Increment number of CPUs */ /* Increment number of CPUs */
CpuCount++; CpuCount++;
} }
}
/* Safely advance pointer using proper subtable length */ /* Go to the next MADT table */
MadtTable += SubTable->Length; MadtTable += ((PACPI_SUBTABLE_HEADER)MadtTable)->Length;
}
else
{
/* Any other MADT table, try to go to the next one byte-by-byte */
MadtTable += 1;
}
} }
/* Store number of CPUs */ /* Store number of CPUs */
@@ -434,7 +364,6 @@ XTSTATUS
HL::Acpi::InitializeAcpiSystemStructure(VOID) HL::Acpi::InitializeAcpiSystemStructure(VOID)
{ {
PHYSICAL_ADDRESS PhysicalAddress; PHYSICAL_ADDRESS PhysicalAddress;
PACPI_SUBTABLE_HEADER SubTable;
PFN_NUMBER PageCount; PFN_NUMBER PageCount;
ULONG_PTR MadtTable; ULONG_PTR MadtTable;
PACPI_MADT Madt; PACPI_MADT Madt;
@@ -454,19 +383,11 @@ HL::Acpi::InitializeAcpiSystemStructure(VOID)
CpuCount = 0; CpuCount = 0;
/* Traverse all MADT tables to get number of processors */ /* Traverse all MADT tables to get number of processors */
while(MadtTable < ((ULONG_PTR)Madt + Madt->Header.Length)) while(MadtTable <= ((ULONG_PTR)Madt + Madt->Header.Length))
{ {
SubTable = (PACPI_SUBTABLE_HEADER)MadtTable;
/* Prevent infinite loops if BIOS provides 0 length */
if(SubTable->Length == 0)
{
/* Broken ACPI table, abort traversal */
break;
}
/* Check if this is a local APIC subtable */ /* Check if this is a local APIC subtable */
if(SubTable->Type == ACPI_MADT_TYPE_LOCAL_APIC && SubTable->Length >= sizeof(ACPI_MADT_LOCAL_APIC)) if((((PACPI_SUBTABLE_HEADER)MadtTable)->Type == ACPI_MADT_TYPE_LOCAL_APIC) &&
(((PACPI_SUBTABLE_HEADER)MadtTable)->Length == sizeof(ACPI_MADT_LOCAL_APIC)))
{ {
/* Make sure, this CPU can be enabled */ /* Make sure, this CPU can be enabled */
if(((PACPI_MADT_LOCAL_APIC)MadtTable)->Flags & ACPI_MADT_PLAOC_ENABLED) if(((PACPI_MADT_LOCAL_APIC)MadtTable)->Flags & ACPI_MADT_PLAOC_ENABLED)
@@ -474,8 +395,12 @@ HL::Acpi::InitializeAcpiSystemStructure(VOID)
/* Increment number of CPUs */ /* Increment number of CPUs */
CpuCount++; CpuCount++;
} }
/* Go to the next MADT table */
MadtTable += ((PACPI_SUBTABLE_HEADER)MadtTable)->Length;
} }
else if(SubTable->Type == ACPI_MADT_TYPE_LOCAL_X2APIC && SubTable->Length >= sizeof(ACPI_MADT_LOCAL_X2APIC)) else if((((PACPI_SUBTABLE_HEADER)MadtTable)->Type == ACPI_MADT_TYPE_LOCAL_X2APIC) &&
(((PACPI_SUBTABLE_HEADER)MadtTable)->Length == sizeof(ACPI_MADT_LOCAL_X2APIC)))
{ {
/* Make sure, this CPU can be enabled */ /* Make sure, this CPU can be enabled */
if(((PACPI_MADT_LOCAL_X2APIC)MadtTable)->Flags & ACPI_MADT_PLAOC_ENABLED) if(((PACPI_MADT_LOCAL_X2APIC)MadtTable)->Flags & ACPI_MADT_PLAOC_ENABLED)
@@ -483,10 +408,15 @@ HL::Acpi::InitializeAcpiSystemStructure(VOID)
/* Increment number of CPUs */ /* Increment number of CPUs */
CpuCount++; CpuCount++;
} }
}
/* Safely advance pointer using proper subtable length */ /* Go to the next MADT table */
MadtTable += SubTable->Length; MadtTable += ((PACPI_SUBTABLE_HEADER)MadtTable)->Length;
}
else
{
/* Any other MADT table, try to go to the next one byte-by-byte */
MadtTable += 1;
}
} }
/* Zero the ACPI system information structure */ /* Zero the ACPI system information structure */
@@ -496,7 +426,7 @@ HL::Acpi::InitializeAcpiSystemStructure(VOID)
PageCount = SIZE_TO_PAGES(CpuCount * sizeof(PROCESSOR_IDENTITY)); PageCount = SIZE_TO_PAGES(CpuCount * sizeof(PROCESSOR_IDENTITY));
/* Allocate memory for CPU information */ /* Allocate memory for CPU information */
Status = MM::HardwarePool::AllocateHardwareMemory(PageCount, TRUE, MM_MAXIMUM_PHYSICAL_ADDRESS, &PhysicalAddress); Status = MM::HardwarePool::AllocateHardwareMemory(PageCount, TRUE, &PhysicalAddress);
if(Status != STATUS_SUCCESS) if(Status != STATUS_SUCCESS)
{ {
/* Failed to allocate memory, return error */ /* Failed to allocate memory, return error */
@@ -592,10 +522,10 @@ HL::Acpi::QueryAcpiCache(IN ULONG Signature,
AcpiCache = CONTAIN_RECORD(ListEntry, ACPI_CACHE_LIST, ListEntry); AcpiCache = CONTAIN_RECORD(ListEntry, ACPI_CACHE_LIST, ListEntry);
/* Check if ACPI table signature matches */ /* Check if ACPI table signature matches */
if(AcpiCache->Table->Signature == Signature) if(AcpiCache->Header.Signature == Signature)
{ {
/* ACPI table found in cache, return it */ /* ACPI table found in cache, return it */
TableHeader = AcpiCache->Table; TableHeader = &AcpiCache->Header;
break; break;
} }
@@ -666,30 +596,17 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
/* Check if DSDT or FACS table requested */ /* Check if DSDT or FACS table requested */
if(Signature == ACPI_DSDT_SIGNATURE) if(Signature == ACPI_DSDT_SIGNATURE)
{ {
/* Prefer 64-bit address on ACPI 2.0+ */ /* Get DSDT address */
if(Fadt->Header.Revision >= 2 && Fadt->XDsdt.QuadPart != 0)
{
TableAddress.QuadPart = Fadt->XDsdt.QuadPart;
}
else
{
TableAddress.LowPart = Fadt->Dsdt; TableAddress.LowPart = Fadt->Dsdt;
TableAddress.HighPart = 0;
}
}
else
{
/* Prefer 64-bit address on ACPI 2.0+ */
if(Fadt->Header.Revision >= 2 && Fadt->XFirmwareCtrl.QuadPart != 0)
{
TableAddress.QuadPart = Fadt->XFirmwareCtrl.QuadPart;
} }
else else
{ {
/* Get FACS address */
TableAddress.LowPart = Fadt->FirmwareCtrl; TableAddress.LowPart = Fadt->FirmwareCtrl;
}
/* Fill in high part of ACPI table address */
TableAddress.HighPart = 0; TableAddress.HighPart = 0;
}
}
/* Map table using hardware memory pool */ /* Map table using hardware memory pool */
Status = MM::HardwarePool::MapHardwareMemory(TableAddress, 2, TRUE, (PVOID*)&TableHeader); Status = MM::HardwarePool::MapHardwareMemory(TableAddress, 2, TRUE, (PVOID*)&TableHeader);
@@ -701,12 +618,11 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
} }
else else
{ {
/* Query cache for XSDT table */ /* Query cache for XSDP table */
Status = QueryAcpiCache(ACPI_XSDT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Xsdt); Status = QueryAcpiCache(ACPI_XSDT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Xsdt);
if(Status != STATUS_SUCCESS) if(Status != STATUS_SUCCESS)
{ {
/* XSDT not found, query cache for RSDT table */ /* XSDP not found, query cache for RSDP table */
Xsdt = NULLPTR;
Status = QueryAcpiCache(ACPI_RSDT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Rsdt); Status = QueryAcpiCache(ACPI_RSDT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Rsdt);
} }
@@ -717,22 +633,22 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
return Status; return Status;
} }
/* Get table count depending on root table type securely */ /* Get table count depending on root table type */
if(Xsdt != NULLPTR) if(Xsdt != NULLPTR)
{ {
if(Xsdt->Header.Length < sizeof(ACPI_DESCRIPTION_HEADER)) return STATUS_INVALID_PARAMETER; /* Get table count from XSDT */
TableCount = (Xsdt->Header.Length - sizeof(ACPI_DESCRIPTION_HEADER)) / 8; TableCount = (Xsdt->Header.Length - sizeof(ACPI_DESCRIPTION_HEADER)) / 8;
} }
else else
{ {
if(Rsdt->Header.Length < sizeof(ACPI_DESCRIPTION_HEADER)) return STATUS_INVALID_PARAMETER; /* Get table count from RSDT */
TableCount = (Rsdt->Header.Length - sizeof(ACPI_DESCRIPTION_HEADER)) / 4; TableCount = (Rsdt->Header.Length - sizeof(ACPI_DESCRIPTION_HEADER)) / 4;
} }
/* Iterate over all ACPI tables */ /* Iterate over all ACPI tables */
for(TableIndex = 0; TableIndex < TableCount; TableIndex++) for(TableIndex = 0; TableIndex < TableCount; TableIndex++)
{ {
/* Check if XSDT or RSDT is used */ /* Check if XSDP or RSDT is used */
if(Xsdt != NULLPTR) if(Xsdt != NULLPTR)
{ {
/* Get table header physical address from XSDT */ /* Get table header physical address from XSDT */
@@ -745,6 +661,13 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
TableAddress.HighPart = 0; TableAddress.HighPart = 0;
} }
/* Check whether some table is already mapped */
if(TableHeader != NULLPTR)
{
/* Unmap previous table */
MM::HardwarePool::UnmapHardwareMemory(TableHeader, 2, TRUE);
}
/* Map table using hardware memory pool */ /* Map table using hardware memory pool */
Status = MM::HardwarePool::MapHardwareMemory(TableAddress, 2, TRUE, (PVOID*)&TableHeader); Status = MM::HardwarePool::MapHardwareMemory(TableAddress, 2, TRUE, (PVOID*)&TableHeader);
if(Status != STATUS_SUCCESS) if(Status != STATUS_SUCCESS)
@@ -759,31 +682,25 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
/* Found requested ACPI table */ /* Found requested ACPI table */
break; break;
} }
/* Unmap non-matching table and try next one */
MM::HardwarePool::UnmapHardwareMemory(TableHeader, 2, TRUE);
TableHeader = NULLPTR;
} }
} }
/* Ensure the table was actually found and mapped */ /* Make sure table was found */
if(TableHeader == NULLPTR)
{
/* ACPI table not found, return error */
return STATUS_NOT_FOUND;
}
/* Check if we broke out of the loop with the wrong table (safety check) */
if(TableHeader->Signature != Signature) if(TableHeader->Signature != Signature)
{ {
/* Unmap non-matching ACPI table and return error */ /* ACPI table not found, check if cleanup is needed */
if(TableHeader != NULLPTR)
{
/* Unmap non-matching ACPI table */
MM::HardwarePool::UnmapHardwareMemory(TableHeader, 2, TRUE); MM::HardwarePool::UnmapHardwareMemory(TableHeader, 2, TRUE);
}
/* Return error */
return STATUS_NOT_FOUND; return STATUS_NOT_FOUND;
} }
/* Don't validate FACS and FADT on old, broken firmwares with ACPI 2.0 or older */ /* Don't validate FADT on old, broken firmwares with ACPI 2.0 or older */
if((TableHeader->Signature != ACPI_FADT_SIGNATURE || TableHeader->Revision > 2) && if(TableHeader->Signature != ACPI_FADT_SIGNATURE || TableHeader->Revision > 2)
(TableHeader->Signature != ACPI_FACS_SIGNATURE))
{ {
/* Validate table checksum */ /* Validate table checksum */
if(!ValidateAcpiTable(TableHeader, TableHeader->Length)) if(!ValidateAcpiTable(TableHeader, TableHeader->Length))
@@ -795,7 +712,7 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
} }
/* Calculate the length of ACPI table and remap it if needed */ /* Calculate the length of ACPI table and remap it if needed */
TablePages = (((TableAddress.LowPart & (MM_PAGE_SIZE - 1)) + TableHeader->Length + (MM_PAGE_SIZE - 1)) >> MM_PAGE_SHIFT); TablePages = (((ULONG_PTR)TableHeader & (MM_PAGE_SIZE - 1)) + TableHeader->Length + (MM_PAGE_SIZE - 1)) >> MM_PAGE_SHIFT;
if(TablePages != 2) if(TablePages != 2)
{ {
/* ACPI table needs less or more than 2 pages, remap it */ /* ACPI table needs less or more than 2 pages, remap it */

View File

@@ -1,13 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/hl/amd64/firmware.cc
* DESCRIPTION: UEFI/BIOS Firmware support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
/* Include common Firmware interface */
#include ARCH_COMMON(firmware.cc)

View File

@@ -1,260 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/hl/amd64/irq.cc
* DESCRIPTION: Interrupts support for AMD64 architecture
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
/**
* Begins a system interrupt handler by raising the processor's run level and re-enabling
* hardware interrupts to allow preemption by higher-priority events.
*
* @param RunLevel
* Supplies the target run level to raise the processor to.
*
* @param OldRunLevel
* Receives the previous run level before the elevation.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HL::Irq::BeginSystemInterrupt(IN KRUNLEVEL RunLevel,
OUT PKRUNLEVEL OldRunLevel)
{
/* Get the current IRQL */
*OldRunLevel = KE::RunLevel::GetCurrentRunLevel();
/* Raise run level */
KE::RunLevel::RaiseRunLevel(RunLevel);
/* Enable interrupts */
AR::CpuFunc::SetInterruptFlag();
}
/**
* Safely concludes an interrupt handler by disabling hardware interrupts.
*
* @param TrapFrame
* Supplies a pointer to the kernel trap frame containing the interrupted execution state.
*
* @param OldRunLevel
* Supplies the previous run level to restore.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HL::Irq::EndInterrupt(IN PKTRAP_FRAME TrapFrame,
IN KRUNLEVEL OldRunLevel)
{
/* Disable interrupts */
AR::CpuFunc::ClearInterruptFlag();
/* End system interrupt */
EndSystemInterrupt(TrapFrame, OldRunLevel);
}
/**
* Concludes a system interrupt by sending an End of Interrupt (EOI) to the hardware
* controller and restoring the processor's previous run level.
*
* @param TrapFrame
* Supplies a pointer to the kernel trap frame containing the interrupted execution state.
*
* @param OldRunLevel
* Supplies the previous run level to restore.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HL::Irq::EndSystemInterrupt(IN PKTRAP_FRAME TrapFrame,
IN KRUNLEVEL OldRunLevel)
{
/* Send EOI */
HL::Pic::SendEoi();
/* Restore previous run level */
KE::RunLevel::LowerRunLevel(OldRunLevel);
}
/**
* Handles profiling interrupt.
*
* @param TrapFrame
* Supplies a kernel trap frame pushed by common interrupt handler.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
HL::Irq::HandleProfileInterrupt(IN PKTRAP_FRAME TrapFrame)
{
/* Send EOI */
HL::Pic::SendEoi();
}
/**
* Handles unexpected or unmapped system interrupts.
*
* @param TrapFrame
* Supplies a kernel trap frame pushed by common interrupt handler.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
HL::Irq::HandleUnexpectedInterrupt(IN PKTRAP_FRAME TrapFrame)
{
UNIMPLEMENTED;
/* Disable interrupts */
AR::CpuFunc::ClearInterruptFlag();
/* Print debug message and raise kernel panic */
DebugPrint(L"ERROR: Caught unexpected interrupt (0x%.2llX)!\n", TrapFrame->Vector);
KE::Crash::Panic(0x47, TrapFrame->Vector, 0, 0, 0);
}
/**
* Returns the registered interrupt handler for the specified IDT vector.
*
* @param Vector
* Supplies the interrupt vector number.
*
* @return This routine returns the pointer to the IDT interrupt handler routine.
*
* @since XT 1.0
*/
XTAPI
PVOID
HL::Irq::QueryInterruptHandler(IN ULONG Vector)
{
PKPROCESSOR_BLOCK ProcessorBlock;
PKIDTENTRY IdtEntry;
/* Get current processor block and IDT entry */
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
IdtEntry = &ProcessorBlock->IdtBase[Vector];
/* Return address of the interrupt handler */
return (PVOID)((ULONGLONG)IdtEntry->OffsetHigh << 32 |
(ULONGLONG)IdtEntry->OffsetMiddle << 16 |
(ULONGLONG)IdtEntry->OffsetLow);
}
/**
* Returns the registered interrupt handler for the specified vector.
*
* @param Vector
* Supplies the interrupt vector number.
*
* @return This routine returns the pointer to the interrupt handler routine.
*
* @since XT 1.0
*/
XTAPI
PVOID
HL::Irq::QuerySystemInterruptHandler(IN ULONG Vector)
{
PKPROCESSOR_BLOCK ProcessorBlock;
/* Get current processor block */
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
return (PVOID)ProcessorBlock->InterruptDispatchTable[Vector];
}
/**
* Registers new interrupt handler for the existing IDT entry.
*
* @param HalVector
* Supplies the interrupt vector number.
*
* @param Handler
* Supplies the pointer to the interrupt handler routine.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HL::Irq::RegisterInterruptHandler(IN ULONG Vector,
IN PVOID Handler)
{
PKPROCESSOR_BLOCK ProcessorBlock;
/* Get current processor block */
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
/* Update interrupt handler */
AR::ProcSup::SetIdtGate(ProcessorBlock->IdtBase,
Vector,
Handler,
KGDT_R0_CODE,
0,
KIDT_ACCESS_RING0,
AMD64_INTERRUPT_GATE);
}
/**
* Registers the interrupt handler for the specified vector.
*
* @param HalVector
* Supplies the interrupt vector number.
*
* @param Handler
* Supplies the pointer to the interrupt handler routine.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HL::Irq::RegisterSystemInterruptHandler(IN ULONG Vector,
IN PINTERRUPT_HANDLER Handler)
{
PKPROCESSOR_BLOCK ProcessorBlock;
/* Get current processor block */
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
/* Update interrupt handler in the processor's interrupt dispatch table */
ProcessorBlock->InterruptDispatchTable[Vector] = Handler;
}
/**
* Requests a software interrupt by sending a Self-IPI mapped to the specified run level.
*
* @param RunLevel
* Supplies the target run level for the software interrupt.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTFASTCALL
VOID
HL::Irq::SendSoftwareInterrupt(IN KRUNLEVEL RunLevel)
{
/* Request a software interrupt */
HL::Pic::SendSelfIpi(HL::RunLevel::TransformRunLevelToSoftwareVector(RunLevel));
}

View File

@@ -1,13 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/hl/amd64/rtc.cc
* DESCRIPTION: Hardware Real-Time Clock (RTC) support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
/* Include common RTC interface */
#include ARCH_COMMON(rtc.cc)

View File

@@ -20,7 +20,6 @@ XTFASTCALL
KRUNLEVEL KRUNLEVEL
HL::RunLevel::GetRunLevel(VOID) HL::RunLevel::GetRunLevel(VOID)
{ {
/* Read current run level */
return (KRUNLEVEL)AR::CpuFunc::ReadControlRegister(8); return (KRUNLEVEL)AR::CpuFunc::ReadControlRegister(8);
} }
@@ -38,7 +37,6 @@ XTFASTCALL
VOID VOID
HL::RunLevel::SetRunLevel(IN KRUNLEVEL RunLevel) HL::RunLevel::SetRunLevel(IN KRUNLEVEL RunLevel)
{ {
/* Set new run level */
AR::CpuFunc::WriteControlRegister(8, RunLevel); AR::CpuFunc::WriteControlRegister(8, RunLevel);
} }
@@ -56,7 +54,6 @@ XTFASTCALL
KRUNLEVEL KRUNLEVEL
HL::RunLevel::TransformApicTprToRunLevel(IN UCHAR Tpr) HL::RunLevel::TransformApicTprToRunLevel(IN UCHAR Tpr)
{ {
/* Transform APIC TPR to run level */
return (KRUNLEVEL)(Tpr >> 4); return (KRUNLEVEL)(Tpr >> 4);
} }
@@ -74,25 +71,5 @@ XTFASTCALL
UCHAR UCHAR
HL::RunLevel::TransformRunLevelToApicTpr(IN KRUNLEVEL RunLevel) HL::RunLevel::TransformRunLevelToApicTpr(IN KRUNLEVEL RunLevel)
{ {
/* Transform run level to APIC TPR */
return (RunLevel << 4); return (RunLevel << 4);
} }
/**
* Transforms a given execution run level into a corresponding hardware interrupt vector
* suitable for software interrupts.
*
* @param RunLevel
* Supplies the run level to be translated into a software interrupt vector.
*
* @return This routine returns the 8-bit APIC vector corresponding to the requested software interrupt level.
*
* @since XT 1.0
*/
XTFASTCALL
UCHAR
HL::RunLevel::TransformRunLevelToSoftwareVector(IN KRUNLEVEL RunLevel)
{
/* Transform run level to APIC interrupt vector */
return TransformRunLevelToApicTpr(RunLevel) | 0xF;
}

View File

@@ -1,13 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/hl/amd64/timer.cc
* DESCRIPTION: Timer support for AMD64
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
/* Include common Timer interface */
#include ARCH_COMMON(timer.cc)

View File

@@ -9,104 +9,26 @@
#include <xtos.hh> #include <xtos.hh>
/* Tracks the total number of currently cached ACPI tables */ /* ACPI tables cache list */
ULONG HL::Acpi::CacheCount = 0;
/* Array holding the cached ACPI tables */
ACPI_CACHE_LIST HL::Acpi::CacheEntries[ACPI_MAX_CACHED_TABLES];
/* Head of the linked list tracking dynamically mapped ACPI tables */
LIST_ENTRY HL::Acpi::CacheList; LIST_ENTRY HL::Acpi::CacheList;
/* Pointer to the ACPI Root System Description Pointer (RSDP) */ /* ACPI Root System Description Pointer (RSDP) */
PACPI_RSDP HL::Acpi::RsdpStructure; PACPI_RSDP HL::Acpi::RsdpStructure;
/* Global architectural system states and hardware feature flags parsed from the ACPI tables */ /* System information */
ACPI_SYSTEM_INFO HL::Acpi::SystemInfo; ACPI_SYSTEM_INFO HL::Acpi::SystemInfo;
/* Hardware configuration details and port addresses for the ACPI Power Management Timer */ /* ACPI timer information */
ACPI_TIMER_INFO HL::Acpi::TimerInfo; ACPI_TIMER_INFO HL::Acpi::TimerInfo;
/* Represents the number of active processors */ /* Active processors count */
KAFFINITY HL::Cpu::ActiveProcessors; KAFFINITY HL::Cpu::ActiveProcessors;
/* Metadata detailing the linear frame buffer geometry */ /* FrameBuffer information */
HL_FRAMEBUFFER_DATA HL::FrameBuffer::FrameBufferData; HL_FRAMEBUFFER_DATA HL::FrameBuffer::FrameBufferData;
/* Pointer to the RAM shadow buffer used for double-buffered rendering */ /* Scroll region information */
PVOID HL::FrameBuffer::ScreenShadowBuffer;
/* Tracks the bounding box, dimensions, and cursor position for the kernel video console */
HL_SCROLL_REGION_DATA HL::FrameBuffer::ScrollRegionData; HL_SCROLL_REGION_DATA HL::FrameBuffer::ScrollRegionData;
/* Indicates the active hardware interrupt controller mode */ /* APIC mode */
APIC_MODE HL::Pic::ApicMode; APIC_MODE HL::Pic::ApicMode;
/* Total number of I/O APIC chips discovered and initialized */
ULONG HL::Pic::ControllerCount;
/* Array containing MMIO bases, IDs, and line counts for all I/O APICs */
IOAPIC_DATA HL::Pic::Controllers[IOAPIC_MAX_CONTROLLERS];
/* Total number of legacy ISA interrupt routing overrides */
ULONG HL::Pic::IrqOverrideCount;
/* Hardware routing definitions mapping legacy ISA interrupts to Global System Interrupts (GSI) */
ACPI_MADT_INTERRUPT_OVERRIDE HL::Pic::IrqOverrides[IOAPIC_MAX_OVERRIDES];
/* Lookup table mapping allocated hardware APIC vectors to their assigned Run Levels */
UCHAR HL::Pic::MappedVectors[256];
/* Accumulated tick value of the ACPI Power Management Timer */
ULONG HL::Timer::AcpiPmPerformanceCounter = 0;
/* Primary hardware timer driving the periodic system clock interrupt */
TIMER_TYPE HL::Timer::ClockType;
/* Fractional remainder used to maintain long-term system clock accuracy */
ULONG HL::Timer::FractionalIncrement = 0;
/* Virtual address mapped to the HPET hardware MMIO registers */
PVOID HL::Timer::HpetAddress = NULLPTR;
/* Operating frequency of the High Precision Event Timer in ticks per second */
ULONGLONG HL::Timer::HpetFrequency = 0;
/* Spinlock protecting concurrent multiprocessor access to the global performance counters */
KSPIN_LOCK HL::Timer::PerformanceCounterLock;
/* The performance counter frequency in ticks per second */
ULONGLONG HL::Timer::PerformanceFrequency = 0;
/* Absolute monotonic tick count driven by the legacy Programmable Interval Timer */
ULONGLONG HL::Timer::PitPerformanceCounter;
/* Programmed hardware divider interval used to increment the PIT performance counter */
ULONG HL::Timer::PitRollover;
/* Flag indicating whether statistical system execution profiling is currently active */
BOOLEAN HL::Timer::ProfilingEnabled = FALSE;
/* Tick interval required to trigger a profile interrupt */
ULONG HL::Timer::ProfilingTicks;
/* Global accumulator for fractional time drift and precision compensation */
ULONG HL::Timer::RunningFraction = 0;
/* System counter driven by the highest precision available hardware */
ULONGLONG HL::Timer::SystemPerformanceCounter;
/* Current base clock increment in standard 100-nanosecond intervals */
ULONG HL::Timer::TimeIncrement = 0;
/* Timer capabilities */
TIMER_CAPABILITIES HL::Timer::TimerCapabilities = {0};
/* APIC timer frequency */
ULONG HL::Timer::TimerFrequency;
/* Function dispatch table for the active hardware timer backend */
TIMER_ROUTINES HL::Timer::TimerRoutines = {0};
/* Identifies the hardware timer backing */
TIMER_TYPE HL::Timer::TimerType;

View File

@@ -9,24 +9,6 @@
#include <xtos.hh> #include <xtos.hh>
/**
* Retrieves the current value of the high-resolution performance counter.
*
* @param PerformanceFrequency
* Suplies an optional pointer to a variable that receives the performance counter frequency in Hz.
*
* @return This routine returns the current 64-bit monotonic tick count.
*
* @since XT 1.0
*/
XTCLINK
XTAPI
LARGE_INTEGER
HlQueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceFrequency)
{
return HL::Timer::QueryPerformanceCounter(PerformanceFrequency);
}
/** /**
* Reads the 8-bit data from the specified I/O port. * Reads the 8-bit data from the specified I/O port.
* *
@@ -135,24 +117,6 @@ HlReadRegister32(IN PVOID Register)
return HL::IoRegister::ReadRegister32(Register); return HL::IoRegister::ReadRegister32(Register);
} }
/**
* Requests a dynamic adjustment of the system clock resolution.
*
* @param Rate
* The requested clock rate change in 100-nanosecond units.
*
* @return This routine returns the actual clock rate granted by the hardware.
*
* @since XT 1.0
*/
XTCLINK
XTAPI
ULONG
HlSetClockRate(IN ULONG Rate)
{
return HL::Timer::SetClockRate(Rate);
}
/** /**
* Writes the 8-bit data to the specified I/O port. * Writes the 8-bit data to the specified I/O port.
* *

View File

@@ -25,9 +25,10 @@ XTAPI
VOID VOID
HL::FrameBuffer::ClearScreen(IN ULONG Color) HL::FrameBuffer::ClearScreen(IN ULONG Color)
{ {
ULONG BackgroundColor, PositionY; ULONG PositionX, PositionY;
PCHAR CurrentLine, TargetBuffer; ULONG BackgroundColor;
UCHAR FillByte; PCHAR CurrentLine;
PULONG Pixel;
/* Make sure frame buffer is already initialized */ /* Make sure frame buffer is already initialized */
if(FrameBufferData.Initialized == FALSE) if(FrameBufferData.Initialized == FALSE)
@@ -36,29 +37,20 @@ HL::FrameBuffer::ClearScreen(IN ULONG Color)
return; return;
} }
/* Convert background color */ /* Convert background color and get pointer to frame buffer */
BackgroundColor = GetRGBColor(Color); BackgroundColor = GetRGBColor(Color);
CurrentLine = (PCHAR)FrameBufferData.Address;
/* Extract the lower byte for SetMemory */
FillByte = (UCHAR)(BackgroundColor & 0xFF);
/* Determine target buffer */
TargetBuffer = (ScreenShadowBuffer != NULLPTR) ? (PCHAR)ScreenShadowBuffer : (PCHAR)FrameBufferData.Address;
CurrentLine = TargetBuffer;
/* Fill the screen with the specified color */ /* Fill the screen with the specified color */
for(PositionY = 0; PositionY < FrameBufferData.Height; PositionY++, CurrentLine += FrameBufferData.Pitch) for(PositionY = 0; PositionY < FrameBufferData.Height; PositionY++, CurrentLine += FrameBufferData.Pitch)
{ {
/* Fill the current scanline with the background color byte */ /* Fill the current line with the specified color */
RTL::Memory::SetMemory(CurrentLine, FillByte, FrameBufferData.Width * FrameBufferData.BytesPerPixel); Pixel = (PULONG)CurrentLine;
} for(PositionX = 0; PositionX < FrameBufferData.Width; PositionX++)
/* Check if Shadow Buffer is active */
if(ScreenShadowBuffer != NULLPTR)
{ {
/* Flush changes to VRAM */ /* Set the color of the pixel */
RTL::Memory::CopyMemory(FrameBufferData.Address, ScreenShadowBuffer, Pixel[PositionX] = BackgroundColor;
FrameBufferData.Pitch * FrameBufferData.Height); }
} }
} }
@@ -76,9 +68,7 @@ XTCDECL
XTSTATUS XTSTATUS
HL::FrameBuffer::DisplayCharacter(IN WCHAR Character) HL::FrameBuffer::DisplayCharacter(IN WCHAR Character)
{ {
ULONG CharacterX, CharacterY;
PSSFN_FONT_HEADER FbFont; PSSFN_FONT_HEADER FbFont;
BOOLEAN VisibleCharacter;
/* Make sure frame buffer is already initialized */ /* Make sure frame buffer is already initialized */
if(FrameBufferData.Initialized == FALSE) if(FrameBufferData.Initialized == FALSE)
@@ -90,9 +80,6 @@ HL::FrameBuffer::DisplayCharacter(IN WCHAR Character)
/* Get font information */ /* Get font information */
FbFont = (PSSFN_FONT_HEADER)FrameBufferData.Font; FbFont = (PSSFN_FONT_HEADER)FrameBufferData.Font;
/* Assume invisible character */
VisibleCharacter = FALSE;
/* Handle special characters */ /* Handle special characters */
switch(Character) switch(Character)
{ {
@@ -104,20 +91,15 @@ HL::FrameBuffer::DisplayCharacter(IN WCHAR Character)
case L'\t': case L'\t':
/* Move cursor to the next tab stop */ /* Move cursor to the next tab stop */
ScrollRegionData.CursorX += (8 - (ScrollRegionData.CursorX - ScrollRegionData.Left) / FbFont->Width % 8) * FbFont->Width; ScrollRegionData.CursorX += (8 - (ScrollRegionData.CursorX - ScrollRegionData.Left) / FbFont->Width % 8) * FbFont->Width;
if(ScrollRegionData.CursorX >= ScrollRegionData.Right) if (ScrollRegionData.CursorX >= ScrollRegionData.Right)
{ {
ScrollRegionData.CursorX = ScrollRegionData.Left; ScrollRegionData.CursorX = ScrollRegionData.Left;
ScrollRegionData.CursorY += FbFont->Height; ScrollRegionData.CursorY += FbFont->Height;
} }
break; break;
default: default:
/* Save cursor position */ /* Draw the character */
CharacterX = ScrollRegionData.CursorX; DrawCharacter(ScrollRegionData.CursorX, ScrollRegionData.CursorY, ScrollRegionData.TextColor, Character);
CharacterY = ScrollRegionData.CursorY;
/* Draw the character to RAM and mark it as visible */
DrawCharacter(CharacterX, CharacterY, ScrollRegionData.TextColor, Character);
VisibleCharacter = TRUE;
/* Advance cursor */ /* Advance cursor */
ScrollRegionData.CursorX += FbFont->Width; ScrollRegionData.CursorX += FbFont->Width;
@@ -125,7 +107,6 @@ HL::FrameBuffer::DisplayCharacter(IN WCHAR Character)
/* Check if cursor reached end of line */ /* Check if cursor reached end of line */
if(ScrollRegionData.CursorX >= ScrollRegionData.Right) if(ScrollRegionData.CursorX >= ScrollRegionData.Right)
{ {
/* Reset cursor to the left margin and advance to the next line */
ScrollRegionData.CursorX = ScrollRegionData.Left; ScrollRegionData.CursorX = ScrollRegionData.Left;
ScrollRegionData.CursorY += FbFont->Height; ScrollRegionData.CursorY += FbFont->Height;
} }
@@ -139,13 +120,6 @@ HL::FrameBuffer::DisplayCharacter(IN WCHAR Character)
ScrollRegion(); ScrollRegion();
ScrollRegionData.CursorY = ScrollRegionData.Bottom - FbFont->Height; ScrollRegionData.CursorY = ScrollRegionData.Bottom - FbFont->Height;
} }
else if(VisibleCharacter == TRUE)
{
/* Flush visible character to VRAM */
UpdateScreenRegion(CharacterX, CharacterY,
CharacterX + FbFont->Width,
CharacterY + FbFont->Height);
}
/* Return success */ /* Return success */
return STATUS_SUCCESS; return STATUS_SUCCESS;
@@ -179,8 +153,9 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
{ {
UINT CurrentFragment, Glyph, GlyphLimit, Index, Line, Mapping; UINT CurrentFragment, Glyph, GlyphLimit, Index, Line, Mapping;
PUCHAR Character, CharacterMapping, Fragment; PUCHAR Character, CharacterMapping, Fragment;
ULONG FontColor, GlyphOffset, PixelOffset; UINT_PTR GlyphPixel, Pixel;
PSSFN_FONT_HEADER FbFont; PSSFN_FONT_HEADER FbFont;
ULONG FontColor;
/* Make sure frame buffer is already initialized */ /* Make sure frame buffer is already initialized */
if(FrameBufferData.Initialized == FALSE) if(FrameBufferData.Initialized == FALSE)
@@ -217,7 +192,7 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
} }
else else
{ {
/* There is a glyph for this character, check if it matches */ /* There's a glyph for this character, check if it matches */
if(Index == WideCharacter) if(Index == WideCharacter)
{ {
/* Found the character, break loop */ /* Found the character, break loop */
@@ -238,7 +213,8 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
} }
/* Find the glyph position on the frame buffer and set font color */ /* Find the glyph position on the frame buffer and set font color */
GlyphOffset = (PositionY * FrameBufferData.Pitch) + (PositionX * FrameBufferData.BytesPerPixel); GlyphPixel = (UINT_PTR)FrameBufferData.Address + PositionY * FrameBufferData.Pitch +
PositionX * FrameBufferData.BytesPerPixel;
FontColor = GetRGBColor(Color); FontColor = GetRGBColor(Color);
/* Check all kerning fragments */ /* Check all kerning fragments */
@@ -267,7 +243,7 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
} }
/* Get initial glyph line */ /* Get initial glyph line */
GlyphOffset += (CharacterMapping[1] - Mapping) * FrameBufferData.Pitch; GlyphPixel += (CharacterMapping[1] - Mapping) * FrameBufferData.Pitch;
Mapping = CharacterMapping[1]; Mapping = CharacterMapping[1];
/* Extract glyph data from fragments table and advance */ /* Extract glyph data from fragments table and advance */
@@ -279,8 +255,7 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
CurrentFragment = 1; CurrentFragment = 1;
while(GlyphLimit--) while(GlyphLimit--)
{ {
/* Set the initial pixel offset for the current glyph fragment */ Pixel = GlyphPixel;
PixelOffset = GlyphOffset;
for(Line = 0; Line < Glyph; Line++) for(Line = 0; Line < Glyph; Line++)
{ {
/* Decode compressed offsets */ /* Decode compressed offsets */
@@ -294,26 +269,17 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
/* Check if pixel should be drawn */ /* Check if pixel should be drawn */
if(*Fragment & CurrentFragment) if(*Fragment & CurrentFragment)
{ {
/* Route the pixel draw operation to the active buffer */ /* Draw glyph pixel */
if(ScreenShadowBuffer != NULLPTR) *((PULONG)Pixel) = FontColor;
{
/* Draw glyph pixel to Shadow Buffer */
*((PULONG)((PCHAR)ScreenShadowBuffer + PixelOffset)) = FontColor;
}
else
{
/* Draw glyph pixel directly to VRAM */
*((PULONG)((PCHAR)FrameBufferData.Address + PixelOffset)) = FontColor;
}
} }
/* Advance pixel pointer */ /* Advance pixel pointer */
PixelOffset += FrameBufferData.BytesPerPixel; Pixel += FrameBufferData.BytesPerPixel;
CurrentFragment <<= 1; CurrentFragment <<= 1;
} }
/* Advance to next line and increase mapping */ /* Advance to next line and increase mapping */
GlyphOffset += FrameBufferData.Pitch; GlyphPixel += FrameBufferData.Pitch;
Mapping++; Mapping++;
} }
@@ -344,7 +310,7 @@ HL::FrameBuffer::DrawPixel(IN ULONG PositionX,
IN ULONG PositionY, IN ULONG PositionY,
IN ULONG Color) IN ULONG Color)
{ {
ULONG Offset; PCHAR PixelAddress;
/* Make sure frame buffer is already initialized */ /* Make sure frame buffer is already initialized */
if(FrameBufferData.Initialized == FALSE) if(FrameBufferData.Initialized == FALSE)
@@ -361,67 +327,11 @@ HL::FrameBuffer::DrawPixel(IN ULONG PositionX,
} }
/* Calculate the address of the pixel in the frame buffer memory */ /* Calculate the address of the pixel in the frame buffer memory */
Offset = (PositionY * FrameBufferData.Pitch) + (PositionX * FrameBufferData.BytesPerPixel); PixelAddress = (PCHAR)FrameBufferData.Address + (PositionY * FrameBufferData.Pitch) +
(PositionX * FrameBufferData.BytesPerPixel);
/* Route the pixel draw operation to the active buffer */ /* Set the color of the pixel by writing to the corresponding memory location */
if(ScreenShadowBuffer != NULLPTR) *((PULONG)PixelAddress) = GetRGBColor(Color);
{
/* Set the color of the pixel by writing to the corresponding memory location (RAM) */
*((PULONG)((PCHAR)ScreenShadowBuffer + Offset)) = GetRGBColor(Color);
}
else
{
/* Set the color of the pixel by writing to the corresponding memory location (VRAM) */
*((PULONG)((PCHAR)FrameBufferData.Address + Offset)) = GetRGBColor(Color);
}
}
/**
* Enables the Shadow Buffer (Double Buffering) for high-performance rendering.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
HL::FrameBuffer::EnableShadowBuffer(VOID)
{
ULONG FrameBufferSize;
XTSTATUS Status;
/* Check if the shadow buffer is already enabled */
if(ScreenShadowBuffer != NULLPTR)
{
/* Nothing to do, return success */
return STATUS_SUCCESS;
}
/* Make sure frame buffer is already initialized */
if(FrameBufferData.Initialized == FALSE)
{
/* Unable to operate on non-initialized frame buffer */
return STATUS_DEVICE_NOT_READY;
}
/* Calculate the total size of the framebuffer */
FrameBufferSize = FrameBufferData.Pitch * FrameBufferData.Height;
/* Allocate non-paged memory for the shadow buffer */
Status = MM::Allocator::AllocatePool(NonPagedPool, FrameBufferSize,
&ScreenShadowBuffer, SIGNATURE32('F', 'B', 'U', 'F'));
if(Status != STATUS_SUCCESS)
{
/* Allocation failed, return status code */
ScreenShadowBuffer = NULLPTR;
return Status;
}
/* Synchronize the newly allocated shadow buffer with the current on-screen contents */
RTL::Memory::CopyMemory(ScreenShadowBuffer, FrameBufferData.Address, FrameBufferSize);
/* Return success */
return STATUS_SUCCESS;
} }
/** /**
@@ -634,9 +544,10 @@ XTAPI
VOID VOID
HL::FrameBuffer::ScrollRegion(VOID) HL::FrameBuffer::ScrollRegion(VOID)
{ {
PCHAR TargetBuffer, Destination, Source; PCHAR Destination, Source;
ULONG Line, PositionX, LineBytes;
PSSFN_FONT_HEADER FbFont; PSSFN_FONT_HEADER FbFont;
ULONG Line, PositionX;
ULONG LineBytes;
PULONG Pixel; PULONG Pixel;
/* Make sure frame buffer is already initialized */ /* Make sure frame buffer is already initialized */
@@ -646,132 +557,37 @@ HL::FrameBuffer::ScrollRegion(VOID)
return; return;
} }
/* Retrieve font metrics and calculate line properties for the scroll operation */ /* Get font information */
FbFont = (PSSFN_FONT_HEADER)FrameBufferData.Font; FbFont = (PSSFN_FONT_HEADER)FrameBufferData.Font;
/* Calculate bytes per line in the scroll region */
LineBytes = (ScrollRegionData.Right - ScrollRegionData.Left) * FrameBufferData.BytesPerPixel; LineBytes = (ScrollRegionData.Right - ScrollRegionData.Left) * FrameBufferData.BytesPerPixel;
TargetBuffer = (ScreenShadowBuffer != NULLPTR) ? (PCHAR)ScreenShadowBuffer : (PCHAR)FrameBufferData.Address;
/* Process every line in the scroll region */ /* Scroll up each scan line in the scroll region */
for(Line = ScrollRegionData.Top; Line < ScrollRegionData.Bottom; Line++) for(Line = ScrollRegionData.Top; Line < ScrollRegionData.Bottom - FbFont->Height; Line++)
{ {
/* Calculate destination address for the current line */ Destination = (PCHAR)FrameBufferData.Address + Line * FrameBufferData.Pitch +
Destination = TargetBuffer + (Line * FrameBufferData.Pitch) + ScrollRegionData.Left * FrameBufferData.BytesPerPixel;
(ScrollRegionData.Left * FrameBufferData.BytesPerPixel);
/* Check if the current line needs to be copied from below or cleared */ /* The source is one full text line (FbFont->Height) below the destination */
if(Line < ScrollRegionData.Bottom - FbFont->Height) Source = (PCHAR)FrameBufferData.Address + (Line + FbFont->Height) * FrameBufferData.Pitch +
{ ScrollRegionData.Left * FrameBufferData.BytesPerPixel;
/* Copy the line from below */
Source = Destination + (FbFont->Height * FrameBufferData.Pitch); /* Move each scan line in the scroll region up */
RTL::Memory::CopyMemory(Destination, Source, LineBytes); RTL::Memory::MoveMemory(Destination, Source, LineBytes);
} }
else
/* Clear the last text line */
for(Line = ScrollRegionData.Bottom - FbFont->Height; Line < ScrollRegionData.Bottom; Line++)
{ {
/* Fill the bottom line(s) with the background color */ /* Get pointer to the start of the scan line to clear */
Pixel = (PULONG)Destination; Pixel = (PULONG)((PCHAR)FrameBufferData.Address + Line * FrameBufferData.Pitch +
ScrollRegionData.Left * FrameBufferData.BytesPerPixel);
/* Clear each pixel in the scan line with the background color */
for(PositionX = 0; PositionX < (ScrollRegionData.Right - ScrollRegionData.Left); PositionX++) for(PositionX = 0; PositionX < (ScrollRegionData.Right - ScrollRegionData.Left); PositionX++)
{ {
/* Overwrite the pixel with the background color */
Pixel[PositionX] = ScrollRegionData.BackgroundColor; Pixel[PositionX] = ScrollRegionData.BackgroundColor;
} }
} }
}
/* Flush changes to VRAM if Shadow Buffer was used */
if(ScreenShadowBuffer != NULLPTR)
{
/* Flush the updated scroll region to VRAM */
UpdateScreenRegion(ScrollRegionData.Left,
ScrollRegionData.Top,
ScrollRegionData.Right,
ScrollRegionData.Bottom);
}
}
/**
* Flushes the current content of the Shadow Buffer to the visible FrameBuffer (VRAM).
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HL::FrameBuffer::UpdateScreen(VOID)
{
/* Make sure framebuffer is already initialized and shadow buffer is ready */
if(FrameBufferData.Initialized == FALSE || ScreenShadowBuffer == NULLPTR)
{
/* Unable to operate on non-initialized frame buffer */
return;
}
/* Flush RAM to VRAM */
RTL::Memory::CopyMemory(FrameBufferData.Address,
ScreenShadowBuffer,
FrameBufferData.Pitch * FrameBufferData.Height);
}
/**
* Flushes a specific rectangular region from the Shadow Buffer to the visible FrameBuffer (VRAM).
*
* @param Left
* Supplies the left pixel coordinate of the region to update.
*
* @param Top
* Supplies the top pixel coordinate of the region to update.
*
* @param Right
* Supplies the right pixel coordinate of the region to update.
*
* @param Bottom
* Supplies the bottom pixel coordinate of the region to update.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HL::FrameBuffer::UpdateScreenRegion(IN ULONG Left,
IN ULONG Top,
IN ULONG Right,
IN ULONG Bottom)
{
ULONG Line, LineBytes;
PCHAR Source, Destination;
/* Make sure framebuffer is already initialized and shadow buffer is ready */
if(FrameBufferData.Initialized == FALSE || ScreenShadowBuffer == NULLPTR)
{
/* Unable to operate on non-initialized frame buffer */
return;
}
/* Make sure parameters are valid to prevent memory corruption */
if(Left >= Right || Top >= Bottom || Right > FrameBufferData.Width || Bottom > FrameBufferData.Height)
{
/* Invalid region coordinates provided */
return;
}
/* Calculate the width of the region */
LineBytes = (Right - Left) * FrameBufferData.BytesPerPixel;
/* Copy the specified region line by line */
for(Line = Top; Line < Bottom; Line++)
{
/* Calculate the source address in the shadow buffer */
Source = (PCHAR)ScreenShadowBuffer +
(Line * FrameBufferData.Pitch) +
(Left * FrameBufferData.BytesPerPixel);
/* Calculate the destination address in the VRAM */
Destination = (PCHAR)FrameBufferData.Address +
(Line * FrameBufferData.Pitch) +
(Left * FrameBufferData.BytesPerPixel);
/* Flush RAM to VRAM */
RTL::Memory::CopyMemory(Destination, Source, LineBytes);
}
} }

View File

@@ -1,13 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/hl/i686/firmware.cc
* DESCRIPTION: UEFI/BIOS Firmware support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
/* Include common Firmware interface */
#include ARCH_COMMON(firmware.cc)

View File

@@ -1,259 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/hl/i686/irq.cc
* DESCRIPTION: Interrupts support for i686 architecture
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
/**
* Begins a system interrupt handler by raising the processor's run level and re-enabling
* hardware interrupts to allow preemption by higher-priority events.
*
* @param RunLevel
* Supplies the target run level to raise the processor to.
*
* @param OldRunLevel
* Receives the previous run level before the elevation.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HL::Irq::BeginSystemInterrupt(IN KRUNLEVEL RunLevel,
OUT PKRUNLEVEL OldRunLevel)
{
/* Get the current IRQL */
*OldRunLevel = KE::RunLevel::GetCurrentRunLevel();
/* Raise run level */
KE::RunLevel::RaiseRunLevel(RunLevel);
/* Enable interrupts */
AR::CpuFunc::SetInterruptFlag();
}
/**
* Safely concludes an interrupt handler by disabling hardware interrupts.
*
* @param TrapFrame
* Supplies a pointer to the kernel trap frame containing the interrupted execution state.
*
* @param OldRunLevel
* Supplies the previous run level to restore.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HL::Irq::EndInterrupt(IN PKTRAP_FRAME TrapFrame,
IN KRUNLEVEL OldRunLevel)
{
/* Disable interrupts */
AR::CpuFunc::ClearInterruptFlag();
/* End system interrupt */
EndSystemInterrupt(TrapFrame, OldRunLevel);
}
/**
* Concludes a system interrupt by sending an End of Interrupt (EOI) to the hardware
* controller and restoring the processor's previous run level.
*
* @param TrapFrame
* Supplies a pointer to the kernel trap frame containing the interrupted execution state.
*
* @param OldRunLevel
* Supplies the previous run level to restore.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HL::Irq::EndSystemInterrupt(IN PKTRAP_FRAME TrapFrame,
IN KRUNLEVEL OldRunLevel)
{
/* Send EOI */
HL::Pic::SendEoi();
/* Restore previous run level */
KE::RunLevel::LowerRunLevel(OldRunLevel);
}
/**
* Handles profiling interrupt.
*
* @param TrapFrame
* Supplies a kernel trap frame pushed by common interrupt handler.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
HL::Irq::HandleProfileInterrupt(IN PKTRAP_FRAME TrapFrame)
{
/* Send EOI */
HL::Pic::SendEoi();
}
/**
* Handles unexpected or unmapped system interrupts.
*
* @param TrapFrame
* Supplies a kernel trap frame pushed by common interrupt handler.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
HL::Irq::HandleUnexpectedInterrupt(IN PKTRAP_FRAME TrapFrame)
{
UNIMPLEMENTED;
/* Disable interrupts */
AR::CpuFunc::ClearInterruptFlag();
/* Print debug message and raise kernel panic */
DebugPrint(L"ERROR: Caught unexpected interrupt (0x%.2lX)!\n", TrapFrame->Vector);
KE::Crash::Panic(0x47, TrapFrame->Vector, 0, 0, 0);
}
/**
* Returns the registered interrupt handler for the specified IDT vector.
*
* @param Vector
* Supplies the interrupt vector number.
*
* @return This routine returns the pointer to the IDT interrupt handler routine.
*
* @since XT 1.0
*/
XTAPI
PVOID
HL::Irq::QueryInterruptHandler(IN ULONG Vector)
{
PKPROCESSOR_BLOCK ProcessorBlock;
PKIDTENTRY IdtEntry;
/* Get current processor block and IDT entry */
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
IdtEntry = &ProcessorBlock->IdtBase[Vector];
/* Return address of the interrupt handler */
return (PVOID)(((IdtEntry->ExtendedOffset << 16) & 0xFFFF0000) | (IdtEntry->Offset & 0xFFFF));
}
/**
* Returns the registered interrupt handler for the specified vector.
*
* @param Vector
* Supplies the interrupt vector number.
*
* @return This routine returns the pointer to the interrupt handler routine.
*
* @since XT 1.0
*/
XTAPI
PVOID
HL::Irq::QuerySystemInterruptHandler(IN ULONG Vector)
{
PKPROCESSOR_BLOCK ProcessorBlock;
/* Get current processor block */
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
return (PVOID)ProcessorBlock->InterruptDispatchTable[Vector];
}
/**
* Registers new interrupt handler for the existing IDT entry.
*
* @param HalVector
* Supplies the interrupt vector number.
*
* @param Handler
* Supplies the pointer to the interrupt handler routine.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HL::Irq::RegisterInterruptHandler(IN ULONG Vector,
IN PVOID Handler)
{
PKPROCESSOR_BLOCK ProcessorBlock;
/* Get current processor block */
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
/* Update interrupt handler */
AR::ProcSup::SetIdtGate(ProcessorBlock->IdtBase,
Vector,
Handler,
KGDT_R0_CODE,
0,
KIDT_ACCESS_RING0,
I686_INTERRUPT_GATE);
}
/**
* Registers the interrupt handler for the specified vector.
*
* @param HalVector
* Supplies the interrupt vector number.
*
* @param Handler
* Supplies the pointer to the interrupt handler routine.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HL::Irq::RegisterSystemInterruptHandler(IN ULONG Vector,
IN PINTERRUPT_HANDLER Handler)
{
PKPROCESSOR_BLOCK ProcessorBlock;
/* Get current processor block */
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
/* Update interrupt handler in the processor's interrupt dispatch table */
ProcessorBlock->InterruptDispatchTable[Vector] = Handler;
}
/**
* Requests a software interrupt by sending a Self-IPI mapped to the specified run level.
*
* @param RunLevel
* Supplies the target run level for the software interrupt.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTFASTCALL
VOID
HL::Irq::SendSoftwareInterrupt(IN KRUNLEVEL RunLevel)
{
/* Request a software interrupt */
HL::Pic::SendSelfIpi(HL::RunLevel::TransformRunLevelToSoftwareVector(RunLevel));
}

View File

@@ -1,13 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/hl/i686/rtc.cc
* DESCRIPTION: Hardware Real-Time Clock (RTC) support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
/* Include common RTC interface */
#include ARCH_COMMON(rtc.cc)

View File

@@ -20,7 +20,6 @@ XTFASTCALL
KRUNLEVEL KRUNLEVEL
HL::RunLevel::GetRunLevel(VOID) HL::RunLevel::GetRunLevel(VOID)
{ {
/* Read current run level */
return TransformApicTprToRunLevel(HL::Pic::ReadApicRegister(APIC_TPR)); return TransformApicTprToRunLevel(HL::Pic::ReadApicRegister(APIC_TPR));
} }
@@ -38,7 +37,6 @@ XTFASTCALL
VOID VOID
HL::RunLevel::SetRunLevel(IN KRUNLEVEL RunLevel) HL::RunLevel::SetRunLevel(IN KRUNLEVEL RunLevel)
{ {
/* Set new run level */
HL::Pic::WriteApicRegister(APIC_TPR, TransformRunLevelToApicTpr(RunLevel)); HL::Pic::WriteApicRegister(APIC_TPR, TransformRunLevelToApicTpr(RunLevel));
} }
@@ -133,23 +131,3 @@ HL::RunLevel::TransformRunLevelToApicTpr(IN KRUNLEVEL RunLevel)
/* Return the TPR corresponding to the run level from the transformation table. */ /* Return the TPR corresponding to the run level from the transformation table. */
return TransformationTable[RunLevel]; return TransformationTable[RunLevel];
} }
/**
* Transforms a given execution run level into a corresponding hardware interrupt vector
* suitable for software interrupts.
*
* @param RunLevel
* Supplies the run level to be translated into a software interrupt vector.
*
* @return This routine returns the 8-bit APIC vector corresponding to the requested software interrupt level.
*
* @since XT 1.0
*/
XTFASTCALL
UCHAR
HL::RunLevel::TransformRunLevelToSoftwareVector(IN KRUNLEVEL RunLevel)
{
/* Transform run level to APIC interrupt vector */
return TransformRunLevelToApicTpr(RunLevel);
}

View File

@@ -1,13 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/hl/i686/timer.cc
* DESCRIPTION: Timer support for i686
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
/* Include common Timer interface */
#include ARCH_COMMON(timer.cc)

View File

@@ -23,25 +23,19 @@ HL::Init::InitializeSystem(VOID)
XTSTATUS Status; XTSTATUS Status;
/* Initialize ACPI */ /* Initialize ACPI */
Status = HL::Acpi::InitializeAcpi(); Status = Acpi::InitializeAcpi();
if(Status != STATUS_SUCCESS) if(Status != STATUS_SUCCESS)
{ {
return Status; return Status;
} }
/* Get system information from ACPI */ /* Get system information from ACPI */
Status = HL::Acpi::InitializeAcpiSystemInformation(); Status = Acpi::InitializeAcpiSystemInformation();
if(Status != STATUS_SUCCESS) if(Status != STATUS_SUCCESS)
{ {
return Status; return Status;
} }
/* Initialize I/O APIC */
HL::Pic::InitializeIOApic();
/* Initialize timer */
HL::Timer::InitializeTimer();
/* Return success */ /* Return success */
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

View File

@@ -40,180 +40,8 @@ HL::Cpu::InitializeProcessor(VOID)
ActiveProcessors |= Affinity; ActiveProcessors |= Affinity;
/* Initialize APIC for this processor */ /* Initialize APIC for this processor */
HL::Pic::InitializePic(); Pic::InitializePic();
/* Set the APIC running level */ /* Set the APIC running level */
HL::RunLevel::SetRunLevel(KE::Processor::GetCurrentProcessorBlock()->RunLevel); HL::RunLevel::SetRunLevel(KE::Processor::GetCurrentProcessorBlock()->RunLevel);
} }
/**
* Wakes up and initializes all Application Processors (APs) and transitions them into the active kernel.
*
* @return This routine returns a status code indicating the success or failure of the operation.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
HL::Cpu::StartAllProcessors(VOID)
{
ULONG CpuNumber, Index, MaxCpus, SipiVector, Timeout, TrampolinePages;
PVOID CpuStructures, TrampolineAddress, TrampolineCode;
ULONG_PTR AllocationSize, TrampolineCodeSize;
PPROCESSOR_START_BLOCK StartBlock;
PKPROCESSOR_BLOCK ProcessorBlock;
PACPI_SYSTEM_INFO SysInfo;
WCHAR ParameterValue[16];
XTSTATUS Status;
/* Determine the maximum number of CPUs to start */
HL::Acpi::GetSystemInformation(&SysInfo);
MaxCpus = SysInfo->CpuCount;
/* Check if user forced a specific CPU limit */
if(KE::BootInformation::GetKernelParameterValue(L"MAXCPUS", ParameterValue, 16) == STATUS_SUCCESS)
{
/* Convert string value to number */
Status = RTL::WideString::WideStringToNumber(ParameterValue, 0, &MaxCpus);
if(Status == STATUS_SUCCESS)
{
/* Ensure safe boundaries */
if(MaxCpus == 0)
{
/* Fallback to 1 CPU (BSP) */
MaxCpus = 1;
}
}
else
{
/* Failed to parse value, fallback to ACPI value */
MaxCpus = SysInfo->CpuCount;
}
}
/* Check if single core CPU or set a CPU limit */
if(MaxCpus == 1 || SysInfo->CpuCount == 1)
{
/* Single core CPU, return success */
return STATUS_SUCCESS;
}
/* Get trampoline information */
AR::ProcSup::GetTrampolineInformation(TrampolineApStartup, &TrampolineCode, &TrampolineCodeSize);
/* Verify trampoline information */
if(TrampolineCode == NULLPTR || TrampolineCodeSize == 0)
{
/* Failed to get trampoline information, return error */
return STATUS_UNSUCCESSFUL;
}
/* Compute trampoline memory allocation size (trampoline + processor start block + temporary stack) */
AllocationSize = TrampolineCodeSize + sizeof(PROCESSOR_START_BLOCK) + 512;
TrampolinePages = (ULONG)(ROUND_UP(AllocationSize, MM_PAGE_SIZE) / MM_PAGE_SIZE);
/* Allocate real mode memory for AP trampoline */
Status = MM::HardwarePool::AllocateRealModeMemory(TrampolinePages, &TrampolineAddress);
if(Status != STATUS_SUCCESS)
{
/* Failed to allocate memory, print error message and return error */
DebugPrint(L"Failed to allocate %lu pages for AP Trampoline!\n", TrampolinePages);
return Status;
}
/* Copy trampoline code to low memory */
RTL::Memory::CopyMemory(TrampolineAddress, TrampolineCode, TrampolineCodeSize);
/* Get start block address relative to trampoline address */
StartBlock = (PPROCESSOR_START_BLOCK)((PUCHAR)TrampolineAddress + TrampolineCodeSize);
/* Get SIPI vector */
SipiVector = (ULONG)((ULONG_PTR)TrampolineAddress >> 12);
/* Loop over all CPUs */
CpuNumber = 0;
for(Index = 0; Index < SysInfo->CpuCount; Index++)
{
/* Check if destination CPU is the BSP */
if(SysInfo->CpuInfo[Index].ApicId == HL::Pic::GetCpuApicId())
{
/* Skip current CPU */
continue;
}
/* Increment CPU number */
CpuNumber++;
/* Verify if the CPU limit has been reached */
if((CpuNumber) >= MaxCpus)
{
/* Maximum allowed CPUs reached, break the loop */
break;
}
/* Allocate memory for the processor structures (Stacks, GDT, and Processor Block) */
Status = MM::KernelPool::AllocateProcessorStructures(&CpuStructures);
if(Status != STATUS_SUCCESS)
{
/* Failed to allocate memory, unmap memory and return error */
MM::HardwarePool::UnmapHardwareMemory(TrampolineAddress, TrampolinePages, TRUE);
return Status;
}
/* Get ProcessorBlock and Stack address */
AR::ProcSup::InitializeProcessorStructures(CpuStructures, NULLPTR, NULLPTR, &ProcessorBlock,
&StartBlock->Stack, NULLPTR, NULLPTR);
/* Set processor number directly in the processor block */
ProcessorBlock->CpuNumber = CpuNumber;
/* Save processor block in the array */
KE::Processor::RegisterProcessorBlock(CpuNumber, ProcessorBlock);
/* Initialize processor start block */
StartBlock->Cr3 = AR::CpuFunc::ReadControlRegister(3);
StartBlock->Cr4 = AR::CpuFunc::ReadControlRegister(4);
StartBlock->EntryPoint = (PVOID)&KE::KernelInit::BootstrapApplicationProcessor;
StartBlock->ProcessorStructures = CpuStructures;
StartBlock->Started = FALSE;
/* Memory barrier */
AR::CpuFunc::MemoryBarrier();
/* Send INIT IPI and wait for 10ms */
HL::Pic::SendIpi(SysInfo->CpuInfo[Index].ApicId, 0, APIC_DM_INIT, APIC_DSH_Destination, APIC_TGM_EDGE);
HL::Timer::StallExecution(10000);
/* Send STARTUP IPI (SIPI) and wait for 200us */
HL::Pic::SendIpi(SysInfo->CpuInfo[Index].ApicId, SipiVector, APIC_DM_STARTUP, APIC_DSH_Destination, APIC_TGM_EDGE);
HL::Timer::StallExecution(200);
/* Send STARTUP IPI (SIPI) again */
HL::Pic::SendIpi(SysInfo->CpuInfo[Index].ApicId, SipiVector, APIC_DM_STARTUP, APIC_DSH_Destination, APIC_TGM_EDGE);
/* Wait until the processor has started or timeout expires */
Timeout = 0;
while(!StartBlock->Started && Timeout < 100000)
{
/* Yield processor and wait for 10us */
AR::CpuFunc::YieldProcessor();
HL::Timer::StallExecution(10);
Timeout++;
}
/* Check if the processor has not started */
if(!StartBlock->Started)
{
/* Free processor structures and unregister processor block */
MM::KernelPool::FreeProcessorStructures(CpuStructures);
KE::Processor::RegisterProcessorBlock(CpuNumber, NULLPTR);
/* Decrement the CPU counter back */
CpuNumber--;
}
}
/* Unmap trampoline memory and return success */
MM::HardwarePool::UnmapHardwareMemory(TrampolineAddress, TrampolinePages, TRUE);
return STATUS_SUCCESS;
}

View File

@@ -1,56 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/hl/x86/firmware.cc
* DESCRIPTION: UEFI/BIOS Firmware support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
/**
* Reads a byte from the specified CMOS register.
*
* @param Register
* Supplies the CMOS register index to read from.
*
* @return This routine returns the data read from the register.
*
* @since XT 1.0
*/
XTFASTCALL
UCHAR
HL::Firmware::ReadCmosRegister(IN UCHAR Register)
{
/* Select the register (Setting the highest bit disables NMI) */
HL::IoPort::WritePort8(CMOS_SELECT_PORT, Register | CMOS_NMI_SELECT);
/* Read value from the data port */
return HL::IoPort::ReadPort8(CMOS_DATA_PORT);
}
/**
* Writes a byte to the specified CMOS register.
*
* @param Register
* Supplies the CMOS register index to write to.
*
* @param Value
* Supplies the value to write to the register.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTFASTCALL
VOID
HL::Firmware::WriteCmosRegister(IN UCHAR Register,
IN UCHAR Value)
{
/* Select the register (Setting the highest bit disables NMI) */
HL::IoPort::WritePort8(CMOS_SELECT_PORT, Register | CMOS_NMI_SELECT);
/* Write the provided value to the data port */
HL::IoPort::WritePort8(CMOS_DATA_PORT, Value);
}

View File

@@ -4,89 +4,11 @@
* FILE: xtoskrnl/hl/x86/pic.cc * FILE: xtoskrnl/hl/x86/pic.cc
* DESCRIPTION: Programmable Interrupt Controller (PIC) for x86 (i686/AMD64) support * DESCRIPTION: Programmable Interrupt Controller (PIC) for x86 (i686/AMD64) support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/ */
#include <xtos.hh> #include <xtos.hh>
/**
* Allocates, maps and commits a requested system interrupt level internally.
*
* @param RunLevel
* Supplies the actual system run level to allocate.
*
* @param Vector
* Supplies the interrupt handler vector assigned to process requests originating on the line.
*
* @return This routine returns the configured target vector.
*
* @since XT 1.0
*/
XTAPI
VOID
HL::Pic::AllocateSystemInterrupt(IN UCHAR Irq,
IN UCHAR RunLevel,
IN UCHAR Vector)
{
IOAPIC_REDIRECTION_REGISTER Register;
PIOAPIC_DATA Controller;
ULONG EntryNumber, Gsi;
XTSTATUS Status;
USHORT Flags;
/* Determine the GSI and flags for the requested IRQ */
ResolveInterruptOverride(Irq, &Gsi, &Flags);
/* Find the APIC controller for the GSI */
Status = GetIoApicController(Gsi, &Controller, &EntryNumber);
if(Status != STATUS_SUCCESS)
{
/* GSI maps to an invalid controller, return */
DebugPrint(L"ERROR: Hardware IRQ / GSI maps to an invalid controller!\n");
return;
}
/* Model a logical connection */
Register.LongLong = 0;
Register.DeliveryMode = APIC_DM_FIXED;
Register.DeliveryStatus = 0;
Register.Destination = HL::Pic::ReadApicRegister(APIC_ID) >> 24;
Register.DestinationMode = APIC_DM_Physical;
Register.Mask = 0;
Register.PinPolarity = ((Flags & 0x03) == 0x03) ? 1 : 0;
Register.RemoteIRR = 0;
Register.Reserved = 0;
Register.TriggerMode = (((Flags >> 2) & 0x03) == 0x03) ? APIC_TGM_LEVEL : APIC_TGM_EDGE;
Register.Vector = Vector;
/* Flash logical rules back into the hardware configuration index */
WriteRedirectionEntry(Controller, EntryNumber, Register);
/* Persist the allocated slot so standard routing algorithms don't overlap it */
MappedVectors[Vector] = RunLevel;
}
/**
* 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)
{
PKPROCESSOR_CONTROL_BLOCK Prcb;
/* Get current processor control block */
Prcb = KE::Processor::GetCurrentProcessorControlBlock();
/* Return APIC status */
return (Prcb->CpuId.FeatureBits & KCF_APIC) ? TRUE : FALSE;
}
/** /**
* Checks whether the x2APIC extension is supported by the processor. * Checks whether the x2APIC extension is supported by the processor.
* *
@@ -101,21 +23,28 @@ XTAPI
BOOLEAN BOOLEAN
HL::Pic::CheckX2ApicSupport(VOID) HL::Pic::CheckX2ApicSupport(VOID)
{ {
PKPROCESSOR_CONTROL_BLOCK Prcb; CPUID_REGISTERS CpuRegisters;
PCWSTR KernelParameter;
/* Check if the user forced xAPIC via boot parameters */ /* Prepare CPUID registers */
if(KE::BootInformation::GetKernelParameter(L"NOX2APIC", &KernelParameter) == STATUS_SUCCESS) 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 x2APIC status from the CPUID results */
if(!(CpuRegisters.Ecx & CPUID_FEATURES_ECX_X2APIC))
{ {
/* The NOX2APIC flag is present, explicitly disable x2APIC support */ /* x2APIC is not supported */
return FALSE; return FALSE;
} }
/* Get current processor control block */ /* x2APIC is supported */
Prcb = KE::Processor::GetCurrentProcessorControlBlock(); return TRUE;
/* Return x2APIC status */
return (Prcb->CpuId.FeatureBits & KCF_X2APIC) ? TRUE : FALSE;
} }
/** /**
@@ -133,105 +62,6 @@ HL::Pic::ClearApicErrors(VOID)
WriteApicRegister(APIC_ESR, 0); WriteApicRegister(APIC_ESR, 0);
} }
/**
* Searches the ACPI MADT tables for the I/O APIC controllers.
*
* @return This routine returns the status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
HL::Pic::DetectIoApicControllers(VOID)
{
PACPI_MADT_INTERRUPT_OVERRIDE OverrideDescriptor;
PACPI_MADT_IOAPIC IoApicDescriptor;
PACPI_SUBTABLE_HEADER SubTable;
ULONG_PTR MadtTable;
PACPI_MADT Madt;
XTSTATUS Status;
/* Initialize number of I/O APIC Controllers */
ControllerCount = 0;
/* Get Multiple APIC Description Table (MADT) */
Status = HL::Acpi::GetAcpiTable(ACPI_MADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Madt);
if(Status == STATUS_SUCCESS && Madt != NULLPTR)
{
/* Set APIC table traverse pointer */
MadtTable = (ULONG_PTR)Madt->ApicTables;
/* Traverse all MADT tables to discover IOAPIC configurations */
while(MadtTable < ((ULONG_PTR)Madt + Madt->Header.Length))
{
/* Extract active header element */
SubTable = (PACPI_SUBTABLE_HEADER)MadtTable;
/* Prevent infinite traversal loops on corrupted firmware definitions */
if(SubTable->Length == 0)
{
/* Invalid MADT table, break loop */
break;
}
/* Test specifically for I/O APIC component identity */
if(SubTable->Type == ACPI_MADT_TYPE_IOAPIC &&
SubTable->Length >= sizeof(ACPI_MADT_IOAPIC))
{
/* Extract I/O APIC descriptor */
IoApicDescriptor = (PACPI_MADT_IOAPIC)MadtTable;
/* Set information about this I/O APIC Controller */
Controllers[ControllerCount].GsiBase = IoApicDescriptor->GlobalIrqBase;
Controllers[ControllerCount].Identifier = IoApicDescriptor->IoApicId;
Controllers[ControllerCount].PhysicalAddress.QuadPart = IoApicDescriptor->IoApicAddress;
/* Increment I/O APIC controller index */
ControllerCount++;
}
else if(SubTable->Type == ACPI_MADT_TYPE_INT_OVERRIDE &&
SubTable->Length >= sizeof(ACPI_MADT_INTERRUPT_OVERRIDE))
{
/* Check if maximum number of interrupt overrides has not been reached */
if(IrqOverrideCount < IOAPIC_MAX_OVERRIDES)
{
/* Extract interrupt override descriptor */
OverrideDescriptor = (PACPI_MADT_INTERRUPT_OVERRIDE)MadtTable;
/* Save information about this interrupt override */
IrqOverrides[IrqOverrideCount].Bus = OverrideDescriptor->Bus;
IrqOverrides[IrqOverrideCount].Flags = OverrideDescriptor->Flags;
IrqOverrides[IrqOverrideCount].GlobalSystemInterrupt = OverrideDescriptor->GlobalSystemInterrupt;
IrqOverrides[IrqOverrideCount].SourceIrq = OverrideDescriptor->SourceIrq;
/* Increment interrupt override index */
IrqOverrideCount++;
}
}
/* Ensure, maximum number of I/O APIC controllers has not been reached */
if(ControllerCount >= IOAPIC_MAX_CONTROLLERS)
{
/* No more I/O APIC controllers supported, break loop */
break;
}
/* Go to the next subtable */
MadtTable += SubTable->Length;
}
}
/* Check if any I/O APIC controllers were found */
if(ControllerCount == 0)
{
/* No I/O APIC controllers found, return failure */
return STATUS_NOT_FOUND;
}
/* Return success */
return STATUS_SUCCESS;
}
/** /**
* Gets the local APIC ID of the current processor. * Gets the local APIC ID of the current processor.
* *
@@ -253,52 +83,7 @@ HL::Pic::GetCpuApicId(VOID)
} }
/** /**
* Gets the I/O APIC controller information for the specified GSI. * Allows an APIC spurious interrupts to end up.
*
* @param Gsi
* Supplies the GSI to get the I/O APIC controller information for.
*
* @param Controller
* Supplies a pointer to the memory area where the I/O APIC controller information will be stored.
*
* @param EntryNumber
* Supplies a pointer to the memory area where the entry number will be stored.
*
* @return This routine returns the status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
HL::Pic::GetIoApicController(IN ULONG Gsi,
OUT PIOAPIC_DATA *Controller,
OUT PULONG EntryNumber)
{
ULONG ControllerIndex;
/* Iterate over all available I/O APIC controllers */
for(ControllerIndex = 0; ControllerIndex < ControllerCount; ControllerIndex++)
{
/* Check if the GSI belongs to this I/O APIC controller */
if(Gsi >= Controllers[ControllerIndex].GsiBase &&
Gsi < (Controllers[ControllerIndex].GsiBase + Controllers[ControllerIndex].LineCount))
{
/* Return I/O APIC controller information */
*Controller = &Controllers[ControllerIndex];
*EntryNumber = (ULONG)(Gsi - Controllers[ControllerIndex].GsiBase);
return STATUS_SUCCESS;
}
}
/* GSI does not belong to any I/O APIC controller, return failure */
return STATUS_NOT_FOUND;
}
/**
* Services the APIC Error interrupt, invoked when the APIC detects an internal hardware or message passing error.
*
* @param TrapFrame
* Supplies a pointer to the hardware trap frame representing the interrupted execution context.
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
@@ -306,19 +91,21 @@ HL::Pic::GetIoApicController(IN ULONG Gsi,
*/ */
XTCDECL XTCDECL
VOID VOID
HL::Pic::HandleApicErrorInterrupt(IN PKTRAP_FRAME TrapFrame) HL::Pic::HandleApicSpuriousService(VOID)
{ {
ULONG ErrorStatus; }
/* Write 0 to the ESR register to trigger an internal state update, then read the latched status */ /**
WriteApicRegister(APIC_ESR, 0); * Allows a PIC spurious interrupts to end up.
ErrorStatus = (ULONG)ReadApicRegister(APIC_ESR); *
* @return This routine does not return any value.
/* Log the detected hardware error */ *
DebugPrint(L"Caught APIC Error interrupt with ESR = 0x%08X\n", ErrorStatus); * @since XT 1.0
*/
/* Acknowledge the interrupt to allow further interrupt delivery */ XTCDECL
SendEoi(); VOID
HL::Pic::HandlePicSpuriousService(VOID)
{
} }
/** /**
@@ -337,14 +124,6 @@ HL::Pic::InitializeApic(VOID)
APIC_LVT_REGISTER LvtRegister; APIC_LVT_REGISTER LvtRegister;
ULONG CpuNumber; ULONG CpuNumber;
/* Check APIC support */
if(!CheckApicSupport())
{
/* APIC is not supported, raise kernel panic */
DebugPrint(L"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) */ /* Determine APIC mode (xAPIC compatibility or x2APIC) */
if(CheckX2ApicSupport()) if(CheckX2ApicSupport())
{ {
@@ -380,9 +159,6 @@ HL::Pic::InitializeApic(VOID)
WriteApicRegister(APIC_LDR, (1UL << CpuNumber) << 24); WriteApicRegister(APIC_LDR, (1UL << CpuNumber) << 24);
} }
/* Report the APIC ID to the kernel logic */
KE::Processor::RegisterHardwareId(GetCpuApicId());
/* Configure the spurious interrupt vector */ /* Configure the spurious interrupt vector */
SpuriousRegister.Long = ReadApicRegister(APIC_SIVR); SpuriousRegister.Long = ReadApicRegister(APIC_SIVR);
SpuriousRegister.Vector = APIC_VECTOR_SPURIOUS; SpuriousRegister.Vector = APIC_VECTOR_SPURIOUS;
@@ -393,9 +169,13 @@ HL::Pic::InitializeApic(VOID)
/* Setup the LVT Error entry to deliver APIC errors on a dedicated vector */ /* Setup the LVT Error entry to deliver APIC errors on a dedicated vector */
WriteApicRegister(APIC_ERRLVTR, APIC_VECTOR_ERROR); WriteApicRegister(APIC_ERRLVTR, APIC_VECTOR_ERROR);
/* Mask the APIC Timer */ /* Program the APIC timer for periodic mode */
LvtRegister.Long = 0; LvtRegister.Long = 0;
LvtRegister.Mask = 1; LvtRegister.Mask = 1;
LvtRegister.DeliveryMode = APIC_DM_FIXED;
LvtRegister.TimerMode = 1;
LvtRegister.TriggerMode = APIC_TGM_EDGE;
LvtRegister.Vector = APIC_VECTOR_PROFILE;
WriteApicRegister(APIC_TMRLVTR, LvtRegister.Long); WriteApicRegister(APIC_TMRLVTR, LvtRegister.Long);
/* Configure the performance counter overflow */ /* Configure the performance counter overflow */
@@ -426,9 +206,8 @@ HL::Pic::InitializeApic(VOID)
WriteApicRegister(APIC_LINT1, LvtRegister.Long); WriteApicRegister(APIC_LINT1, LvtRegister.Long);
/* Register interrupt handlers */ /* Register interrupt handlers */
HL::Irq::RegisterSystemInterruptHandler(APIC_VECTOR_ERROR, HandleApicErrorInterrupt); KE::Irq::SetInterruptHandler(APIC_VECTOR_SPURIOUS, (PVOID)HandleApicSpuriousService);
HL::Irq::RegisterSystemInterruptHandler(APIC_VECTOR_PROFILE, HL::Irq::HandleProfileInterrupt); KE::Irq::SetInterruptHandler(PIC1_VECTOR_SPURIOUS, (PVOID)HandlePicSpuriousService);
HL::Irq::RegisterInterruptHandler(APIC_VECTOR_SPURIOUS, (PVOID)ArHandleSpuriousInterrupt);
/* Clear any pre-existing errors */ /* Clear any pre-existing errors */
WriteApicRegister(APIC_ESR, 0); WriteApicRegister(APIC_ESR, 0);
@@ -437,90 +216,6 @@ HL::Pic::InitializeApic(VOID)
WriteApicRegister(APIC_TPR, 0x00); WriteApicRegister(APIC_TPR, 0x00);
} }
/**
* Initializes the global I/O APIC controller setup over the entire redirection span.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HL::Pic::InitializeIOApic(VOID)
{
ULONG ControllerIndex, LineIndex, Vector, VersionRegister;
IOAPIC_REDIRECTION_REGISTER Register;
XTSTATUS Status;
/* Detect I/O APIC controllers */
Status = DetectIoApicControllers();
if(Status != STATUS_SUCCESS)
{
DebugPrint(L"ERROR: I/O APIC Controller not present.\n");
KE::Crash::Panic(0x5D, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
}
/* Iterate over all I/O APIC controllers */
ControllerIndex = 0;
while(ControllerIndex < ControllerCount)
{
/* Map the I/O APIC controller memory into hardware space */
Status = MM::HardwarePool::MapHardwareMemory(Controllers[ControllerIndex].PhysicalAddress,
1,
FALSE,
(PVOID*)&Controllers[ControllerIndex].VirtualAddress);
if(Status != STATUS_SUCCESS || Controllers[ControllerIndex].VirtualAddress == 0)
{
DebugPrint(L"ERROR: Failed to map I/O APIC Controller\n");
KE::Crash::Panic(0x0E, 0x0, 0x0, 0x0, 0x0);
}
/* Perform a memory barrier */
AR::CpuFunc::MemoryBarrier();
AR::CpuFunc::ReadWriteBarrier();
/* Read the version register and calculate the maximum number of redirection entries */
VersionRegister = ReadIOApicRegister(&Controllers[ControllerIndex], IOAPIC_VER);
Controllers[ControllerIndex].LineCount = ((VersionRegister >> 16) & 0xFF) + 1;
/* Set up the default redirection entry for this controller */
Register.LongLong = 0;
Register.DeliveryMode = APIC_DM_FIXED;
Register.DeliveryStatus = 0;
Register.Destination = ReadIOApicRegister(&Controllers[ControllerIndex], IOAPIC_ID) >> 24;
Register.DestinationMode = 0;
Register.Mask = 1;
Register.PinPolarity = 0;
Register.RemoteIRR = 0;
Register.Reserved = 0;
Register.TriggerMode = APIC_TGM_EDGE;
Register.Vector = IOAPIC_VECTOR_FREE;
/* Propagate defaults across the array of potential handlers */
for(LineIndex = 0; LineIndex < Controllers[ControllerIndex].LineCount; LineIndex++)
{
/* Write default values into the redirection table */
WriteRedirectionEntry(&Controllers[ControllerIndex], LineIndex, Register);
}
/* Print information about the I/O APIC controller */
DebugPrint(L"Initialized I/O APIC Controller #%lu at 0x%llX (ID: %lu, GSI Base: %lu, Line Count: %lu)\n",
ControllerIndex, Controllers[ControllerIndex].VirtualAddress,
Controllers[ControllerIndex].Identifier, Controllers[ControllerIndex].GsiBase,
Controllers[ControllerIndex].LineCount);
/* Go to the next I/O APIC controller */
ControllerIndex++;
}
/* Assign initial clean state for mapping translations */
for(Vector = 0; Vector <= 255; Vector++)
{
/* Set vector to free */
MappedVectors[Vector] = IOAPIC_VECTOR_FREE;
}
}
/** /**
* Initializes the legacy PIC interrupt controller. * Initializes the legacy PIC interrupt controller.
* *
@@ -594,9 +289,6 @@ HL::Pic::InitializeLegacyPic(VOID)
/* Mask all interrupts on PIC2 port */ /* Mask all interrupts on PIC2 port */
HL::IoPort::WritePort8(PIC2_DATA_PORT, 0xFF); HL::IoPort::WritePort8(PIC2_DATA_PORT, 0xFF);
/* Register interrupt handler */
HL::Irq::RegisterInterruptHandler(PIC1_VECTOR_SPURIOUS, (PVOID)ArHandleSpuriousInterrupt);
} }
/** /**
@@ -641,181 +333,7 @@ HL::Pic::ReadApicRegister(IN APIC_REGISTER Register)
else else
{ {
/* Read from xAPIC */ /* Read from xAPIC */
return HL::IoRegister::ReadRegister32((PULONG)(APIC_BASE + (Register << 4))); return IoRegister::ReadRegister32((PULONG)(APIC_BASE + (Register << 4)));
}
}
/**
* Reads from the I/O APIC register.
*
* @param Controller
* Supplies the I/O APIC controller to read from.
*
* @param Register
* Supplies the I/O APIC register to read from.
*
* @return This routine returns the value read from the given IO APIC register.
*
* @since XT 1.0
*/
XTFASTCALL
ULONG
HL::Pic::ReadIOApicRegister(IN PIOAPIC_DATA Controller,
IN UCHAR Register)
{
/* Write the target address into the index register */
HL::IoRegister::WriteRegister32((PULONG)(Controller->VirtualAddress + IOAPIC_IOREGSEL), Register);
/* Fetch the resultant value from the data window */
return HL::IoRegister::ReadRegister32((PULONG)(Controller->VirtualAddress + IOAPIC_IOWIN));
}
/**
* Reads a configuration entry from the I/O APIC redirection table.
*
* @param Controller
* Supplies the I/O APIC controller to read from.
*
* @param EntryNumber
* Supplies the redirection table entry number to read.
*
* @return This routine returns the populated redirection table entry.
*
* @since XT 1.0
*/
XTFASTCALL
IOAPIC_REDIRECTION_REGISTER
HL::Pic::ReadRedirectionEntry(IN PIOAPIC_DATA Controller,
IN ULONG EntryNumber)
{
IOAPIC_REDIRECTION_REGISTER Register;
ULONG Offset;
/* Derive the offset corresponding to the index */
Offset = IOAPIC_REDTBL + (EntryNumber * IOAPIC_RTE_SIZE);
/* Read the low and high portions mapping to the 64-bit construct */
Register.Base = ReadIOApicRegister(Controller, Offset);
Register.Extended = ReadIOApicRegister(Controller, Offset + 1);
/* Return the redirection table entry */
return Register;
}
/**
* Resolves the GSI and flags for the specified IRQ.
*
* @param Irq
* Supplies the IRQ number to get the GSI and flags for.
*
* @param Gsi
* Supplies a pointer to the memory area where the GSI will be stored.
*
* @param Flags
* Supplies a pointer to the memory area where the flags will be stored.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HL::Pic::ResolveInterruptOverride(IN UCHAR Irq,
OUT PULONG Gsi,
OUT PUSHORT Flags)
{
ULONG Index;
/* Iterate over all I/O APIC overrides */
for(Index = 0; Index < IrqOverrideCount; Index++)
{
/* Check if this IRQ has been overridden */
if(IrqOverrides[Index].SourceIrq == Irq)
{
/* Return overridden GSI and flags */
*Flags = IrqOverrides[Index].Flags;
*Gsi = IrqOverrides[Index].GlobalSystemInterrupt;
return;
}
}
/* Return original IRQ number as GSI and no flags */
*Flags = 0;
*Gsi = (ULONG)Irq;
}
/**
* Sends a Broadcast IPI (Inter-Processor Interrupt) to all processors in the system.
*
* @param Vector
* Supplies the hardware interrupt vector to trigger on the target processors.
*
* @param Self
* Supplies a boolean value indicating the broadcast scope.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HL::Pic::SendBroadcastIpi(IN ULONG Vector,
IN BOOLEAN Self)
{
PKPROCESSOR_BLOCK CurrentProcessorBlock, TargetProcessorBlock;
PACPI_SYSTEM_INFO SysInfo;
BOOLEAN Interrupts;
ULONG Index;
/* Get the current processor block */
CurrentProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
if(CurrentProcessorBlock == NULLPTR)
{
/* Processor block not available, return */
return;
}
/* Get the ACPI system information */
HL::Acpi::GetSystemInformation(&SysInfo);
/* Check whether interrupts are enabled */
Interrupts = AR::CpuFunc::InterruptsEnabled();
/* Disable interrupts */
AR::CpuFunc::ClearInterruptFlag();
/* Iterate over all logical CPUs */
for(Index = 0; Index < SysInfo->CpuCount; Index++)
{
/* Retrieve the target processor block by its Logical CPU Number */
TargetProcessorBlock = KE::Processor::GetProcessorBlock(Index);
/* Only send to processors that exist and have successfully started */
if(TargetProcessorBlock != NULLPTR && TargetProcessorBlock->Started)
{
/* Check if this processor originated the broadcast */
if(TargetProcessorBlock->HardwareId == CurrentProcessorBlock->HardwareId)
{
/* Check if this is a self broadcast */
if(Self)
{
/* Dispatch the IPI to the current processor */
SendSelfIpi(Vector);
}
}
else
{
/* Dispatch the IPI to the target processor */
SendIpi(TargetProcessorBlock->HardwareId, Vector, APIC_DM_FIXED, APIC_DSH_Destination, APIC_TGM_EDGE);
}
}
}
/* Check whether interrupts need to be re-enabled */
if(Interrupts)
{
/* Re-enable interrupts */
AR::CpuFunc::SetInterruptFlag();
} }
} }
@@ -843,153 +361,27 @@ HL::Pic::SendEoi(VOID)
* @param Vector * @param Vector
* Supplies the IPI vector to send. * Supplies the IPI vector to send.
* *
* @param DeliveryMode
* Supplies the delivery mode for the IPI.
*
* @param DestinationShorthand
* Supplies the shorthand.
*
* @param TriggerMode
* Supplies the trigger mode (Edge or Level).
*
* @return This routine does not return any value. * @return This routine does not return any value.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
XTAPI XTAPI
VOID VOID
HL::Pic::SendIpi(IN ULONG ApicId, HL::Pic::SendIpi(ULONG ApicId,
IN ULONG Vector, ULONG Vector)
IN APIC_DM DeliveryMode,
IN APIC_DSH DestinationShortHand,
IN ULONG TriggerMode)
{ {
APIC_COMMAND_REGISTER Register;
BOOLEAN Interrupts;
/* Check whether interrupts are enabled */
Interrupts = AR::CpuFunc::InterruptsEnabled();
/* Disable interrupts */
AR::CpuFunc::ClearInterruptFlag();
/* Check current APIC mode and destination */
if(ApicMode == APIC_MODE_X2APIC && DestinationShortHand == APIC_DSH_Self)
{
/* In x2APIC mode, a dedicated Self-IPI register is used */
WriteApicRegister(APIC_SIPI, Vector);
/* Check whether interrupts need to be re-enabled */
if(Interrupts)
{
/* Check whether interrupts need to be re-enabled */
AR::CpuFunc::SetInterruptFlag();
}
/* Nothing more to do */
return;
}
/* Prepare APIC command register struct */
Register.LongLong = 0;
Register.DeliveryMode = DeliveryMode;
Register.Destination = ApicId;
Register.DestinationShortHand = DestinationShortHand;
Register.Level = 1;
Register.TriggerMode = TriggerMode;
Register.Vector = Vector;
/* Check current APIC mode */ /* Check current APIC mode */
if(ApicMode == APIC_MODE_X2APIC) if(ApicMode == APIC_MODE_X2APIC)
{ {
/* Set destination APIC ID */
Register.Long1 = ApicId;
/* Send IPI using x2APIC mode */ /* Send IPI using x2APIC mode */
WriteApicRegister(APIC_ICR0, Register.LongLong); WriteApicRegister(APIC_ICR0, ((ULONGLONG)ApicId << 32) | Vector);
} }
else else
{ {
/* Wait for the APIC to clear the delivery status */ /* Send IPI using xAPIC compatibility mode */
while((ReadApicRegister(APIC_ICR0) & 0x1000) != 0) WriteApicRegister(APIC_ICR1, ApicId << 24);
{ WriteApicRegister(APIC_ICR0, Vector);
/* Yield the processor */
AR::CpuFunc::YieldProcessor();
} }
/* In xAPIC compatibility mode, write the command to the ICR registers */
WriteApicRegister(APIC_ICR1, Register.Long1);
WriteApicRegister(APIC_ICR0, Register.Long0);
/* Check if this is a Self-IPI */
if(DestinationShortHand == APIC_DSH_Self)
{
/* Wait until the interrupt physically arrives in the requested state */
while((ReadApicRegister((APIC_REGISTER)(APIC_IRR + (Vector / 32))) & (1UL << (Vector % 32))) == 0)
{
/* Yield the processor */
AR::CpuFunc::YieldProcessor();
}
}
}
/* Check whether interrupts need to be re-enabled */
if(Interrupts)
{
/* Re-enable interrupts */
AR::CpuFunc::SetInterruptFlag();
}
}
/**
* Sends a Self-IPI (Inter-Processor Interrupt) to the current CPU.
*
* @param Vector
* Supplies the IPI vector to send.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HL::Pic::SendSelfIpi(IN ULONG Vector)
{
SendIpi(0, Vector, APIC_DM_FIXED, APIC_DSH_Self, APIC_TGM_EDGE);
}
/**
* Translates a given Global System Interrupt (GSI) into an active system interrupt vector.
*
* @param Gsi
* Supplies the GSI to translate.
*
* @return This routine returns the underlying associated system vector mapping.
*
* @since XT 1.0
*/
XTFASTCALL
UCHAR
HL::Pic::TranslateGsiToVector(IN ULONG Gsi)
{
IOAPIC_REDIRECTION_REGISTER Register;
PIOAPIC_DATA Controller;
ULONG EntryNumber;
XTSTATUS Status;
/* Find the APIC controller for the GSI */
Status = GetIoApicController(Gsi, &Controller, &EntryNumber);
if(Status != STATUS_SUCCESS)
{
/* GSI maps to an invalid controller, return free */
return IOAPIC_VECTOR_FREE;
}
/* Read the redirection table entry */
Register.Base = ReadIOApicRegister(Controller, IOAPIC_REDTBL + (EntryNumber * IOAPIC_RTE_SIZE));
/* Return the vector */
return (UCHAR)Register.Vector;
} }
/** /**
@@ -1018,70 +410,6 @@ HL::Pic::WriteApicRegister(IN APIC_REGISTER Register,
else else
{ {
/* Write to xAPIC */ /* Write to xAPIC */
HL::IoRegister::WriteRegister32((PULONG)(APIC_BASE + (Register << 4)), Value); IoRegister::WriteRegister32((PULONG)(APIC_BASE + (Register << 4)), Value);
} }
} }
/**
* Writes a value to the I/O APIC register.
*
* @param Controller
* Supplies the I/O APIC controller to write to.
*
* @param Register
* Supplies the I/O APIC register to write to.
*
* @param DataValue
* Supplies the value to write to the designated I/O APIC register.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTFASTCALL
VOID
HL::Pic::WriteIOApicRegister(IN PIOAPIC_DATA Controller,
IN UCHAR Register,
IN ULONG DataValue)
{
/* Provide the index to the control port */
HL::IoRegister::WriteRegister32((PULONG)(Controller->VirtualAddress + IOAPIC_IOREGSEL), Register);
/* Commit the value via the data port */
HL::IoRegister::WriteRegister32((PULONG)(Controller->VirtualAddress + IOAPIC_IOWIN), DataValue);
}
/**
* Writes a configuration entry into the I/O APIC redirection table.
*
* @param Controller
* Supplies the I/O APIC controller to write to.
*
* @param EntryNumber
* Supplies the redirection table entry number to write.
*
* @param EntryData
* Supplies the redirection table entry data to write.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTFASTCALL
VOID
HL::Pic::WriteRedirectionEntry(IN PIOAPIC_DATA Controller,
IN ULONG EntryNumber,
IN IOAPIC_REDIRECTION_REGISTER EntryData)
{
ULONG Offset;
/* Calculate the offset of the redirection entry */
Offset = IOAPIC_REDTBL + (EntryNumber * IOAPIC_RTE_SIZE);
/* Mask the entry to prevent spurious interrupts */
WriteIOApicRegister(Controller, Offset, IOAPIC_RTE_MASKED);
/* Write the lower and upper chunks of the entry */
WriteIOApicRegister(Controller, Offset + 1, EntryData.Extended);
WriteIOApicRegister(Controller, Offset, EntryData.Base);
}

View File

@@ -1,328 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/hl/x86/rtc.cc
* DESCRIPTION: Hardware Real-Time Clock (RTC) support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
/**
* Queries the hardware Real-Time Clock (RTC) for the current date and time.
*
* @param Time
* Supplies a pointer to a structure to receive the system time.
*
* @return This routine returns the status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
HL::Rtc::GetRealTimeClock(OUT PTIME_FIELDS Time)
{
UCHAR Century1, Century2, CenturyRegister, RegisterB;
TIME_FIELDS TimeProbe1, TimeProbe2;
PACPI_FADT FadtTable;
BOOLEAN PostMeridiem;
XTSTATUS Status;
ULONG Index;
/* Locate the ACPI FADT table */
Status = HL::Acpi::GetAcpiTable(ACPI_FADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&FadtTable);
if(Status == STATUS_SUCCESS && FadtTable && FadtTable->CenturyAlarmIndex)
{
/* Cache the dynamically provided Century register index */
CenturyRegister = FadtTable->CenturyAlarmIndex;
}
else
{
/* Century register is unavailable */
CenturyRegister = 0;
Century1 = 0;
Century2 = 0;
}
/* Read the RTC Status Register B to determine hardware data formats */
RegisterB = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_B);
/* Assume failure */
Status = STATUS_UNSUCCESSFUL;
/* Execute a maximum of 100 retries to obtain a stable RTC snapshot */
for(Index = 0; Index < 100; Index++)
{
/* Wait until the RTC hardware finishes any ongoing background updates */
while(HL::Firmware::ReadCmosRegister(CMOS_REGISTER_A) & CMOS_REGISTER_A_UPDATE_IN_PROGRESS)
{
/* Yield the processor */
AR::CpuFunc::YieldProcessor();
}
/* Latch the first sequential hardware time snapshot */
TimeProbe1.Hour = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_HOUR);
TimeProbe1.Minute = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_MINUTE);
TimeProbe1.Second = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_SECOND);
TimeProbe1.Day = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_DAY);
TimeProbe1.Month = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_MONTH);
TimeProbe1.Year = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_YEAR);
TimeProbe1.Weekday = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_WEEKDAY);
/* Check if Century register is available */
if(CenturyRegister)
{
/* Read the corresponding Century register */
Century1 = HL::Firmware::ReadCmosRegister(CenturyRegister);
}
/* Wait until the RTC hardware finishes any ongoing background updates */
while(HL::Firmware::ReadCmosRegister(CMOS_REGISTER_A) & CMOS_REGISTER_A_UPDATE_IN_PROGRESS)
{
/* Yield the processor */
AR::CpuFunc::YieldProcessor();
}
/* Latch the second sequential hardware time snapshot for verification */
TimeProbe2.Hour = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_HOUR);
TimeProbe2.Minute = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_MINUTE);
TimeProbe2.Second = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_SECOND);
TimeProbe2.Day = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_DAY);
TimeProbe2.Month = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_MONTH);
TimeProbe2.Year = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_YEAR);
TimeProbe2.Weekday = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_WEEKDAY);
/* Check if Century register is available */
if(CenturyRegister)
{
/* Read the corresponding Century register */
Century2 = HL::Firmware::ReadCmosRegister(CenturyRegister);
}
/* Compare both snapshots to guarantee data consistency */
if((TimeProbe1.Hour == TimeProbe2.Hour) &&
(TimeProbe1.Minute == TimeProbe2.Minute) &&
(TimeProbe1.Second == TimeProbe2.Second) &&
(TimeProbe1.Day == TimeProbe2.Day) &&
(TimeProbe1.Month == TimeProbe2.Month) &&
(TimeProbe1.Year == TimeProbe2.Year) &&
(TimeProbe1.Weekday == TimeProbe2.Weekday) &&
(Century1 == Century2))
{
/* A stable time sample was acquired, break the loop */
Status = STATUS_SUCCESS;
break;
}
}
/* Copy the validated data into the output buffer */
Time->Hour = TimeProbe1.Hour;
Time->Minute = TimeProbe1.Minute;
Time->Second = TimeProbe1.Second;
Time->Milliseconds = 0;
Time->Day = TimeProbe1.Day;
Time->Month = TimeProbe1.Month;
Time->Year = TimeProbe1.Year;
Time->Weekday = TimeProbe1.Weekday;
/* Check if RTC is operating in 12-hour mode */
if(!(RegisterB & CMOS_REGISTER_B_24_HOUR))
{
/* Cache the PM status and strip the hardware flag */
PostMeridiem = (Time->Hour & CMOS_RTC_POST_MERIDIEM) != 0;
Time->Hour &= ~CMOS_RTC_POST_MERIDIEM;
}
/* Convert Binary-Coded Decimal (BCD) values to standard integers if necessary */
if(!(RegisterB & CMOS_REGISTER_B_BINARY))
{
/* Decode all standard time fields */
Time->Hour = BCD_TO_DECIMAL(Time->Hour);
Time->Minute = BCD_TO_DECIMAL(Time->Minute);
Time->Second = BCD_TO_DECIMAL(Time->Second);
Time->Day = BCD_TO_DECIMAL(Time->Day);
Time->Month = BCD_TO_DECIMAL(Time->Month);
Time->Year = BCD_TO_DECIMAL(Time->Year);
Time->Weekday = BCD_TO_DECIMAL(Time->Weekday);
/* Check if Century byte is available */
if(CenturyRegister)
{
/* Convert Century byte */
Century1 = BCD_TO_DECIMAL(Century1);
}
}
/* Standardize hours into a strict 24-hour format */
if(!(RegisterB & CMOS_REGISTER_B_24_HOUR))
{
/* Adjust for midnight and noon boundary cases */
if(Time->Hour == 12)
{
/* 12 AM evaluates to 00:00, 12 PM evaluates to 12:00 */
Time->Hour = PostMeridiem ? 12 : 0;
}
else
{
/* Add 12 hours for PM times */
Time->Hour += PostMeridiem ? 12 : 0;
}
}
/* Merge the century offset with the 2-digit hardware year */
if(Century1 >= 19 && Century1 <= 30)
{
/* Utilize the hardware-provided century base */
Time->Year += (Century1 * 100);
}
else
{
/* Century byte is invalid; apply the sliding window */
Time->Year += (Time->Year > 80) ? 1900 : 2000;
}
/* Return status code */
return Status;
}
/**
* Updates the hardware Real-Time Clock (RTC) with the provided date and time.
*
* @param Time
* Supplies a pointer to a structure with populated data and time.
*
* @return This routine returns the status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
HL::Rtc::SetRealTimeClock(IN PTIME_FIELDS Time)
{
UCHAR Century, CenturyRegister, RegisterB;
TIME_FIELDS SystemTime;
BOOLEAN PostMeridiem;
PACPI_FADT FadtTable;
XTSTATUS Status;
/* Validate the input time boundaries against calendar limits */
if(Time->Hour > 23 || Time->Minute > 59 || Time->Second > 59 ||
Time->Day == 0 || Time->Day > 31 || Time->Month == 0 ||
Time->Month > 12 || Time->Weekday == 0 || Time->Weekday > 7)
{
/* Invalid time parameters, return error code */
return STATUS_INVALID_PARAMETER;
}
/* Assume Ante Meridiem */
PostMeridiem = FALSE;
/* Extract local copy */
SystemTime.Hour = Time->Hour;
SystemTime.Minute = Time->Minute;
SystemTime.Second = Time->Second;
SystemTime.Day = Time->Day;
SystemTime.Month = Time->Month;
SystemTime.Year = (Time->Year % 100);
SystemTime.Weekday = Time->Weekday;
Century = (UCHAR)(Time->Year / 100);
/* Locate the ACPI FADT table */
Status = HL::Acpi::GetAcpiTable(ACPI_FADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&FadtTable);
if(Status == STATUS_SUCCESS && FadtTable && FadtTable->CenturyAlarmIndex)
{
/* Cache the dynamically provided Century register index */
CenturyRegister = FadtTable->CenturyAlarmIndex;
}
else
{
/* Century register is unavailable */
CenturyRegister = 0;
}
/* Read the RTC Status Register B to determine hardware data formats */
RegisterB = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_B);
/* Format hours if the hardware is running in 12-hour mode */
if(!(RegisterB & CMOS_REGISTER_B_24_HOUR))
{
/* Determine if the time is PM */
PostMeridiem = (SystemTime.Hour >= 12);
/* Adjust for midnight and noon boundary cases */
if(SystemTime.Hour == 0)
{
/* Midnight evaluates to 12 AM */
SystemTime.Hour = 12;
}
else if(SystemTime.Hour > 12)
{
/* Post-noon hour */
SystemTime.Hour -= 12;
}
/* Convert to BCD first if needed and apply the hardware PM flag */
if(!(RegisterB & CMOS_REGISTER_B_BINARY))
{
/* Encode to BCD */
SystemTime.Hour = DECIMAL_TO_BCD(SystemTime.Hour);
}
/* Apply the hardware PM flag to the highest bit */
if(PostMeridiem)
{
/* Set PM flag */
SystemTime.Hour |= CMOS_RTC_POST_MERIDIEM;
}
}
else
{
/* 24-hour mode, simply encode to BCD if necessary */
if(!(RegisterB & CMOS_REGISTER_B_BINARY))
{
/* Encode to BCD */
SystemTime.Hour = DECIMAL_TO_BCD(SystemTime.Hour);
}
}
/* Convert remaining standard fields to BCD if necessary */
if(!(RegisterB & CMOS_REGISTER_B_BINARY))
{
/* Encode all standard time fields */
SystemTime.Minute = DECIMAL_TO_BCD(SystemTime.Minute);
SystemTime.Second = DECIMAL_TO_BCD(SystemTime.Second);
SystemTime.Day = DECIMAL_TO_BCD(SystemTime.Day);
SystemTime.Month = DECIMAL_TO_BCD(SystemTime.Month);
SystemTime.Year = DECIMAL_TO_BCD(SystemTime.Year);
SystemTime.Weekday = DECIMAL_TO_BCD((UCHAR)SystemTime.Weekday);
/* Encode the Century byte */
Century = DECIMAL_TO_BCD(Century);
}
/* Freeze the RTC to prevent data tearing */
HL::Firmware::WriteCmosRegister(CMOS_REGISTER_B, RegisterB | CMOS_REGISTER_B_SET_CLOCK);
/* Push the formatted time values into the hardware registers */
HL::Firmware::WriteCmosRegister(CMOS_REGISTER_HOUR, SystemTime.Hour);
HL::Firmware::WriteCmosRegister(CMOS_REGISTER_MINUTE, SystemTime.Minute);
HL::Firmware::WriteCmosRegister(CMOS_REGISTER_SECOND, SystemTime.Second);
HL::Firmware::WriteCmosRegister(CMOS_REGISTER_DAY, SystemTime.Day);
HL::Firmware::WriteCmosRegister(CMOS_REGISTER_MONTH, SystemTime.Month);
HL::Firmware::WriteCmosRegister(CMOS_REGISTER_YEAR, SystemTime.Year);
HL::Firmware::WriteCmosRegister(CMOS_REGISTER_WEEKDAY, SystemTime.Weekday);
/* Check if Century register is available */
if(CenturyRegister)
{
/* Write the corresponding Century register */
HL::Firmware::WriteCmosRegister(CenturyRegister, Century);
}
/* Unfreeze the RTC */
HL::Firmware::WriteCmosRegister(CMOS_REGISTER_B, RegisterB);
/* Return success status code */
return STATUS_SUCCESS;
}

File diff suppressed because it is too large Load Diff

View File

@@ -11,7 +11,7 @@
#include <xtos.hh> #include <xtos.hh>
#include XTOS_ARCH_HEADER(ar, asmsup.hh) #include XTOS_ARCH_HEADER(ar, assembly.hh)
#include XTOS_ARCH_HEADER(ar, cpufunc.hh) #include XTOS_ARCH_HEADER(ar, cpufunc.hh)
#include XTOS_ARCH_HEADER(ar, procsup.hh) #include XTOS_ARCH_HEADER(ar, procsup.hh)
#include XTOS_ARCH_HEADER(ar, traps.hh) #include XTOS_ARCH_HEADER(ar, traps.hh)

View File

@@ -0,0 +1,66 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/amd64/asm.h
* DESCRIPTION: AMD64 architecture assembly definitions
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTOSKRNL_AMD64_ASMSUP_H
#define __XTOSKRNL_AMD64_ASMSUP_H
/* Control Register bit definitions */
#define CR0_PG 0x80000000
#define CR4_PGE 0x00000080
#define CR4_LA57 0x00001000
#define CR4_PCIDE 0x00020000
/* GDT selectors */
#define GDT_R0_CMCODE 0x08
#define GDT_R0_CODE 0x10
#define GDT_R0_DATA 0x18
/* MSR registers */
#define X86_MSR_EFER 0xC0000080
#define X86_MSR_EFER_LME (1 << 8)
/* KTRAP_FRAME structure offsets */
#define TrapXmm0 0
#define TrapXmm1 16
#define TrapXmm2 32
#define TrapXmm3 48
#define TrapXmm4 64
#define TrapXmm5 80
#define TrapXmm6 96
#define TrapXmm7 112
#define TrapXmm8 128
#define TrapXmm9 144
#define TrapXmm10 160
#define TrapXmm11 176
#define TrapXmm12 192
#define TrapXmm13 208
#define TrapXmm14 224
#define TrapXmm15 240
#define TrapMxCsr 256
#define TrapPreviousMode 260
#define TrapCr2 264
#define TrapCr3 272
#define TrapDr0 280
#define TrapDr1 288
#define TrapDr2 296
#define TrapDr3 304
#define TrapDr6 312
#define TrapDr7 320
#define TrapSegDs 328
#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
#define TRAP_REGISTERS_SIZE 176
#endif /* __XTOSKRNL_AMD64_ASMSUP_H */

View File

@@ -1,43 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ar/amd64/asmsup.hh
* DESCRIPTION: Architecture-specific assembler prototypes
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_AR_ASMSUP_HH
#define __XTOSKRNL_AR_ASMSUP_HH
#include <xtos.hh>
/* TrampolineEnableXpa end address to calculate trampoline size */
XTCLINK PVOID ArEnableExtendedPhysicalAddressingEnd[];
/* External array of pointers to the interrupt handlers */
XTCLINK ULONG_PTR ArInterruptEntry[256];
/* TrampolineApStartup end address to calculate trampoline size */
XTCLINK PVOID ArStartApplicationProcessorEnd[];
/* External array of pointers to the trap handlers */
XTCLINK ULONG_PTR ArTrapEntry[256];
/* Forward reference for assembler code */
XTCLINK
XTCDECL
VOID
ArEnableExtendedPhysicalAddressing(IN ULONG_PTR PageMap);
XTCLINK
XTCDECL
VOID
ArHandleSpuriousInterrupt(VOID);
XTCLINK
XTCDECL
VOID
ArStartApplicationProcessor(VOID);
#endif /* __XTOSKRNL_AR_ASMSUP_HH */

View File

@@ -0,0 +1,158 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ar/amd64/assembly.hh
* DESCRIPTION: Architecture-specific assembler prototypes
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_AR_ASSEMBLY_HH
#define __XTOSKRNL_AR_ASSEMBLY_HH
#include <xtos.hh>
/* TrampolineEnableXpa end address to calculate trampoline size */
XTCLINK PVOID ArEnableExtendedPhysicalAddressingEnd[];
/* TrampolineApStartup end address to calculate trampoline size */
XTCLINK PVOID ArStartApplicationProcessorEnd[];
/* Forward reference for assembler code */
XTCLINK
XTCDECL
VOID
ArEnableExtendedPhysicalAddressing(IN ULONG_PTR PageMap);
XTCLINK
XTCDECL
VOID
ArStartApplicationProcessor(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x00(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x01(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x02(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x03(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x04(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x05(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x06(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x07(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x08(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x09(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0A(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0B(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0C(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0D(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0E(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x10(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x11(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x12(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x13(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x1F(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2C(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2D(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2F(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0xE1(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0xFF(VOID);
#endif /* __XTOSKRNL_AR_ASSEMBLY_HH */

View File

@@ -40,7 +40,6 @@ namespace AR
STATIC XTCDECL ULONGLONG ReadModelSpecificRegister(IN ULONG Register); STATIC XTCDECL ULONGLONG ReadModelSpecificRegister(IN ULONG Register);
STATIC XTCDECL UINT ReadMxCsrRegister(VOID); STATIC XTCDECL UINT ReadMxCsrRegister(VOID);
STATIC XTCDECL ULONGLONG ReadTimeStampCounter(VOID); STATIC XTCDECL ULONGLONG ReadTimeStampCounter(VOID);
STATIC XTCDECL ULONGLONG ReadTimeStampCounterProcessor(OUT PULONG TscAux);
STATIC XTCDECL VOID ReadWriteBarrier(VOID); STATIC XTCDECL VOID ReadWriteBarrier(VOID);
STATIC XTCDECL VOID SetInterruptFlag(VOID); STATIC XTCDECL VOID SetInterruptFlag(VOID);
STATIC XTCDECL VOID StoreGlobalDescriptorTable(OUT PVOID Destination); STATIC XTCDECL VOID StoreGlobalDescriptorTable(OUT PVOID Destination);

View File

@@ -24,7 +24,6 @@ namespace AR
STATIC KIDTENTRY InitialIdt[IDT_ENTRIES]; STATIC KIDTENTRY InitialIdt[IDT_ENTRIES];
STATIC KPROCESSOR_BLOCK InitialProcessorBlock; STATIC KPROCESSOR_BLOCK InitialProcessorBlock;
STATIC KTSS InitialTss; STATIC KTSS InitialTss;
STATIC UCHAR NmiStack[KERNEL_STACK_SIZE];
public: public:
STATIC XTAPI PVOID GetBootStack(VOID); STATIC XTAPI PVOID GetBootStack(VOID);
@@ -32,24 +31,9 @@ namespace AR
OUT PVOID *TrampolineCode, OUT PVOID *TrampolineCode,
OUT PULONG_PTR TrampolineSize); OUT PULONG_PTR TrampolineSize);
STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures); STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures);
STATIC XTAPI VOID InitializeProcessorStructures(IN PVOID ProcessorStructures,
OUT PKGDTENTRY *Gdt,
OUT PKTSS *Tss,
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
OUT PVOID *KernelBootStack,
OUT PVOID *KernelFaultStack,
OUT PVOID *KernelNmiStack);
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: private:
STATIC XTAPI VOID IdentifyProcessor(VOID); STATIC XTAPI VOID IdentifyProcessor(VOID);
STATIC XTAPI VOID IdentifyProcessorFeatures(VOID);
STATIC XTAPI VOID InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock); STATIC XTAPI VOID InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock);
STATIC XTAPI VOID InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock); STATIC XTAPI VOID InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock);
STATIC XTAPI VOID InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, STATIC XTAPI VOID InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
@@ -58,11 +42,16 @@ namespace AR
IN PKTSS Tss, IN PKTSS Tss,
IN PVOID DpcStack); IN PVOID DpcStack);
STATIC XTAPI VOID InitializeProcessorRegisters(VOID); STATIC XTAPI VOID InitializeProcessorRegisters(VOID);
STATIC XTAPI VOID InitializeProcessorStructures(IN PVOID ProcessorStructures,
OUT PKGDTENTRY *Gdt,
OUT PKTSS *Tss,
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
OUT PVOID *KernelBootStack,
OUT PVOID *KernelFaultStack);
STATIC XTAPI VOID InitializeSegments(VOID); STATIC XTAPI VOID InitializeSegments(VOID);
STATIC XTAPI VOID InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, STATIC XTAPI VOID InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelBootStack, IN PVOID KernelBootStack,
IN PVOID KernelFaultStack, IN PVOID KernelFaultStack);
IN PVOID KernelNmiStack);
STATIC XTAPI VOID SetGdtEntry(IN PKGDTENTRY Gdt, STATIC XTAPI VOID SetGdtEntry(IN PKGDTENTRY Gdt,
IN USHORT Selector, IN USHORT Selector,
IN ULONG_PTR Base, IN ULONG_PTR Base,
@@ -73,6 +62,13 @@ namespace AR
STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt, STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt,
IN USHORT Selector, IN USHORT Selector,
IN ULONG_PTR Base); 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 Dpl,
IN USHORT Type);
}; };
} }

View File

@@ -17,14 +17,9 @@ namespace AR
{ {
class Traps class Traps
{ {
private:
STATIC PINTERRUPT_HANDLER UnhandledInterruptRoutine;
public: public:
STATIC XTCDECL VOID DispatchInterrupt(IN PKTRAP_FRAME TrapFrame) XTSYMBOL("ArDispatchInterrupt"); STATIC XTCDECL VOID DispatchTrap(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID DispatchTrap(IN PKTRAP_FRAME TrapFrame) XTSYMBOL("ArDispatchTrap");
STATIC XTCDECL VOID InitializeSystemCallMsrs(VOID); STATIC XTCDECL VOID InitializeSystemCallMsrs(VOID);
STATIC XTCDECL VOID SetUnhandledInterruptRoutine(PINTERRUPT_HANDLER Handler);
private: private:
STATIC XTCDECL VOID HandleSystemCall32(VOID); STATIC XTCDECL VOID HandleSystemCall32(VOID);

View File

@@ -0,0 +1,34 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/i686/asm.h
* DESCRIPTION: i686 architecture assembly definitions
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTOSKRNL_I686_ASMSUP_H
#define __XTOSKRNL_I686_ASMSUP_H
/* KTRAP_FRAME structure offsets */
#define TrapPreviousMode 0
#define TrapCr2 4
#define TrapCr3 8
#define TrapDr0 12
#define TrapDr1 16
#define TrapDr2 20
#define TrapDr3 24
#define TrapDr6 28
#define TrapDr7 32
#define TrapSegDs 36
#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_I686_ASMSUP_H */

View File

@@ -1,43 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ar/i686/asmsup.hh
* DESCRIPTION: Architecture-specific assembler prototypes
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_AR_ASMSUP_HH
#define __XTOSKRNL_AR_ASMSUP_HH
#include <xtos.hh>
/* TrampolineEnableXpa end address to calculate trampoline size */
XTCLINK PVOID ArEnableExtendedPhysicalAddressingEnd[];
/* External array of pointers to the interrupt handlers */
XTCLINK ULONG_PTR ArInterruptEntry[256];
/* TrampolineApStartup end address to calculate trampoline size */
XTCLINK PVOID ArStartApplicationProcessorEnd[];
/* External array of pointers to the trap handlers */
XTCLINK ULONG_PTR ArTrapEntry[256];
/* Forward reference for assembler code */
XTCLINK
XTCDECL
VOID
ArEnableExtendedPhysicalAddressing(IN ULONG_PTR PageMap);
XTCLINK
XTCDECL
VOID
ArHandleSpuriousInterrupt(VOID);
XTCLINK
XTCDECL
VOID
ArStartApplicationProcessor(VOID);
#endif /* __XTOSKRNL_AR_ASMSUP_HH */

View File

@@ -0,0 +1,151 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ar/i686/assembly.hh
* DESCRIPTION: Architecture-specific assembler prototypes
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_AR_ASSEMBLY_HH
#define __XTOSKRNL_AR_ASSEMBLY_HH
#include <xtos.hh>
/* TrampolineApStartup end address to calculate trampoline size */
XTCLINK PVOID ArStartApplicationProcessorEnd[];
/* Forward reference for assembler code */
XTCLINK
XTCDECL
VOID
ArStartApplicationProcessor(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x00(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x01(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x02(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x03(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x04(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x05(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x06(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x07(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x08(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x09(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0A(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0B(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0C(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0D(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0E(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x10(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x11(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x12(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x13(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2A(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2B(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2C(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2D(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2E(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0xFF(VOID);
#endif /* __XTOSKRNL_AR_ASSEMBLY_HH */

Some files were not shown because too many files have changed in this diff Show More