272 Commits

Author SHA1 Message Date
465a23633e Sync CMakeLists with current source tree 2025-09-08 22:39:07 +02:00
7c5d6326f8 Migrate EX subsystem to C++ 2025-09-08 22:35:59 +02:00
3f5f57ef12 Remove leftover test code 2025-09-08 15:44:12 +02:00
4e24b239a4 Fix cmake source path 2025-09-08 15:40:26 +02:00
c8dc2a1407 Migrate AR subsystem to C++ 2025-09-08 15:29:13 +02:00
27fec1bacb Add boot options with on-screen debugging 2025-09-05 21:30:01 +02:00
d8e0e07805 Correct format specifier for partition size to prevent stack corruption 2025-09-04 12:21:04 +02:00
8898a427df Rewrite and clarify kernel subsystem descriptions 2025-09-04 11:16:03 +02:00
7e039c47ae Simplify BlpDebugPutChar return path 2025-09-04 10:56:17 +02:00
c2a4ad026a Implement KD subsystem, add serial & framebuffer debug providers 2025-09-04 10:49:40 +02:00
db81e43525 Add missing forward references for RTL types 2025-09-04 10:28:32 +02:00
9cc776e06a Add generic kernel information support 2025-09-03 21:00:18 +02:00
602da0960c Unify string API parameter types to PCSTR/PCWSTR 2025-09-03 19:54:46 +02:00
9577a39046 Fix initialization block size calculation to account for variable-length kernel parameters 2025-09-03 18:10:42 +02:00
f9fe20ba68 Adjust forward references for HL_FRAMEBUFFER_DATA and HL_SCROLL_REGION_DATA 2025-09-03 16:44:52 +02:00
227da47bfc Add scroll region support and refactor framebuffer handling 2025-09-03 15:06:25 +02:00
9f5daafad9 Unify wide string types across console and debug functions 2025-09-03 10:41:24 +02:00
b2df65f5cc Fix KeDbgPrint prototype to use PCWSTR 2025-09-03 10:29:21 +02:00
d6999fad2f Extend RTL with substring search and character case functions 2025-09-02 21:51:10 +02:00
e4981b52ed Comment RtlTokenizeWideString for clarity 2025-09-02 20:18:33 +02:00
3c25934495 Add explanatory comments to string handling code 2025-09-02 19:31:13 +02:00
e23a4c71a2 Fix framebuffer address calculations by using Pitch and BytesPerPixel 2025-09-02 12:42:06 +02:00
6ee7243e04 Refactor APIC delivery mode handling and unify naming 2025-09-01 19:54:12 +02:00
d45cc5ffe5 Fix incorrect APIC delivery mode definitions 2025-09-01 19:32:29 +02:00
3c8b7cb1f2 Remove unused variable 2025-09-01 19:25:45 +02:00
2e415f6ec2 Remove broadcast INIT IPI 2025-09-01 19:23:02 +02:00
5ff9303bd1 Add debug screen clear at end of kernel initialization 2025-09-01 16:27:28 +02:00
84ac8f00e0 Fix APIC initialization and refine comments 2025-09-01 15:41:06 +02:00
418ff68be4 Add ESP boot support and improve block device enumeration 2025-09-01 14:02:38 +02:00
2d1b6363e6 Add CTRL-B shortcut to boot OS directly from edit menu 2025-09-01 12:43:33 +02:00
34cebf2810 Allow editing boot options using 'e' key 2025-09-01 11:47:36 +02:00
0fa4a175e0 Correct Backspace behavior in input dialog 2025-09-01 11:40:48 +02:00
72a832f190 Fix type mismatch in BlGetEditableOptions OptionsCount parameter 2025-08-30 20:35:01 +02:00
ba65264d1e Remove unnecessary console input buffer reset 2025-08-27 22:21:39 +02:00
2ee33ab229 Refactor BlGetConfigValue to return EFI_STATUS and output value via parameter 2025-08-27 19:44:52 +02:00
1eea654a36 Expose BlGetBootOptionValue, BlGetEditableOptions and BlSetBootOptionValue 2025-08-27 19:26:01 +02:00
c6643125e1 Implement boot entry editor 2025-08-27 19:15:38 +02:00
b68514b176 Limit boot menu entry names to available menu width 2025-08-25 19:03:57 +02:00
960e913222 Optimize boot menu drawing to eliminate screen flickering 2025-08-25 17:56:40 +02:00
e99e563aff Correct .modinfo section parsing 2025-08-25 12:07:49 +02:00
0b40a3fb10 Refactor MMU for multi-paging support and add 5-Level paging 2025-08-23 20:03:56 +02:00
a84ef21571 Adjust LA57 base addresses to prevent overflow 2025-08-21 01:42:36 +02:00
1ef2560ef6 Enable LA57 by invoking the trampoline code 2025-08-21 00:14:49 +02:00
d1b14fccdd Resolve build issues caused by the last commit 2025-08-20 21:08:43 +02:00
88b3a57962 Allow specifying an allocation type when allocating pages 2025-08-20 20:59:31 +02:00
9f6121e9b2 Map the physical page for trampoline code 2025-08-20 20:37:55 +02:00
4a7ea6009d Expose ArEnableExtendedPhysicalAddressing function in XTDK 2025-08-20 20:23:44 +02:00
c4a7df6f38 Extract trampoline code into a separate file 2025-08-20 20:20:35 +02:00
2468d80078 Add trampoline to enable 5-level paging 2025-08-20 00:20:10 +02:00
ebae8c655c Expand CR4, MSR, and EFER register definitions 2025-08-19 23:59:58 +02:00
1a0bc7f65f Update and correct CR4 bit definitions 2025-08-19 21:45:13 +02:00
91a5db2ee4 Implement PML5 support in XtpMapHardwareMemoryPool 2025-08-18 12:13:48 +02:00
b639bf3077 Implement PML5 self-mapping 2025-08-18 11:59:05 +02:00
c409400cbf Correct VA masking in AMD64 page mapping functions 2025-08-18 01:07:28 +02:00
d602038858 Temporarily disable LA57 paging 2025-08-18 00:10:32 +02:00
017b8603d5 Align parameters in PTE manipulation functions 2025-08-17 21:55:21 +02:00
a9dd1eaacd Implement MmpSetPteCaching function for AMD64 architecture 2025-08-17 21:51:43 +02:00
f30d3df5b3 Implement PTE manipulation functions for AMD64 architecture 2025-08-17 21:48:28 +02:00
c3ece4f317 Fix type usage in XtpMapHardwareMemoryPool 2025-08-17 00:51:26 +02:00
1e11acee72 Refactor hardware memory mapping to use page map routine callbacks 2025-08-17 00:47:56 +02:00
57193eecc0 Implement PML2/PML3 page table routines 2025-08-17 00:45:12 +02:00
720d525b95 Assign page map routines 2025-08-17 00:29:28 +02:00
f77f2bbf92 Introduce architecture-specific page map routines 2025-08-17 00:23:19 +02:00
0ed59f223c Relocate page mapping helpers and add PML5 support 2025-08-16 21:07:54 +02:00
de2973ac42 Implement page map info initialization 2025-08-16 20:28:05 +02:00
8491e5fed1 Remove PageMapLevel from the loader information block 2025-08-16 20:18:34 +02:00
6a330e38f2 Consolidate paging-related globals into MmpPageMapInfo 2025-08-16 20:14:18 +02:00
1dcd3fceed Define page map information structure for both supported architectures 2025-08-16 20:08:12 +02:00
5768d4bba6 Prepare for architecture-specific paging initialization 2025-08-16 19:58:00 +02:00
f85fe31b38 Adapt i686 memory mapping to new PML3 types 2025-08-16 00:36:20 +02:00
22f81a106b Update forward declarations for PML2/PML3 types 2025-08-16 00:33:18 +02:00
7e08dc286e Separate types for legacy (PML2) and PAE (PML3) paging 2025-08-16 00:29:20 +02:00
3ca6d04f6b Add definitions for 5-level paging and refactor constants 2025-08-16 00:22:21 +02:00
e57985da8d Rename MM_LA57_SHIFT to MM_P5I_SHIFT for consistency 2025-08-15 20:49:25 +02:00
8a23cc444f Merge branch 'master' into harraiken_mm 2025-08-15 11:30:48 +02:00
2e0a87e596 Use __asm__ to comply with disabled GNU extensions 2025-08-15 11:07:07 +02:00
e8771dfc5b Use __asm__ to comply with disabled GNU extensions 2025-08-15 00:32:56 +02:00
030575592c Revert 'Fix broken HlpInitializeAcpiSystemDescriptionTable implementation' 2025-08-11 23:30:40 +02:00
88fba6d408 revert 'Fix broken HlpInitializeAcpiSystemDescriptionTable declaration' 2025-08-11 23:29:57 +02:00
2375a653fe Resolve potential PDE conflict in non-PAE boot path 2025-08-11 20:59:00 +02:00
bf291613a3 Add debug messages to display PML set by bootloader 2025-08-10 18:07:26 +02:00
406c0a0cd2 Fix broken HlpInitializeAcpiSystemDescriptionTable declaration 2025-08-10 17:48:48 +02:00
c9f9f87973 Fix broken HlpInitializeAcpiSystemDescriptionTable implementation 2025-08-10 17:48:01 +02:00
383d5eeb06 Add missing forward declaration to resolve compile issue 2025-08-10 17:43:27 +02:00
dce2c50b9d Replace hardcoded PML level with dynamic detection using XtpDeterminePagingLevel 2025-08-10 17:39:38 +02:00
e888befee1 Add boot menu entry for booting ExectOS with XPA (eXtended Physical Addressing) disabled 2025-08-10 17:35:37 +02:00
a33a45fc20 Implement paging level detection for AMD64 based on CPUID and boot parameters 2025-08-10 17:27:12 +02:00
23e8be1097 Remove PAE support check to allow both PAE and non-PAE configurations 2025-08-10 17:25:04 +02:00
800810169d Fix XtpDeterminePagingLevel after renaming CPUID requests 2025-08-10 17:19:44 +02:00
eeb5e8d455 Fix broken AcGetApicBase 2025-08-10 17:16:48 +02:00
d806c8e1f2 Resolve compilation errors due to renamed CPUID requests 2025-08-10 17:12:06 +02:00
2ea306097d Resolve compilation errors due to renamed CPUID requests 2025-08-10 17:10:01 +02:00
3472b448c7 Fix broken AcGetApicBase implementation 2025-08-10 17:05:13 +02:00
e62820187d Resolve compilation errors due to updated CPUID requests 2025-08-10 17:01:28 +02:00
a6814aa2a3 Resolve compilation errors due to renamed CPUID requests 2025-08-10 16:59:32 +02:00
560bd8b65e Update CPUID requests 2025-08-10 16:53:45 +02:00
a431816243 Update CPUID requests 2025-08-10 16:52:59 +02:00
574582f977 Add forward declarations for CPUID feature enums 2025-08-10 16:36:32 +02:00
23f022965a Add forward declarations for CPUID feature enums 2025-08-10 16:35:40 +02:00
aef81760d0 Rename enumeration lists 2025-08-10 16:33:36 +02:00
bb5deb10d5 Rename enumeration lists 2025-08-10 16:32:49 +02:00
69d4e0cd84 Add enums for CPU feature flags used in CPUID detection 2025-08-10 16:27:14 +02:00
a9a264252a Add enums for CPU feature flags used in CPUID detection 2025-08-10 16:25:26 +02:00
a539191a33 Implement paging level detection for i686 based on CPUID and boot parameters 2025-08-10 15:42:41 +02:00
3f2496644f Compile bootutil.c 2025-08-10 00:12:01 +02:00
daf8b87832 Expose GetBooleanParameter via loader protocol 2025-08-10 00:10:36 +02:00
a2b9af56dd Add boot utils to loader protocol 2025-08-10 00:07:40 +02:00
8de661494a Add BlGetBooleanParameter declaration 2025-08-10 00:04:25 +02:00
07f2e73a22 Add helper functions used by the boot protocol during system startup 2025-08-09 23:58:52 +02:00
2472cbbff4 Revert 'Simplify and correct hardware pool mapping' 2025-08-09 17:15:35 +02:00
58c2092049 Revert latest changes 2025-08-09 14:53:31 +02:00
311d5e1f5c Simplify and correct hardware pool mapping 2025-08-08 21:49:21 +02:00
39d8f82caf Define MM_HARDWARE_POOL_PAGE_COUNT 2025-08-08 21:44:33 +02:00
d7552f1dce Fix race condition in HlComPortReadLsr
The static local variable RingFlag in HlComPortReadLsr caused shared state across multiple calls and ports, leading to race conditions and incorrect behavior.
2025-08-06 09:01:47 +02:00
9badf36ce0 Add ring indicator field to CPPORT structure 2025-08-05 23:25:30 +02:00
aff069dd1a Add i686-specific implementation of BlpGetNextPageTable supporting PML2 and PML3 2025-08-04 23:28:12 +02:00
f29f2bca74 Add AMD64-specific implementation of BlpGetNextPageTable matching new signature 2025-08-04 23:25:57 +02:00
544ec63d6e Remove global BlpGetNextPageTable implementation in favor of arch-specific versions 2025-08-04 23:22:23 +02:00
ed75060482 Update BlpGetNextPageTable declaration to support multiple levels of PML 2025-08-04 23:01:03 +02:00
1d376486cd Add myself to the list of authors due to significant contributions 2025-08-04 14:34:40 +02:00
1ffddfd0e2 Add non-PAE paging support to BlMapPage 2025-08-04 14:18:21 +02:00
0d3fb550f2 Initialize page directory for non-PAE paging 2025-08-04 14:05:58 +02:00
ca6c913fa7 Clarify PAE state management logic 2025-08-02 18:30:23 +02:00
ca06f9ebb5 Correctly manage PAE state when enabling paging 2025-08-02 18:26:01 +02:00
e6ebac7cda Correct status variable type in XtpMapHardwareMemoryPool 2025-07-30 21:50:36 +02:00
4453b95f5c Correct status variable type in XtpMapHardwareMemoryPool 2025-07-30 21:48:38 +02:00
61d5e36a4e Partially revert previous commit 2025-07-30 17:23:11 +02:00
410b96b58a Zero-initialize Page Directory entries before use 2025-07-30 17:19:37 +02:00
66e136c7d6 Enable paging 2025-07-30 16:58:25 +02:00
d61b48740f Declare CpuRegisters as a local structure instead of a pointer 2025-07-30 16:53:07 +02:00
3607a6d930 Zero-initialize Page Directory entries before use 2025-07-30 16:49:49 +02:00
c8787c3bd6 Zero-initialize Page Directory entries before use 2025-07-30 16:38:17 +02:00
b83c3923da Change artifact URL to show newest builds first for easier access 2025-07-29 18:33:36 +02:00
a694be3795 Ensure all artifacts are published by the pipeline 2025-07-29 18:27:03 +02:00
9eae01cc98 Disable built-in compiler functions 2025-07-29 18:20:20 +02:00
58e3371fac Extend matrix to include release configuration alongside debug 2025-07-29 14:12:02 +02:00
98c3b93c3d Include build type in build dir name 2025-07-29 13:57:47 +02:00
15a81b03d9 Include build type in build dir name and remove misleading symlink 2025-07-29 12:32:31 +02:00
7fce778ee4 Harden BlpDuplicateDevicePath against malformed device paths 2025-07-29 12:15:27 +02:00
b0aabf96b8 Improve device enumeration logic in BlEnumerateBlockDevices
These changes result in a more robust and reliable device enumeration process, better prepared to handle edge cases and non-standard firmware behavior.
2025-07-29 10:44:50 +02:00
486e987b71 Ensure correct boot volume is used by the chainloader 2025-07-29 08:04:33 +02:00
ecaf923e6d Ensure correct boot volume is used to boot XTOS 2025-07-29 08:01:32 +02:00
953de7fb5f Correct default OS selection in boot menu 2025-07-28 21:39:07 +02:00
55ef9bf686 Correct function declaration for BlpFindParentBlockDevice 2025-07-28 19:45:19 +02:00
6823982227 Correctly return parent device in BlpFindParentBlockDevice 2025-07-28 19:43:13 +02:00
ff41b0d4f7 Fix incorrect TSS descriptor limit according to architecture specification 2025-07-28 18:25:47 +02:00
6130a34587 Align stack as required by the ABI 2025-07-28 17:57:16 +02:00
2ca708fe43 Define stack alignment required by the architecture's ABI 2025-07-28 17:53:50 +02:00
d2ce921676 Remove completed item 2025-07-20 16:49:06 +02:00
a81bad32fe Implement scrolling in the boot menu 2025-07-20 16:45:15 +02:00
da3e039a05 Use correct address when clearing COM port buffer
The code was reading from Port->Address to clear the RBR before the field was initialized.
2025-07-20 14:53:04 +02:00
e778a95a01 Use portable affinity mask for the idle process 2025-07-20 12:34:20 +02:00
24b6cc2250 Use portable affinity mask for the idle process
The hardcoded value 0xFFFFFFFF restricted the idle process to the first 32 processors on 64-bit system.
2025-07-20 12:33:10 +02:00
fdf649fcec Correctly initialize the boot stack pointer, as the stack grows downwards 2025-07-19 17:41:38 +02:00
61fcf8e0ec Update readme 2025-07-17 19:58:51 +02:00
d85ed34ce2 Remove duplicated XTchain detection 2025-07-09 10:52:48 +02:00
dcb0b8fb4b Initialize UBSAN mismatch data without relying on memset() 2025-07-09 10:40:15 +02:00
6729d72322 Add missing copyright notice 2025-07-09 10:31:36 +02:00
b229854ae0 Add configuration script for setting up Windows build environment 2025-07-09 10:28:46 +02:00
e0125dda54 Use virtual FAT disk images 2025-01-24 09:19:59 +01:00
7b8f4f15cc Add APIC Logical Destination Register (LDR) shifts and correct APIC delivery mode values 2024-07-23 20:14:06 +02:00
2e7793dc2b Implement HlpGetCpuApicId() routine 2024-07-22 23:31:20 +02:00
2c5b680426 Implement HlpSendIpi() routine 2024-07-22 23:23:55 +02:00
626ece8046 HlReadApicRegister() should return and HlWriteApicRegister() should take ULONGLONG value 2024-07-16 22:36:45 +02:00
088940424d Fix data types and rename some fields to avoid confusion 2024-07-16 16:28:12 +02:00
7abd0f3017 Revert unintentional change 2024-07-14 12:13:56 +02:00
f8519ec09d Rename HlpAcpiSystemInfo global variable to HlpSystemInfo 2024-07-14 12:11:39 +02:00
3bda67be0a Basic ACPI system info initialization code for traversing MADT tables 2024-07-13 21:08:58 +02:00
cb64235953 Use PHYSICAL_ADDRESS data type in MmAllocateHardwareMemory() routine as it is used in MmMapHardwareMemory() as well to avoid the need of data conversion 2024-07-13 15:54:10 +02:00
ceb36ae8ec Add PAGES_TO_SIZE macro definition 2024-07-13 15:39:08 +02:00
94076b7471 Separate image base address per architecture 2024-07-10 22:42:48 +02:00
ebc2607446 Update compiler optimization flags 2024-07-10 17:57:29 +02:00
801cf64f45 Update kernel readme 2024-07-10 16:10:48 +02:00
f52c50242a Correct comment 2024-07-09 22:57:02 +02:00
3f10e1b59e Fix page fault when trying to find ACPI table 2024-07-09 22:47:26 +02:00
47219585d4 Fix pointer operation overflow 2024-07-09 22:40:32 +02:00
e46f2e6116 Ensure that table header is not set before attempting to find ACPI table 2024-07-09 22:36:40 +02:00
3804786e89 All ACPI related structures should be packed 2024-07-07 22:13:34 +02:00
6bcf3e134f Unify naming convention and switch to ULONG in memory map related routines 2024-07-06 22:59:10 +02:00
cc0edeeb47 Add missing forward reference update to fix build 2024-06-22 19:16:00 +02:00
156cb7bcac Refactor system resources to be able to distinguish if requested resource does not exist or if it is locked and cannot be reused 2024-06-22 18:54:34 +02:00
c2db94125d Add appropriate crediting for Minoca authors for the System Resources component 2024-06-21 17:00:20 +02:00
330d3fa72e Fix routines order for better maintainability 2024-06-21 16:50:05 +02:00
6b70074ec6 Update Discord badge 2024-06-14 16:33:16 +02:00
712107ae10 Simplify XTOS library 2024-06-12 18:40:52 +02:00
906e09fd9f Refactor COM port support, to get rid of global variables in library 2024-06-12 18:02:29 +02:00
91e8a86ee2 Implement kernel undefined behavior sanitizer support 2024-06-12 16:19:24 +02:00
c7e96184e6 Correct typo 2024-06-12 16:11:38 +02:00
3c1eea33d9 Update ideas 2024-06-10 18:40:33 +02:00
bfe3d4b18a Fix pointer overflow 2024-06-10 16:01:19 +02:00
bd7d4f5a0d Fix function type mismatch undefined behavior when calling through a pointer 2024-06-09 22:26:01 +02:00
3097ff6250 Get rid of NULL pointer dereference 2024-06-09 12:45:01 +02:00
2f16f4f613 Traverse Local x2APIC structures to find all processors 2024-06-07 23:05:12 +02:00
f36b59c961 Store processor identities in system info structure 2024-06-07 20:19:56 +02:00
86bc2042e5 Cleanup XTDK headers 2024-06-06 23:09:03 +02:00
658cb2d3c8 Get system information based on the ACPI (currently only number of CPUs) 2024-06-06 22:05:32 +02:00
829fc49aac Fix ACPI cache causing some undefined behavior 2024-06-06 21:52:41 +02:00
92e861ebae Cleanup APIC related headers 2024-06-06 21:50:20 +02:00
4212453cf5 Fix APIC initialization code 2024-06-06 16:49:08 +02:00
ef65bceccd Initialize legacy PIC and mask all interrupts 2024-06-05 16:08:54 +02:00
b061c87fc9 Fix routines with no prototype using XTAPI calling convention compiler warnings 2024-06-04 21:41:16 +02:00
8a4caba26f Fix routine with no prototype using XTAPI calling convention compiler warning 2024-06-04 21:39:10 +02:00
76e1fc6099 Enable hardware layer initialization code 2024-06-04 21:36:09 +02:00
7b29897efb Initialize ACPI Timer 2024-06-04 21:04:09 +02:00
7704e5d399 Initial kernel ACPI support 2024-06-04 16:24:13 +02:00
db5d6c42c9 Rework AcpChecksumTable() routine into AcpValidateAcpiTable() 2024-06-03 23:31:33 +02:00
54b7e46f1b Simplify AcGetAcpiTable() routine a bit 2024-06-03 23:24:54 +02:00
de709162e3 ACPI_RSDT structure does not need to be packed 2024-06-03 22:27:36 +02:00
5d2d409d0f Add more XTSTATUS status codes 2024-06-03 22:14:58 +02:00
f265810a5c Fix AcGetAcpiTable() routine failing to validate FADT checksum on some ACPI 2.0 and older machines 2024-06-03 21:58:19 +02:00
9124574bc5 Fixes and improvements to ACPI related structures and definitions 2024-06-03 21:17:31 +02:00
7f922dd864 Let XTLDR provide ACPI system resource 2024-06-02 22:30:52 +02:00
c289dab514 Add ACPI resource type 2024-06-02 21:36:59 +02:00
29ff9e114e Mark XtMapHardwareMemoryPool() routine private 2024-06-02 17:34:30 +02:00
c1ab5fe98d Cleanup hardware allocation memory pool related code for i686 2024-06-02 17:32:39 +02:00
6176ca38a8 Cleanup hardware allocation memory pool related code 2024-06-02 17:29:31 +02:00
abb65b99fe HlPool manages hardware related memory 2024-06-02 17:01:45 +02:00
6b1ccc4ce5 Do not hardcode PML shift values 2024-05-27 22:26:05 +02:00
f968eb21fd Cleanup the code 2024-05-27 22:20:53 +02:00
7f8846f23d Map memory for hardware layer on i686 2024-05-27 22:17:30 +02:00
ae243a9d07 Map memory for hardware layer on amd64 2024-05-27 21:54:21 +02:00
a7c4f6c2aa Fix MmMapHalMemory() not using the ReturnAddress for calculating virtual address 2024-05-26 10:50:31 +02:00
4a275b3dec Just skip unsupported system resources 2024-05-26 00:09:31 +02:00
70d1295919 Do not support non-PAE systems 2024-05-24 23:47:29 +02:00
03ba3b5583 Add missing forward references for APIC related structures 2024-05-24 23:41:27 +02:00
94a40501d4 Mask APIC ICR0 and disable APIC interrupts for initialization time by raising APIC TPR 2024-05-24 23:39:06 +02:00
b4588d5b4c Make ExectOS only run on processors which support PAE 2024-05-24 16:30:39 +02:00
5221db2e63 Rename LOADER_MEMORY_MAPPING structure to more meaningful LOADER_MEMORY_DESCRIPTOR 2024-05-23 19:00:50 +02:00
143803aad9 PPE needs PAE on i686 2024-05-22 23:09:30 +02:00
edbc2cc045 Initialize architecture specific hardware extensions 2024-05-22 22:53:29 +02:00
609538b9be Implement MmpGetPdeAddress() and MmpGetPteAddress() routines for i686 architecture as well as MmpMemoryExtensionEnabled() for checking PAE/LA57 support 2024-05-22 22:47:28 +02:00
4db5425238 Add PHYSICAL_ADDRESS type definition 2024-05-22 18:52:57 +02:00
03727a61d3 Implement hardware layer pool memory management 2024-05-22 18:51:09 +02:00
28903e0c10 Add missing forward reference for AcGetAcpiTable() routine 2024-05-20 15:34:49 +02:00
500498508e Rename PACK definition 2024-05-20 15:34:15 +02:00
ac33b86c3d Implement AcGetAcpiTable() routine 2024-05-19 23:45:28 +02:00
4931f1b9a3 Cleanup loader information block after switching to system resources 2024-05-18 17:32:56 +02:00
c17f6a95d4 Use relative path in debug output 2024-05-18 17:30:11 +02:00
34cc81c446 Provide framebuffer information via system resource 2024-05-18 17:06:44 +02:00
2103b2dafd Make sure frame buffer is initialized before drawing 2024-05-18 16:57:38 +02:00
d2014a5e82 Use HlpRGBColor() internally 2024-05-17 23:29:03 +02:00
811b173387 Re-enable interrupts only if they were enabled previously 2024-05-17 23:24:04 +02:00
740df726e9 Implement ArInterruptsEnabled() routine 2024-05-17 23:19:25 +02:00
5591e1b377 Fix ArGetCpuFlags() routine 2024-05-17 23:16:16 +02:00
41bc673694 Initialize framebuffer device based on a system resource provided by boot loader 2024-05-17 22:37:42 +02:00
8a15d46198 Initialize system resource as soon as possible 2024-05-17 22:31:29 +02:00
1e2efce26a Add a system resources list to the initialization block 2024-05-16 23:20:57 +02:00
74c1b03a6b Implement a system resources management routines 2024-05-16 23:08:59 +02:00
058649036f Take care about blink first, otherwise BlPhysicalListToVirtual() fails to properly map single-element linked list 2024-05-16 22:17:40 +02:00
f74a5521ba Update KPROCESS and KTHREAD structure definitions 2024-05-14 19:44:10 +02:00
9f1a4f0ced Compose the AMD family and model IDs according to the AMD CPUID manual, section 2 2024-05-14 19:39:07 +02:00
2a8cc7397e Implement ArGetCpuFlags() routine 2024-05-14 16:26:02 +02:00
efef3cb80d Cleanup EFLAGS related definitions 2024-05-14 16:22:10 +02:00
01d127f49e Consider not initialized list as empty, what prevents page faults 2024-05-14 15:53:21 +02:00
60a9e4b534 Rename source file with fb-related stuff, fix build 2024-05-13 15:59:24 +02:00
086d9ed7e2 Rename source file with fb-related stuff 2024-05-13 15:55:39 +02:00
78424385fc Convert RGB colors to FrameBuffer format 2024-05-13 08:51:27 +02:00
e311cad8f7 Allow to clear framebuffer screen with any, custom background color 2024-05-12 22:43:06 +02:00
c576f7f8f2 Provide pixel information to the kernel 2024-05-12 22:28:06 +02:00
615a1457bf Fixes to FbpGetPixelInformation() and FbpGetColorMask() routines 2024-05-12 22:20:22 +02:00
3d08be4fac Refactor kernel startup code 2024-05-12 09:06:24 +02:00
eeeb9d6ed7 Update PoInitializeProcessorControlBlock() routine and corresponding structures 2024-05-09 22:12:50 +02:00
c34b6ff6c1 Take CPU number from processor block 2024-05-08 21:59:18 +02:00
38b0b2ac7d Use correct stack when using preallocated processor structures 2024-05-08 15:57:24 +02:00
3c3a756771 Allow to initialize CPU with allocated processor structures 2024-05-08 00:02:47 +02:00
fb099a1988 Preallocate buffer for all supported CPUs 2024-05-07 23:47:58 +02:00
b65ff2a767 Implement MmAllocateProcessorStructures() routine as a temporary hack to get a buffer for AP initialization 2024-05-07 23:30:11 +02:00
8d6d27651c Implement KeGetCurrentProcessorNumber() routine 2024-05-07 18:52:43 +02:00
f66e9aea9e Store CPU number and mask interrupts in processor block 2024-05-07 16:21:38 +02:00
276eb77862 Update KPROCESSOR_BLOCK structure 2024-05-07 16:20:40 +02:00
ac0b8ab36a Allow to specify CPU number when initializing (A)PIC 2024-05-07 16:16:49 +02:00
2c384d780f Fix storing CPU vendor name in PRCB 2024-05-06 20:01:19 +02:00
164 changed files with 15019 additions and 4759 deletions

View File

@@ -7,6 +7,7 @@ jobs:
strategy: strategy:
matrix: matrix:
arch: [amd64, i686] arch: [amd64, i686]
build: [debug, release]
runs-on: oscw runs-on: oscw
container: container:
image: codingworkshop/oscw-runner:latest image: codingworkshop/oscw-runner:latest
@@ -17,7 +18,7 @@ jobs:
fetch-depth: 0 fetch-depth: 0
- name: Build ExectOS - name: Build ExectOS
run: | run: |
echo "charch ${{ matrix.arch }} && ./configure.sh && cd build-${{ matrix.arch }}-xtchain && xbuild -v && xbuild diskimg -v" > build.cmds echo "charch ${{ matrix.arch }} && chbuild ${{ matrix.build }} && ./configure.sh && cd build-${{ matrix.arch }}-${{ matrix.build }} && xbuild -v && xbuild diskimg -v" > build.cmds
xtchain < build.cmds xtchain < build.cmds
- name: Publish binaries - name: Publish binaries
if: ${{ github.ref == 'refs/heads/master' }} if: ${{ github.ref == 'refs/heads/master' }}
@@ -26,8 +27,8 @@ jobs:
OSCW_ARTIFACTS_USERNAME: ${{ secrets.OSCW_ARTIFACTS_USERNAME }} OSCW_ARTIFACTS_USERNAME: ${{ secrets.OSCW_ARTIFACTS_USERNAME }}
OSCW_ARTIFACTS_USERKEY: ${{ secrets.OSCW_ARTIFACTS_USERKEY }} OSCW_ARTIFACTS_USERKEY: ${{ secrets.OSCW_ARTIFACTS_USERKEY }}
run: | run: |
tar -I 'gzip' -cpf ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}-bin.tar.gz -C build-${{ matrix.arch }}-xtchain/output/binaries . tar -I 'gzip' -cpf ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}-${{ matrix.build }}-bin.tar.gz -C build-${{ matrix.arch }}-${{ matrix.build }}/output/binaries .
tar -I 'gzip' -cpf ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}-lib.tar.gz -C build-${{ matrix.arch }}-xtchain/output/library . tar -I 'gzip' -cpf ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}-${{ matrix.build }}-lib.tar.gz -C build-${{ matrix.arch }}-${{ matrix.build }}/output/library .
tar -I 'gzip' -cpf ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}-sym.tar.gz -C build-${{ matrix.arch }}-xtchain/output/symbols . tar -I 'gzip' -cpf ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}-${{ matrix.build }}-sym.tar.gz -C build-${{ matrix.arch }}-${{ matrix.build }}/output/symbols .
gzip -c build-${{ matrix.arch }}-xtchain/output/disk.img > ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}.img.gz gzip -c build-${{ matrix.arch }}-${{ matrix.build }}/output/disk.img > ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}-${{ matrix.build }}.img.gz
artifact_publish "ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}*.gz" ExectOS artifact_publish "ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}-${{ matrix.build }}*.gz" ExectOS

View File

@@ -1,8 +1,5 @@
# Detect XTChain toolchain # Minimum CMake version requirement
cmake_minimum_required(VERSION 3.19.0) cmake_minimum_required(VERSION 3.19.0)
if(NOT CMAKE_VERSION MATCHES "XTC")
message(FATAL_ERROR "XTChain not detected or corrupted!")
endif()
# Lowercase target architecture # Lowercase target architecture
string(TOLOWER ${ARCH} ARCH) string(TOLOWER ${ARCH} ARCH)
@@ -44,7 +41,7 @@ set(CMAKE_TOOLCHAIN_FILE "sdk/cmake/toolchain.cmake")
project(EXECTOS) project(EXECTOS)
# Load all the CMake SDK # Load all the CMake SDK
include(sdk/cmake/baseaddress.cmake) include(sdk/cmake/baseaddress/${ARCH}.cmake)
include(sdk/cmake/emulation.cmake) include(sdk/cmake/emulation.cmake)
include(sdk/cmake/functions.cmake) include(sdk/cmake/functions.cmake)
include(sdk/cmake/version.cmake) include(sdk/cmake/version.cmake)

View File

@@ -11,15 +11,13 @@ This is a list of ideas that migh but not must be realized.
### XTLDR ### XTLDR
- [ ] Rewrite memory mapping and paging support in bootloader to make it more flexible and architecture independent. - [ ] Rewrite memory mapping and paging support in bootloader to make it more flexible and architecture independent.
This should support paging levels, thus allowing to make a use of PML5 on modern AMD64 processors and increasing This should support paging levels, thus allowing to make a use of PML5 on modern AMD64 processors and increasing
the addressable virtual memory from 256TB to 128PB. the addressable virtual memory from 256TB to 128PB. This is partially done.
- [ ] Find graphics card from all PCI devices and identify its framebuffer address when GOP is not supported by UEFI - [ ] Implement editing boot menu entries directly from the boot menu. Changes should be runtime only (not stored on
firmware and UGA has to be used instead. disk).
### XTOSKRNL ### XTOSKRNL
- [ ] Implement mechanism for detecting CPU features and checking hardware requirements. If CPU does not meet - [ ] Implement mechanism for detecting CPU features and checking hardware requirements. If CPU does not meet
requirements, it should cause a kernel panic before any non-supported instruction is being used. requirements, it should cause a kernel panic before any non-supported instruction is being used.
- [ ] Design a mechanism of sharing common code between some architectures (i.e. both i686 and amd64 supports APIC,
while it is not available on ARM).
- [ ] Finish framebuffer and terminal implementation. Initialization code is already prepared as well as routines for - [ ] Finish framebuffer and terminal implementation. Initialization code is already prepared as well as routines for
clearing the screen and drawing single points. Terminal should be instantiable (should be able to create many clearing the screen and drawing single points. Terminal should be instantiable (should be able to create many
terminals and switch between them) and work on top of FB. It should define ANSI colors and scrollback buffer. terminals and switch between them) and work on top of FB. It should define ANSI colors and scrollback buffer.

View File

@@ -8,20 +8,20 @@
<a href="https://git.codingworkshop.eu.org/xt-sys/exectos/actions"> <a href="https://git.codingworkshop.eu.org/xt-sys/exectos/actions">
<img alt="Build Status" src="https://codingworkshop.eu.org/actions.php?project=xt-sys/exectos"> <img alt="Build Status" src="https://codingworkshop.eu.org/actions.php?project=xt-sys/exectos">
</a> </a>
<a href="https://artifacts.codingworkshop.eu.org/ExectOS"> <a href="https://artifacts.codingworkshop.eu.org/ExectOS/?C=M&O=D">
<img alt="CI/CD Artifacts" src="https://img.shields.io/badge/Download-%F0%9F%A1%87-blueviolet"> <img alt="CI/CD Artifacts" src="https://img.shields.io/badge/Download-%F0%9F%A1%87-blueviolet">
</a> </a>
<a href="https://git.codingworkshop.eu.org/xt-sys/exectos/src/branch/master/COPYING.md"> <a href="https://git.codingworkshop.eu.org/xt-sys/exectos/src/branch/master/COPYING.md">
<img alt="License" src="https://img.shields.io/badge/License-GPLv3-blue.svg"> <img alt="License" src="https://img.shields.io/badge/License-GPLv3-blue.svg">
</a> </a>
<a href="https://codeium.com/"> <a href="https://exectos.eu.org/ai-assisted">
<img alt="Codeium" src="https://img.shields.io/badge/Powered%20By-Codeium-09B6A2?logo=Codeium"> <img alt="AI Assisted" src="https://img.shields.io/badge/AI-Assisted-darkcyan">
</a> </a>
<a href="https://github.com/sponsors/xt-sys/"> <a href="https://github.com/sponsors/xt-sys/">
<img alt="Sponsor" src="https://img.shields.io/badge/Sponsor-%E2%9D%A4-red?logo=GitHub"> <img alt="Sponsor" src="https://img.shields.io/badge/Sponsor-%E2%9D%A4-red?logo=GitHub">
</a> </a>
<a href="https://discord.com/invite/zBzJ5qMGX7"> <a href="https://discord.com/invite/zBzJ5qMGX7">
<img alt="Discord" src="https://img.shields.io/discord/723186294540206100?label=Chat"> <img alt="Discord" src="https://img.shields.io/badge/Chat-Join%20Discord-success">
</a> </a>
</p> </p>
@@ -69,15 +69,12 @@ design, it requires a modern EFI enabled hardware. It is not possible currently
| xtldr | XTOS boot loader source code | | xtldr | XTOS boot loader source code |
# Build # Build
XTOS can be built only by using [XTChain](https://git.codingworkshop.eu.org/xt-sys/xtchain), a special toolchain XTOS can only be built using [XTchain](https://git.codingworkshop.eu.org/xt-sys/xtchain), a dedicated toolchain designed
prepared for compiling XT software. Currently, there is only a Linux version available, so a Linux distribution or WSL specifically for compiling XT software. XTChain is currently available for both Linux and Windows. Detailed instructions
is needed. If XTChain is already installed and available, then building ExectOS is quiet easy. First, open a terminal on how to configure and run XTChain can be found [here](https://exectos.eu.org/contributing/setting-up-xtchain).
or WSL console and type the following command to launch XTChain build console:
``` With the XTchain environment already running, navigate to the directory containing the ExectOS source code and use the
xtchain following commands to set the target build architecture and configure the sources:
```
While the console is already running, navigate to the directory containing ExectOS source code and use the following
commands to first set target build architecture and configure the sources:
``` ```
charch [i686|amd64] charch [i686|amd64]
chbuild [DEBUG|RELEASE] chbuild [DEBUG|RELEASE]

View File

@@ -40,6 +40,30 @@ SystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOS
KernelFile=xtoskrnl.exe KernelFile=xtoskrnl.exe
Parameters=DEBUG=COM1,115200 Parameters=DEBUG=COM1,115200
[ExectOS_FBDEBUG]
SystemName="ExectOS Operating System (FBDEBUG)"
SystemType=XTOS
BootModules=xtos_o
SystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOS
KernelFile=xtoskrnl.exe
Parameters=DEBUG=COM1,115200;SCREEN
[ExectOS_NOXPA]
SystemName="ExectOS Operating System (NOXPA)"
SystemType=XTOS
BootModules=xtos_o
SystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOS
KernelFile=xtoskrnl.exe
Parameters=DEBUG=COM1,115200 NOXPA
[ExectOS_NOXPA_FBDEBUG]
SystemName="ExectOS Operating System (NOXPA / FBDEBUG)"
SystemType=XTOS
BootModules=xtos_o
SystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOS
KernelFile=xtoskrnl.exe
Parameters=DEBUG=COM1,115200;SCREEN NOXPA
[Windows] [Windows]
SystemName="Microsoft Windows 2000" SystemName="Microsoft Windows 2000"
SystemType=NT50 SystemType=NT50

51
configure.ps1 Normal file
View File

@@ -0,0 +1,51 @@
# PROJECT: ExectOS
# LICENSE: See the COPYING.md in the top level directory
# FILE: configure.ps1
# DESCRIPTION: Project configuration script for preparing the build environment
# DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
# Check XTchain
if (-not $env:XTCVER) {
Write-Host "XTChain not detected or corrupted!"
exit 1
}
# Set target architecture
if ($env:TARGET) {
$ARCH = $env:TARGET
} else {
$ARCH = "amd64"
}
# Set target build type
if (-not $env:BUILD_TYPE) {
$env:BUILD_TYPE = "DEBUG"
}
# Set variables
$EXECTOS_SOURCE_DIR = (Get-Location).Path
$EXECTOS_BINARY_DIR = "build-$($ARCH)-$($env:BUILD_TYPE.ToLower())"
# Create directories if needed
if ($EXECTOS_SOURCE_DIR -eq (Get-Location).Path) {
Write-Host "Creating directories in $EXECTOS_BINARY_DIR"
New-Item -ItemType Directory -Path $EXECTOS_BINARY_DIR -Force | Out-Null
Set-Location -Path $EXECTOS_BINARY_DIR
}
# Delete old cache
Remove-Item -Path "CMakeCache.txt" -ErrorAction SilentlyContinue
Remove-Item -Path "host-tools/CMakeCache.txt" -ErrorAction SilentlyContinue
# Configure project using CMake
& cmake -G Ninja -DARCH:STRING=$($ARCH) -DBUILD_TYPE:STRING=$($env:BUILD_TYPE) $EXECTOS_SOURCE_DIR
# Check if configuration succeeded
if ($LASTEXITCODE -ne 0) {
Write-Host "Configure script failed."
exit 1
} else {
"$($ARCH)" | Out-File -Encoding ASCII -NoNewline build.arch
Write-Host "Configure script completed. Enter '$EXECTOS_BINARY_DIR' directory and execute 'xbuild' to build ExectOS."
}

View File

@@ -1,4 +1,10 @@
#!/bin/bash #!/bin/bash
# PROJECT: ExectOS
# LICENSE: See the COPYING.md in the top level directory
# FILE: configure.sh
# DESCRIPTION: Project configuration script for preparing the build environment
# DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
# Check XTCHain # Check XTCHain
if [ "x${XTCVER}" = "x" ]; then if [ "x${XTCVER}" = "x" ]; then
@@ -16,13 +22,12 @@ fi
# Set variables # Set variables
EXECTOS_SOURCE_DIR=$(cd `dirname ${0}` && pwd) EXECTOS_SOURCE_DIR=$(cd `dirname ${0}` && pwd)
EXECTOS_BINARY_DIR=build-${ARCH}-xtchain EXECTOS_BINARY_DIR=build-${ARCH}-${BUILD_TYPE,,}
# Create directories if needed # Create directories if needed
if [ "${EXECTOS_SOURCE_DIR}" = "${PWD}" ]; then if [ "${EXECTOS_SOURCE_DIR}" = "${PWD}" ]; then
echo Creating directories in ${EXECTOS_BINARY_DIR} echo Creating directories in ${EXECTOS_BINARY_DIR}
mkdir -p "${EXECTOS_BINARY_DIR}" mkdir -p "${EXECTOS_BINARY_DIR}"
ln -sf ${EXECTOS_BINARY_DIR} build
cd "${EXECTOS_BINARY_DIR}" cd "${EXECTOS_BINARY_DIR}"
fi fi

View File

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

View File

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

View File

@@ -27,22 +27,22 @@ add_custom_target(bochsvm
# This target starts up a QEMU+OVMF virtual machine using KVM accelerator # This target starts up a QEMU+OVMF virtual machine using KVM accelerator
add_custom_target(testkvm add_custom_target(testkvm
DEPENDS diskimg DEPENDS install
COMMAND ${QEMU_COMMAND} -name "ExectOS-${ARCH}-KVM" -machine type=q35,kernel_irqchip=on,accel=kvm,mem-merge=off,vmport=off -enable-kvm -cpu host,-hypervisor,+topoext COMMAND ${QEMU_COMMAND} -name "ExectOS-${ARCH}-KVM" -machine type=q35,kernel_irqchip=on,accel=kvm,mem-merge=off,vmport=off -enable-kvm -cpu host,-hypervisor,+topoext
-smp 2,sockets=1,cores=1,threads=2 -m 4G -overcommit mem-lock=off -rtc clock=host,base=localtime,driftfix=none -smp 2,sockets=1,cores=1,threads=2 -m 4G -overcommit mem-lock=off -rtc clock=host,base=localtime,driftfix=none
-drive file=${EXECTOS_SOURCE_DIR}/sdk/firmware/ovmf_code_${ARCH}.fd,if=pflash,format=raw,unit=0,readonly=on -drive file=${EXECTOS_SOURCE_DIR}/sdk/firmware/ovmf_code_${ARCH}.fd,if=pflash,format=raw,unit=0,readonly=on
-drive file=${EXECTOS_SOURCE_DIR}/sdk/firmware/ovmf_vars_${ARCH}.fd,if=pflash,format=raw,unit=1 -drive file=${EXECTOS_SOURCE_DIR}/sdk/firmware/ovmf_vars_${ARCH}.fd,if=pflash,format=raw,unit=1
-hda ${EXECTOS_BINARY_DIR}/output/disk.img -hda fat:rw:${EXECTOS_BINARY_DIR}/output/binaries
-boot menu=on -d int -M smm=off -no-reboot -no-shutdown -serial stdio -boot menu=on -d int -M smm=off -no-reboot -no-shutdown -serial stdio
VERBATIM USES_TERMINAL) VERBATIM USES_TERMINAL)
# This target starts up a QEMU+OVMF virtual machine using TCG accelerator # This target starts up a QEMU+OVMF virtual machine using TCG accelerator
add_custom_target(testtcg add_custom_target(testtcg
DEPENDS diskimg DEPENDS install
COMMAND ${QEMU_COMMAND} -name "ExectOS-${ARCH}-TCG" -machine type=q35,accel=tcg -cpu max,-hypervisor COMMAND ${QEMU_COMMAND} -name "ExectOS-${ARCH}-TCG" -machine type=q35,accel=tcg -cpu max,-hypervisor
-smp 2,sockets=1,cores=1,threads=2 -m 4G -overcommit mem-lock=off -rtc clock=host,base=localtime,driftfix=none -smp 2,sockets=1,cores=1,threads=2 -m 4G -overcommit mem-lock=off -rtc clock=host,base=localtime,driftfix=none
-drive file=${EXECTOS_SOURCE_DIR}/sdk/firmware/ovmf_code_${ARCH}.fd,if=pflash,format=raw,unit=0,readonly=on -drive file=${EXECTOS_SOURCE_DIR}/sdk/firmware/ovmf_code_${ARCH}.fd,if=pflash,format=raw,unit=0,readonly=on
-drive file=${EXECTOS_SOURCE_DIR}/sdk/firmware/ovmf_vars_${ARCH}.fd,if=pflash,format=raw,unit=1 -drive file=${EXECTOS_SOURCE_DIR}/sdk/firmware/ovmf_vars_${ARCH}.fd,if=pflash,format=raw,unit=1
-hda ${EXECTOS_BINARY_DIR}/output/disk.img -hda fat:rw:${EXECTOS_BINARY_DIR}/output/binaries
-boot menu=on -d int -M smm=off -no-reboot -no-shutdown -serial stdio -boot menu=on -d int -M smm=off -no-reboot -no-shutdown -serial stdio
VERBATIM USES_TERMINAL) VERBATIM USES_TERMINAL)

View File

@@ -20,8 +20,9 @@ set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_C_STANDARD 23) set(CMAKE_C_STANDARD 23)
set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD 23)
# Disable standard C libraries # Disable standard C and C++ libraries
set(CMAKE_C_STANDARD_LIBRARIES "" CACHE INTERNAL "") set(CMAKE_C_STANDARD_LIBRARIES "" CACHE INTERNAL "")
set(CMAKE_CXX_STANDARD_LIBRARIES "" CACHE INTERNAL "")
# Clean linker flags # Clean linker flags
set(CMAKE_STATIC_LINKER_FLAGS "") set(CMAKE_STATIC_LINKER_FLAGS "")

View File

@@ -11,11 +11,10 @@ endif()
# Set build optimisation # Set build optimisation
if(BUILD_TYPE STREQUAL "DEBUG") if(BUILD_TYPE STREQUAL "DEBUG")
add_compiler_ccxxflags("/Zi") add_compiler_ccxxflags("/GS- /Zi /Ob0 /Od")
add_compiler_ccxxflags("-Ob0 -Od")
add_linker_flags("/DEBUG /INCREMENTAL /OPT:NOREF /OPT:NOICF /PDBSOURCEPATH:build") add_linker_flags("/DEBUG /INCREMENTAL /OPT:NOREF /OPT:NOICF /PDBSOURCEPATH:build")
else() else()
add_compiler_ccxxflags("-Ob2 -Oy") add_compiler_ccxxflags("/GS- /Ob2 /Ot /Ox /Oy")
add_linker_flags("/INCREMENTAL:NO /OPT:REF /OPT:ICF") add_linker_flags("/INCREMENTAL:NO /OPT:REF /OPT:ICF")
endif() endif()
@@ -48,6 +47,9 @@ add_compiler_ccxxflags("-nostdinc -Wno-char-subscripts -Wno-incompatible-library
add_compiler_ccxxflags("-Wno-microsoft-enum-forward-reference -Wno-multichar -Wno-parentheses-equality -Wno-undefined-inline") add_compiler_ccxxflags("-Wno-microsoft-enum-forward-reference -Wno-multichar -Wno-parentheses-equality -Wno-undefined-inline")
add_compiler_ccxxflags("-Wno-gnu-folding-constant") add_compiler_ccxxflags("-Wno-gnu-folding-constant")
# Disable compiler builtins
add_compiler_ccxxflags("-fno-builtin")
# Set debugging symbols output directory # Set debugging symbols output directory
set(CMAKE_PDB_OUTPUT_DIRECTORY "${EXECTOS_BINARY_DIR}/output/symbols") set(CMAKE_PDB_OUTPUT_DIRECTORY "${EXECTOS_BINARY_DIR}/output/symbols")

View File

@@ -1,13 +0,0 @@
## XT Building Kit (XTBK)
The XTBK, or XT Building Kit is a kind of SDK (Software Development Kit) utilized internally by XTOS, the XT Operating
System. It is designed to provide a collection of public functions that are available within the operating system but
not necessarily exposed or accessible to software and driver developers.
Unlike XTDK, which focuses on providing headers for external developers to create kernel mode drivers and user mode
applications, XTBK serves as an extension to XTDK and aids in the code-sharing process between different XTOS
components. This enables the reuse of code across various components of the operating system, resulting in a more
efficient and streamlined development process.
By incorporating XTBK, XTOS can optimize code reuse, particularly in low-level kernel code that can be shared with other
components like the boot loader. This approach helps in reducing code duplication and improving overall code
maintainability. Additionally, it allows for consistent implementation of functionality across different parts of the OS.

View File

@@ -16,26 +16,37 @@
/* Routines used by XTLDR */ /* Routines used by XTLDR */
XTCLINK
XTCDECL XTCDECL
VOID VOID
ArClearInterruptFlag(VOID); ArClearInterruptFlag(VOID);
XTCLINK
XTCDECL XTCDECL
BOOLEAN BOOLEAN
ArCpuId(IN OUT PCPUID_REGISTERS Registers); ArCpuId(IN OUT PCPUID_REGISTERS Registers);
XTCLINK
XTCDECL
VOID
ArEnableExtendedPhysicalAddressing(IN ULONG_PTR PageMap);
XTCLINK
XTCDECL XTCDECL
VOID VOID
ArHalt(VOID); ArHalt(VOID);
XTCLINK
XTCDECL XTCDECL
ULONG_PTR ULONG_PTR
ArReadControlRegister(IN USHORT ControlRegister); ArReadControlRegister(IN USHORT ControlRegister);
XTCLINK
XTCDECL XTCDECL
ULONGLONG ULONGLONG
ArReadModelSpecificRegister(IN ULONG Register); ArReadModelSpecificRegister(IN ULONG Register);
XTCLINK
XTCDECL XTCDECL
VOID VOID
ArWriteControlRegister(IN USHORT ControlRegister, ArWriteControlRegister(IN USHORT ControlRegister,

View File

@@ -39,13 +39,22 @@
#define CR4_PCE 0x00000100 #define CR4_PCE 0x00000100
#define CR4_FXSR 0x00000200 #define CR4_FXSR 0x00000200
#define CR4_XMMEXCPT 0x00000400 #define CR4_XMMEXCPT 0x00000400
#define CR4_UMIP 0x00000800
#define CR4_LA57 0x00001000 #define CR4_LA57 0x00001000
#define CR4_RESERVED1 0x00001800
#define CR4_VMXE 0x00002000 #define CR4_VMXE 0x00002000
#define CR4_SMXE 0x00004000 #define CR4_SMXE 0x00004000
#define CR4_RESERVED2 0x00018000 #define CR4_FSGSBASE 0x00010000
#define CR4_XSAVE 0x00020000 #define CR4_PCIDE 0x00020000
#define CR4_RESERVED3 0xFFFC0000 #define CR4_XSAVE 0x00040000
#define CR4_KL 0x00080000
#define CR4_SMEP 0x00100000
#define CR4_SMAP 0x00200000
#define CR4_PKE 0x00400000
#define CR4_CET 0x00800000
#define CR4_PKS 0x01000000
#define CR4_UINTR 0x02000000
#define CR4_LASS 0x08000000
#define CR4_LAM_SUP 0x10000000
/* Descriptors size */ /* Descriptors size */
#define GDT_ENTRIES 128 #define GDT_ENTRIES 128
@@ -84,6 +93,7 @@
#define X86_MSR_FSBASE 0xC0000100 #define X86_MSR_FSBASE 0xC0000100
#define X86_MSR_GSBASE 0xC0000101 #define X86_MSR_GSBASE 0xC0000101
#define X86_MSR_KERNEL_GSBASE 0xC0000102 #define X86_MSR_KERNEL_GSBASE 0xC0000102
#define X86_MSR_TSC_AUX 0xC0000103
/* Processor features in the EFER MSR */ /* Processor features in the EFER MSR */
#define X86_MSR_EFER_SCE (1 << 0) #define X86_MSR_EFER_SCE (1 << 0)
@@ -91,36 +101,83 @@
#define X86_MSR_EFER_LMA (1 << 10) #define X86_MSR_EFER_LMA (1 << 10)
#define X86_MSR_EFER_NXE (1 << 11) #define X86_MSR_EFER_NXE (1 << 11)
#define X86_MSR_EFER_SVME (1 << 12) #define X86_MSR_EFER_SVME (1 << 12)
#define X86_EFER_LMSLE (1 << 13)
#define X86_EFER_FFXSR (1 << 14)
#define X86_EFER_TCE (1 << 15)
#define X86_EFER_AUTOIBRS (1 << 21)
/* X86 EFLAG bit masks definitions */ /* X86 EFLAG bit masks definitions */
#define X86_EFLAGS_CF_MASK 0x00000001 #define X86_EFLAGS_NF_MASK 0x00000000 /* None */
#define X86_EFLAGS_PF_MASK 0x00000004 #define X86_EFLAGS_CF_MASK 0x00000001 /* Carry */
#define X86_EFALGS_AF_MASK 0x00000010 #define X86_EFLAGS_PF_MASK 0x00000004 /* Parity */
#define X86_EFLAGS_ZF_MASK 0x00000040 #define X86_EFALGS_AF_MASK 0x00000010 /* Aux Carry */
#define X86_EFLAGS_SF_MASK 0x00000080 #define X86_EFLAGS_ZF_MASK 0x00000040 /* Zero */
#define X86_EFLAGS_TF_MASK 0x00000100 #define X86_EFLAGS_SF_MASK 0x00000080 /* Sign */
#define X86_EFLAGS_IF_MASK 0x00000200 #define X86_EFLAGS_TF_MASK 0x00000100 /* Trap */
#define X86_EFLAGS_DF_MASK 0x00000400 #define X86_EFLAGS_IF_MASK 0x00000200 /* Interrupt */
#define X86_EFLAGS_OF_MASK 0x00000800 #define X86_EFLAGS_DF_MASK 0x00000400 /* Direction */
#define X86_EFLAGS_IOPL_MASK 0x00003000 #define X86_EFLAGS_OF_MASK 0x00000800 /* Overflow */
#define X86_EFLAGS_NT_MASK 0x00004000 #define X86_EFLAGS_IOPL_MASK 0x00003000 /* I/O Privilege */
#define X86_EFLAGS_RF_MASK 0x00010000 #define X86_EFLAGS_NT_MASK 0x00004000 /* Nested Task */
#define X86_EFLAGS_VM_MASK 0x00020000 #define X86_EFLAGS_SIGN_MASK 0x00008000 /* Sign */
#define X86_EFLAGS_AC_MASK 0x00040000 #define X86_EFLAGS_RF_MASK 0x00010000 /* Resume */
#define X86_EFLAGS_VIF_MASK 0x00080000 #define X86_EFLAGS_V86_MASK 0x00020000 /* Virtual 8086 */
#define X86_EFLAGS_VIP_MASK 0x00100000 #define X86_EFLAGS_AC_MASK 0x00040000 /* Alignment Check */
#define X86_EFLAGS_ID_MASK 0x00200000 #define X86_EFLAGS_VIF_MASK 0x00080000 /* Virtual Interrupt */
#define X86_EFLAGS_VIP_MASK 0x00100000 /* Virtual Interrupt Pending */
#define X86_EFLAGS_ID_MASK 0x00200000 /* Identification */
/* CPU vendor enumeration list */ /* CPU vendor enumeration list */
typedef enum _CPU_VENDOR typedef enum _CPU_VENDOR
{ {
CPU_VENDOR_AMD = 0x68747541, CPU_VENDOR_AMD = 0x68747541,
CPU_VENDOR_INTEL = 0x756e6547, CPU_VENDOR_INTEL = 0x756E6547,
CPU_VENDOR_UNKNOWN = 0xFFFFFFFF CPU_VENDOR_UNKNOWN = 0xFFFFFFFF
} CPU_VENDOR, *PCPU_VENDOR; } CPU_VENDOR, *PCPU_VENDOR;
/* CPUID features enumeration list */ /* CPUID extended features (0x80000001) enumeration list */
typedef enum _CPUID_FEATURES typedef enum _CPUID_FEATURES_EXTENDED
{
CPUID_FEATURES_ECX_LAHF_SAHF = 1 << 0,
CPUID_FEATURES_ECX_CMP_LEGACY = 1 << 1,
CPUID_FEATURES_ECX_SVM = 1 << 2,
CPUID_FEATURES_ECX_EXT_APIC_SPACE = 1 << 3,
CPUID_FEATURES_ECX_ALT_MOV_CR8 = 1 << 4,
CPUID_FEATURES_ECX_LZCNT = 1 << 5,
CPUID_FEATURES_ECX_SSE4A = 1 << 6,
CPUID_FEATURES_ECX_MISALIGNED_SSE = 1 << 7,
CPUID_FEATURES_ECX_PREFETCHW = 1 << 8,
CPUID_FEATURES_ECX_OSVW = 1 << 9,
CPUID_FEATURES_ECX_IBS = 1 << 10,
CPUID_FEATURES_ECX_XOP = 1 << 11,
CPUID_FEATURES_ECX_SKINIT = 1 << 12,
CPUID_FEATURES_ECX_WDT = 1 << 13,
CPUID_FEATURES_ECX_LWP = 1 << 15,
CPUID_FEATURES_ECX_FMA4 = 1 << 16,
CPUID_FEATURES_ECX_TCE = 1 << 17,
CPUID_FEATURES_ECX_NODEID = 1 << 19,
CPUID_FEATURES_ECX_TBM = 1 << 21,
CPUID_FEATURES_ECX_TOPOLOGY_EXTENSIONS = 1 << 22,
CPUID_FEATURES_ECX_PERFCTR_EXT_CORE = 1 << 23,
CPUID_FEATURES_ECX_PERFCTR_EXT_NB = 1 << 24,
CPUID_FEATURES_ECX_DATA_BREAKPOINT_EXT = 1 << 26,
CPUID_FEATURES_ECX_PERF_TSC = 1 << 27,
CPUID_FEATURES_ECX_PERFCTR_EXT_L2I = 1 << 28,
CPUID_FEATURES_ECX_MONITORX_MWAITX = 1 << 29,
CPUID_FEATURES_ECX_CODEBP_ADDRMASK_EXT = 1 << 30,
CPUID_FEATURES_EDX_SYSCALL_SYSRET = 1 << 11,
CPUID_FEATURES_EDX_NX = 1 << 20,
CPUID_FEATURES_EDX_AMD_MMX_EXT = 1 << 22,
CPUID_FEATURES_EDX_FFXSR = 1 << 25,
CPUID_FEATURES_EDX_1G_PAGES = 1 << 26,
CPUID_FEATURES_EDX_RDTSCP = 1 << 27,
CPUID_FEATURES_EDX_LONG_MODE = 1 << 29,
CPUID_FEATURES_EDX_3DNOW_EXT = 1 << 30,
CPUID_FEATURES_EDX_3DNOW = 1 << 31
} CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
/* CPUID STD1 features (0x00000001) enumeration list */
typedef enum _CPUID_FEATURES_STANDARD1
{ {
CPUID_FEATURES_ECX_SSE3 = 1 << 0, CPUID_FEATURES_ECX_SSE3 = 1 << 0,
CPUID_FEATURES_ECX_PCLMUL = 1 << 1, CPUID_FEATURES_ECX_PCLMUL = 1 << 1,
@@ -183,15 +240,150 @@ typedef enum _CPUID_FEATURES
CPUID_FEATURES_EDX_TM = 1 << 29, CPUID_FEATURES_EDX_TM = 1 << 29,
CPUID_FEATURES_EDX_IA64 = 1 << 30, CPUID_FEATURES_EDX_IA64 = 1 << 30,
CPUID_FEATURES_EDX_PBE = 1 << 31 CPUID_FEATURES_EDX_PBE = 1 << 31
} CPUID_FEATURES, *PCPUID_FEATURES; } CPUID_FEATURES_STANDARD1, *PCPUID_FEATURES_STANDARD1;
/* CPUID STD7 features (0x00000007, subleaf 0) enumeration list */
typedef enum _CPUID_FEATURES_STANDARD7_LEAF0
{
CPUID_FEATURES_EBX_FSGSBASE = 1 << 0,
CPUID_FEATURES_EBX_TSC_ADJUST = 1 << 1,
CPUID_FEATURES_EBX_SGX = 1 << 2,
CPUID_FEATURES_EBX_BMI1 = 1 << 3,
CPUID_FEATURES_EBX_HLE = 1 << 4,
CPUID_FEATURES_EBX_AVX2 = 1 << 5,
CPUID_FEATURES_EBX_FDP_DEPRECATION = 1 << 6,
CPUID_FEATURES_EBX_SMEP = 1 << 7,
CPUID_FEATURES_EBX_BMI2 = 1 << 8,
CPUID_FEATURES_EBX_ERMS = 1 << 9,
CPUID_FEATURES_EBX_INVPCID = 1 << 10,
CPUID_FEATURES_EBX_RTM = 1 << 11,
CPUID_FEATURES_EBX_QOS_MONITORING = 1 << 12,
CPUID_FEATURES_EBX_DEPRECATE_FCS_FDS = 1 << 13,
CPUID_FEATURES_EBX_MPX = 1 << 14,
CPUID_FEATURES_EBX_QOS_ENFORCEMENT = 1 << 15,
CPUID_FEATURES_EBX_AVX512F = 1 << 16,
CPUID_FEATURES_EBX_AVX512DQ = 1 << 17,
CPUID_FEATURES_EBX_RDSEED = 1 << 18,
CPUID_FEATURES_EBX_ADX = 1 << 19,
CPUID_FEATURES_EBX_SMAP = 1 << 20,
CPUID_FEATURES_EBX_AVX512IFMA52 = 1 << 21,
CPUID_FEATURES_EBX_CLFLUSHOPT = 1 << 23,
CPUID_FEATURES_EBX_CLWB = 1 << 24,
CPUID_FEATURES_EBX_PROCESSOR_TRACE = 1 << 25,
CPUID_FEATURES_EBX_AVX512PF = 1 << 26,
CPUID_FEATURES_EBX_AVX512ER = 1 << 27,
CPUID_FEATURES_EBX_AVX512CD = 1 << 28,
CPUID_FEATURES_EBX_SHA = 1 << 29,
CPUID_FEATURES_EBX_AVX512BW = 1 << 30,
CPUID_FEATURES_EBX_AVX512VL = 1 << 31,
CPUID_FEATURES_ECX_PREFETCHWT1 = 1 << 0,
CPUID_FEATURES_ECX_AVX512_VBMI = 1 << 1,
CPUID_FEATURES_ECX_UMIP = 1 << 2,
CPUID_FEATURES_ECX_PKU = 1 << 3,
CPUID_FEATURES_ECX_OSPKE = 1 << 4,
CPUID_FEATURES_ECX_WAITPKG = 1 << 5,
CPUID_FEATURES_ECX_AVX512_VBMI2 = 1 << 6,
CPUID_FEATURES_ECX_CET_SS = 1 << 7,
CPUID_FEATURES_ECX_GFNI = 1 << 8,
CPUID_FEATURES_ECX_VAES = 1 << 9,
CPUID_FEATURES_ECX_VPCLMULQDQ = 1 << 10,
CPUID_FEATURES_ECX_AVX512_VNNI = 1 << 11,
CPUID_FEATURES_ECX_AVX512_BITALG = 1 << 12,
CPUID_FEATURES_ECX_TME = 1 << 13,
CPUID_FEATURES_ECX_AVX512_VPOPCNTDQ = 1 << 14,
CPUID_FEATURES_ECX_LA57 = 1 << 16,
CPUID_FEATURES_ECX_RDPID = 1 << 22,
CPUID_FEATURES_ECX_KEYLOCKER = 1 << 23,
CPUID_FEATURES_ECX_BUS_LOCK_DETECT = 1 << 24,
CPUID_FEATURES_ECX_CLDEMOTE = 1 << 25,
CPUID_FEATURES_ECX_MOVDIRI = 1 << 27,
CPUID_FEATURES_ECX_MOVDIR64B = 1 << 28,
CPUID_FEATURES_ECX_ENQCMD = 1 << 29,
CPUID_FEATURES_ECX_SGX_LAUNCH_CONFIG = 1 << 30,
CPUID_FEATURES_ECX_PKS = 1 << 31,
CPUID_FEATURES_EDX_SGX_KEYS = 1 << 1,
CPUID_FEATURES_EDX_AVX512_4VNNIW = 1 << 2,
CPUID_FEATURES_EDX_AVX512_4FMAPS = 1 << 3,
CPUID_FEATURES_EDX_FAST_SHORT_REP_MOV = 1 << 4,
CPUID_FEATURES_EDX_UINTR = 1 << 5,
CPUID_FEATURES_EDX_AVX512_VPINTERSECT = 1 << 8,
CPUID_FEATURES_EDX_SRBDS_CTRL = 1 << 9,
CPUID_FEATURES_EDX_MD_CLEAR = 1 << 10,
CPUID_FEATURES_EDX_RTM_ALWAYS_ABORT = 1 << 11,
CPUID_FEATURES_EDX_RTM_FORCE_ABORT = 1 << 13,
CPUID_FEATURES_EDX_SERIALIZE = 1 << 14,
CPUID_FEATURES_EDX_HYBRID = 1 << 15,
CPUID_FEATURES_EDX_TSXLDTRK = 1 << 16,
CPUID_FEATURES_EDX_PCONFIG = 1 << 18,
CPUID_FEATURES_EDX_ARCH_LBR = 1 << 19,
CPUID_FEATURES_EDX_CET_IBT = 1 << 20,
CPUID_FEATURES_EDX_AMX_BF16 = 1 << 22,
CPUID_FEATURES_EDX_AVX512_FP16 = 1 << 23,
CPUID_FEATURES_EDX_AMX_TILE = 1 << 24,
CPUID_FEATURES_EDX_AMX_INT8 = 1 << 25,
CPUID_FEATURES_EDX_SCA_IBRS_IBPB = 1 << 26,
CPUID_FEATURES_EDX_SCA_STIBP = 1 << 27,
CPUID_FEATURES_EDX_L1D_FLUSH = 1 << 28,
CPUID_FEATURES_EDX_ARCH_CAPABILITIES_MSR = 1 << 29,
CPUID_FEATURES_EDX_CORE_CAPABILITIES_MSR = 1 << 30,
CPUID_FEATURES_EDX_SCA_SSBD = 1 << 31
} CPUID_FEATURES_STANDARD7_LEAF0, *PCPUID_FEATURES_STANDARD7_LEAF0;
/* CPUID STD7 features (0x00000007, subleaf 1) enumeration list */
typedef enum _CPUID_FEATURES_STANDARD7_LEAF1
{
CPUID_FEATURES_EAX_SHA512 = 1 << 0,
CPUID_FEATURES_EAX_SM3 = 1 << 1,
CPUID_FEATURES_EAX_SM4 = 1 << 2,
CPUID_FEATURES_EAX_RAO_INT = 1 << 3,
CPUID_FEATURES_EAX_AVX_VNNI = 1 << 4,
CPUID_FEATURES_EAX_AVX512_BF16 = 1 << 5,
CPUID_FEATURES_EAX_LASS = 1 << 6,
CPUID_FEATURES_EAX_CMPCCXADD = 1 << 7,
CPUID_FEATURES_EAX_ARCH_PERFMON = 1 << 8,
CPUID_FEATURES_EAX_FAST_ZEROLEN_REP_MOVSB = 1 << 10,
CPUID_FEATURES_EAX_FAST_ZEROLEN_REP_STOSB = 1 << 11,
CPUID_FEATURES_EAX_FAST_ZEROLEN_REP_CMPSB = 1 << 12,
CPUID_FEATURES_EAX_FRED = 1 << 17,
CPUID_FEATURES_EAX_LKGS = 1 << 18,
CPUID_FEATURES_EAX_WRMSRNS = 1 << 19,
CPUID_FEATURES_EAX_NMI_SOURCE_REPORTING = 1 << 20,
CPUID_FEATURES_EAX_AMX_FP16 = 1 << 21,
CPUID_FEATURES_EAX_HRESET = 1 << 22,
CPUID_FEATURES_EAX_AVX_IFMA = 1 << 23,
CPUID_FEATURES_EAX_LAM = 1 << 26,
CPUID_FEATURES_EAX_MSRLIST = 1 << 27,
CPUID_FEATURES_EAX_INVD_DISABLE = 1 << 30,
CPUID_FEATURES_EAX_MOVRS = 1 << 31,
CPUID_FEATURES_EBX_PPIN = 1 << 0,
CPUID_FEATURES_EBX_TSE = 1 << 1,
CPUID_FEATURES_EBX_CPUIDMAXVAL_LIM_RMV = 1 << 3,
CPUID_FEATURES_ECX_MSR_IMM = 1 << 5,
CPUID_FEATURES_EDX_AVX_VNNI_INT8 = 1 << 4,
CPUID_FEATURES_EDX_AVX_NE_CONVERT = 1 << 5,
CPUID_FEATURES_EDX_AMX_COMPLEX = 1 << 8,
CPUID_FEATURES_EDX_AVX_VNNI_INT16 = 1 << 10,
CPUID_FEATURES_EDX_USER_TIMER = 1 << 13,
CPUID_FEATURES_EDX_PREFETCHI = 1 << 14,
CPUID_FEATURES_EDX_USER_MSR = 1 << 15,
CPUID_FEATURES_EDX_UIRET_UIF = 1 << 17,
CPUID_FEATURES_EDX_CET_SSS = 1 << 18,
CPUID_FEATURES_EDX_AVX10 = 1 << 19,
CPUID_FEATURES_EDX_APX = 1 << 21,
CPUID_FEATURES_EDX_MWAIT_AND_LEAF5 = 1 << 23
} CPUID_FEATURES_STANDARD7_LEAF1, *PCPUID_FEATURES_STANDARD7_LEAF1;
/* CPUID requests */ /* CPUID requests */
typedef enum _CPUID_REQUESTS typedef enum _CPUID_REQUESTS
{ {
CPUID_GET_VENDOR_STRING, CPUID_GET_VENDOR_STRING,
CPUID_GET_CPU_FEATURES, CPUID_GET_STANDARD1_FEATURES,
CPUID_GET_TLB, CPUID_GET_TLB_CACHE,
CPUID_GET_SERIAL CPUID_GET_SERIAL,
CPUID_GET_CACHE_TOPOLOGY,
CPUID_GET_MONITOR_MWAIT,
CPUID_GET_POWER_MANAGEMENT,
CPUID_GET_STANDARD7_FEATURES
} CPUID_REQUESTS, *PCPUID_REQUESTS; } CPUID_REQUESTS, *PCPUID_REQUESTS;
/* Processor identification information */ /* Processor identification information */

View File

@@ -16,28 +16,34 @@
/* HAL library routines forward references */ /* HAL library routines forward references */
XTCLINK
XTCDECL XTCDECL
UCHAR UCHAR
HlIoPortInByte(IN USHORT Port); HlIoPortInByte(IN USHORT Port);
XTCLINK
XTCDECL XTCDECL
ULONG ULONG
HlIoPortInLong(IN USHORT Port); HlIoPortInLong(IN USHORT Port);
XTCLINK
XTCDECL XTCDECL
USHORT USHORT
HlIoPortInShort(IN USHORT Port); HlIoPortInShort(IN USHORT Port);
XTCLINK
XTCDECL XTCDECL
VOID VOID
HlIoPortOutByte(IN USHORT Port, HlIoPortOutByte(IN USHORT Port,
IN UCHAR Data); IN UCHAR Data);
XTCLINK
XTCDECL XTCDECL
VOID VOID
HlIoPortOutLong(IN USHORT Port, HlIoPortOutLong(IN USHORT Port,
IN ULONG Value); IN ULONG Value);
XTCLINK
XTCDECL XTCDECL
VOID VOID
HlIoPortOutShort(IN USHORT Port, HlIoPortOutShort(IN USHORT Port,

View File

@@ -42,37 +42,143 @@
#define APIC_DF_FLAT 0xFFFFFFFF #define APIC_DF_FLAT 0xFFFFFFFF
#define APIC_DF_CLUSTER 0x0FFFFFFF #define APIC_DF_CLUSTER 0x0FFFFFFF
/* APIC delivery modes */
#define APIC_DM_FIXED 0
#define APIC_DM_LOWPRIO 1
#define APIC_DM_SMI 2
#define APIC_DM_REMOTE 3
#define APIC_DM_NMI 4
#define APIC_DM_INIT 5
#define APIC_DM_STARTUP 6
#define APIC_DM_EXTINT 7
/* APIC trigger modes */ /* APIC trigger modes */
#define APIC_TGM_EDGE 0 #define APIC_TGM_EDGE 0
#define APIC_TGM_LEVEL 1 #define APIC_TGM_LEVEL 1
/* APIC LDR (Logical Destination Register) shifts */
#define APIC_X2APIC_LDR_SHIFT 16
#define APIC_XAPIC_LDR_SHIFT 24
/* Maximum number of I/O APICs */
#define APIC_MAX_IOAPICS 64
/* 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
#define PIC1_ELCR_PORT 0x04D0
#define PIC2_CONTROL_PORT 0xA0 #define PIC2_CONTROL_PORT 0xA0
#define PIC2_DATA_PORT 0xA1 #define PIC2_DATA_PORT 0xA1
#define PIC2_ELCR_PORT 0x04D1
/* PIC vector definitions */ /* PIC vector definitions */
#define PIC1_VECTOR_SPURIOUS 0x37 #define PIC1_VECTOR_SPURIOUS 0x37
/* Serial port I/O addresses */ /* Serial ports information */
#define COMPORT_ADDRESSES {0x000, 0x3F8, 0x2F8, 0x3E8, 0x2E8, 0x5F8, 0x4F8, 0x5E8, 0x4E8} #define COMPORT_ADDRESS {0x3F8, 0x2F8, 0x3E8, 0x2E8, 0x5F8, 0x4F8, 0x5E8, 0x4E8}
#define COMPORT_COUNT 8
/* Initial stall factor */ /* Initial stall factor */
#define INITIAL_STALL_FACTOR 100 #define INITIAL_STALL_FACTOR 100
/* APIC delivery mode enumeration list */
typedef enum _APIC_DM
{
APIC_DM_FIXED,
APIC_DM_LOWPRIO,
APIC_DM_SMI,
APIC_DM_REMOTE,
APIC_DM_NMI,
APIC_DM_INIT,
APIC_DM_STARTUP,
APIC_DM_EXTINT,
} APIC_DM, *PAPIC_DM;
/* APIC destination short-hand enumeration list */
typedef enum _APIC_DSH
{
APIC_DSH_Destination,
APIC_DSH_Self,
APIC_DSH_AllIncludingSelf,
APIC_DSH_AllExclusingSelf
} APIC_DSH, *PAPIC_DSH;
/* APIC mode list */
typedef enum _APIC_MODE
{
APIC_MODE_COMPAT,
APIC_MODE_X2APIC
} APIC_MODE, *PAPIC_MODE;
/* APIC Register Address Map */
typedef enum _APIC_REGISTER
{
APIC_ID = 0x02, /* APIC ID Register */
APIC_VER = 0x03, /* APIC Version Register */
APIC_TPR = 0x08, /* Task Priority Register */
APIC_APR = 0x09, /* Arbitration Priority Register */
APIC_PPR = 0x0A, /* Processor Priority Register (R) */
APIC_EOI = 0x0B, /* EOI Register */
APIC_RRR = 0x0C, /* Remote Read Register */
APIC_LDR = 0x0D, /* Logical Destination Register */
APIC_DFR = 0x0E, /* Destination Format Register (not available in extended mode) */
APIC_SIVR = 0x0F, /* Spurious Interrupt Vector Register */
APIC_ISR = 0x10, /* Interrupt Service Register*/
APIC_TMR = 0x18, /* Trigger Mode Register */
APIC_IRR = 0x20, /* Interrupt Request Register */
APIC_ESR = 0x28, /* Error Status Register */
APIC_ICR0 = 0x30, /* Interrupt Command Register */
APIC_ICR1 = 0x31, /* Interrupt Command Register (not available in extended mode) */
APIC_TMRLVTR = 0x32, /* Timer Local Vector Table */
APIC_THRMLVTR = 0x33, /* Thermal Local Vector Table */
APIC_PCLVTR = 0x34, /* Performance Counter Local Vector Table */
APIC_LINT0 = 0x35, /* LINT0 Local Vector Table */
APIC_LINT1 = 0x36, /* LINT1 Local Vector Table */
APIC_ERRLVTR = 0x37, /* Error Local Vector Table */
APIC_TICR = 0x38, /* Initial Count Register for Timer */
APIC_TCCR = 0x39, /* Current Count Register for Timer */
APIC_TDCR = 0x3E, /* Timer Divide Configuration Register */
APIC_EAFR = 0x40, /* extended APIC Feature register */
APIC_EACR = 0x41, /* Extended APIC Control Register */
APIC_SEOI = 0x42, /* Specific End Of Interrupt Register */
APIC_EXT0LVTR = 0x50, /* Extended Interrupt 0 Local Vector Table */
APIC_EXT1LVTR = 0x51, /* Extended Interrupt 1 Local Vector Table */
APIC_EXT2LVTR = 0x52, /* Extended Interrupt 2 Local Vector Table */
APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */
} APIC_REGISTER, *PAPIC_REGISTER;
/* I8259 PIC interrupt mode enumeration list */
typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE
{
EdgeTriggered,
LevelTriggered
} PIC_I8259_ICW1_INTERRUPT_MODE, *PPIC_I8259_ICW1_INTERRUPT_MODE;
/* I8259 PIC interval enumeration list */
typedef enum _PIC_I8259_ICW1_INTERVAL
{
Interval8,
Interval4
} PIC_I8259_ICW1_INTERVAL, *PPIC_I8259_ICW1_INTERVAL;
/* I8259 PIC operating mode enumeration list */
typedef enum _PIC_I8259_ICW1_OPERATING_MODE
{
Cascade,
Single
} PIC_I8259_ICW1_OPERATING_MODE, *PPIC_I8259_ICW1_OPERATING_MODE;
/* I8259 PIC buffered mode enumeration list */
typedef enum _PIC_I8259_ICW4_BUFFERED_MODE
{
NonBuffered,
NonBuffered2,
BufferedSlave,
BufferedMaster
} PIC_I8259_ICW4_BUFFERED_MODE, *PPIC_I8259_ICW4_BUFFERED_MODE;
/* I8259 PIC End Of Interrupt (EOI) mode enumeration list */
typedef enum _PIC_I8259_ICW4_EOI_MODE
{
NormalEoi,
AutomaticEoi
} PIC_I8259_ICW4_EOI_MODE, *PPIC_I8259_ICW4_EOI_MODE;
/* I8259 PIC system mode enumeration list */
typedef enum _PIC_I8259_ICW4_SYSTEM_MODE
{
Mcs8085Mode,
New8086Mode
} PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;
/* APIC Base Register */ /* APIC Base Register */
typedef union _APIC_BASE_REGISTER typedef union _APIC_BASE_REGISTER
{ {
@@ -89,6 +195,31 @@ typedef union _APIC_BASE_REGISTER
}; };
} APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER; } APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER;
/* APIC Command Register */
typedef union _APIC_COMMAND_REGISTER
{
ULONGLONG LongLong;
struct
{
ULONG Long0;
ULONG Long1;
};
struct
{
ULONGLONG Vector:8;
ULONGLONG DeliveryMode:3;
ULONGLONG DestinationMode:1;
ULONGLONG DeliveryStatus:1;
ULONGLONG ReservedMBZ:1;
ULONGLONG Level:1;
ULONGLONG TriggerMode:1;
ULONGLONG RemoteReadStatus:2;
ULONGLONG DestinationShortHand:2;
ULONGLONG Reserved2MBZ:36;
ULONGLONG Destination:8;
};
} APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGISTER;
/* APIC Local Vector Table (LVT) Register */ /* APIC Local Vector Table (LVT) Register */
typedef union _APIC_LVT_REGISTER typedef union _APIC_LVT_REGISTER
{ {
@@ -96,7 +227,7 @@ typedef union _APIC_LVT_REGISTER
struct struct
{ {
ULONG Vector:8; ULONG Vector:8;
ULONG MessageType:3; ULONG DeliveryMode:3;
ULONG Reserved1:1; ULONG Reserved1:1;
ULONG DeliveryStatus:1; ULONG DeliveryStatus:1;
ULONG Reserved2:1; ULONG Reserved2:1;
@@ -121,14 +252,69 @@ typedef union _APIC_SPURIOUS_REGISTER
}; };
} APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER; } APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
/* Processor identity structure */ /* I8259 PIC register structure */
typedef struct _HAL_PROCESSOR_IDENTITY typedef union _PIC_I8259_ICW1
{ {
UCHAR ProcessorId; struct
UCHAR LApicId; {
BOOLEAN Bsp; UCHAR NeedIcw4:1;
BOOLEAN Started; UCHAR OperatingMode:1;
PKPROCESSOR_BLOCK ProcessorBlock; UCHAR Interval:1;
} HAL_PROCESSOR_IDENTITY, *PHAL_PROCESSOR_IDENTITY; UCHAR InterruptMode:1;
UCHAR Init:1;
UCHAR InterruptVectorAddress:3;
};
UCHAR Bits;
} PIC_I8259_ICW1, *PPIC_I8259_ICW1;
/* I8259 PIC register structure */
typedef union _PIC_I8259_ICW2
{
struct
{
UCHAR Sbz:3;
UCHAR InterruptVector:5;
};
UCHAR Bits;
} PIC_I8259_ICW2, *PPIC_I8259_ICW2;
/* I8259 PIC register structure */
typedef union _PIC_I8259_ICW3
{
union
{
struct
{
UCHAR SlaveIrq0:1;
UCHAR SlaveIrq1:1;
UCHAR SlaveIrq2:1;
UCHAR SlaveIrq3:1;
UCHAR SlaveIrq4:1;
UCHAR SlaveIrq5:1;
UCHAR SlaveIrq6:1;
UCHAR SlaveIrq7:1;
};
struct
{
UCHAR SlaveId:3;
UCHAR Reserved:5;
};
};
UCHAR Bits;
} PIC_I8259_ICW3, *PPIC_I8259_ICW3;
/* I8259 PIC register structure */
typedef union _PIC_I8259_ICW4
{
struct
{
UCHAR SystemMode:1;
UCHAR EoiMode:1;
UCHAR BufferedMode:2;
UCHAR SpecialFullyNestedMode:1;
UCHAR Reserved:3;
};
UCHAR Bits;
} PIC_I8259_ICW4, *PPIC_I8259_ICW4;
#endif /* __XTDK_AMD64_HLTYPES_H */ #endif /* __XTDK_AMD64_HLTYPES_H */

View File

@@ -67,31 +67,6 @@
#define AMD64_INTERRUPT_GATE 0xE #define AMD64_INTERRUPT_GATE 0xE
#define AMD64_TRAP_GATE 0xF #define AMD64_TRAP_GATE 0xF
/* EFLAGS bits definitions */
#define EFLAGS_NF_MASK 0x00000000L /* None */
#define EFLAGS_CF_MASK 0x00000001L /* Carry */
#define EFLAGS_PF_MASK 0x00000004L /* Parity */
#define EFLAGS_AF_MASK 0x00000010L /* Aux Carry */
#define EFLAGS_ZF_MASK 0x00000040L /* Zero */
#define EFLAGS_SF_MASK 0x00000080L /* Sign */
#define EFLAGS_TF 0x00000100L /* Trap */
#define EFLAGS_INTERRUPT_MASK 0x00000200L /* Interrupt */
#define EFLAGS_DF_MASK 0x00000400L /* Direction */
#define EFLAGS_OF_MASK 0x00000800L /* Overflow */
#define EFLAGS_IOPL_MASK 0x00003000L /* I/O Privilege */
#define EFLAGS_NT 0x00004000L /* Nested Task */
#define EFLAGS_SIGN_MASK 0x00008000L /* Sign */
#define EFLAGS_RF 0x00010000L /* Resume */
#define EFLAGS_V86_MASK 0x00020000L /* Virtual 8086 */
#define EFLAGS_ALIGN_CHECK 0x00040000L /* Alignment Check */
#define EFLAGS_VIF 0x00080000L /* Virtual Interrupt */
#define EFLAGS_VIP 0x00100000L /* Virtual Interrupt Pending */
#define EFLAGS_ID_MASK 0x00200000L /* Identification */
/* EFLAGS sanitize masks */
#define EFLAGS_KERNELMODE 0x00210FD5L
#define EFLAGS_USERMODE 0x00010DD5L
/* 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)
@@ -142,6 +117,10 @@
/* 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 */
#define KPROCESSOR_STRUCTURES_SIZE ((2 * KERNEL_STACK_SIZE) + sizeof(ArInitialGdt) + sizeof(ArInitialTss) + \
sizeof(ArInitialProcessorBlock) + MM_PAGE_SIZE)
/* Kernel frames */ /* Kernel frames */
#define KEXCEPTION_FRAME_SIZE sizeof(KEXCEPTION_FRAME) #define KEXCEPTION_FRAME_SIZE sizeof(KEXCEPTION_FRAME)
#define KSWITCH_FRAME_SIZE sizeof(KSWITCH_FRAME) #define KSWITCH_FRAME_SIZE sizeof(KSWITCH_FRAME)
@@ -314,7 +293,7 @@ typedef struct _KTSS
ULONG64 Reserved1; ULONG64 Reserved1;
USHORT Reserved2; USHORT Reserved2;
USHORT IoMapBase; USHORT IoMapBase;
} PACK KTSS, *PKTSS; } PACKED KTSS, *PKTSS;
/* Exception frame definition */ /* Exception frame definition */
typedef struct _KEXCEPTION_FRAME typedef struct _KEXCEPTION_FRAME
@@ -491,7 +470,7 @@ typedef struct _KPROCESSOR_STATE
typedef struct _KPROCESSOR_CONTROL_BLOCK typedef struct _KPROCESSOR_CONTROL_BLOCK
{ {
ULONG MxCsr; ULONG MxCsr;
UCHAR Number; UCHAR CpuNumber;
PKTHREAD CurrentThread; PKTHREAD CurrentThread;
PKTHREAD IdleThread; PKTHREAD IdleThread;
PKTHREAD NextThread; PKTHREAD NextThread;
@@ -526,8 +505,13 @@ typedef struct _KPROCESSOR_BLOCK
PKIDTENTRY IdtBase; PKIDTENTRY IdtBase;
KRUNLEVEL RunLevel; KRUNLEVEL RunLevel;
KPROCESSOR_CONTROL_BLOCK Prcb; KPROCESSOR_CONTROL_BLOCK Prcb;
ULONG Irr;
ULONG IrrActive;
ULONG Idr;
ULONG ContextSwitches; ULONG ContextSwitches;
KAFFINITY SetMember;
ULONG StallScaleFactor; ULONG StallScaleFactor;
UCHAR CpuNumber;
} KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK; } KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK;
/* Thread Environment Block (TEB) structure definition */ /* Thread Environment Block (TEB) structure definition */

View File

@@ -14,22 +14,35 @@
/* Pages related definitions */ /* Pages related definitions */
#define MM_PAGE_MASK 0xFFF #define MM_PAGE_MASK (MM_PAGE_SIZE - 1)
#define MM_PAGE_SHIFT 12L #define MM_PAGE_SHIFT 12L
#define MM_PAGE_SIZE 4096 #define MM_PAGE_SIZE 4096
#define MM_PTE_BASE 0xFFFFF68000000000UI64 /* Page directory and page base addresses for 4-level paging */
#define MM_PDE_BASE 0xFFFFF6FB40000000UI64 #define MM_PTE_BASE 0xFFFFF68000000000ULL
#define MM_PPE_BASE 0xFFFFF6FB7DA00000UI64 #define MM_PDE_BASE 0xFFFFF6FB40000000ULL
#define MM_PXE_BASE 0xFFFFF6FB7DBED000UI64 #define MM_PPE_BASE 0xFFFFF6FB7DA00000ULL
#define MM_PXE_BASE 0xFFFFF6FB7DBED000ULL
/* Page directory and page base addresses for 5-level paging */
#define MM_PTE_LA57_BASE 0xFFFF000000000000ULL
#define MM_PDE_LA57_BASE 0xFFFF010000000000ULL
#define MM_PPE_LA57_BASE 0xFFFF010800000000ULL
#define MM_PXE_LA57_BASE 0xFFFF010840000000ULL
#define MM_P5E_LA57_BASE 0xFFFF010840200000ULL
/* PTE shift values */
#define MM_PTE_SHIFT 3
#define MM_PTI_SHIFT 12 #define MM_PTI_SHIFT 12
#define MM_PDI_SHIFT 21 #define MM_PDI_SHIFT 21
#define MM_PPI_SHIFT 30 #define MM_PPI_SHIFT 30
#define MM_PXI_SHIFT 39 #define MM_PXI_SHIFT 39
#define MM_P5I_SHIFT 48
#define MM_PTE_SHIFT 3 /* Number of PTEs per page */
#define MM_PTE_PER_PAGE 512
#define MM_PDE_PER_PAGE 512
#define MM_PPE_PER_PAGE 512
#define MM_PXE_PER_PAGE 512 #define MM_PXE_PER_PAGE 512
/* Minimum number of physical pages needed by the system */ /* Minimum number of physical pages needed by the system */
@@ -38,6 +51,21 @@
/* Default number of secondary colors */ /* Default number of secondary colors */
#define MM_DEFAULT_SECONDARY_COLORS 64 #define MM_DEFAULT_SECONDARY_COLORS 64
/* Number of HAL allocation descriptors */
#define MM_HARDWARE_ALLOCATION_DESCRIPTORS 64
/* Kernel HAL heap initial start address */
#define MM_HARDWARE_HEAP_START_ADDRESS ((PVOID)(((ULONG_PTR)MM_HARDWARE_VA_START) + 1024 * 1024))
/* HAL memory pool virtual address start */
#define MM_HARDWARE_VA_START 0xFFFFFFFFFFC00000ULL
/* Maximum physical address used by HAL allocations */
#define MM_MAXIMUM_PHYSICAL_ADDRESS 0x00000000FFFFFFFFULL
/* Trampoline code address */
#define MM_TRAMPOLINE_ADDRESS 0x80000
/* Page size enumeration list */ /* Page size enumeration list */
typedef enum _PAGE_SIZE typedef enum _PAGE_SIZE
{ {
@@ -67,6 +95,18 @@ typedef struct _HARDWARE_PTE
ULONGLONG NoExecute:1; ULONGLONG NoExecute:1;
} HARDWARE_PTE, *PHARDWARE_PTE; } HARDWARE_PTE, *PHARDWARE_PTE;
/* Page map information structure definition */
typedef struct _MMPAGEMAP_INFO
{
BOOLEAN Xpa;
ULONGLONG PteBase;
ULONGLONG PdeBase;
ULONGLONG PpeBase;
ULONGLONG PxeBase;
ULONGLONG P5eBase;
ULONG VaBits;
} MMPAGEMAP_INFO, *PMMPAGEMAP_INFO;
/* A Page Table Entry on AMD64 system */ /* A Page Table Entry on AMD64 system */
typedef struct _MMPTE_HARDWARE typedef struct _MMPTE_HARDWARE
{ {

View File

@@ -13,10 +13,23 @@
/* Architecture-specific enumeration lists forward references */ /* Architecture-specific enumeration lists forward references */
typedef enum _APIC_DM APIC_DM, *PAPIC_DM;
typedef enum _APIC_DSH APIC_DSH, *PAPIC_DSH;
typedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE;
typedef enum _APIC_REGISTER APIC_REGISTER, *PAPIC_REGISTER;
typedef enum _CPU_VENDOR CPU_VENDOR, *PCPU_VENDOR; typedef enum _CPU_VENDOR CPU_VENDOR, *PCPU_VENDOR;
typedef enum _CPUID_FEATURES CPUID_FEATURES, *PCPUID_FEATURES; typedef enum _CPUID_FEATURES_EXTENDED CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
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_LEAF1 CPUID_FEATURES_STANDARD7_LEAF1, *PCPUID_FEATURES_STANDARD7_LEAF1;
typedef enum _CPUID_REQUESTS CPUID_REQUESTS, *PCPUID_REQUESTS; typedef enum _CPUID_REQUESTS CPUID_REQUESTS, *PCPUID_REQUESTS;
typedef enum _PAGE_SIZE PAGE_SIZE, *PPAGE_SIZE; typedef enum _PAGE_SIZE PAGE_SIZE, *PPAGE_SIZE;
typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE PIC_I8259_ICW1_INTERRUPT_MODE, *PPIC_I8259_ICW1_INTERRUPT_MODE;
typedef enum _PIC_I8259_ICW1_INTERVAL PIC_I8259_ICW1_INTERVAL, *PPIC_I8259_ICW1_INTERVAL;
typedef enum _PIC_I8259_ICW1_OPERATING_MODE PIC_I8259_ICW1_OPERATING_MODE, *PPIC_I8259_ICW1_OPERATING_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_SYSTEM_MODE PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;
/* Architecture-specific structures forward references */ /* Architecture-specific structures forward references */
typedef struct _CONTEXT CONTEXT, *PCONTEXT; typedef struct _CONTEXT CONTEXT, *PCONTEXT;
@@ -38,6 +51,7 @@ typedef struct _KSWITCH_FRAME KSWITCH_FRAME, *PKSWITCH_FRAME;
typedef struct _KTHREAD_INIT_FRAME KTHREAD_INIT_FRAME, *PKTHREAD_INIT_FRAME; typedef struct _KTHREAD_INIT_FRAME KTHREAD_INIT_FRAME, *PKTHREAD_INIT_FRAME;
typedef struct _KTRAP_FRAME KTRAP_FRAME, *PKTRAP_FRAME; typedef struct _KTRAP_FRAME KTRAP_FRAME, *PKTRAP_FRAME;
typedef struct _KTSS KTSS, *PKTSS; typedef struct _KTSS KTSS, *PKTSS;
typedef struct _MMPAGEMAP_INFO MMPAGEMAP_INFO, *PMMPAGEMAP_INFO;
typedef struct _MMPFN MMPFN, *PMMPFN; typedef struct _MMPFN MMPFN, *PMMPFN;
typedef struct _MMPTE_HARDWARE MMPTE_HARDWARE, *PMMPTE_HARDWARE; typedef struct _MMPTE_HARDWARE MMPTE_HARDWARE, *PMMPTE_HARDWARE;
typedef struct _MMPTE_HARDWARE_LARGEPAGE MMPTE_HARDWARE_LARGEPAGE, *PMMPTE_HARDWARE_LARGEPAGE; typedef struct _MMPTE_HARDWARE_LARGEPAGE MMPTE_HARDWARE_LARGEPAGE, *PMMPTE_HARDWARE_LARGEPAGE;
@@ -49,9 +63,18 @@ typedef struct _MMPTE_TRANSITION MMPTE_TRANSITION, *PMMPTE_TRANSITION;
typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK; typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
/* Unions forward references */ /* Unions forward references */
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_LVT_REGISTER APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER;
typedef union _APIC_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
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;
typedef union _MMPTE MMPTE, *PMMPTE; typedef union _MMPTE MMPTE, *PMMPTE;
typedef union _MMPTE MMPXE, *PMMPXE; typedef union _MMPTE MMPXE, *PMMPXE;
typedef union _PIC_I8259_ICW1 PIC_I8259_ICW1, *PPIC_I8259_ICW1;
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_ICW4 PIC_I8259_ICW4, *PPIC_I8259_ICW4;
#endif /* __XTDK_AMD64_XTSTRUCT_H */ #endif /* __XTDK_AMD64_XTSTRUCT_H */

View File

@@ -14,6 +14,7 @@
/* XT BootLoader routines forward references */ /* XT BootLoader routines forward references */
XTCLINK
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable, BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable,

View File

@@ -18,10 +18,11 @@
/* EFI XT boot devices */ /* EFI XT boot devices */
#define XTBL_BOOT_DEVICE_UNKNOWN 0x00 #define XTBL_BOOT_DEVICE_UNKNOWN 0x00
#define XTBL_BOOT_DEVICE_CDROM 0x01 #define XTBL_BOOT_DEVICE_ESP 0x01
#define XTBL_BOOT_DEVICE_FLOPPY 0x02 #define XTBL_BOOT_DEVICE_CDROM 0x02
#define XTBL_BOOT_DEVICE_HARDDISK 0x03 #define XTBL_BOOT_DEVICE_FLOPPY 0x04
#define XTBL_BOOT_DEVICE_RAMDISK 0x04 #define XTBL_BOOT_DEVICE_HARDDISK 0x08
#define XTBL_BOOT_DEVICE_RAMDISK 0x10
/* XTLDR Debug Port type definitions */ /* XTLDR Debug Port type definitions */
#define XTBL_DEBUGPORT_SCREEN 1 #define XTBL_DEBUGPORT_SCREEN 1
@@ -40,30 +41,34 @@
#define XTBL_TUI_MAX_DIALOG_WIDTH 100 #define XTBL_TUI_MAX_DIALOG_WIDTH 100
/* XTLDR Routine pointers */ /* XTLDR Routine pointers */
typedef LONG (*PBL_GET_MEMTYPE_ROUTINE)(IN LONG EfiMemoryType); typedef LONG (*PBL_GET_MEMTYPE_ROUTINE)(IN EFI_MEMORY_TYPE EfiMemoryType);
/* Boot Loader protocol routine pointers */ /* Boot Loader protocol routine pointers */
typedef EFI_STATUS (*PBL_ALLOCATE_PAGES)(IN ULONGLONG Size, OUT PEFI_PHYSICAL_ADDRESS Memory); typedef EFI_STATUS (*PBL_ALLOCATE_PAGES)(IN EFI_ALLOCATE_TYPE AllocationType, IN ULONGLONG Size, OUT PEFI_PHYSICAL_ADDRESS Memory);
typedef EFI_STATUS (*PBL_ALLOCATE_POOL)(IN UINT_PTR Size, OUT PVOID *Memory); typedef EFI_STATUS (*PBL_ALLOCATE_POOL)(IN UINT_PTR Size, OUT PVOID *Memory);
typedef EFI_STATUS (*PBL_BOOTMENU_INITIALIZE_OS_LIST)(OUT PXTBL_BOOTMENU_ITEM *MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId); typedef EFI_STATUS (*PBL_BOOTMENU_INITIALIZE_OS_LIST)(IN ULONG MaxNameLength, OUT PXTBL_BOOTMENU_ITEM *MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId);
typedef BOOLEAN (*PBL_BOOTUTIL_GET_BOOLEAN_PARAMETER)(IN CONST PWCHAR Parameters, IN CONST PWCHAR Needle);
typedef EFI_STATUS (*PBL_BUILD_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR SelfMapAddress); typedef EFI_STATUS (*PBL_BUILD_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR SelfMapAddress);
typedef EFI_STATUS (*PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle); typedef EFI_STATUS (*PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle);
typedef VOID (*PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo); typedef VOID (*PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo);
typedef EFI_STATUS (*PBL_CLOSE_XT_PROTOCOL)(IN PEFI_HANDLE Handle, IN PEFI_GUID ProtocolGuid); typedef EFI_STATUS (*PBL_CLOSE_XT_PROTOCOL)(IN PEFI_HANDLE Handle, IN PEFI_GUID ProtocolGuid);
typedef BOOLEAN (*PBL_CONFIG_GET_BOOLEAN_VALUE)(IN CONST PWCHAR ConfigName); typedef BOOLEAN (*PBL_CONFIG_GET_BOOLEAN_VALUE)(IN CONST PWCHAR ConfigName);
typedef PWCHAR (*PBL_CONFIG_GET_VALUE)(IN CONST PWCHAR ConfigName); typedef EFI_STATUS (*PBL_CONFIG_GET_BOOT_OPTION_VALUE)(IN PLIST_ENTRY Options, IN CONST PWCHAR OptionName, OUT PWCHAR *OptionValue);
typedef VOID (*PBL_CONFIG_GET_EDITABLE_OPTIONS)(OUT CONST PWCHAR **OptionsArray, OUT PULONG OptionsCount);
typedef EFI_STATUS (*PBL_CONFIG_GET_VALUE)(IN CONST PWCHAR ConfigName, OUT PWCHAR *ConfigValue);
typedef EFI_STATUS (*PBL_CONFIG_SET_BOOT_OPTION_VALUE)(IN PLIST_ENTRY Options, IN CONST PWCHAR OptionName, IN CONST PWCHAR OptionValue);
typedef VOID (*PBL_CONSOLE_CLEAR_SCREEN)(); typedef VOID (*PBL_CONSOLE_CLEAR_SCREEN)();
typedef VOID (*PBL_CONSOLE_DISABLE_CURSOR)(); typedef VOID (*PBL_CONSOLE_DISABLE_CURSOR)();
typedef VOID (*PBL_CONSOLE_ENABLE_CURSOR)(); typedef VOID (*PBL_CONSOLE_ENABLE_CURSOR)();
typedef VOID (*PBL_CONSOLE_PRINT)(IN PUSHORT Format, IN ...); typedef VOID (*PBL_CONSOLE_PRINT)(IN PCWSTR Format, IN ...);
typedef VOID (*PBL_CONSOLE_QUERY_MODE)(OUT PUINT_PTR ResX, OUT PUINT_PTR ResY); typedef VOID (*PBL_CONSOLE_QUERY_MODE)(OUT PUINT_PTR ResX, OUT PUINT_PTR ResY);
typedef VOID (*PBL_CONSOLE_READ_KEY_STROKE)(OUT PEFI_INPUT_KEY Key); typedef VOID (*PBL_CONSOLE_READ_KEY_STROKE)(OUT PEFI_INPUT_KEY Key);
typedef VOID (*PBL_CONSOLE_RESET_INPUT_BUFFER)(); typedef VOID (*PBL_CONSOLE_RESET_INPUT_BUFFER)();
typedef VOID (*PBL_CONSOLE_SET_ATTRIBUTES)(IN ULONGLONG Attributes); typedef VOID (*PBL_CONSOLE_SET_ATTRIBUTES)(IN ULONGLONG Attributes);
typedef VOID (*PBL_CONSOLE_SET_CURSOR_POSITION)(IN ULONGLONG PosX, IN ULONGLONG PosY); typedef VOID (*PBL_CONSOLE_SET_CURSOR_POSITION)(IN ULONGLONG PosX, IN ULONGLONG PosY);
typedef VOID (*PBL_CONSOLE_WRITE)(IN PUSHORT String); typedef VOID (*PBL_CONSOLE_WRITE)(IN PCWSTR String);
typedef VOID (XTAPI *PBL_COPY_MEMORY)(OUT PVOID Destination, IN PCVOID Source, IN SIZE_T Length); typedef VOID (XTAPI *PBL_COPY_MEMORY)(OUT PVOID Destination, IN PCVOID Source, IN SIZE_T Length);
typedef VOID (*PBL_DEBUG_PRINT)(IN PUSHORT Format, IN ...); typedef VOID (*PBL_DEBUG_PRINT)(IN PCWSTR Format, IN ...);
typedef EFI_STATUS (*PBL_ENTER_FIRMWARE_SETUP)(); typedef EFI_STATUS (*PBL_ENTER_FIRMWARE_SETUP)();
typedef EFI_STATUS (*PBL_EXIT_BOOT_SERVICES)(); typedef EFI_STATUS (*PBL_EXIT_BOOT_SERVICES)();
typedef EFI_STATUS (*PBL_FIND_BOOT_PROTOCOL)(IN PWCHAR SystemType, OUT PEFI_GUID BootProtocolGuid); typedef EFI_STATUS (*PBL_FIND_BOOT_PROTOCOL)(IN PWCHAR SystemType, OUT PEFI_GUID BootProtocolGuid);
@@ -84,7 +89,7 @@ typedef EFI_STATUS (*PBL_INVOKE_BOOT_PROTOCOL)(IN PWCHAR ShortName, IN PLIST_ENT
typedef EFI_STATUS (*PBL_LOCATE_PROTOCOL_HANDLES)(OUT PEFI_HANDLE *Handles, OUT PUINT_PTR Count, IN PEFI_GUID ProtocolGuid); typedef EFI_STATUS (*PBL_LOCATE_PROTOCOL_HANDLES)(OUT PEFI_HANDLE *Handles, OUT PUINT_PTR Count, IN PEFI_GUID ProtocolGuid);
typedef EFI_STATUS (*PBL_LOAD_EFI_IMAGE)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, IN PVOID ImageData, IN SIZE_T ImageSize, OUT PEFI_HANDLE ImageHandle); typedef EFI_STATUS (*PBL_LOAD_EFI_IMAGE)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, IN PVOID ImageData, IN SIZE_T ImageSize, OUT PEFI_HANDLE ImageHandle);
typedef EFI_STATUS (*PBL_MAP_EFI_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN OUT PVOID *MemoryMapAddress, IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine); typedef EFI_STATUS (*PBL_MAP_EFI_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN OUT PVOID *MemoryMapAddress, IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine);
typedef EFI_STATUS (*PBL_MAP_PAGE)(IN PXTBL_PAGE_MAPPING PageMap, IN UINT_PTR VirtualAddress, IN UINT_PTR PhysicalAddress, IN UINT NumberOfPages); typedef EFI_STATUS (*PBL_MAP_PAGE)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR VirtualAddress, IN ULONG_PTR PhysicalAddress, IN ULONG NumberOfPages);
typedef EFI_STATUS (*PBL_MAP_VIRTUAL_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN PVOID VirtualAddress, IN PVOID PhysicalAddress, IN ULONGLONG NumberOfPages, IN LOADER_MEMORY_TYPE MemoryType); typedef EFI_STATUS (*PBL_MAP_VIRTUAL_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN PVOID VirtualAddress, IN PVOID PhysicalAddress, IN ULONGLONG NumberOfPages, IN LOADER_MEMORY_TYPE MemoryType);
typedef EFI_STATUS (*PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle); typedef EFI_STATUS (*PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle);
typedef EFI_STATUS (*PBL_OPEN_PROTOCOL)(OUT PEFI_HANDLE Handle, OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid); typedef EFI_STATUS (*PBL_OPEN_PROTOCOL)(OUT PEFI_HANDLE Handle, OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid);
@@ -110,6 +115,7 @@ typedef VOID (XTAPI *PBL_ZERO_MEMORY)(OUT PVOID Destination, IN SIZE_T Length);
/* Module protocols routine pointers */ /* Module protocols routine pointers */
typedef EFI_STATUS (*PBL_ACPI_GET_ACPI_DESCRIPTION_POINTER)(OUT PVOID *AcpiTable); typedef EFI_STATUS (*PBL_ACPI_GET_ACPI_DESCRIPTION_POINTER)(OUT PVOID *AcpiTable);
typedef EFI_STATUS (*PBL_ACPI_GET_ACPI_TABLE)(IN CONST UINT Signature, IN PVOID PreviousTable, OUT PVOID *AcpiTable);
typedef EFI_STATUS (*PBL_ACPI_GET_APIC_BASE)(OUT PVOID *ApicBase); typedef EFI_STATUS (*PBL_ACPI_GET_APIC_BASE)(OUT PVOID *ApicBase);
typedef EFI_STATUS (*PBL_ACPI_GET_RSDP_TABLE)(OUT PVOID *AcpiTable); typedef EFI_STATUS (*PBL_ACPI_GET_RSDP_TABLE)(OUT PVOID *AcpiTable);
typedef EFI_STATUS (*PBL_ACPI_GET_SMBIOS_TABLE)(OUT PVOID *SmBiosTable); typedef EFI_STATUS (*PBL_ACPI_GET_SMBIOS_TABLE)(OUT PVOID *SmBiosTable);
@@ -151,6 +157,7 @@ typedef struct _XTBL_BOOT_PARAMETERS
typedef struct _XTBL_BOOTMENU_ITEM typedef struct _XTBL_BOOTMENU_ITEM
{ {
PWCHAR EntryName; PWCHAR EntryName;
PWCHAR FullName;
PWCHAR ShortName; PWCHAR ShortName;
PLIST_ENTRY Options; PLIST_ENTRY Options;
} XTBL_BOOTMENU_ITEM, *PXTBL_BOOTMENU_ITEM; } XTBL_BOOTMENU_ITEM, *PXTBL_BOOTMENU_ITEM;
@@ -269,14 +276,14 @@ typedef struct _XTBL_FRAMEBUFFER_MODE_INFORMATION
EFI_GRAPHICS_PIXEL_FORMAT PixelFormat; EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;
struct struct
{ {
USHORT BlueMask;
USHORT BlueShift; USHORT BlueShift;
USHORT GreenMask; USHORT BlueSize;
USHORT GreenShift; USHORT GreenShift;
USHORT RedMask; USHORT GreenSize;
USHORT RedShift; USHORT RedShift;
USHORT ReservedMask; USHORT RedSize;
USHORT ReservedShift; USHORT ReservedShift;
USHORT ReservedSize;
} PixelInformation; } PixelInformation;
} XTBL_FRAMEBUFFER_MODE_INFORMATION, *PXTBL_FRAMEBUFFER_MODE_INFORMATION; } XTBL_FRAMEBUFFER_MODE_INFORMATION, *PXTBL_FRAMEBUFFER_MODE_INFORMATION;
@@ -301,6 +308,7 @@ typedef struct _XTBL_FRAMEBUFFER_INFORMATION
typedef struct _XTBL_ACPI_PROTOCOL typedef struct _XTBL_ACPI_PROTOCOL
{ {
PBL_ACPI_GET_ACPI_DESCRIPTION_POINTER GetAcpiDescriptionPointer; PBL_ACPI_GET_ACPI_DESCRIPTION_POINTER GetAcpiDescriptionPointer;
PBL_ACPI_GET_ACPI_TABLE GetAcpiTable;
PBL_ACPI_GET_APIC_BASE GetApicBase; PBL_ACPI_GET_APIC_BASE GetApicBase;
PBL_ACPI_GET_RSDP_TABLE GetRsdpTable; PBL_ACPI_GET_RSDP_TABLE GetRsdpTable;
PBL_ACPI_GET_SMBIOS_TABLE GetSMBiosTable; PBL_ACPI_GET_SMBIOS_TABLE GetSMBiosTable;
@@ -352,9 +360,16 @@ typedef struct _XTBL_LOADER_PROTOCOL
PBL_REGISTER_BOOT_PROTOCOL RegisterProtocol; PBL_REGISTER_BOOT_PROTOCOL RegisterProtocol;
} Boot; } Boot;
struct struct
{
PBL_BOOTUTIL_GET_BOOLEAN_PARAMETER GetBooleanParameter;
} BootUtil;
struct
{ {
PBL_CONFIG_GET_BOOLEAN_VALUE GetBooleanValue; PBL_CONFIG_GET_BOOLEAN_VALUE GetBooleanValue;
PBL_CONFIG_GET_BOOT_OPTION_VALUE GetBootOptionValue;
PBL_CONFIG_GET_EDITABLE_OPTIONS GetEditableOptions;
PBL_CONFIG_GET_VALUE GetValue; PBL_CONFIG_GET_VALUE GetValue;
PBL_CONFIG_SET_BOOT_OPTION_VALUE SetBootOptionValue;
} Config; } Config;
struct struct
{ {

View File

@@ -14,26 +14,32 @@
/* Kernel Executive routines forward references */ /* Kernel Executive routines forward references */
XTCLINK
XTFASTCALL XTFASTCALL
BOOLEAN BOOLEAN
ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor); ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
XTCLINK
XTFASTCALL XTFASTCALL
VOID VOID
ExCompleteRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor); ExCompleteRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
XTCLINK
XTFASTCALL XTFASTCALL
VOID VOID
ExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor); ExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
XTCLINK
XTFASTCALL XTFASTCALL
VOID VOID
ExReInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor); ExReInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
XTCLINK
XTFASTCALL XTFASTCALL
VOID VOID
ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor); ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
XTCLINK
XTFASTCALL XTFASTCALL
VOID VOID
ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor); ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor);

View File

@@ -15,15 +15,16 @@
/* Routines used by XTLDR */ /* Routines used by XTLDR */
XTCLINK
XTCDECL XTCDECL
XTSTATUS XTSTATUS
HlComPortPutByte(IN PCPPORT Port, HlComPortPutByte(IN PCPPORT Port,
IN UCHAR Byte); IN UCHAR Byte);
XTCLINK
XTCDECL XTCDECL
XTSTATUS XTSTATUS
HlInitializeComPort(IN OUT PCPPORT Port, HlInitializeComPort(IN OUT PCPPORT Port,
IN ULONG PortNumber,
IN PUCHAR PortAddress, IN PUCHAR PortAddress,
IN ULONG BaudRate); IN ULONG BaudRate);

View File

@@ -9,9 +9,98 @@
#ifndef __XTDK_HLTYPES_H #ifndef __XTDK_HLTYPES_H
#define __XTDK_HLTYPES_H #define __XTDK_HLTYPES_H
#include <xtbase.h>
#include <xtdefs.h>
#include <xttypes.h> #include <xttypes.h>
#include ARCH_HEADER(hltypes.h)
/* ACPI Root System Description Pointer (RSDP) signature */
#define ACPI_RSDP_SIGNATURE 0x2052545020445352
/* ACPI table signatures */
#define ACPI_BERT_SIGNATURE 0x54524542 /* Boot Error Record Table */
#define ACPI_BGRT_SIGNATURE 0x54524742 /* Boot Graphics Record Table */
#define ACPI_BOOT_SIGNATURE 0x544F4F42 /* ACPI BOOT Table */
#define ACPI_CPEP_SIGNATURE 0x50455043 /* Corrected Platform Error Polling Table */
#define ACPI_DBG2_SIGNATURE 0x32474244 /* Debug Port Table v2 */
#define ACPI_DBGP_SIGNATURE 0x50474244 /* Debug Port Table */
#define ACPI_DMAR_SIGNATURE 0x52414D44 /* DMA Remapping Table */
#define ACPI_DSDT_SIGNATURE 0x54445344 /* Differentiated System Description Table */
#define ACPI_ECDT_SIGNATURE 0x54444345 /* Embedded Controller Description Table */
#define ACPI_ERST_SIGNATURE 0x54535245 /* Error Record Serialization Table */
#define ACPI_FACS_SIGNATURE 0x53434146 /* Firmware ACPI Control Structure */
#define ACPI_FADT_SIGNATURE 0x50434146 /* Fixed ACPI Description Table */
#define ACPI_FBPT_SIGNATURE 0x54504246 /* Firmware Boot Performance Table */
#define ACPI_FPDT_SIGNATURE 0x54445046 /* Firmware Performance Data Table */
#define ACPI_GTDT_SIGNATURE 0x54445447 /* Generic Timer Description Table */
#define ACPI_HPET_SIGNATURE 0x54455048 /* High Precision Event Timer */
#define ACPI_IVRS_SIGNATURE 0x53525649 /* AMD IOMMU Resource Table */
#define ACPI_MADT_SIGNATURE 0x43495041 /* MADT/APIC Description Table */
#define ACPI_MCFG_SIGNATURE 0x4746434D /* Memory Mapped Configuration Space Access Table */
#define ACPI_MPST_SIGNATURE 0x5453504D /* Memory Power State Table*/
#define ACPI_MSCT_SIGNATURE 0x5443534D /* Maximum System Characteristics Table */
#define ACPI_NFIT_SIGNATURE 0x5449464E /* NVDIMM Firmware Interface Table */
#define ACPI_PMMT_SIGNATURE 0x544D4D50 /* Platform Memory Topology Table */
#define ACPI_PSDT_SIGNATURE 0x54445350 /* Persistent System Description Table */
#define ACPI_RAS2_SIGNATURE 0x32534152 /* ACPI RAS2 Feature Table */
#define ACPI_RASF_SIGNATURE 0x46534152 /* ACPI RAS Feature Table */
#define ACPI_RSDT_SIGNATURE 0x54445352 /* Root System Description Table */
#define ACPI_SBST_SIGNATURE 0x54534253 /* Smart Battery Subsystem Table */
#define ACPI_SDEV_SIGNATURE 0x56454453 /* Secure Device Table */
#define ACPI_SLIT_SIGNATURE 0x54494C53 /* System Locality Distance Information Table */
#define ACPI_SPCR_SIGNATURE 0x52435053 /* Serial Port Console Redirection Table */
#define ACPI_SRAT_SIGNATURE 0x54415253 /* Static Resource Affinity Table */
#define ACPI_SSDT_SIGNATURE 0x54445353 /* Secondary System Descriptor Table */
#define ACPI_TPM2_SIGNATURE 0x324D5054 /* ACPI TPM 2.0 Table */
#define ACPI_WAET_SIGNATURE 0x54454157 /* Windows ACPI Enlightenment Table */
#define ACPI_WDAT_SIGNATURE 0x54414457 /* Watch Dog Action Table */
#define ACPI_WDTT_SIGNATURE 0x54524457 /* Watchdog Timer Resource Table */
#define ACPI_WPBT_SIGNATURE 0x54425057 /* Windows Platform Binary Table */
#define ACPI_WSMT_SIGNATURE 0x544D5357 /* Windows SMM Security Mitigation Table */
#define ACPI_XSDT_SIGNATURE 0x54445358 /* eXtended System Descriptor Table */
/* ACPI FADT flags masks */
#define ACPI_FADT_32BIT_TIMER (1<<8)
/* ACPI Timer bit masks */
#define ACPI_FADT_TIMER_32BIT 0x80000000
#define ACPI_FADT_TIMER_24BIT 0x00800000
/* ACPI MADT subtable type definitions */
#define ACPI_MADT_TYPE_LOCAL_APIC 0
#define ACPI_MADT_TYPE_IOAPIC 1
#define ACPI_MADT_TYPE_INT_OVERRIDE 2
#define ACPI_MADT_TYPE_NMI_SOURCE 3
#define ACPI_MADT_TYPE_LOCAL_APIC_NMI 4
#define ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE 5
#define ACPI_MADT_TYPE_IO_SAPIC 6
#define ACPI_MADT_TYPE_LOCAL_SAPIC 7
#define ACPI_MADT_TYPE_INTERRUPT_SOURCE 8
#define ACPI_MADT_TYPE_LOCAL_X2APIC 9
#define ACPI_MADT_TYPE_LOCAL_X2APIC_NMI 10
#define ACPI_MADT_TYPE_GENERIC_INTERRUPT 11
#define ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR 12
#define ACPI_MADT_TYPE_GENERIC_MSI_FRAME 13
#define ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR 14
#define ACPI_MADT_TYPE_GENERIC_TRANSLATOR 15
#define ACPI_MADT_TYPE_MULTIPROC_WAKEUP 16
#define ACPI_MADT_TYPE_CORE_PIC 17
#define ACPI_MADT_TYPE_LIO_PIC 18
#define ACPI_MADT_TYPE_HT_PIC 19
#define ACPI_MADT_TYPE_EIO_PIC 20
#define ACPI_MADT_TYPE_MSI_PIC 21
#define ACPI_MADT_TYPE_BIO_PIC 22
#define ACPI_MADT_TYPE_LPC_PIC 23
#define ACPI_MADT_TYPE_RINTC 24
#define ACPI_MADT_TYPE_IMSIC 25
#define ACPI_MADT_TYPE_APLIC 26
#define ACPI_MADT_TYPE_PLIC 27
/* ACPI MADT Processor Local APIC Flags */
#define ACPI_MADT_PLACE_ENABLED 0 /* Processor Local APIC CPU Enabled */
#define ACPI_MADT_PLAOC_ENABLED 1 /* Processor Local APIC Online Capable */
/* 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
@@ -90,60 +179,195 @@
#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 */
/* APIC Register Address Map */ /* Generic Address structure */
typedef enum _APIC_REGISTER typedef struct _GENERIC_ADDRESS
{ {
APIC_ID = 0x02, /* APIC ID Register */ UCHAR AddressSpaceID;
APIC_VER = 0x03, /* APIC Version Register */ UCHAR BitWidth;
APIC_TPR = 0x08, /* Task Priority Register */ UCHAR BitOffset;
APIC_APR = 0x09, /* Arbitration Priority Register */ UCHAR Reserved;
APIC_PPR = 0x0A, /* Processor Priority Register (R) */ PHYSICAL_ADDRESS Address;
APIC_EOI = 0x0B, /* EOI Register */ } PACKED GENERIC_ADDRESS, *PGENERIC_ADDRESS;
APIC_RRR = 0x0C, /* Remote Read Register */
APIC_LDR = 0x0D, /* Logical Destination Register */
APIC_DFR = 0x0E, /* Destination Format Register (not available in extended mode) */
APIC_SIVR = 0x0F, /* Spurious Interrupt Vector Register */
APIC_ISR = 0x10, /* Interrupt Service Register*/
APIC_TMR = 0x18, /* Trigger Mode Register */
APIC_IRR = 0x20, /* Interrupt Request Register */
APIC_ESR = 0x28, /* Error Status Register */
APIC_ICR0 = 0x30, /* Interrupt Command Register */
APIC_ICR1 = 0x31, /* Interrupt Command Register (not available in extended mode) */
APIC_TMRLVTR = 0x32, /* Timer Local Vector Table */
APIC_THRMLVTR = 0x33, /* Thermal Local Vector Table */
APIC_PCLVTR = 0x34, /* Performance Counter Local Vector Table */
APIC_LINT0 = 0x35, /* LINT0 Local Vector Table */
APIC_LINT1 = 0x36, /* LINT1 Local Vector Table */
APIC_ERRLVTR = 0x37, /* Error Local Vector Table */
APIC_TICR = 0x38, /* Initial Count Register for Timer */
APIC_TCCR = 0x39, /* Current Count Register for Timer */
APIC_TDCR = 0x3E, /* Timer Divide Configuration Register */
APIC_EAFR = 0x40, /* extended APIC Feature register */
APIC_EACR = 0x41, /* Extended APIC Control Register */
APIC_SEOI = 0x42, /* Specific End Of Interrupt Register */
APIC_EXT0LVTR = 0x50, /* Extended Interrupt 0 Local Vector Table */
APIC_EXT1LVTR = 0x51, /* Extended Interrupt 1 Local Vector Table */
APIC_EXT2LVTR = 0x52, /* Extended Interrupt 2 Local Vector Table */
APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */
} APIC_REGISTER, *PAPIC_REGISTER;
/* APIC mode list */ /* Each ACPI table description header structure */
typedef enum _HAL_APIC_MODE typedef struct _ACPI_DESCRIPTION_HEADER
{ {
APIC_MODE_COMPAT, ULONG Signature;
APIC_MODE_X2APIC ULONG Length;
} HAL_APIC_MODE, *PHAL_APIC_MODE; UCHAR Revision;
UCHAR Checksum;
UCHAR OemId[6];
UCHAR OemTableID[8];
ULONG OemRevision;
UCHAR CreatorID[4];
ULONG CreatorRev;
} PACKED ACPI_DESCRIPTION_HEADER, *PACPI_DESCRIPTION_HEADER;
/* Serial (COM) port initial state */ /* Each ACPI subtable description header structure */
typedef struct _ACPI_SUBTABLE_HEADER
{
UCHAR Type;
UCHAR Length;
} PACKED ACPI_SUBTABLE_HEADER, *PACPI_SUBTABLE_HEADER;
/* ACPI cache list structure */
typedef struct _ACPI_CACHE_LIST
{
LIST_ENTRY ListEntry;
ACPI_DESCRIPTION_HEADER Header;
} ACPI_CACHE_LIST, *PACPI_CACHE_LIST;
/* ACPI Root System Description Table Pointer (RSDP) structure */
typedef struct _ACPI_RSDP
{
ULONGLONG Signature;
UCHAR Checksum;
UCHAR OemId[6];
UCHAR Revision;
ULONG RsdtAddress;
ULONG Length;
ULONGLONG XsdtAddress;
UCHAR XChecksum;
UCHAR Reserved[3];
} PACKED ACPI_RSDP, *PACPI_RSDP;
/* ACPI Root System Description Table (RSDT) structure */
typedef struct _ACPI_RSDT
{
ACPI_DESCRIPTION_HEADER Header;
ULONG Tables[];
} PACKED ACPI_RSDT, *PACPI_RSDT;
/* ACPI eXtended Root System Description Table (XSDT) structure */
typedef struct _ACPI_XSDT
{
ACPI_DESCRIPTION_HEADER Header;
ULONGLONG Tables[];
} PACKED ACPI_XSDT, *PACPI_XSDT;
/* Fixed ACPI Description Table (FADT) structure */
typedef struct _ACPI_FADT
{
ACPI_DESCRIPTION_HEADER Header;
ULONG FirmwareCtrl;
ULONG Dsdt;
UCHAR IntModel;
UCHAR PmProfile;
USHORT SciIntVector;
ULONG SmiCmdIoPort;
UCHAR AcpiOnValue;
UCHAR AcpiOffValue;
UCHAR S4BiosReq;
UCHAR PStateControl;
ULONG Pm1aEvtBlkIoPort;
ULONG Pm1bEvtBlkIoPort;
ULONG Pm1aCtrlBlkIoPort;
ULONG Pm1bCtrlBlkIoPort;
ULONG Pm2CtrlBlkIoPort;
ULONG PmTmrBlkIoPort;
ULONG Gp0BlkIoPort;
ULONG Gp1BlkIoPort;
UCHAR Pm1EvtLen;
UCHAR Pm1CtrlLen;
UCHAR Pm2CtrlLen;
UCHAR PmTmrLen;
UCHAR Gp0BlkLen;
UCHAR Gp1BlkLen;
UCHAR Gp1Base;
UCHAR CStateControl;
USHORT Lvl2Latency;
USHORT Lvl3Latency;
USHORT FlushSize;
USHORT FlushStride;
UCHAR DutyOffset;
UCHAR DutyWidth;
UCHAR DayAlarmIndex;
UCHAR MonthAlarmIndex;
UCHAR CenturyAlarmIndex;
USHORT BootArch;
UCHAR Reserved0;
ULONG Flags;
GENERIC_ADDRESS ResetReg;
UCHAR ResetVal;
USHORT ArmBootArch;
UCHAR Reserved1;
PHYSICAL_ADDRESS XFirmwareCtrl;
PHYSICAL_ADDRESS XDsdt;
GENERIC_ADDRESS XPm1aEvtBlk;
GENERIC_ADDRESS XPm1bEvtBlk;
GENERIC_ADDRESS XPm1aCtrlBlk;
GENERIC_ADDRESS XPm1bCtrlBlk;
GENERIC_ADDRESS XPm2CtrlBlk;
GENERIC_ADDRESS XPmTmrBlk;
GENERIC_ADDRESS XGp0Blk;
GENERIC_ADDRESS XGp1Blk;
GENERIC_ADDRESS SleepControlReg;
GENERIC_ADDRESS SleepStatusReg;
} PACKED ACPI_FADT, *PACPI_FADT;
/* ACPI Multiple APIC Description Table (MADT) structure */
typedef struct _ACPI_MADT
{
ACPI_DESCRIPTION_HEADER Header;
ULONG LocalApicAddress;
ULONG Flags;
ULONG ApicTables[];
} PACKED ACPI_MADT, *PACPI_MADT;
/* ACPI Local APIC MADT subtable structure */
typedef struct _ACPI_MADT_LOCAL_APIC
{
ACPI_SUBTABLE_HEADER Header;
UCHAR AcpiId;
UCHAR ApicId;
ULONG Flags;
} PACKED ACPI_MADT_LOCAL_APIC, *PACPI_MADT_LOCAL_APIC;
/* ACPI Local X2APIC MADT subtable structure */
typedef struct _ACPI_MADT_LOCAL_X2APIC
{
ACPI_SUBTABLE_HEADER Header;
USHORT Reserved;
ULONG ApicId;
ULONG Flags;
ULONG AcpiId;
} PACKED ACPI_MADT_LOCAL_X2APIC, *PACPI_MADT_LOCAL_X2APIC;
/* ACPI System Information structure */
typedef struct _ACPI_SYSTEM_INFO
{
ULONG CpuCount;
ULONG RunningCpus;
ULONG BusCount;
ULONG IoApicCount;
ULONG IntiCount;
ULONG LintiCount;
BOOLEAN ImcrPresent;
ULONG ApicBase;
PPROCESSOR_IDENTITY CpuInfo;
ULONG IoApicPhysicalBase[APIC_MAX_IOAPICS];
ULONG IoApicVirtualBase[APIC_MAX_IOAPICS];
ULONG IoApicVectorBase[APIC_MAX_IOAPICS];
} ACPI_SYSTEM_INFO, *PACPI_SYSTEM_INFO;
/* ACPI Timer information structure */
typedef struct _ACPI_TIMER_INFO
{
ULONG TimerPort;
ULONG MsbMask;
} ACPI_TIMER_INFO, *PACPI_TIMER_INFO;
/* Serial (COM) port state */
typedef struct _CPPORT typedef struct _CPPORT
{ {
PUCHAR Address; PUCHAR Address;
ULONG Baud; ULONG Baud;
USHORT Flags; USHORT Flags;
UCHAR Ring;
} CPPORT, *PCPPORT; } CPPORT, *PCPPORT;
/* HAL framebuffer data structure */ /* Framebuffer data structure */
typedef struct _HAL_FRAMEBUFFER_DATA typedef struct _HL_FRAMEBUFFER_DATA
{ {
BOOLEAN Initialized; BOOLEAN Initialized;
PVOID Address; PVOID Address;
@@ -151,10 +375,46 @@ typedef struct _HAL_FRAMEBUFFER_DATA
UINT Width; UINT Width;
UINT Height; UINT Height;
UINT PixelsPerScanLine; UINT PixelsPerScanLine;
UINT BitsPerPixel; UINT BytesPerPixel;
UINT Pitch; UINT Pitch;
PVOID Font; PVOID Font;
} HAL_FRAMEBUFFER_DATA, *PHAL_FRAMEBUFFER_DATA; struct
{
USHORT BlueShift;
USHORT BlueSize;
USHORT GreenShift;
USHORT GreenSize;
USHORT RedShift;
USHORT RedSize;
USHORT ReservedShift;
USHORT ReservedSize;
} Pixels;
} HL_FRAMEBUFFER_DATA, *PHL_FRAMEBUFFER_DATA;
/* Scroll region data structure */
typedef struct _HL_SCROLL_REGION_DATA
{
ULONG Left;
ULONG Top;
ULONG Right;
ULONG Bottom;
ULONG WidthInChars;
ULONG HeightInChars;
ULONG CursorX;
ULONG CursorY;
ULONG BackgroundColor;
ULONG TextColor;
} HL_SCROLL_REGION_DATA, *PHL_SCROLL_REGION_DATA;
/* Processor identity structure */
typedef struct _PROCESSOR_IDENTITY
{
ULONG AcpiId;
ULONG ApicId;
USHORT CpuNumber;
BOOLEAN Bsp;
BOOLEAN Started;
} PROCESSOR_IDENTITY, *PPROCESSOR_IDENTITY;
/* SMBIOS table header structure */ /* SMBIOS table header structure */
typedef struct _SMBIOS_TABLE_HEADER typedef struct _SMBIOS_TABLE_HEADER

View File

@@ -16,26 +16,32 @@
/* Routines used by XTLDR */ /* Routines used by XTLDR */
XTCLINK
XTCDECL XTCDECL
VOID VOID
ArClearInterruptFlag(VOID); ArClearInterruptFlag(VOID);
XTCLINK
XTCDECL XTCDECL
BOOLEAN BOOLEAN
ArCpuId(IN OUT PCPUID_REGISTERS Registers); ArCpuId(IN OUT PCPUID_REGISTERS Registers);
XTCLINK
XTCDECL XTCDECL
VOID VOID
ArHalt(VOID); ArHalt(VOID);
XTCLINK
XTCDECL XTCDECL
ULONG_PTR ULONG_PTR
ArReadControlRegister(IN USHORT ControlRegister); ArReadControlRegister(IN USHORT ControlRegister);
XTCLINK
XTCDECL XTCDECL
ULONGLONG ULONGLONG
ArReadModelSpecificRegister(IN ULONG Register); ArReadModelSpecificRegister(IN ULONG Register);
XTCLINK
XTCDECL XTCDECL
VOID VOID
ArWriteControlRegister(IN USHORT ControlRegister, ArWriteControlRegister(IN USHORT ControlRegister,

View File

@@ -39,13 +39,22 @@
#define CR4_PCE 0x00000100 #define CR4_PCE 0x00000100
#define CR4_FXSR 0x00000200 #define CR4_FXSR 0x00000200
#define CR4_XMMEXCPT 0x00000400 #define CR4_XMMEXCPT 0x00000400
#define CR4_UMIP 0x00000800
#define CR4_LA57 0x00001000 #define CR4_LA57 0x00001000
#define CR4_RESERVED1 0x00001800
#define CR4_VMXE 0x00002000 #define CR4_VMXE 0x00002000
#define CR4_SMXE 0x00004000 #define CR4_SMXE 0x00004000
#define CR4_RESERVED2 0x00018000 #define CR4_FSGSBASE 0x00010000
#define CR4_XSAVE 0x00020000 #define CR4_PCIDE 0x00020000
#define CR4_RESERVED3 0xFFFC0000 #define CR4_XSAVE 0x00040000
#define CR4_KL 0x00080000
#define CR4_SMEP 0x00100000
#define CR4_SMAP 0x00200000
#define CR4_PKE 0x00400000
#define CR4_CET 0x00800000
#define CR4_PKS 0x01000000
#define CR4_UINTR 0x02000000
#define CR4_LASS 0x08000000
#define CR4_LAM_SUP 0x10000000
/* Descriptors size */ /* Descriptors size */
#define GDT_ENTRIES 128 #define GDT_ENTRIES 128
@@ -62,6 +71,27 @@
#define SEGMENT_FS 0x64 #define SEGMENT_FS 0x64
#define SEGMENT_GS 0x65 #define SEGMENT_GS 0x65
/* X86 EFLAG bit masks definitions */
#define X86_EFLAGS_NF_MASK 0x00000000 /* None */
#define X86_EFLAGS_CF_MASK 0x00000001 /* Carry */
#define X86_EFLAGS_PF_MASK 0x00000004 /* Parity */
#define X86_EFALGS_AF_MASK 0x00000010 /* Aux Carry */
#define X86_EFLAGS_ZF_MASK 0x00000040 /* Zero */
#define X86_EFLAGS_SF_MASK 0x00000080 /* Sign */
#define X86_EFLAGS_TF_MASK 0x00000100 /* Trap */
#define X86_EFLAGS_IF_MASK 0x00000200 /* Interrupt */
#define X86_EFLAGS_DF_MASK 0x00000400 /* Direction */
#define X86_EFLAGS_OF_MASK 0x00000800 /* Overflow */
#define X86_EFLAGS_IOPL_MASK 0x00003000 /* I/O Privilege */
#define X86_EFLAGS_NT_MASK 0x00004000 /* Nested Task */
#define X86_EFLAGS_SIGN_MASK 0x00008000 /* Sign */
#define X86_EFLAGS_RF_MASK 0x00010000 /* Resume */
#define X86_EFLAGS_V86_MASK 0x00020000 /* Virtual 8086 */
#define X86_EFLAGS_AC_MASK 0x00040000 /* Alignment Check */
#define X86_EFLAGS_VIF_MASK 0x00080000 /* Virtual Interrupt */
#define X86_EFLAGS_VIP_MASK 0x00100000 /* Virtual Interrupt Pending */
#define X86_EFLAGS_ID_MASK 0x00200000 /* Identification */
/* CPU vendor enumeration list */ /* CPU vendor enumeration list */
typedef enum _CPU_VENDOR typedef enum _CPU_VENDOR
{ {
@@ -70,8 +100,49 @@ typedef enum _CPU_VENDOR
CPU_VENDOR_UNKNOWN = 0xFFFFFFFF CPU_VENDOR_UNKNOWN = 0xFFFFFFFF
} CPU_VENDOR, *PCPU_VENDOR; } CPU_VENDOR, *PCPU_VENDOR;
/* CPUID features enumeration list */ /* CPUID extended features (0x80000001) enumeration list */
typedef enum _CPUID_FEATURES typedef enum _CPUID_FEATURES_EXTENDED
{
CPUID_FEATURES_ECX_LAHF_SAHF = 1 << 0,
CPUID_FEATURES_ECX_CMP_LEGACY = 1 << 1,
CPUID_FEATURES_ECX_SVM = 1 << 2,
CPUID_FEATURES_ECX_EXT_APIC_SPACE = 1 << 3,
CPUID_FEATURES_ECX_ALT_MOV_CR8 = 1 << 4,
CPUID_FEATURES_ECX_LZCNT = 1 << 5,
CPUID_FEATURES_ECX_SSE4A = 1 << 6,
CPUID_FEATURES_ECX_MISALIGNED_SSE = 1 << 7,
CPUID_FEATURES_ECX_PREFETCHW = 1 << 8,
CPUID_FEATURES_ECX_OSVW = 1 << 9,
CPUID_FEATURES_ECX_IBS = 1 << 10,
CPUID_FEATURES_ECX_XOP = 1 << 11,
CPUID_FEATURES_ECX_SKINIT = 1 << 12,
CPUID_FEATURES_ECX_WDT = 1 << 13,
CPUID_FEATURES_ECX_LWP = 1 << 15,
CPUID_FEATURES_ECX_FMA4 = 1 << 16,
CPUID_FEATURES_ECX_TCE = 1 << 17,
CPUID_FEATURES_ECX_NODEID = 1 << 19,
CPUID_FEATURES_ECX_TBM = 1 << 21,
CPUID_FEATURES_ECX_TOPOLOGY_EXTENSIONS = 1 << 22,
CPUID_FEATURES_ECX_PERFCTR_EXT_CORE = 1 << 23,
CPUID_FEATURES_ECX_PERFCTR_EXT_NB = 1 << 24,
CPUID_FEATURES_ECX_DATA_BREAKPOINT_EXT = 1 << 26,
CPUID_FEATURES_ECX_PERF_TSC = 1 << 27,
CPUID_FEATURES_ECX_PERFCTR_EXT_L2I = 1 << 28,
CPUID_FEATURES_ECX_MONITORX_MWAITX = 1 << 29,
CPUID_FEATURES_ECX_CODEBP_ADDRMASK_EXT = 1 << 30,
CPUID_FEATURES_EDX_SYSCALL_SYSRET = 1 << 11,
CPUID_FEATURES_EDX_NX = 1 << 20,
CPUID_FEATURES_EDX_AMD_MMX_EXT = 1 << 22,
CPUID_FEATURES_EDX_FFXSR = 1 << 25,
CPUID_FEATURES_EDX_1G_PAGES = 1 << 26,
CPUID_FEATURES_EDX_RDTSCP = 1 << 27,
CPUID_FEATURES_EDX_LONG_MODE = 1 << 29,
CPUID_FEATURES_EDX_3DNOW_EXT = 1 << 30,
CPUID_FEATURES_EDX_3DNOW = 1 << 31
} CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
/* CPUID STD1 features (0x00000001) enumeration list */
typedef enum _CPUID_FEATURES_STANDARD1
{ {
CPUID_FEATURES_ECX_SSE3 = 1 << 0, CPUID_FEATURES_ECX_SSE3 = 1 << 0,
CPUID_FEATURES_ECX_PCLMUL = 1 << 1, CPUID_FEATURES_ECX_PCLMUL = 1 << 1,
@@ -134,15 +205,150 @@ typedef enum _CPUID_FEATURES
CPUID_FEATURES_EDX_TM = 1 << 29, CPUID_FEATURES_EDX_TM = 1 << 29,
CPUID_FEATURES_EDX_IA64 = 1 << 30, CPUID_FEATURES_EDX_IA64 = 1 << 30,
CPUID_FEATURES_EDX_PBE = 1 << 31 CPUID_FEATURES_EDX_PBE = 1 << 31
} CPUID_FEATURES, *PCPUID_FEATURES; } CPUID_FEATURES_STANDARD1, *PCPUID_FEATURES_STANDARD1;
/* CPUID STD7 features (0x00000007, subleaf 0) enumeration list */
typedef enum _CPUID_FEATURES_STANDARD7_LEAF0
{
CPUID_FEATURES_EBX_FSGSBASE = 1 << 0,
CPUID_FEATURES_EBX_TSC_ADJUST = 1 << 1,
CPUID_FEATURES_EBX_SGX = 1 << 2,
CPUID_FEATURES_EBX_BMI1 = 1 << 3,
CPUID_FEATURES_EBX_HLE = 1 << 4,
CPUID_FEATURES_EBX_AVX2 = 1 << 5,
CPUID_FEATURES_EBX_FDP_DEPRECATION = 1 << 6,
CPUID_FEATURES_EBX_SMEP = 1 << 7,
CPUID_FEATURES_EBX_BMI2 = 1 << 8,
CPUID_FEATURES_EBX_ERMS = 1 << 9,
CPUID_FEATURES_EBX_INVPCID = 1 << 10,
CPUID_FEATURES_EBX_RTM = 1 << 11,
CPUID_FEATURES_EBX_QOS_MONITORING = 1 << 12,
CPUID_FEATURES_EBX_DEPRECATE_FCS_FDS = 1 << 13,
CPUID_FEATURES_EBX_MPX = 1 << 14,
CPUID_FEATURES_EBX_QOS_ENFORCEMENT = 1 << 15,
CPUID_FEATURES_EBX_AVX512F = 1 << 16,
CPUID_FEATURES_EBX_AVX512DQ = 1 << 17,
CPUID_FEATURES_EBX_RDSEED = 1 << 18,
CPUID_FEATURES_EBX_ADX = 1 << 19,
CPUID_FEATURES_EBX_SMAP = 1 << 20,
CPUID_FEATURES_EBX_AVX512IFMA52 = 1 << 21,
CPUID_FEATURES_EBX_CLFLUSHOPT = 1 << 23,
CPUID_FEATURES_EBX_CLWB = 1 << 24,
CPUID_FEATURES_EBX_PROCESSOR_TRACE = 1 << 25,
CPUID_FEATURES_EBX_AVX512PF = 1 << 26,
CPUID_FEATURES_EBX_AVX512ER = 1 << 27,
CPUID_FEATURES_EBX_AVX512CD = 1 << 28,
CPUID_FEATURES_EBX_SHA = 1 << 29,
CPUID_FEATURES_EBX_AVX512BW = 1 << 30,
CPUID_FEATURES_EBX_AVX512VL = 1 << 31,
CPUID_FEATURES_ECX_PREFETCHWT1 = 1 << 0,
CPUID_FEATURES_ECX_AVX512_VBMI = 1 << 1,
CPUID_FEATURES_ECX_UMIP = 1 << 2,
CPUID_FEATURES_ECX_PKU = 1 << 3,
CPUID_FEATURES_ECX_OSPKE = 1 << 4,
CPUID_FEATURES_ECX_WAITPKG = 1 << 5,
CPUID_FEATURES_ECX_AVX512_VBMI2 = 1 << 6,
CPUID_FEATURES_ECX_CET_SS = 1 << 7,
CPUID_FEATURES_ECX_GFNI = 1 << 8,
CPUID_FEATURES_ECX_VAES = 1 << 9,
CPUID_FEATURES_ECX_VPCLMULQDQ = 1 << 10,
CPUID_FEATURES_ECX_AVX512_VNNI = 1 << 11,
CPUID_FEATURES_ECX_AVX512_BITALG = 1 << 12,
CPUID_FEATURES_ECX_TME = 1 << 13,
CPUID_FEATURES_ECX_AVX512_VPOPCNTDQ = 1 << 14,
CPUID_FEATURES_ECX_LA57 = 1 << 16,
CPUID_FEATURES_ECX_RDPID = 1 << 22,
CPUID_FEATURES_ECX_KEYLOCKER = 1 << 23,
CPUID_FEATURES_ECX_BUS_LOCK_DETECT = 1 << 24,
CPUID_FEATURES_ECX_CLDEMOTE = 1 << 25,
CPUID_FEATURES_ECX_MOVDIRI = 1 << 27,
CPUID_FEATURES_ECX_MOVDIR64B = 1 << 28,
CPUID_FEATURES_ECX_ENQCMD = 1 << 29,
CPUID_FEATURES_ECX_SGX_LAUNCH_CONFIG = 1 << 30,
CPUID_FEATURES_ECX_PKS = 1 << 31,
CPUID_FEATURES_EDX_SGX_KEYS = 1 << 1,
CPUID_FEATURES_EDX_AVX512_4VNNIW = 1 << 2,
CPUID_FEATURES_EDX_AVX512_4FMAPS = 1 << 3,
CPUID_FEATURES_EDX_FAST_SHORT_REP_MOV = 1 << 4,
CPUID_FEATURES_EDX_UINTR = 1 << 5,
CPUID_FEATURES_EDX_AVX512_VPINTERSECT = 1 << 8,
CPUID_FEATURES_EDX_SRBDS_CTRL = 1 << 9,
CPUID_FEATURES_EDX_MD_CLEAR = 1 << 10,
CPUID_FEATURES_EDX_RTM_ALWAYS_ABORT = 1 << 11,
CPUID_FEATURES_EDX_RTM_FORCE_ABORT = 1 << 13,
CPUID_FEATURES_EDX_SERIALIZE = 1 << 14,
CPUID_FEATURES_EDX_HYBRID = 1 << 15,
CPUID_FEATURES_EDX_TSXLDTRK = 1 << 16,
CPUID_FEATURES_EDX_PCONFIG = 1 << 18,
CPUID_FEATURES_EDX_ARCH_LBR = 1 << 19,
CPUID_FEATURES_EDX_CET_IBT = 1 << 20,
CPUID_FEATURES_EDX_AMX_BF16 = 1 << 22,
CPUID_FEATURES_EDX_AVX512_FP16 = 1 << 23,
CPUID_FEATURES_EDX_AMX_TILE = 1 << 24,
CPUID_FEATURES_EDX_AMX_INT8 = 1 << 25,
CPUID_FEATURES_EDX_SCA_IBRS_IBPB = 1 << 26,
CPUID_FEATURES_EDX_SCA_STIBP = 1 << 27,
CPUID_FEATURES_EDX_L1D_FLUSH = 1 << 28,
CPUID_FEATURES_EDX_ARCH_CAPABILITIES_MSR = 1 << 29,
CPUID_FEATURES_EDX_CORE_CAPABILITIES_MSR = 1 << 30,
CPUID_FEATURES_EDX_SCA_SSBD = 1 << 31
} CPUID_FEATURES_STANDARD7_LEAF0, *PCPUID_FEATURES_STANDARD7_LEAF0;
/* CPUID STD7 features (0x00000007, subleaf 1) enumeration list */
typedef enum _CPUID_FEATURES_STANDARD7_LEAF1
{
CPUID_FEATURES_EAX_SHA512 = 1 << 0,
CPUID_FEATURES_EAX_SM3 = 1 << 1,
CPUID_FEATURES_EAX_SM4 = 1 << 2,
CPUID_FEATURES_EAX_RAO_INT = 1 << 3,
CPUID_FEATURES_EAX_AVX_VNNI = 1 << 4,
CPUID_FEATURES_EAX_AVX512_BF16 = 1 << 5,
CPUID_FEATURES_EAX_LASS = 1 << 6,
CPUID_FEATURES_EAX_CMPCCXADD = 1 << 7,
CPUID_FEATURES_EAX_ARCH_PERFMON = 1 << 8,
CPUID_FEATURES_EAX_FAST_ZEROLEN_REP_MOVSB = 1 << 10,
CPUID_FEATURES_EAX_FAST_ZEROLEN_REP_STOSB = 1 << 11,
CPUID_FEATURES_EAX_FAST_ZEROLEN_REP_CMPSB = 1 << 12,
CPUID_FEATURES_EAX_FRED = 1 << 17,
CPUID_FEATURES_EAX_LKGS = 1 << 18,
CPUID_FEATURES_EAX_WRMSRNS = 1 << 19,
CPUID_FEATURES_EAX_NMI_SOURCE_REPORTING = 1 << 20,
CPUID_FEATURES_EAX_AMX_FP16 = 1 << 21,
CPUID_FEATURES_EAX_HRESET = 1 << 22,
CPUID_FEATURES_EAX_AVX_IFMA = 1 << 23,
CPUID_FEATURES_EAX_LAM = 1 << 26,
CPUID_FEATURES_EAX_MSRLIST = 1 << 27,
CPUID_FEATURES_EAX_INVD_DISABLE = 1 << 30,
CPUID_FEATURES_EAX_MOVRS = 1 << 31,
CPUID_FEATURES_EBX_PPIN = 1 << 0,
CPUID_FEATURES_EBX_TSE = 1 << 1,
CPUID_FEATURES_EBX_CPUIDMAXVAL_LIM_RMV = 1 << 3,
CPUID_FEATURES_ECX_MSR_IMM = 1 << 5,
CPUID_FEATURES_EDX_AVX_VNNI_INT8 = 1 << 4,
CPUID_FEATURES_EDX_AVX_NE_CONVERT = 1 << 5,
CPUID_FEATURES_EDX_AMX_COMPLEX = 1 << 8,
CPUID_FEATURES_EDX_AVX_VNNI_INT16 = 1 << 10,
CPUID_FEATURES_EDX_USER_TIMER = 1 << 13,
CPUID_FEATURES_EDX_PREFETCHI = 1 << 14,
CPUID_FEATURES_EDX_USER_MSR = 1 << 15,
CPUID_FEATURES_EDX_UIRET_UIF = 1 << 17,
CPUID_FEATURES_EDX_CET_SSS = 1 << 18,
CPUID_FEATURES_EDX_AVX10 = 1 << 19,
CPUID_FEATURES_EDX_APX = 1 << 21,
CPUID_FEATURES_EDX_MWAIT_AND_LEAF5 = 1 << 23
} CPUID_FEATURES_STANDARD7_LEAF1, *PCPUID_FEATURES_STANDARD7_LEAF1;
/* CPUID requests */ /* CPUID requests */
typedef enum _CPUID_REQUESTS typedef enum _CPUID_REQUESTS
{ {
CPUID_GET_VENDOR_STRING, CPUID_GET_VENDOR_STRING,
CPUID_GET_CPU_FEATURES, CPUID_GET_STANDARD1_FEATURES,
CPUID_GET_TLB, CPUID_GET_TLB_CACHE,
CPUID_GET_SERIAL CPUID_GET_SERIAL,
CPUID_GET_CACHE_TOPOLOGY,
CPUID_GET_MONITOR_MWAIT,
CPUID_GET_POWER_MANAGEMENT,
CPUID_GET_STANDARD7_FEATURES
} CPUID_REQUESTS, *PCPUID_REQUESTS; } CPUID_REQUESTS, *PCPUID_REQUESTS;
/* Processor identification information */ /* Processor identification information */

View File

@@ -16,28 +16,34 @@
/* HAL library routines forward references */ /* HAL library routines forward references */
XTCLINK
XTCDECL XTCDECL
UCHAR UCHAR
HlIoPortInByte(IN USHORT Port); HlIoPortInByte(IN USHORT Port);
XTCLINK
XTCDECL XTCDECL
ULONG ULONG
HlIoPortInLong(IN USHORT Port); HlIoPortInLong(IN USHORT Port);
XTCLINK
XTCDECL XTCDECL
USHORT USHORT
HlIoPortInShort(IN USHORT Port); HlIoPortInShort(IN USHORT Port);
XTCLINK
XTCDECL XTCDECL
VOID VOID
HlIoPortOutByte(IN USHORT Port, HlIoPortOutByte(IN USHORT Port,
IN UCHAR Data); IN UCHAR Data);
XTCLINK
XTCDECL XTCDECL
VOID VOID
HlIoPortOutLong(IN USHORT Port, HlIoPortOutLong(IN USHORT Port,
IN ULONG Value); IN ULONG Value);
XTCLINK
XTCDECL XTCDECL
VOID VOID
HlIoPortOutShort(IN USHORT Port, HlIoPortOutShort(IN USHORT Port,

View File

@@ -47,20 +47,17 @@
#define APIC_DF_FLAT 0xFFFFFFFF #define APIC_DF_FLAT 0xFFFFFFFF
#define APIC_DF_CLUSTER 0x0FFFFFFF #define APIC_DF_CLUSTER 0x0FFFFFFF
/* APIC delivery modes */
#define APIC_DM_FIXED 0
#define APIC_DM_LOWPRIO 1
#define APIC_DM_SMI 2
#define APIC_DM_REMOTE 3
#define APIC_DM_NMI 4
#define APIC_DM_INIT 5
#define APIC_DM_STARTUP 6
#define APIC_DM_EXTINT 7
/* APIC trigger modes */ /* APIC trigger modes */
#define APIC_TGM_EDGE 0 #define APIC_TGM_EDGE 0
#define APIC_TGM_LEVEL 1 #define APIC_TGM_LEVEL 1
/* APIC LDR (Logical Destination Register) shifts */
#define APIC_X2APIC_LDR_SHIFT 16
#define APIC_XAPIC_LDR_SHIFT 24
/* Maximum number of I/O APICs */
#define APIC_MAX_IOAPICS 64
/* 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
@@ -72,12 +69,123 @@
/* PIC vector definitions */ /* PIC vector definitions */
#define PIC1_VECTOR_SPURIOUS 0x37 #define PIC1_VECTOR_SPURIOUS 0x37
/* Serial port I/O addresses */ /* Serial ports information */
#define COMPORT_ADDRESSES {0x000, 0x3F8, 0x2F8, 0x3E8, 0x2E8, 0x5F8, 0x4F8, 0x5E8, 0x4E8} #define COMPORT_ADDRESS {0x3F8, 0x2F8, 0x3E8, 0x2E8, 0x5F8, 0x4F8, 0x5E8, 0x4E8}
#define COMPORT_COUNT 8
/* Initial stall factor */ /* Initial stall factor */
#define INITIAL_STALL_FACTOR 100 #define INITIAL_STALL_FACTOR 100
/* APIC delivery mode enumeration list */
typedef enum _APIC_DM
{
APIC_DM_FIXED,
APIC_DM_LOWPRIO,
APIC_DM_SMI,
APIC_DM_REMOTE,
APIC_DM_NMI,
APIC_DM_INIT,
APIC_DM_STARTUP,
APIC_DM_EXTINT,
} APIC_DM, *PAPIC_DM;
/* APIC destination short-hand enumeration list */
typedef enum _APIC_DSH
{
APIC_DSH_Destination,
APIC_DSH_Self,
APIC_DSH_AllIncludingSelf,
APIC_DSH_AllExclusingSelf
} APIC_DSH, *PAPIC_DSH;
/* APIC mode list */
typedef enum _APIC_MODE
{
APIC_MODE_COMPAT,
APIC_MODE_X2APIC
} APIC_MODE, *PAPIC_MODE;
/* APIC Register Address Map */
typedef enum _APIC_REGISTER
{
APIC_ID = 0x02, /* APIC ID Register */
APIC_VER = 0x03, /* APIC Version Register */
APIC_TPR = 0x08, /* Task Priority Register */
APIC_APR = 0x09, /* Arbitration Priority Register */
APIC_PPR = 0x0A, /* Processor Priority Register (R) */
APIC_EOI = 0x0B, /* EOI Register */
APIC_RRR = 0x0C, /* Remote Read Register */
APIC_LDR = 0x0D, /* Logical Destination Register */
APIC_DFR = 0x0E, /* Destination Format Register (not available in extended mode) */
APIC_SIVR = 0x0F, /* Spurious Interrupt Vector Register */
APIC_ISR = 0x10, /* Interrupt Service Register*/
APIC_TMR = 0x18, /* Trigger Mode Register */
APIC_IRR = 0x20, /* Interrupt Request Register */
APIC_ESR = 0x28, /* Error Status Register */
APIC_ICR0 = 0x30, /* Interrupt Command Register */
APIC_ICR1 = 0x31, /* Interrupt Command Register (not available in extended mode) */
APIC_TMRLVTR = 0x32, /* Timer Local Vector Table */
APIC_THRMLVTR = 0x33, /* Thermal Local Vector Table */
APIC_PCLVTR = 0x34, /* Performance Counter Local Vector Table */
APIC_LINT0 = 0x35, /* LINT0 Local Vector Table */
APIC_LINT1 = 0x36, /* LINT1 Local Vector Table */
APIC_ERRLVTR = 0x37, /* Error Local Vector Table */
APIC_TICR = 0x38, /* Initial Count Register for Timer */
APIC_TCCR = 0x39, /* Current Count Register for Timer */
APIC_TDCR = 0x3E, /* Timer Divide Configuration Register */
APIC_EAFR = 0x40, /* extended APIC Feature register */
APIC_EACR = 0x41, /* Extended APIC Control Register */
APIC_SEOI = 0x42, /* Specific End Of Interrupt Register */
APIC_EXT0LVTR = 0x50, /* Extended Interrupt 0 Local Vector Table */
APIC_EXT1LVTR = 0x51, /* Extended Interrupt 1 Local Vector Table */
APIC_EXT2LVTR = 0x52, /* Extended Interrupt 2 Local Vector Table */
APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */
} APIC_REGISTER, *PAPIC_REGISTER;
/* I8259 PIC interrupt mode enumeration list */
typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE
{
EdgeTriggered,
LevelTriggered
} PIC_I8259_ICW1_INTERRUPT_MODE, *PPIC_I8259_ICW1_INTERRUPT_MODE;
/* I8259 PIC interval enumeration list */
typedef enum _PIC_I8259_ICW1_INTERVAL
{
Interval8,
Interval4
} PIC_I8259_ICW1_INTERVAL, *PPIC_I8259_ICW1_INTERVAL;
/* I8259 PIC operating mode enumeration list */
typedef enum _PIC_I8259_ICW1_OPERATING_MODE
{
Cascade,
Single
} PIC_I8259_ICW1_OPERATING_MODE, *PPIC_I8259_ICW1_OPERATING_MODE;
/* I8259 PIC buffered mode enumeration list */
typedef enum _PIC_I8259_ICW4_BUFFERED_MODE
{
NonBuffered,
NonBuffered2,
BufferedSlave,
BufferedMaster
} PIC_I8259_ICW4_BUFFERED_MODE, *PPIC_I8259_ICW4_BUFFERED_MODE;
/* I8259 PIC End Of Interrupt (EOI) mode enumeration list */
typedef enum _PIC_I8259_ICW4_EOI_MODE
{
NormalEoi,
AutomaticEoi
} PIC_I8259_ICW4_EOI_MODE, *PPIC_I8259_ICW4_EOI_MODE;
/* I8259 PIC system mode enumeration list */
typedef enum _PIC_I8259_ICW4_SYSTEM_MODE
{
Mcs8085Mode,
New8086Mode
} PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;
/* APIC Base Register */ /* APIC Base Register */
typedef union _APIC_BASE_REGISTER typedef union _APIC_BASE_REGISTER
{ {
@@ -94,6 +202,31 @@ typedef union _APIC_BASE_REGISTER
}; };
} APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER; } APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER;
/* APIC Command Register */
typedef union _APIC_COMMAND_REGISTER
{
ULONGLONG LongLong;
struct
{
ULONG Long0;
ULONG Long1;
};
struct
{
ULONGLONG Vector:8;
ULONGLONG DeliveryMode:3;
ULONGLONG DestinationMode:1;
ULONGLONG DeliveryStatus:1;
ULONGLONG ReservedMBZ:1;
ULONGLONG Level:1;
ULONGLONG TriggerMode:1;
ULONGLONG RemoteReadStatus:2;
ULONGLONG DestinationShortHand:2;
ULONGLONG Reserved2MBZ:36;
ULONGLONG Destination:8;
};
} APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGISTER;
/* APIC Local Vector Table (LVT) Register */ /* APIC Local Vector Table (LVT) Register */
typedef union _APIC_LVT_REGISTER typedef union _APIC_LVT_REGISTER
{ {
@@ -101,7 +234,7 @@ typedef union _APIC_LVT_REGISTER
struct struct
{ {
ULONG Vector:8; ULONG Vector:8;
ULONG MessageType:3; ULONG DeliveryMode:3;
ULONG Reserved1:1; ULONG Reserved1:1;
ULONG DeliveryStatus:1; ULONG DeliveryStatus:1;
ULONG Reserved2:1; ULONG Reserved2:1;
@@ -126,14 +259,69 @@ typedef union _APIC_SPURIOUS_REGISTER
}; };
} APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER; } APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
/* Processor identity structure */ /* I8259 PIC register structure */
typedef struct _HAL_PROCESSOR_IDENTITY typedef union _PIC_I8259_ICW1
{ {
UCHAR ProcessorId; struct
UCHAR LApicId; {
BOOLEAN Bsp; UCHAR NeedIcw4:1;
BOOLEAN Started; UCHAR OperatingMode:1;
PKPROCESSOR_BLOCK ProcessorBlock; UCHAR Interval:1;
} HAL_PROCESSOR_IDENTITY, *PHAL_PROCESSOR_IDENTITY; UCHAR InterruptMode:1;
UCHAR Init:1;
UCHAR InterruptVectorAddress:3;
};
UCHAR Bits;
} PIC_I8259_ICW1, *PPIC_I8259_ICW1;
/* I8259 PIC register structure */
typedef union _PIC_I8259_ICW2
{
struct
{
UCHAR Sbz:3;
UCHAR InterruptVector:5;
};
UCHAR Bits;
} PIC_I8259_ICW2, *PPIC_I8259_ICW2;
/* I8259 PIC register structure */
typedef union _PIC_I8259_ICW3
{
union
{
struct
{
UCHAR SlaveIrq0:1;
UCHAR SlaveIrq1:1;
UCHAR SlaveIrq2:1;
UCHAR SlaveIrq3:1;
UCHAR SlaveIrq4:1;
UCHAR SlaveIrq5:1;
UCHAR SlaveIrq6:1;
UCHAR SlaveIrq7:1;
};
struct
{
UCHAR SlaveId:3;
UCHAR Reserved:5;
};
};
UCHAR Bits;
} PIC_I8259_ICW3, *PPIC_I8259_ICW3;
/* I8259 PIC register structure */
typedef union _PIC_I8259_ICW4
{
struct
{
UCHAR SystemMode:1;
UCHAR EoiMode:1;
UCHAR BufferedMode:2;
UCHAR SpecialFullyNestedMode:1;
UCHAR Reserved:3;
};
UCHAR Bits;
} PIC_I8259_ICW4, *PPIC_I8259_ICW4;
#endif /* __XTDK_I686_HLTYPES_H */ #endif /* __XTDK_I686_HLTYPES_H */

View File

@@ -95,31 +95,6 @@
#define I686_INTERRUPT_GATE 0xE #define I686_INTERRUPT_GATE 0xE
#define I686_TRAP_GATE 0xF #define I686_TRAP_GATE 0xF
/* EFlags bits definitions */
#define EFLAGS_NF_MASK 0x00000000L /* None */
#define EFLAGS_CF_MASK 0x00000001L /* Carry */
#define EFLAGS_PF_MASK 0x00000004L /* Parity */
#define EFLAGS_AF_MASK 0x00000010L /* Aux Carry */
#define EFLAGS_ZF_MASK 0x00000040L /* Zero */
#define EFLAGS_SF_MASK 0x00000080L /* Sign */
#define EFLAGS_TF 0x00000100L /* Trap */
#define EFLAGS_INTERRUPT_MASK 0x00000200L /* Interrupt */
#define EFLAGS_DF_MASK 0x00000400L /* Direction */
#define EFLAGS_OF_MASK 0x00000800L /* Overflow */
#define EFLAGS_IOPL_MASK 0x00003000L /* I/O Privilege */
#define EFLAGS_NT 0x00004000L /* Nested Task */
#define EFLAGS_SIGN_MASK 0x00008000L /* Sign */
#define EFLAGS_RF 0x00010000L /* Resume */
#define EFLAGS_V86_MASK 0x00020000L /* Virtual 8086 */
#define EFLAGS_ALIGN_CHECK 0x00040000L /* Alignment Check */
#define EFLAGS_VIF 0x00080000L /* Virtual Interrupt */
#define EFLAGS_VIP 0x00100000L /* Virtual Interrupt Pending */
#define EFLAGS_ID_MASK 0x00200000L /* Identification */
/* EFLAGS sanitize masks */
#define EFLAGS_KERNELMODE 0x003F0FD7L
#define EFLAGS_USERMODE 0x003F4DD7L
/* 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)
@@ -168,6 +143,10 @@
/* 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 */
#define KPROCESSOR_STRUCTURES_SIZE ((2 * KERNEL_STACK_SIZE) + sizeof(ArInitialGdt) + sizeof(ArInitialTss) + \
sizeof(ArInitialProcessorBlock) + MM_PAGE_SIZE)
/* Kernel frames */ /* Kernel frames */
#define KTRAP_FRAME_ALIGN 0x08 #define KTRAP_FRAME_ALIGN 0x08
#define KTRAP_FRAME_SIZE sizeof(KTRAP_FRAME) #define KTRAP_FRAME_SIZE sizeof(KTRAP_FRAME)
@@ -453,7 +432,7 @@ typedef struct _KPROCESSOR_CONTROL_BLOCK
PKTHREAD CurrentThread; PKTHREAD CurrentThread;
PKTHREAD IdleThread; PKTHREAD IdleThread;
PKTHREAD NextThread; PKTHREAD NextThread;
UCHAR Number; UCHAR CpuNumber;
ULONG_PTR SetMember; ULONG_PTR SetMember;
CPU_IDENTIFICATION CpuId; CPU_IDENTIFICATION CpuId;
KPROCESSOR_STATE ProcessorState; KPROCESSOR_STATE ProcessorState;
@@ -470,16 +449,27 @@ typedef struct _KPROCESSOR_CONTROL_BLOCK
/* Processor Block structure definition */ /* Processor Block structure definition */
typedef struct _KPROCESSOR_BLOCK typedef struct _KPROCESSOR_BLOCK
{ {
union
{
THREAD_INFORMATION_BLOCK ThreadInformationBlock; THREAD_INFORMATION_BLOCK ThreadInformationBlock;
PKPROCESSOR_BLOCK Self; struct
PKPROCESSOR_CONTROL_BLOCK CurrentPrcb; {
KRUNLEVEL RunLevel;
PKIDTENTRY IdtBase;
PKGDTENTRY GdtBase; PKGDTENTRY GdtBase;
PKTSS TssBase; PKTSS TssBase;
PKPROCESSOR_BLOCK Self;
PKPROCESSOR_CONTROL_BLOCK CurrentPrcb;
};
};
PKIDTENTRY IdtBase;
KRUNLEVEL RunLevel;
KPROCESSOR_CONTROL_BLOCK Prcb; KPROCESSOR_CONTROL_BLOCK Prcb;
ULONG Irr;
ULONG IrrActive;
ULONG Idr;
ULONG ContextSwitches; ULONG ContextSwitches;
KAFFINITY SetMember;
ULONG StallScaleFactor; ULONG StallScaleFactor;
UCHAR CpuNumber;
} KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK; } KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK;
/* Thread Environment Block (TEB) structure definition */ /* Thread Environment Block (TEB) structure definition */

View File

@@ -14,16 +14,48 @@
/* Pages related definitions */ /* Pages related definitions */
#define MM_PAGE_MASK 0xFFF #define MM_PAGE_MASK (MM_PAGE_SIZE - 1)
#define MM_PAGE_SHIFT 12 #define MM_PAGE_SHIFT 12
#define MM_PAGE_SIZE 4096 #define MM_PAGE_SIZE 4096
/* Page directory and page base addresses */
#define MM_PTE_BASE 0xC0000000
#define MM_PDE_BASE 0xC0600000
/* PTE shift values */
#define MM_PTE_SHIFT 3
#define MM_PTI_SHIFT 12
#define MM_PDI_SHIFT 21
#define MM_PPI_SHIFT 30
/* Page directory and page base legacy address */
#define MM_PDE_LEGACY_BASE 0xC0300000
/* PTE legacy shift values */
#define MM_PTE_LEGACY_SHIFT 2
#define MM_PDI_LEGACY_SHIFT 22
/* Minimum number of physical pages needed by the system */ /* Minimum number of physical pages needed by the system */
#define MM_MINIMUM_PHYSICAL_PAGES 1100 #define MM_MINIMUM_PHYSICAL_PAGES 1100
/* Default number of secondary colors */ /* Default number of secondary colors */
#define MM_DEFAULT_SECONDARY_COLORS 64 #define MM_DEFAULT_SECONDARY_COLORS 64
/* Number of HAL allocation descriptors */
#define MM_HARDWARE_ALLOCATION_DESCRIPTORS 64
/* Kernel HAL heap initial start address */
#define MM_HARDWARE_HEAP_START_ADDRESS ((PVOID)(((ULONG_PTR)MM_HARDWARE_VA_START) + 1024 * 1024))
/* HAL memory pool virtual address start */
#define MM_HARDWARE_VA_START 0xFFC00000
/* Maximum physical address used by HAL allocations */
#define MM_MAXIMUM_PHYSICAL_ADDRESS 0xFFFFFFFF
/* Trampoline code address */
#define MM_TRAMPOLINE_ADDRESS 0x80000
/* Page size enumeration list */ /* Page size enumeration list */
typedef enum _PAGE_SIZE typedef enum _PAGE_SIZE
{ {
@@ -32,123 +64,7 @@ typedef enum _PAGE_SIZE
Size4M Size4M
} PAGE_SIZE, *PPAGE_SIZE; } PAGE_SIZE, *PPAGE_SIZE;
/* Page Table entry structure definition (with PAE support) */ /* Legacy Page Table entry structure definition (PML2) */
typedef struct _HARDWARE_PTE
{
ULONGLONG Valid:1;
ULONGLONG Writable:1;
ULONGLONG Owner:1;
ULONGLONG WriteThrough:1;
ULONGLONG CacheDisable:1;
ULONGLONG Accessed:1;
ULONGLONG Dirty:1;
ULONGLONG LargePage:1;
ULONGLONG Global:1;
ULONGLONG CopyOnWrite:1;
ULONGLONG Prototype:1;
ULONGLONG Reserved0:1;
ULONGLONG PageFrameNumber:26;
ULONGLONG Reserved1:14;
ULONGLONG SoftwareWsIndex:11;
ULONGLONG NoExecute:1;
} HARDWARE_PTE, *PHARDWARE_PTE;
/* Page Table Entry on PAE enabled system */
typedef struct _MMPTE_HARDWARE
{
ULONGLONG Valid:1;
ULONGLONG Writable:1;
ULONGLONG Owner:1;
ULONGLONG WriteThrough:1;
ULONGLONG CacheDisable:1;
ULONGLONG Accessed:1;
ULONGLONG Dirty:1;
ULONGLONG LargePage:1;
ULONGLONG Global:1;
ULONGLONG CopyOnWrite:1;
ULONGLONG Prototype:1;
ULONGLONG Write:1;
ULONGLONG PageFrameNumber:26;
ULONGLONG Reserved1:25;
ULONGLONG NoExecute:1;
} MMPTE_HARDWARE, *PMMPTE_HARDWARE;
/* Page Table Entry list structure definition (with PAE support) */
typedef struct _MMPTE_LIST
{
ULONGLONG Valid:1;
ULONGLONG OneEntry:1;
ULONGLONG Reserved1:8;
ULONGLONG Prototype:1;
ULONGLONG Reserved2:21;
ULONGLONG NextEntry:32;
} MMPTE_LIST, *PMMPTE_LIST;
/* Page Table Entry subsection structure definition (with PAE support) */
typedef struct _MMPTE_PROTOTYPE
{
ULONGLONG Valid:1;
ULONGLONG Reserved1:7;
ULONGLONG ReadOnly:1;
ULONGLONG Reserved2:1;
ULONGLONG Prototype:1;
ULONGLONG Protection:5;
ULONGLONG Reserved3:16;
ULONGLONG ProtoAddress:32;
} MMPTE_PROTOTYPE, *PMMPTE_PROTOTYPE;
/* Page Table Entry software structure definition (with PAE support) */
typedef struct _MMPTE_SOFTWARE
{
ULONGLONG Valid:1;
ULONGLONG PageFileLow:4;
ULONGLONG Protection:5;
ULONGLONG Prototype:1;
ULONGLONG Transition:1;
ULONGLONG Reserved1:20;
ULONGLONG PageFileHigh:32;
} MMPTE_SOFTWARE, *PMMPTE_SOFTWARE;
/* Page Table Entry subsection structure definition (with PAE support) */
typedef struct _MMPTE_SUBSECTION
{
ULONGLONG Valid:1;
ULONGLONG Reserved1:4;
ULONGLONG Protection:5;
ULONGLONG Prototype:1;
ULONGLONG Reserved2:21;
ULONGLONG SubsectionAddress:32;
} MMPTE_SUBSECTION, *PMMPTE_SUBSECTION;
/* Page Table Entry transition structure definition (with PAE support) */
typedef struct _MMPTE_TRANSITION
{
ULONGLONG Valid:1;
ULONGLONG Write:1;
ULONGLONG Owner:1;
ULONGLONG WriteThrough:1;
ULONGLONG CacheDisable:1;
ULONGLONG Protection:5;
ULONGLONG Prototype:1;
ULONGLONG Transition:1;
ULONGLONG PageFrameNumber:26;
ULONGLONG Unused:26;
} MMPTE_TRANSITION, *PMMPTE_TRANSITION;
/* Page Table Entry structure definition (with PAE support) */
typedef union _MMPTE
{
ULONGLONG Long;
HARDWARE_PTE Flush;
MMPTE_HARDWARE Hardware;
MMPTE_PROTOTYPE Prototype;
MMPTE_SOFTWARE Software;
MMPTE_TRANSITION Transition;
MMPTE_SUBSECTION Subsection;
MMPTE_LIST List;
} MMPTE, *PMMPTE;
/* Legacy Page Table entry structure definition (without PAE support) */
typedef struct _HARDWARE_LEGACY_PTE typedef struct _HARDWARE_LEGACY_PTE
{ {
ULONG Valid:1; ULONG Valid:1;
@@ -166,8 +82,47 @@ typedef struct _HARDWARE_LEGACY_PTE
ULONG PageFrameNumber:20; ULONG PageFrameNumber:20;
} HARDWARE_LEGACY_PTE, *PHARDWARE_LEGACY_PTE; } HARDWARE_LEGACY_PTE, *PHARDWARE_LEGACY_PTE;
/* Legacy Page Table Entry on non-PAE system */ /* Page Table entry structure definition (PML3) */
typedef struct _MMPTE_LEGACY_HARDWARE typedef struct _HARDWARE_MODERN_PTE
{
ULONGLONG Valid:1;
ULONGLONG Writable:1;
ULONGLONG Owner:1;
ULONGLONG WriteThrough:1;
ULONGLONG CacheDisable:1;
ULONGLONG Accessed:1;
ULONGLONG Dirty:1;
ULONGLONG LargePage:1;
ULONGLONG Global:1;
ULONGLONG CopyOnWrite:1;
ULONGLONG Prototype:1;
ULONGLONG Reserved0:1;
ULONGLONG PageFrameNumber:26;
ULONGLONG Reserved1:14;
ULONGLONG SoftwareWsIndex:11;
ULONGLONG NoExecute:1;
} HARDWARE_MODERN_PTE, *PHARDWARE_MODERN_PTE;
/* Generic Page Table entry union to abstract PML2 and PML3 formats */
typedef union _HARDWARE_PTE
{
ULONGLONG Long;
HARDWARE_LEGACY_PTE Pml2;
HARDWARE_MODERN_PTE Pml3;
} HARDWARE_PTE, *PHARDWARE_PTE;
/* Page map information structure definition */
typedef struct _MMPAGEMAP_INFO
{
BOOLEAN Xpa;
ULONG PteBase;
ULONG PdeBase;
ULONG PdiShift;
ULONG PteShift;
} MMPAGEMAP_INFO, *PMMPAGEMAP_INFO;
/* Legacy Page Table Entry hardware structure definition (PML2) */
typedef struct _MMPML2_PTE_HARDWARE
{ {
ULONG Valid:1; ULONG Valid:1;
ULONG Writable:1; ULONG Writable:1;
@@ -182,21 +137,21 @@ typedef struct _MMPTE_LEGACY_HARDWARE
ULONG Prototype:1; ULONG Prototype:1;
ULONG Write:1; ULONG Write:1;
ULONG PageFrameNumber:20; ULONG PageFrameNumber:20;
} MMPTE_LEGACY_HARDWARE, *PMMPTE_LEGACY_HARDWARE; } MMPML2_PTE_HARDWARE, *PMMPML2_PTE_HARDWARE;
/* Legacy Page Table Entry list structure definition (without PAE support) */ /* Legacy Page Table Entry list structure definition (PML2) */
typedef struct _MMPTE_LEGACY_LIST typedef struct _MMPML2_PTE_LIST
{ {
ULONG Valid:1; ULONG Valid:1;
ULONG OneEntry:1; ULONG OneEntry:1;
ULONG Reserved1:8; ULONG Reserved0:8;
ULONG Prototype:1; ULONG Prototype:1;
ULONG Reserved2:1; ULONG Reserved1:1;
ULONG NextEntry:20; ULONG NextEntry:20;
} MMPTE_LEGACY_LIST, *PMMPTE_LEGACY_LIST; } MMPML2_PTE_LIST, *PMMPML2_PTE_LIST;
/* Legacy Page Table Entry prototype structure definition (without PAE support) */ /* Legacy Page Table Entry subsection structure definition (PML2) */
typedef struct _MMPTE_LEGACY_PROTOTYPE typedef struct _MMPML2_PTE_PROTOTYPE
{ {
ULONG Valid:1; ULONG Valid:1;
ULONG ProtoAddressLow:7; ULONG ProtoAddressLow:7;
@@ -204,10 +159,10 @@ typedef struct _MMPTE_LEGACY_PROTOTYPE
ULONG WhichPool:1; ULONG WhichPool:1;
ULONG Prototype:1; ULONG Prototype:1;
ULONG ProtoAddressHigh:21; ULONG ProtoAddressHigh:21;
} MMPTE_LEGACY_PROTOTYPE, *PMMPTE_LEGACY_PROTOTYPE; } MMPML2_PTE_PROTOTYPE, *PMMPML2_PTE_PROTOTYPE;
/* Legacy Page Table Entry software structure definition (without PAE support) */ /* Legacy Page Table Entry software structure definition (PML2) */
typedef struct _MMPTE_LEGACY_SOFTWARE typedef struct _MMPML2_PTE_SOFTWARE
{ {
ULONG Valid:1; ULONG Valid:1;
ULONG PageFileLow:4; ULONG PageFileLow:4;
@@ -215,10 +170,10 @@ typedef struct _MMPTE_LEGACY_SOFTWARE
ULONG Prototype:1; ULONG Prototype:1;
ULONG Transition:1; ULONG Transition:1;
ULONG PageFileHigh:20; ULONG PageFileHigh:20;
} MMPTE_LEGACY_SOFTWARE, *PMMPTE_LEGACY_SOFTWARE; } MMPML2_PTE_SOFTWARE, *PMMPML2_PTE_SOFTWARE;
/* Legacy Page Table Entry subsection structure definition (without PAE support) */ /* Legacy Page Table Entry subsection structure definition (PML2) */
typedef struct _MMPTE_LEGACY_SUBSECTION typedef struct _MMPML2_PTE_SUBSECTION
{ {
ULONG Valid:1; ULONG Valid:1;
ULONG SubsectionAddressLow:4; ULONG SubsectionAddressLow:4;
@@ -226,10 +181,10 @@ typedef struct _MMPTE_LEGACY_SUBSECTION
ULONG Prototype:1; ULONG Prototype:1;
ULONG SubsectionAddressHigh:20; ULONG SubsectionAddressHigh:20;
ULONG WhichPool:1; ULONG WhichPool:1;
} MMPTE_LEGACY_SUBSECTION, *PMMPTE_LEGACY_SUBSECTION; } MMPML2_PTE_SUBSECTION, *PMMPML2_PTE_SUBSECTION;
/* Legacy Page Table Entry transition structure definition (without PAE support) */ /* Legacy Page Table Entry transition structure definition (PML2) */
typedef struct _MMPTE_LEGACY_TRANSITION typedef struct _MMPML2_PTE_TRANSITION
{ {
ULONG Valid:1; ULONG Valid:1;
ULONG Write:1; ULONG Write:1;
@@ -240,20 +195,123 @@ typedef struct _MMPTE_LEGACY_TRANSITION
ULONG Prototype:1; ULONG Prototype:1;
ULONG Transition:1; ULONG Transition:1;
ULONG PageFrameNumber:20; ULONG PageFrameNumber:20;
} MMPTE_LEGACY_TRANSITION, *PMMPTE_LEGACY_TRANSITION; } MMPML2_PTE_TRANSITION, *PMMPML2_PTE_TRANSITION;
/* Legacy Page Table Entry structure definition (without PAE support) */ /* Legacy Page Table Entry union definition (PML2) */
typedef union _MMPTE_LEGACY typedef union _MMPML2_PTE
{ {
ULONG Long; ULONG Long;
HARDWARE_LEGACY_PTE Flush; HARDWARE_PTE Flush;
MMPTE_LEGACY_HARDWARE Hardware; MMPML2_PTE_HARDWARE Hard;
MMPTE_LEGACY_PROTOTYPE Prototype; MMPML2_PTE_PROTOTYPE Proto;
MMPTE_LEGACY_SOFTWARE Software; MMPML2_PTE_SOFTWARE Soft;
MMPTE_LEGACY_TRANSITION Transition; MMPML2_PTE_TRANSITION Trans;
MMPTE_LEGACY_SUBSECTION Subsection; MMPML2_PTE_SUBSECTION Subsect;
MMPTE_LEGACY_LIST List; MMPML2_PTE_LIST List;
} MMPTE_LEGACY, *PMMPTE_LEGACY; } MMPML2_PTE, *PMMPML2_PTE;
/* Page Table Entry hardware structure definition (PML3) */
typedef struct _MMPML3_PTE_HARDWARE
{
ULONGLONG Valid:1;
ULONGLONG Writable:1;
ULONGLONG Owner:1;
ULONGLONG WriteThrough:1;
ULONGLONG CacheDisable:1;
ULONGLONG Accessed:1;
ULONGLONG Dirty:1;
ULONGLONG LargePage:1;
ULONGLONG Global:1;
ULONGLONG CopyOnWrite:1;
ULONGLONG Prototype:1;
ULONGLONG Write:1;
ULONGLONG PageFrameNumber:26;
ULONGLONG Reserved0:25;
ULONGLONG NoExecute:1;
} MMPML3_PTE_HARDWARE, *PMMPML3_PTE_HARDWARE;
/* Page Table Entry list structure definition (PML3) */
typedef struct _MMPML3_PTE_LIST
{
ULONGLONG Valid:1;
ULONGLONG OneEntry:1;
ULONGLONG Reserved0:8;
ULONGLONG Prototype:1;
ULONGLONG Reserved1:21;
ULONGLONG NextEntry:32;
} MMPML3_PTE_LIST, *PMMPML3_PTE_LIST;
/* Page Table Entry subsection structure definition (PML3) */
typedef struct _MMPML3_PTE_PROTOTYPE
{
ULONGLONG Valid:1;
ULONGLONG Reserved0:7;
ULONGLONG ReadOnly:1;
ULONGLONG Reserved1:1;
ULONGLONG Prototype:1;
ULONGLONG Protection:5;
ULONGLONG Reserved2:16;
ULONGLONG ProtoAddress:32;
} MMPML3_PTE_PROTOTYPE, *PMMPML3_PTE_PROTOTYPE;
/* Page Table Entry software structure definition (PML3) */
typedef struct _MMPML3_PTE_SOFTWARE
{
ULONGLONG Valid:1;
ULONGLONG PageFileLow:4;
ULONGLONG Protection:5;
ULONGLONG Prototype:1;
ULONGLONG Transition:1;
ULONGLONG Reserved0:20;
ULONGLONG PageFileHigh:32;
} MMPML3_PTE_SOFTWARE, *PMMPML3_PTE_SOFTWARE;
/* Page Table Entry subsection structure definition (PML3) */
typedef struct _MMPML3_PTE_SUBSECTION
{
ULONGLONG Valid:1;
ULONGLONG Reserved0:4;
ULONGLONG Protection:5;
ULONGLONG Prototype:1;
ULONGLONG Reserved1:21;
ULONGLONG SubsectionAddress:32;
} MMPML3_PTE_SUBSECTION, *PMMPML3_PTE_SUBSECTION;
/* Page Table Entry transition structure definition (PML3) */
typedef struct _MMPML3_PTE_TRANSITION
{
ULONGLONG Valid:1;
ULONGLONG Write:1;
ULONGLONG Owner:1;
ULONGLONG WriteThrough:1;
ULONGLONG CacheDisable:1;
ULONGLONG Protection:5;
ULONGLONG Prototype:1;
ULONGLONG Transition:1;
ULONGLONG PageFrameNumber:26;
ULONGLONG Unused:26;
} MMPML3_PTE_TRANSITION, *PMMPML3_PTE_TRANSITION;
/* Page Table Entry union definition (PML3) */
typedef union _MMPML3_PTE
{
ULONGLONG Long;
HARDWARE_PTE Flush;
MMPML3_PTE_HARDWARE Hardware;
MMPML3_PTE_PROTOTYPE Prototype;
MMPML3_PTE_SOFTWARE Software;
MMPML3_PTE_TRANSITION Transition;
MMPML3_PTE_SUBSECTION Subsection;
MMPML3_PTE_LIST List;
} MMPML3_PTE, *PMMPML3_PTE;
/* Generic Page Table Entry union to abstract PML2 and PML3 formats */
typedef union _MMPTE
{
ULONGLONG Long;
MMPML2_PTE Pml2;
MMPML3_PTE Pml3;
} MMPTE, *PMMPTE;
/* Page Frame Number structure definition */ /* Page Frame Number structure definition */
typedef struct _MMPFN typedef struct _MMPFN

View File

@@ -13,10 +13,23 @@
/* Architecture-specific enumeration lists forward references */ /* Architecture-specific enumeration lists forward references */
typedef enum _APIC_DM APIC_DM, *PAPIC_DM;
typedef enum _APIC_DSH APIC_DSH, *PAPIC_DSH;
typedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE;
typedef enum _APIC_REGISTER APIC_REGISTER, *PAPIC_REGISTER;
typedef enum _CPU_VENDOR CPU_VENDOR, *PCPU_VENDOR; typedef enum _CPU_VENDOR CPU_VENDOR, *PCPU_VENDOR;
typedef enum _CPUID_FEATURES CPUID_FEATURES, *PCPUID_FEATURES; typedef enum _CPUID_FEATURES_EXTENDED CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
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_LEAF1 CPUID_FEATURES_STANDARD7_LEAF1, *PCPUID_FEATURES_STANDARD7_LEAF1;
typedef enum _CPUID_REQUESTS CPUID_REQUESTS, *PCPUID_REQUESTS; typedef enum _CPUID_REQUESTS CPUID_REQUESTS, *PCPUID_REQUESTS;
typedef enum _PAGE_SIZE PAGE_SIZE, *PPAGE_SIZE; typedef enum _PAGE_SIZE PAGE_SIZE, *PPAGE_SIZE;
typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE PIC_I8259_ICW1_INTERRUPT_MODE, *PPIC_I8259_ICW1_INTERRUPT_MODE;
typedef enum _PIC_I8259_ICW1_INTERVAL PIC_I8259_ICW1_INTERVAL, *PPIC_I8259_ICW1_INTERVAL;
typedef enum _PIC_I8259_ICW1_OPERATING_MODE PIC_I8259_ICW1_OPERATING_MODE, *PPIC_I8259_ICW1_OPERATING_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_SYSTEM_MODE PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;
/* Architecture-specific structures forward references */ /* Architecture-specific structures forward references */
typedef struct _CONTEXT CONTEXT, *PCONTEXT; typedef struct _CONTEXT CONTEXT, *PCONTEXT;
@@ -27,7 +40,7 @@ typedef struct _FN_SAVE_FORMAT FN_SAVE_FORMAT, *PFN_SAVE_FORMAT;
typedef struct _FX_SAVE_AREA FX_SAVE_AREA, *PFX_SAVE_AREA; 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_PTE HARDWARE_PTE, *PHARDWARE_PTE; typedef struct _HARDWARE_MODERN_PTE HARDWARE_MODERN_PTE, *PHARDWARE_MODERN_PTE;
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;
@@ -42,25 +55,36 @@ typedef struct _KSWITCH_FRAME KSWITCH_FRAME, *PKSWITCH_FRAME;
typedef struct _KTHREAD_INIT_FRAME KTHREAD_INIT_FRAME, *PKTHREAD_INIT_FRAME; typedef struct _KTHREAD_INIT_FRAME KTHREAD_INIT_FRAME, *PKTHREAD_INIT_FRAME;
typedef struct _KTRAP_FRAME KTRAP_FRAME, *PKTRAP_FRAME; typedef struct _KTRAP_FRAME KTRAP_FRAME, *PKTRAP_FRAME;
typedef struct _KTSS KTSS, *PKTSS; typedef struct _KTSS KTSS, *PKTSS;
typedef struct _MMPAGEMAP_INFO MMPAGEMAP_INFO, *PMMPAGEMAP_INFO;
typedef struct _MMPFN MMPFN, *PMMPFN; typedef struct _MMPFN MMPFN, *PMMPFN;
typedef struct _MMPTE_HARDWARE MMPTE_HARDWARE, *PMMPTE_HARDWARE; typedef struct _MMPML2_PTE_HARDWARE MMPML2_PTE_HARDWARE, *PMMPML2_PTE_HARDWARE;
typedef struct _MMPTE_LEGACY_HARDWARE MMPTE_LEGACY_HARDWARE, *PMMPTE_LEGACY_HARDWARE; typedef struct _MMPML2_PTE_LIST MMPML2_PTE_LIST, *PMMPML2_PTE_LIST;
typedef struct _MMPTE_LEGACY_LIST MMPTE_LEGACY_LIST, *PMMPTE_LEGACY_LIST; typedef struct _MMPML2_PTE_PROTOTYPE MMPML2_PTE_PROTOTYPE, *PMMPML2_PTE_PROTOTYPE;
typedef struct _MMPTE_LEGACY_PROTOTYPE MMPTE_LEGACY_PROTOTYPE, *PMMPTE_LEGACY_PROTOTYPE; typedef struct _MMPML2_PTE_SOFTWARE MMPML2_PTE_SOFTWARE, *PMMPML2_PTE_SOFTWARE;
typedef struct _MMPTE_LEGACY_SOFTWARE MMPTE_LEGACY_SOFTWARE, *PMMPTE_LEGACY_SOFTWARE; typedef struct _MMPML2_PTE_SUBSECTION MMPML2_PTE_SUBSECTION, *PMMPML2_PTE_SUBSECTION;
typedef struct _MMPTE_LEGACY_SUBSECTION MMPTE_LEGACY_SUBSECTION, *PMMPTE_LEGACY_SUBSECTION; typedef struct _MMPML2_PTE_TRANSITION MMPML2_PTE_TRANSITION, *PMMPML2_PTE_TRANSITION;
typedef struct _MMPTE_LEGACY_TRANSITION MMPTE_LEGACY_TRANSITION, *PMMPTE_LEGACY_TRANSITION; typedef struct _MMPML3_PTE_HARDWARE MMPML3_PTE_HARDWARE, *PMMPML3_PTE_HARDWARE;
typedef struct _MMPTE_LIST MMPTE_LIST, *PMMPTE_LIST; typedef struct _MMPML3_PTE_LIST MMPML3_PTE_LIST, *PMMPML3_PTE_LIST;
typedef struct _MMPTE_PROTOTYPE MMPTE_PROTOTYPE, *PMMPTE_PROTOTYPE; typedef struct _MMPML3_PTE_PROTOTYPE MMPML3_PTE_PROTOTYPE, *PMMPML3_PTE_PROTOTYPE;
typedef struct _MMPTE_SOFTWARE MMPTE_SOFTWARE, *PMMPTE_SOFTWARE; typedef struct _MMPML3_PTE_SOFTWARE MMPML3_PTE_SOFTWARE, *PMMPML3_PTE_SOFTWARE;
typedef struct _MMPTE_SUBSECTION MMPTE_SUBSECTION, *PMMPTE_SUBSECTION; typedef struct _MMPML3_PTE_SUBSECTION MMPML3_PTE_SUBSECTION, *PMMPML3_PTE_SUBSECTION;
typedef struct _MMPTE_TRANSITION MMPTE_TRANSITION, *PMMPTE_TRANSITION; typedef struct _MMPML3_PTE_TRANSITION MMPML3_PTE_TRANSITION, *PMMPML3_PTE_TRANSITION;
typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK; typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
/* Unions forward references */ /* Unions forward references */
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_LVT_REGISTER APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER;
typedef union _APIC_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
typedef union _HARDWARE_PTE HARDWARE_PTE, *PHARDWARE_PTE;
typedef union _MMPML2_PTE MMPML2_PTE, *PMMPML2_PTE;
typedef union _MMPML3_PTE MMPML3_PTE, *PMMPML3_PTE;
typedef union _MMPTE MMPDE, *PMMPDE; typedef union _MMPTE MMPDE, *PMMPDE;
typedef union _MMPTE MMPPE, *PMMPPE;
typedef union _MMPTE MMPTE, *PMMPTE; typedef union _MMPTE MMPTE, *PMMPTE;
typedef union _MMPTE_LEGACY MMPDE_LEGACY, *PMMPDE_LEGACY; typedef union _PIC_I8259_ICW1 PIC_I8259_ICW1, *PPIC_I8259_ICW1;
typedef union _MMPTE_LEGACY MMPTE_LEGACY, *PMMPTE_LEGACY; 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_ICW4 PIC_I8259_ICW4, *PPIC_I8259_ICW4;
#endif /* __XTDK_I686_XTSTRUCT_H */ #endif /* __XTDK_I686_XTSTRUCT_H */

45
sdk/xtdk/kdtypes.h Normal file
View File

@@ -0,0 +1,45 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: sdk/xtdk/kdtypes.h
* DESCRIPTION: Kernel Debugger data structures
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTDK_KDTYPES_H
#define __XTDK_KDTYPES_H
#include <xtbase.h>
#include <xtstruct.h>
#include <rtltypes.h>
/* Number of debug providers */
#define KDBG_PROVIDERS_COUNT 2
/* Debug providers bitmask definitions */
#define DEBUG_PROVIDER_COMPORT 0x00000001
#define DEBUG_PROVIDER_FRAMEBUFFER 0x00000002
/* Kernel routine callbacks */
typedef XTSTATUS (XTAPI *PKD_INIT_ROUTINE)();
typedef VOID (*PKD_PRINT_ROUTINE)(IN PCWSTR Format, IN ...);
/* Debug mode structure definition */
typedef struct _KD_DEBUG_MODE
{
BOOLEAN Enabled;
ULONG Mode;
ULONG ComPortAddress;
ULONG ComPortNumber;
ULONG ComPortBaudRate;
} KD_DEBUG_MODE, *PKD_DEBUG_MODE;
/* Kernel debugger dispatch table structure definition */
typedef struct _KD_DISPATCH_TABLE
{
LIST_ENTRY ListEntry;
RTL_PRINT_CONTEXT PrintContext;
} KD_DISPATCH_TABLE, *PKD_DISPATCH_TABLE;
#endif /* __XTDK_KDTYPES_H */

View File

@@ -16,26 +16,44 @@
/* Kernel services routines forward references */ /* Kernel services routines forward references */
XTCLINK
XTFASTCALL XTFASTCALL
VOID VOID
KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel); KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
XTCLINK
XTFASTCALL XTFASTCALL
VOID VOID
KeAcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock); KeAcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock);
XTCLINK
XTAPI
XTSTATUS
KeAcquireSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader);
XTCLINK
XTAPI XTAPI
BOOLEAN BOOLEAN
KeCancelTimer(IN PKTIMER Timer); KeCancelTimer(IN PKTIMER Timer);
XTCLINK
XTFASTCALL XTFASTCALL
KRUNLEVEL KRUNLEVEL
KeGetCurrentRunLevel(VOID); KeGetCurrentRunLevel(VOID);
XTCLINK
XTAPI
XTSTATUS
KeGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader);
XTCLINK
XTAPI XTAPI
BOOLEAN BOOLEAN
KeGetTimerState(IN PKTIMER Timer); KeGetTimerState(IN PKTIMER Timer);
XTCLINK
XTAPI XTAPI
VOID VOID
KeInitializeApc(IN PKAPC Apc, KeInitializeApc(IN PKAPC Apc,
@@ -47,45 +65,54 @@ KeInitializeApc(IN PKAPC Apc,
IN KPROCESSOR_MODE ApcMode, IN KPROCESSOR_MODE ApcMode,
IN PVOID Context); IN PVOID Context);
XTCLINK
XTAPI XTAPI
VOID VOID
KeInitializeDpc(IN PKDPC Dpc, KeInitializeDpc(IN PKDPC Dpc,
IN PKDEFERRED_ROUTINE DpcRoutine, IN PKDEFERRED_ROUTINE DpcRoutine,
IN PVOID DpcContext); IN PVOID DpcContext);
XTCLINK
XTAPI XTAPI
VOID VOID
KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, KeInitializeSemaphore(IN PKSEMAPHORE Semaphore,
IN LONG Count, IN LONG Count,
IN LONG Limit); IN LONG Limit);
XTCLINK
XTAPI XTAPI
VOID VOID
KeInitializeSpinLock(IN PKSPIN_LOCK SpinLock); KeInitializeSpinLock(IN PKSPIN_LOCK SpinLock);
XTCLINK
XTAPI XTAPI
VOID VOID
KeInitializeThreadedDpc(IN PKDPC Dpc, KeInitializeThreadedDpc(IN PKDPC Dpc,
IN PKDEFERRED_ROUTINE DpcRoutine, IN PKDEFERRED_ROUTINE DpcRoutine,
IN PVOID DpcContext); IN PVOID DpcContext);
XTCLINK
XTAPI XTAPI
VOID VOID
KeInitializeTimer(OUT PKTIMER Timer, KeInitializeTimer(OUT PKTIMER Timer,
IN KTIMER_TYPE Type); IN KTIMER_TYPE Type);
XTCLINK
XTFASTCALL XTFASTCALL
VOID VOID
KeLowerRunLevel(IN KRUNLEVEL RunLevel); KeLowerRunLevel(IN KRUNLEVEL RunLevel);
XTCLINK
XTFASTCALL XTFASTCALL
KRUNLEVEL KRUNLEVEL
KeRaiseRunLevel(IN KRUNLEVEL RunLevel); KeRaiseRunLevel(IN KRUNLEVEL RunLevel);
XTCLINK
XTAPI XTAPI
LONG LONG
KeReadSemaphoreState(IN PKSEMAPHORE Semaphore); KeReadSemaphoreState(IN PKSEMAPHORE Semaphore);
XTCLINK
XTAPI XTAPI
LONG LONG
KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, KeReleaseSemaphore(IN PKSEMAPHORE Semaphore,
@@ -93,19 +120,28 @@ KeReleaseSemaphore(IN PKSEMAPHORE Semaphore,
IN LONG Adjustment, IN LONG Adjustment,
IN BOOLEAN Wait); IN BOOLEAN Wait);
XTCLINK
XTFASTCALL XTFASTCALL
VOID VOID
KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel); KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
XTCLINK
XTFASTCALL XTFASTCALL
VOID VOID
KeReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock); KeReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock);
XTCLINK
XTAPI
VOID
KeReleaseSystemResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader);
XTCLINK
XTAPI XTAPI
VOID VOID
KeSetTargetProcessorDpc(IN PKDPC Dpc, KeSetTargetProcessorDpc(IN PKDPC Dpc,
IN CCHAR Number); IN CCHAR Number);
XTCLINK
XTAPI XTAPI
VOID VOID
KeSetTimer(IN PKTIMER Timer, KeSetTimer(IN PKTIMER Timer,
@@ -113,10 +149,12 @@ KeSetTimer(IN PKTIMER Timer,
IN LONG Period, IN LONG Period,
IN PKDPC Dpc); IN PKDPC Dpc);
XTCLINK
XTAPI XTAPI
VOID VOID
KeSignalCallDpcDone(IN PVOID SystemArgument); KeSignalCallDpcDone(IN PVOID SystemArgument);
XTCLINK
XTAPI XTAPI
BOOLEAN BOOLEAN
KeSignalCallDpcSynchronize(IN PVOID SystemArgument); KeSignalCallDpcSynchronize(IN PVOID SystemArgument);

View File

@@ -183,6 +183,14 @@ typedef enum _MODE
MaximumMode MaximumMode
} MODE, *PMODE; } MODE, *PMODE;
/* System resource types */
typedef enum _SYSTEM_RESOURCE_TYPE
{
SystemResourceInvalid,
SystemResourceAcpi,
SystemResourceFrameBuffer
} SYSTEM_RESOURCE_TYPE, *PSYSTEM_RESOURCE_TYPE;
/* Wait type */ /* Wait type */
typedef enum _WAIT_TYPE typedef enum _WAIT_TYPE
{ {
@@ -190,6 +198,14 @@ typedef enum _WAIT_TYPE
WaitAny WaitAny
} WAIT_TYPE, *PWAIT_TYPE; } WAIT_TYPE, *PWAIT_TYPE;
/* Kernel UBSAN data types enumeration list */
typedef enum _KUBSAN_DATA_TYPE
{
DataTypeInt,
DataTypeFloat,
DataTypeUnknown = 0xFFFF
} KUBSAN_DATA_TYPE, *PKUBSAN_DATA_TYPE;
/* Kernel routine callbacks */ /* Kernel routine callbacks */
typedef EXCEPTION_DISPOSITION (XTCDECL *PEXCEPTION_ROUTINE)(IN PEXCEPTION_RECORD ExceptionRecord, IN PVOID EstablisherFrame, IN OUT PCONTEXT ContextRecord, IN OUT PVOID DispatcherContext); typedef EXCEPTION_DISPOSITION (XTCDECL *PEXCEPTION_ROUTINE)(IN PEXCEPTION_RECORD ExceptionRecord, IN PVOID EstablisherFrame, IN OUT PCONTEXT ContextRecord, IN OUT PVOID DispatcherContext);
typedef VOID (XTAPI *PKDEFERRED_ROUTINE)(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2); typedef VOID (XTAPI *PKDEFERRED_ROUTINE)(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2);
@@ -365,25 +381,35 @@ typedef struct _KPROCESS
LIST_ENTRY ProfileListHead; LIST_ENTRY ProfileListHead;
ULONG_PTR DirectoryTable[2]; ULONG_PTR DirectoryTable[2];
USHORT IopmOffset; USHORT IopmOffset;
UCHAR Iopl;
VOLATILE KAFFINITY ActiveProcessors; VOLATILE KAFFINITY ActiveProcessors;
ULONG KernelTime;
ULONG UserTime;
LIST_ENTRY ReadyListHead; LIST_ENTRY ReadyListHead;
SINGLE_LIST_ENTRY SwapListEntry;
PVOID VdmTrapHandler;
LIST_ENTRY ThreadListHead; LIST_ENTRY ThreadListHead;
KSPIN_LOCK ProcessLock;
KAFFINITY Affinity; KAFFINITY Affinity;
union union
{ {
struct struct
{ {
LONG AutoAlignment:1; BOOLEAN AutoAlignment;
LONG DisableBoost:1; BOOLEAN DisableBoost;
LONG DisableQuantum:1; BOOLEAN DisableQuantum;
LONG ReservedFlags:29; LONG ReservedFlags:29;
}; };
LONG ProcessFlags; LONG ProcessFlags;
}; };
ULONG_PTR StackCount;
SCHAR BasePriority; SCHAR BasePriority;
SCHAR Quantum; SCHAR Quantum;
UCHAR State; UCHAR State;
ULONG_PTR StackCount; UCHAR ThreadSeed;
UCHAR PowerState;
UCHAR IdealNode;
UCHAR Spare;
} KPROCESS, *PKPROCESS; } KPROCESS, *PKPROCESS;
/* Thread control block structure definition */ /* Thread control block structure definition */
@@ -396,7 +422,13 @@ typedef struct _KTHREAD
PVOID StackBase; PVOID StackBase;
PVOID StackLimit; PVOID StackLimit;
KSPIN_LOCK ThreadLock; KSPIN_LOCK ThreadLock;
volatile UCHAR State;
ULONG ContextSwitches;
VOLATILE UCHAR State;
UCHAR NpxState;
KRUNLEVEL WaitRunLevel;
KPROCESSOR_MODE WaitMode;
PTHREAD_ENVIRONMENT_BLOCK EnvironmentBlock;
union union
{ {
KAPC_STATE ApcState; KAPC_STATE ApcState;
@@ -411,13 +443,8 @@ typedef struct _KTHREAD
}; };
}; };
KSPIN_LOCK ApcQueueLock; KSPIN_LOCK ApcQueueLock;
ULONG ContextSwitches;
LONG_PTR WaitStatus; LONG_PTR WaitStatus;
union
{
PKWAIT_BLOCK WaitBlockList; PKWAIT_BLOCK WaitBlockList;
PKGATE GateObject;
};
BOOLEAN Alertable; BOOLEAN Alertable;
BOOLEAN WaitNext; BOOLEAN WaitNext;
UCHAR WaitReason; UCHAR WaitReason;
@@ -431,43 +458,191 @@ typedef struct _KTHREAD
SINGLE_LIST_ENTRY SwapListEntry; SINGLE_LIST_ENTRY SwapListEntry;
}; };
PKQUEUE Queue; PKQUEUE Queue;
CHAR PreviousMode; ULONG WaitTime;
union
{
struct
{
SHORT KernelApcDisable;
SHORT SpecialApcDisable; SHORT SpecialApcDisable;
PTHREAD_ENVIRONMENT_BLOCK EnvironmentBlock; };
union ULONG CombinedApcDisable;
{ };
KTIMER Timer; KTIMER Timer;
struct
{
UCHAR TimerFill[KTIMER_LENGTH];
union
{
struct
{
LONG AutoAlignment:1;
LONG DisableBoost:1;
LONG ReservedFlags:30;
};
LONG ThreadFlags;
};
};
};
KWAIT_BLOCK WaitBlock[KTHREAD_WAIT_BLOCK + 1]; KWAIT_BLOCK WaitBlock[KTHREAD_WAIT_BLOCK + 1];
UCHAR NpxState;
KRUNLEVEL WaitRunLevel;
LIST_ENTRY QueueListEntry; LIST_ENTRY QueueListEntry;
PKTRAP_FRAME TrapFrame;
PVOID CallbackStack;
PVOID ServiceTable;
ULONG KernelLimit;
UCHAR ApcStateIndex; UCHAR ApcStateIndex;
BOOLEAN StackResident; BOOLEAN Preempted;
BOOLEAN ProcessReadyQueue;
BOOLEAN KernelStackResident;
CHAR Saturation;
UCHAR IdealProcessor;
SCHAR BasePriority;
UCHAR Spare4;
SCHAR PriorityDecrement;
SCHAR Quantum;
BOOLEAN SystemAffinityActive;
CHAR PreviousMode;
UCHAR ResourceIndex;
UCHAR DisableBoost;
KAFFINITY UserAffinity;
PKPROCESS Process; PKPROCESS Process;
KAFFINITY Affinity; KAFFINITY Affinity;
PVOID ServiceTable;
PKAPC_STATE ApcStatePointer[2]; PKAPC_STATE ApcStatePointer[2];
KAPC_STATE SavedApcState; KAPC_STATE SavedApcState;
PVOID CallbackStack;
PVOID SubSystemThread;
PKTRAP_FRAME TrapFrame;
ULONG KernelTime;
ULONG UserTime;
KAPC SuspendApc; KAPC SuspendApc;
KSEMAPHORE SuspendSemaphore; KSEMAPHORE SuspendSemaphore;
PVOID TlsArray;
PVOID LegoData;
LIST_ENTRY ThreadListEntry;
UCHAR LargeStack;
UCHAR PowerState;
UCHAR NpxIrql;
UCHAR Spare5;
BOOLEAN AutoAlignment;
UCHAR Iopl;
CCHAR FreezeCount;
CCHAR SuspendCount;
UCHAR Spare0[1];
UCHAR UserIdealProcessor;
UCHAR Spare2[3];
ULONG KernelLimit;
BOOLEAN StackResident;
} KTHREAD, *PKTHREAD; } KTHREAD, *PKTHREAD;
/* System resource common header structure definition */
typedef struct _SYSTEM_RESOURCE_HEADER
{
LIST_ENTRY ListEntry;
SYSTEM_RESOURCE_TYPE ResourceType;
BOOLEAN ResourceLocked;
ULONG ResourceSize;
PVOID PhysicalAddress;
PVOID VirtualAddress;
} SYSTEM_RESOURCE_HEADER, *PSYSTEM_RESOURCE_HEADER;
/* ACPI system resource structure definition */
typedef struct _SYSTEM_RESOURCE_ACPI
{
SYSTEM_RESOURCE_HEADER Header;
PVOID ApicBase;
} SYSTEM_RESOURCE_ACPI, *PSYSTEM_RESOURCE_ACPI;
/* FrameBuffer system resource structure definition */
typedef struct _SYSTEM_RESOURCE_FRAMEBUFFER
{
SYSTEM_RESOURCE_HEADER Header;
ULONG_PTR BufferSize;
UINT Width;
UINT Height;
UINT Depth;
UINT PixelsPerScanLine;
UINT BitsPerPixel;
UINT Pitch;
PVOID Font;
struct
{
USHORT BlueShift;
USHORT BlueSize;
USHORT GreenShift;
USHORT GreenSize;
USHORT RedShift;
USHORT RedSize;
USHORT ReservedShift;
USHORT ReservedSize;
} Pixels;
} SYSTEM_RESOURCE_FRAMEBUFFER, *PSYSTEM_RESOURCE_FRAMEBUFFER;
/* Kernel UBSAN source location structure definition */
typedef struct _KUBSAN_SOURCE_LOCATION
{
PCCHAR FileName;
union
{
ULONG Reported;
struct
{
UINT Line;
UINT Column;
};
};
} KUBSAN_SOURCE_LOCATION, *PKUBSAN_SOURCE_LOCATION;
/* Kernel UBSAN type descriptor structure definition */
typedef struct _KUBSAN_TYPE_DESCRIPTOR
{
USHORT DataType;
USHORT TypeInfo;
CHAR TypeName[1];
} KUBSAN_TYPE_DESCRIPTOR, *PKUBSAN_TYPE_DESCRIPTOR;
/* Kernel UBSAN float cast overflow data structure definition */
typedef struct _KUBSAN_FLOAT_CAST_OVERFLOW_DATA
{
KUBSAN_SOURCE_LOCATION Location;
PKUBSAN_TYPE_DESCRIPTOR LhsType;
PKUBSAN_TYPE_DESCRIPTOR RhsType;
} KUBSAN_FLOAT_CAST_OVERFLOW_DATA, *PKUBSAN_FLOAT_CAST_OVERFLOW_DATA;
/* Kernel UBSAN function type mismatch data structure definition */
typedef struct _KUBSAN_FUNCTION_TYPE_MISMATCH_DATA
{
KUBSAN_SOURCE_LOCATION Location;
PKUBSAN_TYPE_DESCRIPTOR Type;
} KUBSAN_FUNCTION_TYPE_MISMATCH_DATA, *PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA;
/* Kernel UBSAN invalid builtin data structure definition */
typedef struct _KUBSAN_INVALID_BUILTIN_DATA
{
KUBSAN_SOURCE_LOCATION Location;
UCHAR Kind;
} KUBSAN_INVALID_BUILTIN_DATA, *PKUBSAN_INVALID_BUILTIN_DATA;
/* Kernel UBSAN shift out of bounds data structure definition */
typedef struct _KUBSAN_SHIFT_OUT_OF_BOUNDS_DATA
{
KUBSAN_SOURCE_LOCATION Location;
PKUBSAN_TYPE_DESCRIPTOR LhsType;
PKUBSAN_TYPE_DESCRIPTOR RhsType;
} KUBSAN_SHIFT_OUT_OF_BOUNDS_DATA, *PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA;
/* Kernel UBSAN out of bounds data structure definition */
typedef struct _KUBSAN_OUT_OF_BOUNDS_DATA
{
KUBSAN_SOURCE_LOCATION Location;
PKUBSAN_TYPE_DESCRIPTOR ArrayType;
PKUBSAN_TYPE_DESCRIPTOR IndexType;
} KUBSAN_OUT_OF_BOUNDS_DATA, *PKUBSAN_OUT_OF_BOUNDS_DATA;
/* Kernel UBSAN overflow data structure definition */
typedef struct _KUBSAN_OVERFLOW_DATA
{
KUBSAN_SOURCE_LOCATION Location;
PKUBSAN_TYPE_DESCRIPTOR Type;
} KUBSAN_OVERFLOW_DATA, *PKUBSAN_OVERFLOW_DATA;
/* Kernel UBSAN type mismatch data structure definition */
typedef struct _KUBSAN_TYPE_MISMATCH_DATA
{
KUBSAN_SOURCE_LOCATION Location;
PKUBSAN_TYPE_DESCRIPTOR Type;
ULONG Alignment;
UCHAR TypeCheckKind;
} KUBSAN_TYPE_MISMATCH_DATA, *PKUBSAN_TYPE_MISMATCH_DATA;
/* Kernel UBSAN type mismatch data structure definition */
typedef struct _KUBSAN_TYPE_MISMATCH_DATA_V1
{
KUBSAN_SOURCE_LOCATION Location;
PKUBSAN_TYPE_DESCRIPTOR Type;
UCHAR LogAlignment;
UCHAR TypeCheckKind;
} KUBSAN_TYPE_MISMATCH_DATA_V1, *PKUBSAN_TYPE_MISMATCH_DATA_V1;
#endif /* __XTDK_KEFUNCS_H */ #endif /* __XTDK_KEFUNCS_H */

View File

@@ -10,8 +10,18 @@
#define __XTDK_MMTYPES_H #define __XTDK_MMTYPES_H
#include <xtbase.h> #include <xtbase.h>
#include ARCH_HEADER(xtstruct.h)
/* Page map routines structure definition */
typedef CONST STRUCT _CMMPAGEMAP_ROUTINES
{
VOID (XTAPI *ClearPte)(PHARDWARE_PTE PtePointer);
BOOLEAN (XTAPI *PteValid)(PHARDWARE_PTE PtePointer);
VOID (XTAPI *SetPteCaching)(PHARDWARE_PTE PtePointer, BOOLEAN CacheDisable, BOOLEAN WriteThrough);
VOID (XTAPI *SetPte)(PHARDWARE_PTE PtePointer, PFN_NUMBER PageFrameNumber, BOOLEAN Writable);
} CMMPAGEMAP_ROUTINES, *PCMMPAGEMAP_ROUTINES;
/* Color tables structure definition */ /* Color tables structure definition */
typedef struct _MMCOLOR_TABLES typedef struct _MMCOLOR_TABLES
{ {

View File

@@ -15,16 +15,77 @@
/* Power Manager routine callbacks */ /* Power Manager routine callbacks */
typedef VOID (XTFASTCALL *PPROCESSOR_IDLE_FUNCTION)(PPROCESSOR_POWER_STATE PowerState); typedef VOID (XTFASTCALL *PPROCESSOR_IDLE_FUNCTION)(IN PPROCESSOR_POWER_STATE PowerState);
typedef XTSTATUS (XTFASTCALL *PSET_PROCESSOR_THROTTLE)(IN UCHAR Throttle);
/* Processor IDLE times structure definition */
typedef struct _PROCESSOR_IDLE_TIMES
{
ULONGLONG StartTime;
ULONGLONG EndTime;
ULONG IdleHandlerReserved[4];
} PROCESSOR_IDLE_TIMES, *PPROCESSOR_IDLE_TIMES;
/* Processor performance state structure definition */
typedef struct _PROCESSOR_PERF_STATE
{
UCHAR PercentFrequency;
UCHAR MinCapacity;
USHORT Power;
UCHAR IncreaseLevel;
UCHAR DecreaseLevel;
USHORT Flags;
ULONG IncreaseTime;
ULONG DecreaseTime;
ULONG IncreaseCount;
ULONG DecreaseCount;
ULONGLONG PerformanceTime;
} PROCESSOR_PERF_STATE, *PPROCESSOR_PERF_STATE;
/* Processor power state structure definition */ /* Processor power state structure definition */
typedef struct _PROCESSOR_POWER_STATE typedef struct _PROCESSOR_POWER_STATE
{ {
PPROCESSOR_IDLE_FUNCTION IdleFunction; PPROCESSOR_IDLE_FUNCTION IdleFunction;
ULONG Idle0TimeLimit; ULONG Idle0TimeLimit;
ULONG Idle0LastTime;
PVOID IdleHandlers;
PVOID IdleState;
ULONG IdleHandlersCount;
ULONGLONG LastCheck;
PROCESSOR_IDLE_TIMES IdleTimes;
ULONG IdleTime1;
ULONG PromotionCheck;
ULONG IdleTime2;
UCHAR CurrentThrottle; UCHAR CurrentThrottle;
UCHAR ThermalThrottleLimit;
UCHAR CurrentThrottleIndex;
UCHAR ThermalThrottleIndex;
ULONG PerfSystemTime;
ULONG PerfIdleTime;
ULONG LastSysTime;
ULONGLONG TotalIdleStateTime[3];
ULONG TotalIdleTransitions[3];
ULONGLONG PreviousC3StateTime;
UCHAR KneeThrottleIndex;
UCHAR ThrottleLimitIndex;
UCHAR PerfStatesCount;
UCHAR ProcessorMinThrottle;
UCHAR ProcessorMaxThrottle;
UCHAR LastBusyPercentage;
UCHAR LastC3Percentage;
UCHAR LastAdjustedBusyPercentage;
ULONG PromotionCount;
ULONG DemotionCount;
ULONG ErrorCount;
ULONG RetryCount;
ULONG Flags;
LARGE_INTEGER PerfCounterFrequency;
ULONG PerfTickCount;
KTIMER PerfTimer; KTIMER PerfTimer;
KDPC PerfDpc; KDPC PerfDpc;
PPROCESSOR_PERF_STATE PerfStates;
PSET_PROCESSOR_THROTTLE PerfSetThrottle;
ULONG LastC3UserTime;
} PROCESSOR_POWER_STATE, *PPROCESSOR_POWER_STATE; } PROCESSOR_POWER_STATE, *PPROCESSOR_POWER_STATE;
#endif /* __XTDK_POTYPES_H */ #endif /* __XTDK_POTYPES_H */

View File

@@ -83,26 +83,26 @@ RtlCompareMemory(IN PCVOID LeftBuffer,
XTAPI XTAPI
SIZE_T SIZE_T
RtlCompareString(IN CONST PCHAR String1, RtlCompareString(IN PCSTR String1,
IN CONST PCHAR String2, IN PCSTR String2,
IN SIZE_T Length); IN SIZE_T Length);
XTAPI XTAPI
SIZE_T SIZE_T
RtlCompareStringInsensitive(IN CONST PCHAR String1, RtlCompareStringInsensitive(IN PCSTR String1,
IN CONST PCHAR String2, IN PCSTR String2,
IN SIZE_T Length); IN SIZE_T Length);
XTAPI XTAPI
SIZE_T SIZE_T
RtlCompareWideString(IN CONST PWCHAR String1, RtlCompareWideString(IN PCWSTR String1,
IN CONST PWCHAR String2, IN PCWSTR String2,
IN SIZE_T Length); IN SIZE_T Length);
XTAPI XTAPI
SIZE_T SIZE_T
RtlCompareWideStringInsensitive(IN CONST PWCHAR String1, RtlCompareWideStringInsensitive(IN PCWSTR String1,
IN CONST PWCHAR String2, IN PCWSTR String2,
IN SIZE_T Length); IN SIZE_T Length);
XTAPI XTAPI
@@ -134,13 +134,13 @@ RtlCopyMemory(OUT PVOID Destination,
XTAPI XTAPI
VOID VOID
RtlCopyString(IN PCHAR Destination, RtlCopyString(IN PCHAR Destination,
IN PCCHAR Source, IN PCSTR Source,
IN ULONG Length); IN ULONG Length);
XTAPI XTAPI
VOID VOID
RtlCopyWideString(IN PWCHAR Destination, RtlCopyWideString(IN PWCHAR Destination,
IN CONST PWCHAR Source, IN PCWSTR Source,
IN ULONG Length); IN ULONG Length);
XTAPI XTAPI
@@ -161,6 +161,26 @@ RtlFindSetBits(IN PRTL_BITMAP BitMap,
IN ULONG_PTR Length, IN ULONG_PTR Length,
IN ULONG_PTR Index); IN ULONG_PTR Index);
XTAPI
PCSTR
RtlFindString(IN PCSTR Source,
IN PCSTR Search);
XTAPI
PCSTR
RtlFindStringInsensitive(IN PCSTR Source,
IN PCSTR Search);
XTAPI
PCWSTR
RtlFindWideString(IN PCWSTR Source,
IN PCWSTR Search);
XTAPI
PCWSTR
RtlFindWideStringInsensitive(IN PCWSTR Source,
IN PCWSTR Search);
XTAPI XTAPI
XTSTATUS XTSTATUS
RtlFormatWideString(IN PRTL_PRINT_CONTEXT Context, RtlFormatWideString(IN PRTL_PRINT_CONTEXT Context,
@@ -229,13 +249,13 @@ RtlSetMemory(OUT PVOID Destination,
XTAPI XTAPI
SIZE_T SIZE_T
RtlStringLength(IN CONST PCHAR String, RtlStringLength(IN PCSTR String,
IN SIZE_T MaxLength); IN SIZE_T MaxLength);
XTAPI XTAPI
SIZE_T SIZE_T
RtlStringToWideString(OUT PWCHAR Destination, RtlStringToWideString(OUT PWCHAR Destination,
IN CONST PCHAR *Source, IN PCSTR *Source,
IN SIZE_T Length); IN SIZE_T Length);
XTAPI XTAPI
@@ -246,42 +266,58 @@ RtlTestBit(IN PRTL_BITMAP BitMap,
XTAPI XTAPI
PCHAR PCHAR
RtlTokenizeString(IN PCHAR String, RtlTokenizeString(IN PCHAR String,
IN CONST PCHAR Delimiter, IN PCSTR Delimiter,
IN OUT PCHAR *SavePtr); IN OUT PCHAR *SavePtr);
XTAPI XTAPI
PWCHAR PWCHAR
RtlTokenizeWideString(IN PWCHAR String, RtlTokenizeWideString(IN PWCHAR String,
IN CONST PWCHAR Delimiter, IN PCWSTR Delimiter,
IN OUT PWCHAR *SavePtr); IN OUT PWCHAR *SavePtr);
XTAPI XTAPI
PCHAR CHAR
RtlTrimLeftString(IN CONST PCHAR String); RtlToLowerCharacter(IN CHAR Character);
XTAPI XTAPI
PWCHAR WCHAR
RtlTrimLeftWideString(IN CONST PWCHAR String); RtlToLowerWideCharacter(IN WCHAR Character);
XTAPI
CHAR
RtlToUpperCharacter(IN CHAR Character);
XTAPI
WCHAR
RtlToUpperWideCharacter(IN WCHAR Character);
XTAPI XTAPI
PCHAR PCHAR
RtlTrimRightString(IN CONST PCHAR String); RtlTrimLeftString(IN PCHAR String);
XTAPI XTAPI
PWCHAR PWCHAR
RtlTrimRightWideString(IN CONST PWCHAR String); RtlTrimLeftWideString(IN PWCHAR String);
XTAPI XTAPI
PCHAR PCHAR
RtlTrimString(IN CONST PCHAR String); RtlTrimRightString(IN PCHAR String);
XTAPI XTAPI
PWCHAR PWCHAR
RtlTrimWideString(IN CONST PWCHAR String); RtlTrimRightWideString(IN PWCHAR String);
XTAPI
PCHAR
RtlTrimString(IN PCHAR String);
XTAPI
PWCHAR
RtlTrimWideString(IN PWCHAR String);
XTAPI XTAPI
SIZE_T SIZE_T
RtlWideStringLength(IN CONST PWCHAR String, RtlWideStringLength(IN PCWSTR String,
IN SIZE_T MaxLength); IN SIZE_T MaxLength);
XTAPI XTAPI

View File

@@ -32,6 +32,9 @@ typedef ULONG_PTR KSPIN_LOCK, *PKSPIN_LOCK;
/* Page Frame Number */ /* Page Frame Number */
typedef ULONG_PTR PFN_NUMBER, *PPFN_NUMBER; typedef ULONG_PTR PFN_NUMBER, *PPFN_NUMBER;
/* Physical address */
typedef LARGE_INTEGER PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS;
/* 128-bit buffer containing a unique identifier value */ /* 128-bit buffer containing a unique identifier value */
typedef struct _GUID typedef struct _GUID
{ {

View File

@@ -7,6 +7,7 @@
*/ */
/* Base XT headers */ /* Base XT headers */
#include <xtcompat.h>
#include <xtdefs.h> #include <xtdefs.h>
#include <xtstatus.h> #include <xtstatus.h>
#include <xttarget.h> #include <xttarget.h>

21
sdk/xtdk/xtcompat.h Normal file
View File

@@ -0,0 +1,21 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: sdk/xtdk/xtcompat.h
* DESCRIPTION: C/C++ compatibility macros
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTDK_XTCOMPAT_H
#define __XTDK_XTCOMPAT_H
#ifdef __cplusplus
#define XTCLINK extern "C"
typedef wchar_t wchar;
#else
#define XTCLINK
typedef unsigned short wchar;
#endif
#endif /* __XTDK_XTCOMPAT_H */

View File

@@ -11,16 +11,16 @@
/* Debugging macros */ /* Debugging macros */
#define CHECKPOINT DebugPrint(L"Checkpoint reached at %s:%d\n", __FILE__, __LINE__); #define CHECKPOINT DebugPrint(L"Checkpoint reached at %s:%d\n", __RELFILE__, __LINE__);
#define DEPRECATED DebugPrint(L"Called deprecated routine '%s()' at %s:%d\n", \ #define DEPRECATED DebugPrint(L"Called deprecated routine '%s()' at %s:%d\n", \
__FUNCTION__, __FILE__, __LINE__); __FUNCTION__, __RELFILE__, __LINE__);
#define UNIMPLEMENTED DebugPrint(L"Called unimplemented routine '%s()' at %s:%d\n", \ #define UNIMPLEMENTED DebugPrint(L"Called unimplemented routine '%s()' at %s:%d\n", \
__FUNCTION__, __FILE__, __LINE__); __FUNCTION__, __RELFILE__, __LINE__);
/* XTOS platform debugging macros */ /* XTOS platform debugging macros */
#ifdef DBG #ifdef DBG
#define DEBUG 1 #define DEBUG 1
#define DebugPrint(Format, ...) if(KeDbgPrint) KeDbgPrint(Format, __VA_ARGS__); #define DebugPrint(Format, ...) if(KdPrint) KdPrint(Format, __VA_ARGS__);
#else #else
#define DEBUG 0 #define DEBUG 0
#define DebugPrint(Format, ...) ((VOID)NULL) #define DebugPrint(Format, ...) ((VOID)NULL)

View File

@@ -16,6 +16,7 @@
#define XTAPI __stdcall #define XTAPI __stdcall
#define XTCDECL __cdecl #define XTCDECL __cdecl
#define XTFASTCALL __fastcall #define XTFASTCALL __fastcall
#define XTVECTORCALL __vectorcall
#define XTINLINE __inline #define XTINLINE __inline
#define XTASSEMBLY __attribute__((naked)) #define XTASSEMBLY __attribute__((naked))
#define XTINTERRUPT __attribute__((interrupt)) #define XTINTERRUPT __attribute__((interrupt))
@@ -54,32 +55,29 @@
/* Preprocessor macros for defining an additional compiler attributes */ /* Preprocessor macros for defining an additional compiler attributes */
#define ALIGN(Alignment) __attribute__((aligned(Alignment))) #define ALIGN(Alignment) __attribute__((aligned(Alignment)))
#define PACK __attribute__((packed)) #define PACKED __attribute__((packed))
#define SEGMENT(Segment) __attribute__((section(Segment))) #define SEGMENT(Segment) __attribute__((section(Segment)))
#define USED __attribute__((__used__)) #define USED __attribute__((__used__))
/* 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))
/* Macro 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)
/* Macro for accessing the base address of a structure from a structure member */ /* Macro for accessing the base address of a structure from a structure member */
#define CONTAIN_RECORD(Address, Type, Field) ((Type *)(((ULONG_PTR)Address) - (ULONG_PTR)(&(((Type *)0)->Field)))) #define CONTAIN_RECORD(Address, Type, Field) ((Type *)((char *)(Address) - FIELD_OFFSET(Type, Field)))
/* EFI size to pages conversion macro */ /* EFI size to pages conversion macro */
#define EFI_SIZE_TO_PAGES(Size) (((Size) >> EFI_PAGE_SHIFT) + (((Size) & EFI_PAGE_MASK) ? 1 : 0)) #define EFI_SIZE_TO_PAGES(Size) (((Size) >> EFI_PAGE_SHIFT) + (((Size) & EFI_PAGE_MASK) ? 1 : 0))
/* Macro for calculating byte offset of a field in the structure */ /* Macro for calculating byte offset of a field in the structure */
#define FIELD_OFFSET(Structure, Field) ((LONG)(LONG_PTR)&(((Structure *)0)->Field)) #define FIELD_OFFSET(Structure, Field) __builtin_offsetof(Structure, Field)
/* Macro for calculating size of a field in the structure */ /* Macro for calculating size of a field in the structure */
#define FIELD_SIZE(Structure, Field) (sizeof(((Structure *)0)->Field)) #define FIELD_SIZE(Structure, Field) (sizeof(((Structure *)0)->Field))
/* Macro that yields field type in the structure */
#define FIELD_TYPE(Structure, Field) (((Structure*)0)->Field)
/* Macro that page-aligns a virtual address */ /* Macro that page-aligns a virtual address */
#define PAGE_ALIGN(VirtualAddress) ((PVOID)((ULONG_PTR)VirtualAddress & ~MM_PAGE_MASK)) #define PAGE_ALIGN(VirtualAddress) ((PVOID)((ULONG_PTR)VirtualAddress & ~MM_PAGE_MASK))
@@ -97,7 +95,8 @@
#define SIGNATURE32(A, B, C, D) (SIGNATURE16(A, B) | (SIGNATURE16(C, D) << 16)) #define SIGNATURE32(A, B, C, D) (SIGNATURE16(A, B) | (SIGNATURE16(C, D) << 16))
#define SIGNATURE64(A, B, C, D, E, F, G, H) (SIGNATURE32(A, B, C, D) | ((UINT64)(SIGNATURE32(E, F, G, H)) << 32)) #define SIGNATURE64(A, B, C, D, E, F, G, H) (SIGNATURE32(A, B, C, D) | ((UINT64)(SIGNATURE32(E, F, G, H)) << 32))
/* XT size to pages conversion macro */ /* XT size <-> pages conversion macro */
#define PAGES_TO_SIZE(Pages) ((Pages) << MM_PAGE_SHIFT)
#define SIZE_TO_PAGES(Size) (((Size) >> MM_PAGE_SHIFT) + (((Size) & (MM_PAGE_MASK)) ? 1 : 0)) #define SIZE_TO_PAGES(Size) (((Size) >> MM_PAGE_SHIFT) + (((Size) & (MM_PAGE_MASK)) ? 1 : 0))
/* Macros for concatenating strings */ /* Macros for concatenating strings */

View File

@@ -48,7 +48,7 @@ typedef enum _LOADER_MEMORY_TYPE
LoaderBBTMemory, LoaderBBTMemory,
LoaderReserve, LoaderReserve,
LoaderXIPRom, LoaderXIPRom,
LoaderHALCachedMemory, LoaderHardwareCachedMemory,
LoaderMaximum LoaderMaximum
} LOADER_MEMORY_TYPE, *PLOADER_MEMORY_TYPE; } LOADER_MEMORY_TYPE, *PLOADER_MEMORY_TYPE;
@@ -61,11 +61,6 @@ typedef enum _SYSTEM_FIRMWARE_TYPE
SystemFirmwarePcat SystemFirmwarePcat
} SYSTEM_FIRMWARE_TYPE, *PSYSTEM_FIRMWARE_TYPE; } SYSTEM_FIRMWARE_TYPE, *PSYSTEM_FIRMWARE_TYPE;
/* Hardware information block */
typedef struct _HARDWARE_INFORMATION_BLOCK
{
} HARDWARE_INFORMATION_BLOCK, *PHARDWARE_INFORMATION_BLOCK;
/* PCAT Firmware information block */ /* PCAT Firmware information block */
typedef struct _PCAT_FIRMWARE_INFORMATION typedef struct _PCAT_FIRMWARE_INFORMATION
{ {
@@ -90,36 +85,20 @@ typedef struct _FIRMWARE_INFORMATION_BLOCK
}; };
} FIRMWARE_INFORMATION_BLOCK, *PFIRMWARE_INFORMATION_BLOCK; } FIRMWARE_INFORMATION_BLOCK, *PFIRMWARE_INFORMATION_BLOCK;
/* Boot Loader FrameBuffer information block */
typedef struct _LOADER_GRAPHICS_INFORMATION_BLOCK
{
BOOLEAN Initialized;
PVOID Address;
ULONG_PTR BufferSize;
UINT Width;
UINT Height;
UINT PixelsPerScanLine;
UINT BitsPerPixel;
UINT Pitch;
PVOID Font;
} LOADER_GRAPHICS_INFORMATION_BLOCK, *PLOADER_GRAPHICS_INFORMATION_BLOCK;
/* Boot Loader information block */ /* Boot Loader information block */
typedef struct _LOADER_INFORMATION_BLOCK typedef struct _LOADER_INFORMATION_BLOCK
{ {
PVOID DbgPrint; PVOID DbgPrint;
ULONG PageMapLevel;
LOADER_GRAPHICS_INFORMATION_BLOCK FrameBuffer;
} LOADER_INFORMATION_BLOCK, *PLOADER_INFORMATION_BLOCK; } LOADER_INFORMATION_BLOCK, *PLOADER_INFORMATION_BLOCK;
/* Boot Loader memory mapping information */ /* Boot Loader memory mapping information */
typedef struct _LOADER_MEMORY_MAPPING typedef struct _LOADER_MEMORY_DESCRIPTOR
{ {
LIST_ENTRY ListEntry; LIST_ENTRY ListEntry;
LOADER_MEMORY_TYPE MemoryType; LOADER_MEMORY_TYPE MemoryType;
ULONG BasePage; ULONG BasePage;
ULONG PageCount; ULONG PageCount;
} LOADER_MEMORY_MAPPING, *PLOADER_MEMORY_MAPPING; } LOADER_MEMORY_DESCRIPTOR, *PLOADER_MEMORY_DESCRIPTOR;
/* Loader provided information needed by the kernel to initialize */ /* Loader provided information needed by the kernel to initialize */
typedef struct _KERNEL_INITIALIZATION_BLOCK typedef struct _KERNEL_INITIALIZATION_BLOCK
@@ -131,7 +110,7 @@ typedef struct _KERNEL_INITIALIZATION_BLOCK
LIST_ENTRY LoadOrderListHead; LIST_ENTRY LoadOrderListHead;
LIST_ENTRY MemoryDescriptorListHead; LIST_ENTRY MemoryDescriptorListHead;
LIST_ENTRY BootDriverListHead; LIST_ENTRY BootDriverListHead;
HARDWARE_INFORMATION_BLOCK HardwareInformation; LIST_ENTRY SystemResourcesListHead;
LOADER_INFORMATION_BLOCK LoaderInformation; LOADER_INFORMATION_BLOCK LoaderInformation;
FIRMWARE_INFORMATION_BLOCK FirmwareInformation; FIRMWARE_INFORMATION_BLOCK FirmwareInformation;
} KERNEL_INITIALIZATION_BLOCK, *PKERNEL_INITIALIZATION_BLOCK; } KERNEL_INITIALIZATION_BLOCK, *PKERNEL_INITIALIZATION_BLOCK;

View File

@@ -7,6 +7,7 @@
*/ */
/* Base XT headers */ /* Base XT headers */
#include <xtcompat.h>
#include <xtdefs.h> #include <xtdefs.h>
#include <xtstatus.h> #include <xtstatus.h>
#include <xttarget.h> #include <xttarget.h>
@@ -30,6 +31,7 @@
#include <extypes.h> #include <extypes.h>
#include <hltypes.h> #include <hltypes.h>
#include <iotypes.h> #include <iotypes.h>
#include <kdtypes.h>
#include <ketypes.h> #include <ketypes.h>
#include <ldrtypes.h> #include <ldrtypes.h>
#include <mmtypes.h> #include <mmtypes.h>

View File

@@ -48,11 +48,22 @@
/* XT status code definitions */ /* XT status code definitions */
#define STATUS_SUCCESS ((XTSTATUS) 0x00000000L) #define STATUS_SUCCESS ((XTSTATUS) 0x00000000L)
#define STATUS_END_OF_MEDIA ((XTSTATUS) 0x8000001EL)
#define STATUS_RESOURCE_LOCKED ((XTSTATUS) 0xC0000000L)
#define STATUS_UNSUCCESSFUL ((XTSTATUS) 0xC0000001L) #define STATUS_UNSUCCESSFUL ((XTSTATUS) 0xC0000001L)
#define STATUS_NOT_IMPLEMENTED ((XTSTATUS) 0xC0000002L) #define STATUS_NOT_IMPLEMENTED ((XTSTATUS) 0xC0000002L)
#define STATUS_ACCESS_VIOLATION ((XTSTATUS) 0xC0000005L)
#define STATUS_IN_PAGE_ERROR ((XTSTATUS) 0xC0000006L)
#define STATUS_INVALID_HANDLE ((XTSTATUS) 0xC0000008L)
#define STATUS_BAD_INITIAL_STACK ((XTSTATUS) 0xC0000009L)
#define STATUS_INVALID_PARAMETER ((XTSTATUS) 0xC000000DL) #define STATUS_INVALID_PARAMETER ((XTSTATUS) 0xC000000DL)
#define STATUS_END_OF_FILE ((XTSTATUS) 0xC0000011L)
#define STATUS_NO_MEMORY ((XTSTATUS) 0xC0000017L)
#define STATUS_PORT_DISCONNECTED ((XTSTATUS) 0xC0000037L)
#define STATUS_CRC_ERROR ((XTSTATUS) 0xC000003FL)
#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_TIMEOUT ((XTSTATUS) 0x00000102L) #define STATUS_TIMEOUT ((XTSTATUS) 0x00000102L)
#define STATUS_IO_DEVICE_ERROR ((XTSTATUS) 0xC0000185L) #define STATUS_IO_DEVICE_ERROR ((XTSTATUS) 0xC0000185L)
#define STATUS_NOT_FOUND ((XTSTATUS) 0xC0000225L) #define STATUS_NOT_FOUND ((XTSTATUS) 0xC0000225L)

View File

@@ -39,6 +39,7 @@ typedef enum _EFI_TIMER_DELAY EFI_TIMER_DELAY, *PEFI_TIMER_DELAY;
typedef enum _EFI_UART_PARITY_TYPE EFI_UART_PARITY_TYPE, *PEFI_UART_PARITY_TYPE; typedef enum _EFI_UART_PARITY_TYPE EFI_UART_PARITY_TYPE, *PEFI_UART_PARITY_TYPE;
typedef enum _EFI_UART_STOP_BITS_TYPE EFI_UART_STOP_BITS_TYPE, *PEFI_UART_STOP_BITS_TYPE; typedef enum _EFI_UART_STOP_BITS_TYPE EFI_UART_STOP_BITS_TYPE, *PEFI_UART_STOP_BITS_TYPE;
typedef enum _EFI_UNIVERSA_GRAPHICS_BLT_OPERATION EFI_UNIVERSA_GRAPHICS_BLT_OPERATION, *PEFI_UNIVERSA_GRAPHICS_BLT_OPERATION; typedef enum _EFI_UNIVERSA_GRAPHICS_BLT_OPERATION EFI_UNIVERSA_GRAPHICS_BLT_OPERATION, *PEFI_UNIVERSA_GRAPHICS_BLT_OPERATION;
typedef enum _HAL_APIC_MODE HAL_APIC_MODE, *PHAL_APIC_MODE;
typedef enum _KAPC_ENVIRONMENT KAPC_ENVIRONMENT, *PKAPC_ENVIRONMENT; typedef enum _KAPC_ENVIRONMENT KAPC_ENVIRONMENT, *PKAPC_ENVIRONMENT;
typedef enum _KDPC_IMPORTANCE KDPC_IMPORTANCE, *PKDPC_IMPORTANCE; typedef enum _KDPC_IMPORTANCE KDPC_IMPORTANCE, *PKDPC_IMPORTANCE;
typedef enum _KEVENT_TYPE KEVENT_TYPE, *PKEVENT_TYPE; typedef enum _KEVENT_TYPE KEVENT_TYPE, *PKEVENT_TYPE;
@@ -46,16 +47,30 @@ typedef enum _KOBJECTS KOBJECTS, *PKOBJECTS;
typedef enum _KPROCESS_STATE KPROCESS_STATE, *PKPROCESS_STATE; typedef enum _KPROCESS_STATE KPROCESS_STATE, *PKPROCESS_STATE;
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 _LOADER_MEMORY_TYPE LOADER_MEMORY_TYPE, *PLOADER_MEMORY_TYPE; typedef enum _LOADER_MEMORY_TYPE LOADER_MEMORY_TYPE, *PLOADER_MEMORY_TYPE;
typedef enum _MODE MODE, *PMODE; typedef enum _MODE MODE, *PMODE;
typedef enum _RTL_VARIABLE_TYPE RTL_VARIABLE_TYPE, *PRTL_VARIABLE_TYPE;
typedef enum _SYSTEM_FIRMWARE_TYPE SYSTEM_FIRMWARE_TYPE, *PSYSTEM_FIRMWARE_TYPE; typedef enum _SYSTEM_FIRMWARE_TYPE SYSTEM_FIRMWARE_TYPE, *PSYSTEM_FIRMWARE_TYPE;
typedef enum _WAIT_TYPE WAIT_TYPE, *PWAIT_TYPE; typedef enum _WAIT_TYPE WAIT_TYPE, *PWAIT_TYPE;
/* Structures forward references */ /* Structures forward references */
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_FADT ACPI_FADT, *PACPI_FADT;
typedef struct _ACPI_MADT ACPI_MADT, *PACPI_MADT;
typedef struct _ACPI_MADT_TABLE_LOCAL_APIC ACPI_MADT_TABLE_LOCAL_APIC, *PACPI_MADT_TABLE_LOCAL_APIC;
typedef struct _ACPI_RSDP ACPI_RSDP, *PACPI_RSDP;
typedef struct _ACPI_RSDT ACPI_RSDT, *PACPI_RSDT;
typedef struct _ACPI_SUBTABLE_HEADER ACPI_SUBTABLE_HEADER, *PACPI_SUBTABLE_HEADER;
typedef struct _ACPI_SYSTEM_INFO ACPI_SYSTEM_INFO, *PACPI_SYSTEM_INFO;
typedef struct _ACPI_TIMER_INFO ACPI_TIMER_INFO, *PACPI_TIMER_INFO;
typedef struct _ACPI_XSDT ACPI_XSDT, *PACPI_XSDT;
typedef struct _ANSI_STRING ANSI_STRING, *PANSI_STRING; typedef struct _ANSI_STRING ANSI_STRING, *PANSI_STRING;
typedef struct _ANSI_STRING32 ANSI_STRING32, *PANSI_STRING32; typedef struct _ANSI_STRING32 ANSI_STRING32, *PANSI_STRING32;
typedef struct _ANSI_STRING64 ANSI_STRING64, *PANSI_STRING64; typedef struct _ANSI_STRING64 ANSI_STRING64, *PANSI_STRING64;
typedef struct _CPPORT CPPORT, *PCPPORT; typedef struct _CPPORT CPPORT, *PCPPORT;
typedef const struct _CMMPAGEMAP_ROUTINES CMMPAGEMAP_ROUTINES, *PCMMPAGEMAP_ROUTINES;
typedef struct _CSTRING CSTRING, *PCSTRING; typedef struct _CSTRING CSTRING, *PCSTRING;
typedef struct _EFI_1394_DEVICE_PATH EFI_1394_DEVICE_PATH, *PEFI_1394_DEVICE_PATH; typedef struct _EFI_1394_DEVICE_PATH EFI_1394_DEVICE_PATH, *PEFI_1394_DEVICE_PATH;
typedef struct _EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR, *PEFI_ACPI_ADDRESS_SPACE_DESCRIPTOR; typedef struct _EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR, *PEFI_ACPI_ADDRESS_SPACE_DESCRIPTOR;
@@ -218,9 +233,14 @@ typedef struct _EXCEPTION_RECORD EXCEPTION_RECORD, *PEXCEPTION_RECORD;
typedef struct _EXCEPTION_REGISTRATION_RECORD EXCEPTION_REGISTRATION_RECORD, *PEXCEPTION_REGISTRATION_RECORD; typedef struct _EXCEPTION_REGISTRATION_RECORD EXCEPTION_REGISTRATION_RECORD, *PEXCEPTION_REGISTRATION_RECORD;
typedef struct _FIRMWARE_INFORMATION_BLOCK FIRMWARE_INFORMATION_BLOCK, *PFIRMWARE_INFORMATION_BLOCK; typedef struct _FIRMWARE_INFORMATION_BLOCK FIRMWARE_INFORMATION_BLOCK, *PFIRMWARE_INFORMATION_BLOCK;
typedef struct _FLOAT128 FLOAT128, *PFLOAT128; typedef struct _FLOAT128 FLOAT128, *PFLOAT128;
typedef struct _GENERIC_ADDRESS GENERIC_ADDRESS, *PGENERIC_ADDRESS;
typedef struct _GUID GUID, *PGUID; typedef struct _GUID GUID, *PGUID;
typedef struct _HL_FRAMEBUFFER_DATA HL_FRAMEBUFFER_DATA, *PHL_FRAMEBUFFER_DATA;
typedef struct _HL_SCROLL_REGION_DATA HL_SCROLL_REGION_DATA, *PHL_SCROLL_REGION_DATA;
typedef struct _KAPC KAPC, *PKAPC; typedef struct _KAPC KAPC, *PKAPC;
typedef struct _KAPC_STATE KAPC_STATE, *PKAPC_STATE; typedef struct _KAPC_STATE KAPC_STATE, *PKAPC_STATE;
typedef struct _KD_DEBUG_MODE KD_DEBUG_MODE, *PKD_DEBUG_MODE;
typedef struct _KD_DISPATCH_TABLE KD_DISPATCH_TABLE, *PKD_DISPATCH_TABLE;
typedef struct _KDPC KDPC, *PKDPC; typedef struct _KDPC KDPC, *PKDPC;
typedef struct _KDPC_DATA KDPC_DATA, *PKDPC_DATA; typedef struct _KDPC_DATA KDPC_DATA, *PKDPC_DATA;
typedef struct _KERNEL_INITIALIZATION_BLOCK KERNEL_INITIALIZATION_BLOCK, *PKERNEL_INITIALIZATION_BLOCK; typedef struct _KERNEL_INITIALIZATION_BLOCK KERNEL_INITIALIZATION_BLOCK, *PKERNEL_INITIALIZATION_BLOCK;
@@ -234,6 +254,16 @@ typedef struct _KSERVICE_DESCRIPTOR_TABLE KSERVICE_DESCRIPTOR_TABLE, *PKSERVICE_
typedef struct _KSPIN_LOCK_QUEUE KSPIN_LOCK_QUEUE, *PKSPIN_LOCK_QUEUE; typedef struct _KSPIN_LOCK_QUEUE KSPIN_LOCK_QUEUE, *PKSPIN_LOCK_QUEUE;
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_FUNCTION_TYPE_MISMATCH_DATA KUBSAN_FUNCTION_TYPE_MISMATCH_DATA, *PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA;
typedef struct _KUBSAN_INVALID_BUILTIN_DATA KUBSAN_INVALID_BUILTIN_DATA, *PKUBSAN_INVALID_BUILTIN_DATA;
typedef struct _KUBSAN_OUT_OF_BOUNDS_DATA KUBSAN_OUT_OF_BOUNDS_DATA, *PKUBSAN_OUT_OF_BOUNDS_DATA;
typedef struct _KUBSAN_OVERFLOW_DATA KUBSAN_OVERFLOW_DATA, *PKUBSAN_OVERFLOW_DATA;
typedef struct _KUBSAN_SHIFT_OUT_OF_BOUNDS_DATA KUBSAN_SHIFT_OUT_OF_BOUNDS_DATA, *PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA;
typedef struct _KUBSAN_SOURCE_LOCATION KUBSAN_SOURCE_LOCATION, *PKUBSAN_SOURCE_LOCATION;
typedef struct _KUBSAN_TYPE_DESCRIPTOR KUBSAN_TYPE_DESCRIPTOR, *PKUBSAN_TYPE_DESCRIPTOR;
typedef struct _KUBSAN_TYPE_MISMATCH_DATA KUBSAN_TYPE_MISMATCH_DATA, *PKUBSAN_TYPE_MISMATCH_DATA;
typedef struct _KUBSAN_TYPE_MISMATCH_DATA_V1 KUBSAN_TYPE_MISMATCH_DATA_V1, *PKUBSAN_TYPE_MISMATCH_DATA_V1;
typedef struct _KWAIT_BLOCK KWAIT_BLOCK, *PKWAIT_BLOCK; typedef struct _KWAIT_BLOCK KWAIT_BLOCK, *PKWAIT_BLOCK;
typedef struct _LDR_DATA_TABLE_ENTRY LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY; typedef struct _LDR_DATA_TABLE_ENTRY LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
typedef struct _LIST_ENTRY LIST_ENTRY, *PLIST_ENTRY; typedef struct _LIST_ENTRY LIST_ENTRY, *PLIST_ENTRY;
@@ -241,7 +271,7 @@ typedef struct _LIST_ENTRY32 LIST_ENTRY32, *PLIST_ENTRY32;
typedef struct _LIST_ENTRY64 LIST_ENTRY64, *PLIST_ENTRY64; typedef struct _LIST_ENTRY64 LIST_ENTRY64, *PLIST_ENTRY64;
typedef struct _LOADER_GRAPHICS_INFORMATION_BLOCK LOADER_GRAPHICS_INFORMATION_BLOCK, *PLOADER_GRAPHICS_INFORMATION_BLOCK; typedef struct _LOADER_GRAPHICS_INFORMATION_BLOCK LOADER_GRAPHICS_INFORMATION_BLOCK, *PLOADER_GRAPHICS_INFORMATION_BLOCK;
typedef struct _LOADER_INFORMATION_BLOCK LOADER_INFORMATION_BLOCK, *PLOADER_INFORMATION_BLOCK; typedef struct _LOADER_INFORMATION_BLOCK LOADER_INFORMATION_BLOCK, *PLOADER_INFORMATION_BLOCK;
typedef struct _LOADER_MEMORY_MAPPING LOADER_MEMORY_MAPPING, *PLOADER_MEMORY_MAPPING; typedef struct _LOADER_MEMORY_DESCRIPTOR LOADER_MEMORY_DESCRIPTOR, *PLOADER_MEMORY_DESCRIPTOR;
typedef struct _M128 M128, *PM128; typedef struct _M128 M128, *PM128;
typedef struct _MMCOLOR_TABLES MMCOLOR_TABLES, *PMMCOLOR_TABLES; typedef struct _MMCOLOR_TABLES MMCOLOR_TABLES, *PMMCOLOR_TABLES;
typedef struct _MMPFNENTRY MMPFNENTRY, *PMMPFNENTRY; typedef struct _MMPFNENTRY MMPFNENTRY, *PMMPFNENTRY;
@@ -273,8 +303,14 @@ typedef struct _PECOFF_IMAGE_ROM_HEADER PECOFF_IMAGE_ROM_HEADER, *PPECOFF_IMAGE_
typedef struct _PECOFF_IMAGE_ROM_OPTIONAL_HEADER PECOFF_IMAGE_ROM_OPTIONAL_HEADER, *PPECOFF_IMAGE_ROM_OPTIONAL_HEADER; typedef struct _PECOFF_IMAGE_ROM_OPTIONAL_HEADER PECOFF_IMAGE_ROM_OPTIONAL_HEADER, *PPECOFF_IMAGE_ROM_OPTIONAL_HEADER;
typedef struct _PECOFF_IMAGE_SECTION_HEADER PECOFF_IMAGE_SECTION_HEADER, *PPECOFF_IMAGE_SECTION_HEADER; typedef struct _PECOFF_IMAGE_SECTION_HEADER PECOFF_IMAGE_SECTION_HEADER, *PPECOFF_IMAGE_SECTION_HEADER;
typedef struct _PECOFF_IMAGE_VXD_HEADER PECOFF_IMAGE_VXD_HEADER, *PPECOFF_IMAGE_VXD_HEADER; typedef struct _PECOFF_IMAGE_VXD_HEADER PECOFF_IMAGE_VXD_HEADER, *PPECOFF_IMAGE_VXD_HEADER;
typedef struct _PROCESSOR_IDENTITY PROCESSOR_IDENTITY, *PPROCESSOR_IDENTITY;
typedef struct _PROCESSOR_POWER_STATE PROCESSOR_POWER_STATE, *PPROCESSOR_POWER_STATE; typedef struct _PROCESSOR_POWER_STATE PROCESSOR_POWER_STATE, *PPROCESSOR_POWER_STATE;
typedef struct _RTL_BITMAP RTL_BITMAP, *PRTL_BITMAP;
typedef struct _RTL_PRINT_CONTEXT RTL_PRINT_CONTEXT, *PRTL_PRINT_CONTEXT;
typedef struct _RTL_PRINT_FORMAT_PROPERTIES RTL_PRINT_FORMAT_PROPERTIES, *PRTL_PRINT_FORMAT_PROPERTIES;
typedef struct _SINGLE_LIST_ENTRY SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY; typedef struct _SINGLE_LIST_ENTRY SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;
typedef struct _SMBIOS_TABLE_HEADER SMBIOS_TABLE_HEADER, *PSMBIOS_TABLE_HEADER;
typedef struct _SMBIOS3_TABLE_HEADER SMBIOS3_TABLE_HEADER, *PSMBIOS3_TABLE_HEADER;
typedef struct _STRING STRING, *PSTRING; 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;

View File

@@ -29,6 +29,7 @@
#define MEMORY_ALIGNMENT 8 #define MEMORY_ALIGNMENT 8
#define MM_USERPAGE_TABLES 1536 #define MM_USERPAGE_TABLES 1536
#define MM_VIRTUAL_PAGESIZE 20 #define MM_VIRTUAL_PAGESIZE 20
#define STACK_ALIGNMENT 4
#elif defined(__amd64__) || defined(__x86_64__) #elif defined(__amd64__) || defined(__x86_64__)
#define _ARCH amd64 #define _ARCH amd64
#define _ARCH_AMD64 1 #define _ARCH_AMD64 1
@@ -43,6 +44,7 @@
#define MEMORY_ALIGNMENT 16 #define MEMORY_ALIGNMENT 16
#define MM_USERPAGE_TABLES 4194304 #define MM_USERPAGE_TABLES 4194304
#define MM_VIRTUAL_PAGESIZE 52 #define MM_VIRTUAL_PAGESIZE 52
#define STACK_ALIGNMENT 16
#else #else
#error Unknown architecture #error Unknown architecture
#endif #endif

View File

@@ -10,6 +10,7 @@
#define __XTDK_XTTYPES_H #define __XTDK_XTTYPES_H
#include <xttarget.h> #include <xttarget.h>
#include <xtcompat.h>
/* Standard C types */ /* Standard C types */
@@ -128,7 +129,7 @@ typedef CHAR SZ, *PSZ;
typedef const CHAR CSZ, *PCSZ; typedef const CHAR CSZ, *PCSZ;
/* UNICODE character types */ /* UNICODE character types */
typedef USHORT WCHAR, *PWCHAR; typedef wchar WCHAR, *PWCHAR;
typedef WCHAR *PWCH, *LPWCH; typedef WCHAR *PWCH, *LPWCH;
typedef const WCHAR *PCWCH, *LPCWCH; typedef const WCHAR *PCWCH, *LPCWCH;
typedef WCHAR *PWSTR, *LPWSTR, *NWPSTR; typedef WCHAR *PWSTR, *LPWSTR, *NWPSTR;

View File

@@ -16,6 +16,7 @@ list(APPEND LIBXTLDR_SOURCE
# Specify list of source code files # Specify list of source code files
list(APPEND XTLDR_SOURCE list(APPEND XTLDR_SOURCE
${XTLDR_SOURCE_DIR}/arch/${ARCH}/memory.c ${XTLDR_SOURCE_DIR}/arch/${ARCH}/memory.c
${XTLDR_SOURCE_DIR}/bootutil.c
${XTLDR_SOURCE_DIR}/config.c ${XTLDR_SOURCE_DIR}/config.c
${XTLDR_SOURCE_DIR}/console.c ${XTLDR_SOURCE_DIR}/console.c
${XTLDR_SOURCE_DIR}/debug.c ${XTLDR_SOURCE_DIR}/debug.c
@@ -49,6 +50,5 @@ set_install_target(xtldr efi/boot)
# Set loader entrypoint and subsystem # Set loader entrypoint and subsystem
set_entrypoint(xtldr "BlStartXtLoader") set_entrypoint(xtldr "BlStartXtLoader")
set_imagebase(xtldr ${BASEADDRESS_XTLDR})
set_linker_map(xtldr TRUE) set_linker_map(xtldr TRUE)
set_subsystem(xtldr efi_application) set_subsystem(xtldr efi_application)

View File

@@ -4,6 +4,7 @@
* FILE: xtldr/arch/amd64/memory.c * FILE: xtldr/arch/amd64/memory.c
* DESCRIPTION: XT Boot Loader AMD64 specific memory management * DESCRIPTION: XT Boot Loader AMD64 specific memory management
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/ */
#include <xtldr.h> #include <xtldr.h>
@@ -34,7 +35,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
EFI_STATUS Status; EFI_STATUS Status;
/* Allocate pages for the Page Map */ /* Allocate pages for the Page Map */
Status = BlAllocateMemoryPages(1, &Address); Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -53,6 +54,15 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
return Status; return Status;
} }
/* Map the trampoline code area */
Status = BlMapVirtualMemory(PageMap, (PVOID)MM_TRAMPOLINE_ADDRESS,(PVOID)MM_TRAMPOLINE_ADDRESS,
1, LoaderFirmwareTemporary);
if(Status != STATUS_EFI_SUCCESS)
{
/* Mapping trampoline code failed */
return Status;
}
/* Get list of XTLDR modules */ /* Get list of XTLDR modules */
ModulesList = BlGetModulesList(); ModulesList = BlGetModulesList();
ModulesListEntry = ModulesList->Flink; ModulesListEntry = ModulesList->Flink;
@@ -149,12 +159,13 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlMapPage(IN PXTBL_PAGE_MAPPING PageMap, BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
IN UINT_PTR VirtualAddress, IN ULONG_PTR VirtualAddress,
IN UINT_PTR PhysicalAddress, IN ULONG_PTR PhysicalAddress,
IN UINT NumberOfPages) IN ULONG NumberOfPages)
{ {
PVOID Pml1, Pml2, Pml3, Pml4, Pml5;
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry, Pml4Entry, Pml5Entry; SIZE_T Pml1Entry, Pml2Entry, Pml3Entry, Pml4Entry, Pml5Entry;
PHARDWARE_PTE Pml1, Pml2, Pml3, Pml4, Pml5; PHARDWARE_PTE PmlTable;
SIZE_T PageFrameNumber; SIZE_T PageFrameNumber;
EFI_STATUS Status; EFI_STATUS Status;
@@ -165,17 +176,17 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
while(NumberOfPages > 0) while(NumberOfPages > 0)
{ {
/* Calculate the indices in the various Page Tables from the virtual address */ /* Calculate the indices in the various Page Tables from the virtual address */
Pml5Entry = (VirtualAddress & ((ULONGLONG)0x1FF << 48)) >> 48; Pml5Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_P5I_SHIFT)) >> MM_P5I_SHIFT;
Pml4Entry = (VirtualAddress & ((ULONGLONG)0x1FF << 39)) >> 39; Pml4Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PXI_SHIFT)) >> MM_PXI_SHIFT;
Pml3Entry = (VirtualAddress & ((ULONGLONG)0x1FF << 30)) >> 30; Pml3Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PPI_SHIFT)) >> MM_PPI_SHIFT;
Pml2Entry = (VirtualAddress & ((ULONGLONG)0x1FF << 21)) >> 21; Pml2Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PDI_SHIFT)) >> MM_PDI_SHIFT;
Pml1Entry = (VirtualAddress & ((ULONGLONG)0x1FF << 12)) >> 12; Pml1Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PTI_SHIFT)) >> MM_PTI_SHIFT;
/* Check page map level */ /* Check page map level */
if(PageMap->PageMapLevel == 5) if(PageMap->PageMapLevel == 5)
{ {
/* Five level Page Map */ /* Five level Page Map */
Pml5 = ((PHARDWARE_PTE)(PageMap->PtePointer)); Pml5 = PageMap->PtePointer;
/* Get PML4 */ /* Get PML4 */
Status = BlpGetNextPageTable(PageMap, Pml5, Pml5Entry, &Pml4); Status = BlpGetNextPageTable(PageMap, Pml5, Pml5Entry, &Pml4);
@@ -188,7 +199,7 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
else else
{ {
/* Four level Page Map */ /* Four level Page Map */
Pml4 = ((PHARDWARE_PTE)(PageMap->PtePointer)); Pml4 = PageMap->PtePointer;
} }
/* Get PML3 */ /* Get PML3 */
@@ -216,9 +227,11 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
} }
/* Set paging entry settings */ /* Set paging entry settings */
Pml1[Pml1Entry].PageFrameNumber = PageFrameNumber; PmlTable = (PHARDWARE_PTE)Pml1;
Pml1[Pml1Entry].Valid = 1; RtlZeroMemory(&PmlTable[Pml1Entry], sizeof(HARDWARE_PTE));
Pml1[Pml1Entry].Writable = 1; PmlTable[Pml1Entry].PageFrameNumber = PageFrameNumber;
PmlTable[Pml1Entry].Valid = 1;
PmlTable[Pml1Entry].Writable = 1;
/* Take next virtual address and PFN */ /* Take next virtual address and PFN */
VirtualAddress += EFI_PAGE_SIZE; VirtualAddress += EFI_PAGE_SIZE;
@@ -232,6 +245,81 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
/**
* Returns next level of the Page Table.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @param PageTable
* Supplies a pointer to the current Page Table.
*
* @param Entry
* Supplies an index of the current Page Table entry.
*
* @param NextPageTable
* Supplies a pointer to the memory area where the next Page Table level is returned.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID PageTable,
IN SIZE_T Entry,
OUT PVOID *NextPageTable)
{
EFI_PHYSICAL_ADDRESS Address;
ULONGLONG PmlPointer = 0;
PHARDWARE_PTE PmlTable;
EFI_STATUS Status;
PmlTable = (PHARDWARE_PTE)PageTable;
/* Check if this is a valid table */
if(PmlTable[Entry].Valid)
{
/* Get PML pointer */
PmlPointer = PmlTable[Entry].PageFrameNumber;
PmlPointer <<= EFI_PAGE_SHIFT;
}
else
{
/* Allocate pages for new PML entry */
Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
return Status;
}
/* Add new memory mapping */
Status = BlMapVirtualMemory(PageMap, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
return Status;
}
/* Fill allocated memory with zeros */
RtlZeroMemory((PVOID)(ULONGLONG)Address, EFI_PAGE_SIZE);
/* Set paging entry settings */
PmlTable[Entry].PageFrameNumber = Address / EFI_PAGE_SIZE;
PmlTable[Entry].Valid = 1;
PmlTable[Entry].Writable = 1;
PmlPointer = (ULONGLONG)Address;
}
/* Set next Page Map Level (PML) */
*NextPageTable = (PVOID)(ULONGLONG)PmlPointer;
/* Return success */
return STATUS_EFI_SUCCESS;
}
/** /**
* Creates a recursive self mapping for all PML levels. * Creates a recursive self mapping for all PML levels.
* *
@@ -250,26 +338,30 @@ EFI_STATUS
BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap, BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress) IN ULONG_PTR SelfMapAddress)
{ {
PHARDWARE_PTE PmlBase;
ULONGLONG PmlIndex; ULONGLONG PmlIndex;
/* Initialize PML base pointer */
PmlBase = (PHARDWARE_PTE)PageMap->PtePointer;
/* Check page map level */ /* Check page map level */
if(PageMap->PageMapLevel == 5) if(PageMap->PageMapLevel == 5)
{ {
/* Self-mapping for PML5 is not supported */ /* Calculate PML index based on provided self map address for PML5 */
BlDebugPrint(L"PML5 self-mapping not supported yet!\n"); PmlIndex = (SelfMapAddress >> MM_P5I_SHIFT) & 0x1FF;
return STATUS_EFI_UNSUPPORTED;
} }
else else
{ {
/* Calculate PML index based on provided self map address */ /* Calculate PML index based on provided self map address for PML4 */
PmlIndex = (SelfMapAddress >> 39) & 0x1FF; PmlIndex = (SelfMapAddress >> MM_PXI_SHIFT) & 0x1FF;
/* Add self-mapping for PML4 */
((PHARDWARE_PTE)PageMap->PtePointer)[PmlIndex].PageFrameNumber = (UINT_PTR)PageMap->PtePointer / EFI_PAGE_SIZE;
((PHARDWARE_PTE)PageMap->PtePointer)[PmlIndex].Valid = 1;
((PHARDWARE_PTE)PageMap->PtePointer)[PmlIndex].Writable = 1;
} }
/* Add self-mapping */
RtlZeroMemory(&PmlBase[PmlIndex], sizeof(HARDWARE_PTE));
PmlBase[PmlIndex].PageFrameNumber = (UINT_PTR)PageMap->PtePointer / EFI_PAGE_SIZE;
PmlBase[PmlIndex].Valid = 1;
PmlBase[PmlIndex].Writable = 1;
/* Return success */ /* Return success */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }

View File

@@ -4,6 +4,7 @@
* FILE: xtldr/arch/i686/memory.c * FILE: xtldr/arch/i686/memory.c
* DESCRIPTION: XT Boot Loader i686 specific memory management * DESCRIPTION: XT Boot Loader i686 specific memory management
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/ */
#include <xtldr.h> #include <xtldr.h>
@@ -31,39 +32,55 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
EFI_STATUS Status; EFI_STATUS Status;
ULONG Index; ULONG Index;
/* Allocate pages for the Page Map */ /* Check the page map level to determine which paging structure to create */
Status = BlAllocateMemoryPages(1, &Address); if(PageMap->PageMapLevel == 3)
{
/* Allocate a page for the 3-level page map structure (PAE enabled) */
Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failed, cannot proceed with page map creation */
return Status; return Status;
} }
/* Assign and zero-fill memory used by page mappings */ /* Assign the allocated page to the page map and zero it out */
PageMap->PtePointer = (PVOID)(UINT_PTR)Address; PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
RtlZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE); RtlZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
/* Allocate pages for the Page Directory */ /* Allocate 4 pages for the Page Directories (PDs) */
Status = BlAllocateMemoryPages(4, &DirectoryAddress); Status = BlAllocateMemoryPages(AllocateAnyPages, 4, &DirectoryAddress);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failed, cannot proceed with page map creation */
return Status; return Status;
} }
/* Zero fill memory used by Page Directory */ /* Zero-fill the allocated memory for the Page Directories */
RtlZeroMemory((PVOID)DirectoryAddress, EFI_PAGE_SIZE * 4); RtlZeroMemory((PVOID)DirectoryAddress, EFI_PAGE_SIZE * 4);
/* Set the page directory into the PDPT and mark it present */ /* Fill the PDPT with pointers to the Page Directories */
for(Index = 0; Index < 4; Index++) for(Index = 0; Index < 4; Index++)
{ {
/* Set paging entry settings */ RtlZeroMemory(&((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[Index], sizeof(HARDWARE_MODERN_PTE));
((PHARDWARE_PTE)PageMap->PtePointer)[Index].PageFrameNumber = DirectoryAddress / EFI_PAGE_SIZE; ((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[Index].PageFrameNumber = DirectoryAddress / EFI_PAGE_SIZE;
((PHARDWARE_PTE)PageMap->PtePointer)[Index].Valid = 1; ((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[Index].Valid = 1;
/* Next valid PFN address */
DirectoryAddress += EFI_PAGE_SIZE; DirectoryAddress += EFI_PAGE_SIZE;
} }
}
else
{
/* Allocate a page for the 2-level page map structure (PAE disabled) */
Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failed, cannot proceed with page map creation */
return Status;
}
/* Assign the allocated page to the page map and zero it out */
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
RtlZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
}
/* Add page mapping itself to memory mapping */ /* Add page mapping itself to memory mapping */
Status = BlpSelfMapPml(PageMap, SelfMapAddress); Status = BlpSelfMapPml(PageMap, SelfMapAddress);
@@ -73,6 +90,15 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
return Status; return Status;
} }
/* Map the trampoline code area */
Status = BlMapVirtualMemory(PageMap, (PVOID)MM_TRAMPOLINE_ADDRESS,(PVOID)MM_TRAMPOLINE_ADDRESS,
1, LoaderFirmwareTemporary);
if(Status != STATUS_EFI_SUCCESS)
{
/* Mapping trampoline code failed */
return Status;
}
/* Get list of XTLDR modules */ /* Get list of XTLDR modules */
ModulesList = BlGetModulesList(); ModulesList = BlGetModulesList();
ModulesListEntry = ModulesList->Flink; ModulesListEntry = ModulesList->Flink;
@@ -169,58 +195,81 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlMapPage(IN PXTBL_PAGE_MAPPING PageMap, BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
IN UINT_PTR VirtualAddress, IN ULONG_PTR VirtualAddress,
IN UINT_PTR PhysicalAddress, IN ULONG_PTR PhysicalAddress,
IN UINT NumberOfPages) IN ULONG NumberOfPages)
{ {
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry;
PHARDWARE_PTE Pml1, Pml2, Pml3;
SIZE_T PageFrameNumber; SIZE_T PageFrameNumber;
PVOID Pml1, Pml2, Pml3;
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry;
PHARDWARE_LEGACY_PTE LegacyPmlTable;
PHARDWARE_MODERN_PTE PmlTable;
EFI_STATUS Status; EFI_STATUS Status;
/* Set the Page Frame Number (PFN) */ /* Set the Page Frame Number (PFN) */
PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT; PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT;
/* Do the recursive mapping */ /* Map all requested pages */
while(NumberOfPages > 0) while(NumberOfPages > 0)
{ {
/* Calculate the indices in the various Page Tables from the virtual address */ /* Check the paging mode to use the correct page table structure */
Pml3Entry = (VirtualAddress & ((ULONGLONG)0x1FF << 30)) >> 30;
Pml2Entry = (VirtualAddress & ((ULONGLONG)0x1FF << 21)) >> 21;
Pml1Entry = (VirtualAddress & ((ULONGLONG)0x1FF << 12)) >> 12;
/* Check page map level */
if(PageMap->PageMapLevel == 3) if(PageMap->PageMapLevel == 3)
{ {
/* Three level Page Map */ /* Calculate the indices for PAE page tables */
Pml3 = ((PHARDWARE_PTE)(PageMap->PtePointer)); Pml3Entry = (VirtualAddress >> 30) & 0x3;
Pml2Entry = (VirtualAddress >> 21) & 0x1FF;
Pml1Entry = (VirtualAddress >> 12) & 0x1FF;
/* Get PML2 */ /* Get Page Directory Pointer Table (PML3) */
Pml3 = PageMap->PtePointer;
/* Get Page Directory (PML2) */
Status = BlpGetNextPageTable(PageMap, Pml3, Pml3Entry, &Pml2); Status = BlpGetNextPageTable(PageMap, Pml3, Pml3Entry, &Pml2);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory mapping failure */ /* Failed to get the Page Table, abort mapping */
return Status; return Status;
} }
}
else
{
/* Two level Page Map */
Pml2 = ((PHARDWARE_PTE)(PageMap->PtePointer));
}
/* Get PML1 */ /* Get Page Table (PML1) */
Status = BlpGetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1); Status = BlpGetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory mapping failure */ /* Failed to get the Page Table, abort mapping */
return Status; return Status;
} }
/* Set paging entry settings */ /* Set the 64-bit PTE entry */
Pml1[Pml1Entry].PageFrameNumber = PageFrameNumber; PmlTable = (PHARDWARE_MODERN_PTE)Pml1;
Pml1[Pml1Entry].Valid = 1; RtlZeroMemory(&PmlTable[Pml1Entry], sizeof(HARDWARE_MODERN_PTE));
Pml1[Pml1Entry].Writable = 1; PmlTable[Pml1Entry].PageFrameNumber = PageFrameNumber;
PmlTable[Pml1Entry].Valid = 1;
PmlTable[Pml1Entry].Writable = 1;
}
else
{
/* Calculate the indices for non-PAE page tables */
Pml2Entry = (VirtualAddress >> 22) & 0x3FF;
Pml1Entry = (VirtualAddress >> 12) & 0x3FF;
/* Get Page Directory (PML2) */
Pml2 = PageMap->PtePointer;
/* Get Page Table (PML1) */
Status = BlpGetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get the Page Table, abort mapping */
return Status;
}
/* Set the 32-bit PTE entry */
LegacyPmlTable = (PHARDWARE_LEGACY_PTE)Pml1;
RtlZeroMemory(&LegacyPmlTable[Pml1Entry], sizeof(HARDWARE_LEGACY_PTE));
LegacyPmlTable[Pml1Entry].PageFrameNumber = (UINT32)PageFrameNumber;
LegacyPmlTable[Pml1Entry].Valid = 1;
LegacyPmlTable[Pml1Entry].Writable = 1;
}
/* Take next virtual address and PFN */ /* Take next virtual address and PFN */
VirtualAddress += EFI_PAGE_SIZE; VirtualAddress += EFI_PAGE_SIZE;
@@ -234,6 +283,119 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
/**
* Returns next level of the Page Table.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @param PageTable
* Supplies a pointer to the current Page Table.
*
* @param Entry
* Supplies an index of the current Page Table entry.
*
* @param NextPageTable
* Supplies a pointer to the memory area where the next Page Table level is returned.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID PageTable,
IN SIZE_T Entry,
OUT PVOID *NextPageTable)
{
EFI_PHYSICAL_ADDRESS Address;
ULONGLONG PmlPointer = 0;
EFI_STATUS Status;
PHARDWARE_LEGACY_PTE LegacyPmlTable;
PHARDWARE_MODERN_PTE PmlTable;
BOOLEAN ValidPte = FALSE;
/* Check page map level to determine PTE size */
if(PageMap->PageMapLevel >= 3)
{
/* 64-bit PTE for PML3 (PAE enabled) */
PmlTable = (PHARDWARE_MODERN_PTE)PageTable;
if(PmlTable[Entry].Valid)
{
/* Get page frame number from page table entry */
PmlPointer = PmlTable[Entry].PageFrameNumber;
ValidPte = TRUE;
}
}
else
{
/* 32-bit PTE for PML2 (PAE disabled) */
LegacyPmlTable = (PHARDWARE_LEGACY_PTE)PageTable;
if(LegacyPmlTable[Entry].Valid)
{
/* Get page frame number from page table entry */
PmlPointer = LegacyPmlTable[Entry].PageFrameNumber;
ValidPte = TRUE;
}
}
/* Check if page table entry is valid */
if(ValidPte)
{
/* Calculate the base address of the next page table */
PmlPointer <<= EFI_PAGE_SHIFT;
}
else
{
/* Allocate pages for new PML entry */
Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
return Status;
}
/* Add new memory mapping */
Status = BlMapVirtualMemory(PageMap, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
return Status;
}
/* Fill allocated memory with zeros */
RtlZeroMemory((PVOID)(ULONGLONG)Address, EFI_PAGE_SIZE);
/* Set paging entry settings based on level */
if(PageMap->PageMapLevel >= 3)
{
/* 64-bit PTE for PML3 (PAE enabled) */
PmlTable = (PHARDWARE_MODERN_PTE)PageTable;
PmlTable[Entry].PageFrameNumber = Address / EFI_PAGE_SIZE;
PmlTable[Entry].Valid = 1;
PmlTable[Entry].Writable = 1;
}
else
{
/* 32-bit PTE for PML2 (PAE disabled) */
LegacyPmlTable = (PHARDWARE_LEGACY_PTE)PageTable;
LegacyPmlTable[Entry].PageFrameNumber = (UINT32)(Address / EFI_PAGE_SIZE);
LegacyPmlTable[Entry].Valid = 1;
LegacyPmlTable[Entry].Writable = 1;
}
/* Return the address of the new page table */
PmlPointer = (ULONGLONG)Address;
}
/* Set next Page Map Level (PML) */
*NextPageTable = (PVOID)(ULONGLONG)PmlPointer;
/* Return success */
return STATUS_EFI_SUCCESS;
}
/** /**
* Creates a recursive self mapping for all PML levels. * Creates a recursive self mapping for all PML levels.
* *
@@ -252,36 +414,41 @@ EFI_STATUS
BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap, BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress) IN ULONG_PTR SelfMapAddress)
{ {
PHARDWARE_LEGACY_PTE LegacyPml;
PHARDWARE_MODERN_PTE Pml;
ULONGLONG PmlIndex; ULONGLONG PmlIndex;
PHARDWARE_PTE Pml;
ULONG Index; ULONG Index;
/* Check page map level */ /* Check page map level */
if(PageMap->PageMapLevel == 3) if(PageMap->PageMapLevel == 3)
{ {
/* Calculate PML index based on provided self map address */ /* Calculate PML index based on provided self map address */
PmlIndex = (SelfMapAddress >> 21) & 0x1FF; PmlIndex = (SelfMapAddress >> MM_PDI_SHIFT) & 0x1FF;
/* Get Page Directory */ /* Get Page Directory */
Pml = (PHARDWARE_PTE)(((PHARDWARE_PTE)PageMap->PtePointer)[SelfMapAddress >> 30].PageFrameNumber * EFI_PAGE_SIZE); Pml = (PHARDWARE_MODERN_PTE)(((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[SelfMapAddress >> MM_PPI_SHIFT].PageFrameNumber * EFI_PAGE_SIZE);
/* Add self-mapping for PML3 (PAE enabled) */ /* Add self-mapping for PML3 (PAE enabled) */
for(Index = 0; Index < 4; Index++) for(Index = 0; Index < 4; Index++)
{ {
Pml[PmlIndex + Index].PageFrameNumber = ((PHARDWARE_PTE)PageMap->PtePointer)[Index].PageFrameNumber; RtlZeroMemory(&Pml[PmlIndex + Index], sizeof(HARDWARE_MODERN_PTE));
Pml[PmlIndex + Index].PageFrameNumber = ((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[Index].PageFrameNumber;
Pml[PmlIndex + Index].Valid = 1; Pml[PmlIndex + Index].Valid = 1;
Pml[PmlIndex + Index].Writable = 1; Pml[PmlIndex + Index].Writable = 1;
} }
} }
else else
{ {
LegacyPml = (PHARDWARE_LEGACY_PTE)PageMap->PtePointer;
/* Calculate PML index based on provided self map address */ /* Calculate PML index based on provided self map address */
PmlIndex = (SelfMapAddress >> 22); PmlIndex = (SelfMapAddress >> MM_PDI_LEGACY_SHIFT);
/* Add self-mapping for PML2 (PAE disabled) */ /* Add self-mapping for PML2 (PAE disabled) */
((PHARDWARE_LEGACY_PTE)PageMap->PtePointer)[PmlIndex].PageFrameNumber = (UINT_PTR)PageMap->PtePointer / EFI_PAGE_SIZE; RtlZeroMemory(&LegacyPml[PmlIndex], sizeof(HARDWARE_LEGACY_PTE));
((PHARDWARE_LEGACY_PTE)PageMap->PtePointer)[PmlIndex].Valid = 1; LegacyPml[PmlIndex].PageFrameNumber = (UINT_PTR)PageMap->PtePointer / EFI_PAGE_SIZE;
((PHARDWARE_LEGACY_PTE)PageMap->PtePointer)[PmlIndex].Writable = 1; LegacyPml[PmlIndex].Valid = 1;
LegacyPml[PmlIndex].Writable = 1;
} }
/* Return success */ /* Return success */

87
xtldr/bootutil.c Normal file
View File

@@ -0,0 +1,87 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/bootutil.c
* DESCRIPTION: Helper functions used by the boot protocol during system startup
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtldr.h>
/**
* Checks if a specific option exists in the list of provided boot parameters.
*
* @param Parameters
* A pointer to the wide-character string containing the boot parameters, separated by spaces.
*
* @param Needle
* A pointer to the wide-character string representing the kernel option to find.
*
* @return This routine returns TRUE if the option is found, otherwise FALSE.
*
* @since XT 1.0
*/
XTCDECL
BOOLEAN
BlGetBooleanParameter(IN CONST PWCHAR Parameters,
IN CONST PWCHAR Needle)
{
PWCHAR CurrentPosition, TokenEnd, TokenStart;
SIZE_T NeedleLength, TokenLength;
/* Validate input data and ensure the option is not an empty string */
if(Parameters == NULL || Needle == NULL || *Needle == L'\0')
{
/* One of the parameters was invalid */
return FALSE;
}
CurrentPosition = Parameters;
NeedleLength = RtlWideStringLength(Needle, 0);
/* Iterate through the entire parameters string */
while(*CurrentPosition != L'\0')
{
/* Skip any leading whitespace to find the start of the token */
while(*CurrentPosition == L' ')
{
CurrentPosition++;
}
/* Check if end of the string has been reached */
if(*CurrentPosition == L'\0')
{
/* End of string reached, no more tokens */
break;
}
/* Identify the boundaries of the current token */
TokenStart = CurrentPosition;
TokenEnd = TokenStart;
while(*TokenEnd != L'\0' && *TokenEnd != L' ')
{
TokenEnd++;
}
/* Calculate the length of the token found */
TokenLength = TokenEnd - TokenStart;
/* Compare the token length */
if(TokenLength == NeedleLength)
{
/* Length matches, compare the strings */
if(RtlCompareWideStringInsensitive(TokenStart, Needle, NeedleLength) == 0)
{
/* A match was found */
return TRUE;
}
}
/* Move the position past the current token to continue the search */
CurrentPosition = TokenEnd;
}
/* No match was found */
return FALSE;
}

View File

@@ -4,11 +4,84 @@
* FILE: xtldr/config.c * FILE: xtldr/config.c
* DESCRIPTION: XT Boot Loader Configuration * DESCRIPTION: XT Boot Loader Configuration
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/ */
#include <xtldr.h> #include <xtldr.h>
/**
* @brief Retrieves the value of a specific OS boot option from a list.
*
* @param Options
* A pointer to the head of a list of XTBL_CONFIG_ENTRY structures.
*
* @param OptionName
* A pointer to wide string that contains the name of the boot option to retrieve.
*
* @param OptionValue
* A pointer to a variable that receives a pointer to the retrieved boot option's value.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlGetBootOptionValue(IN PLIST_ENTRY Options,
IN CONST PWCHAR OptionName,
OUT PWCHAR *OptionValue)
{
PXTBL_CONFIG_ENTRY ConfigEntry;
PLIST_ENTRY ConfigList;
ULONG KeyLength, ValueLength;
EFI_STATUS Status;
/* Assume the option will not be found */
*OptionValue = NULL;
/* Get the length of the option name we are looking for */
KeyLength = RtlWideStringLength(OptionName, 0);
/* Start iterating from the first entry in the options list */
ConfigList = Options->Flink;
while(ConfigList != Options)
{
/* Get the container record for the current config entry */
ConfigEntry = CONTAIN_RECORD(ConfigList, XTBL_CONFIG_ENTRY, Flink);
/* Compare the current entry's name with the requested option name */
if(RtlCompareWideStringInsensitive(ConfigEntry->Name, OptionName, KeyLength) == 0)
{
/* Found the option, now prepare to copy its value */
ValueLength = RtlWideStringLength(ConfigEntry->Value, 0);
/* Allocate memory for the output value string */
Status = BlAllocateMemoryPool((ValueLength + 1) * sizeof(WCHAR), (PVOID *)OptionValue);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, print debug message and return status code */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status);
*OptionValue = NULL;
return Status;
}
/* Copy the value and NULL-terminate the new string */
RtlCopyMemory(*OptionValue, ConfigEntry->Value, ValueLength * sizeof(WCHAR));
(*OptionValue)[ValueLength] = L'\0';
/* Successfully retrieved the option value, return success */
return STATUS_EFI_SUCCESS;
}
/* Move to the next entry in the list */
ConfigList = ConfigList->Flink;
}
/* Option not found */
return STATUS_EFI_NOT_FOUND;
}
/** /**
* Returns a boolean value of the specified configuration key. * Returns a boolean value of the specified configuration key.
* *
@@ -26,7 +99,7 @@ BlGetConfigBooleanValue(IN CONST PWCHAR ConfigName)
PWCHAR Value; PWCHAR Value;
/* Get config value */ /* Get config value */
Value = BlGetConfigValue(ConfigName); BlGetConfigValue(ConfigName, &Value);
/* Check if option is enabled */ /* Check if option is enabled */
if(RtlCompareWideStringInsensitive(Value, L"ENABLED", 0) == 0 || if(RtlCompareWideStringInsensitive(Value, L"ENABLED", 0) == 0 ||
@@ -53,8 +126,9 @@ BlGetConfigBooleanValue(IN CONST PWCHAR ConfigName)
* @since XT 1.0 * @since XT 1.0
*/ */
XTCDECL XTCDECL
PWCHAR EFI_STATUS
BlGetConfigValue(IN CONST PWCHAR ConfigName) BlGetConfigValue(IN CONST PWCHAR ConfigName,
OUT PWCHAR *ConfigValue)
{ {
PXTBL_CONFIG_ENTRY ConfigEntry; PXTBL_CONFIG_ENTRY ConfigEntry;
PLIST_ENTRY ConfigListEntry; PLIST_ENTRY ConfigListEntry;
@@ -62,6 +136,9 @@ BlGetConfigValue(IN CONST PWCHAR ConfigName)
EFI_STATUS Status; EFI_STATUS Status;
PWCHAR Value; PWCHAR Value;
/* Assume the option will not be found */
*ConfigValue = NULL;
/* Get config entry name length */ /* Get config entry name length */
KeyLength = RtlWideStringLength(ConfigName, 0); KeyLength = RtlWideStringLength(ConfigName, 0);
@@ -84,13 +161,14 @@ BlGetConfigValue(IN CONST PWCHAR ConfigName)
{ {
/* Memory allocation failure, return NULL */ /* Memory allocation failure, return NULL */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status);
return NULL; return Status;
} }
/* Copy value and return it */ /* Copy value and return it */
RtlCopyMemory(Value, ConfigEntry->Value, ValueLength * sizeof(WCHAR)); RtlCopyMemory(Value, ConfigEntry->Value, ValueLength * sizeof(WCHAR));
Value[ValueLength] = L'\0'; Value[ValueLength] = L'\0';
return Value; *ConfigValue = Value;
return STATUS_EFI_SUCCESS;
} }
/* Move to the next config entry */ /* Move to the next config entry */
@@ -98,7 +176,157 @@ BlGetConfigValue(IN CONST PWCHAR ConfigName)
} }
/* Config entry not found, return NULL */ /* Config entry not found, return NULL */
return NULL; return STATUS_EFI_NOT_FOUND;
}
/**
* Retrieves the list of user-editable boot options.
*
* @param OptionsArray
* A pointer to a variable that will receive the pointer to the array of editable option names.
*
* @param OptionsCount
* A pointer to a variable that will be updated with the number of elements in the OptionsArray.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BlGetEditableOptions(OUT CONST PWCHAR **OptionsArray,
OUT PULONG OptionsCount)
{
ULONG Count = 0;
/* Return a pointer to the global array of editable options */
*OptionsArray = BlpEditableConfigOptions;
/* Calculate the number of elements in the array */
while(BlpEditableConfigOptions[Count])
{
Count++;
}
/* Return the number of elements */
*OptionsCount = Count;
}
/**
* Sets the value of a specific OS boot option in a list, or adds it if it doesn't exist.
*
* @param Options
* A pointer to the head of a list of XTBL_CONFIG_ENTRY structures.
*
* @param OptionName
* A pointer to a wide string that contains the name of the boot option to set.
*
* @param OptionValue
* A pointer to a wide string that contains the new value for the boot option.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlSetBootOptionValue(IN PLIST_ENTRY Options,
IN CONST PWCHAR OptionName,
IN CONST PWCHAR OptionValue)
{
PXTBL_CONFIG_ENTRY ConfigEntry;
PLIST_ENTRY ConfigList;
ULONG Length;
EFI_STATUS Status;
/* Get the length of the option name we are looking for */
Length = RtlWideStringLength(OptionName, 0);
/* Start iterating from the first entry in the options list */
ConfigList = Options->Flink;
while(ConfigList != Options)
{
/* Get the container record for the current config entry */
ConfigEntry = CONTAIN_RECORD(ConfigList, XTBL_CONFIG_ENTRY, Flink);
/* Compare the current entry's name with the requested option name */
if(RtlCompareWideStringInsensitive(ConfigEntry->Name, OptionName, Length) == 0)
{
/* Found the option, get its length */
Length = RtlWideStringLength(OptionValue, 0);
/* Reallocate memory for the new value */
Status = BlFreeMemoryPool(ConfigEntry->Value);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to free memory, return status code */
return Status;
}
/* Allocate new memory for the updated value */
Status = BlAllocateMemoryPool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Value);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, print debug message and return status code */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status);
return Status;
}
/* Copy the value and NULL-terminate the new string */
RtlCopyMemory(ConfigEntry->Value, OptionValue, Length * sizeof(WCHAR));
ConfigEntry->Value[Length] = L'\0';
return STATUS_EFI_SUCCESS;
}
/* Move to the next entry in the list */
ConfigList = ConfigList->Flink;
}
/* Option not found, allocate memory for the new one */
Status = BlAllocateMemoryPool(sizeof(XTBL_CONFIG_ENTRY), (PVOID *)&ConfigEntry);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, print debug message and return status code */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status);
return Status;
}
/* Allocate memory for the option name */
Length = RtlWideStringLength(OptionName, 0);
Status = BlAllocateMemoryPool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Name);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, print debug message and return status code */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status);
BlFreeMemoryPool(ConfigEntry);
return Status;
}
/* Copy the option name and NULL-terminate the new string */
RtlCopyMemory(ConfigEntry->Name, OptionName, Length * sizeof(WCHAR));
ConfigEntry->Name[Length] = L'\0';
/* Allocate memory for the option value */
Length = RtlWideStringLength(OptionValue, 0);
Status = BlAllocateMemoryPool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Value);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, print debug message and return status code */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status);
BlFreeMemoryPool(ConfigEntry->Name);
BlFreeMemoryPool(ConfigEntry);
return Status;
}
/* Copy the value and NULL-terminate the new string */
RtlCopyMemory(ConfigEntry->Value, OptionValue, Length * sizeof(WCHAR));
ConfigEntry->Value[Length] = L'\0';
/* Insert the new config entry at the end of the options list */
RtlInsertTailList(Options, &ConfigEntry->Flink);
/* Return success */
return STATUS_EFI_SUCCESS;
} }
/** /**
@@ -110,7 +338,7 @@ BlGetConfigValue(IN CONST PWCHAR ConfigName)
* @param ConfigValue * @param ConfigValue
* Specifies the new configuration value. * Specifies the new configuration value.
* *
* @return This routine returns status code. * @return This routine returns a status code.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
@@ -174,7 +402,7 @@ BlSetConfigValue(IN CONST PWCHAR ConfigName,
/** /**
* Loads and parses XTLDR configuration file. * Loads and parses XTLDR configuration file.
* *
* @return This routine returns status code. * @return This routine returns a status code.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
@@ -453,7 +681,7 @@ BlpParseConfigFile(IN CONST PCHAR RawConfig,
/* Initialize new section and convert its name to wide string */ /* Initialize new section and convert its name to wide string */
RtlInitializeListHead(&Section->Options); RtlInitializeListHead(&Section->Options);
RtlStringToWideString(Section->SectionName, &SectionName, SectionLength); RtlStringToWideString(Section->SectionName, (PCSTR*)&SectionName, SectionLength);
/* Ensure string is NULL-terminated and add new section to the configuration list */ /* Ensure string is NULL-terminated and add new section to the configuration list */
Section->SectionName[SectionLength] = L'\0'; Section->SectionName[SectionLength] = L'\0';
@@ -542,8 +770,8 @@ BlpParseConfigFile(IN CONST PCHAR RawConfig,
} }
/* Convert key and value to wide strings */ /* Convert key and value to wide strings */
RtlStringToWideString(Option->Name, &Key, RtlStringLength(Key, 0) + 1); RtlStringToWideString(Option->Name, (PCSTR*)&Key, RtlStringLength(Key, 0) + 1);
RtlStringToWideString(Option->Value, &Value, RtlStringLength(Value, 0) + 1); RtlStringToWideString(Option->Value, (PCSTR*)&Value, RtlStringLength(Value, 0) + 1);
/* Ensure strings are NULL-terminated and add new option to the list */ /* Ensure strings are NULL-terminated and add new option to the list */
Option->Name[KeyLength] = L'\0'; Option->Name[KeyLength] = L'\0';
@@ -568,7 +796,7 @@ BlpParseConfigFile(IN CONST PCHAR RawConfig,
* @param ConfigData * @param ConfigData
* Provides a buffer to store the data read from the configuration file. * Provides a buffer to store the data read from the configuration file.
* *
* @return This routine returns status code. * @return This routine returns a status code.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
@@ -629,6 +857,7 @@ VOID
BlpUpdateConfiguration(IN PLIST_ENTRY NewConfig) BlpUpdateConfiguration(IN PLIST_ENTRY NewConfig)
{ {
PXTBL_CONFIG_ENTRY ConfigEntry; PXTBL_CONFIG_ENTRY ConfigEntry;
PWCHAR ConfigValue;
PLIST_ENTRY ConfigListEntry, NextListEntry; PLIST_ENTRY ConfigListEntry, NextListEntry;
/* Iterate through new config entries */ /* Iterate through new config entries */
@@ -642,7 +871,8 @@ BlpUpdateConfiguration(IN PLIST_ENTRY NewConfig)
NextListEntry = ConfigListEntry->Flink; NextListEntry = ConfigListEntry->Flink;
/* Make sure config entry does not exist yet */ /* Make sure config entry does not exist yet */
if(BlGetConfigValue(ConfigEntry->Name) == NULL) BlGetConfigValue(ConfigEntry->Name, &ConfigValue);
if(ConfigValue == NULL)
{ {
/* Remove new config entry from input list and put it into global config list */ /* Remove new config entry from input list and put it into global config list */
RtlRemoveEntryList(&ConfigEntry->Flink); RtlRemoveEntryList(&ConfigEntry->Flink);

View File

@@ -95,7 +95,7 @@ BlEnableConsoleCursor()
*/ */
XTCDECL XTCDECL
VOID VOID
BlConsolePrint(IN PUSHORT Format, BlConsolePrint(IN PCWSTR Format,
IN ...) IN ...)
{ {
RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext; RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext;
@@ -138,9 +138,9 @@ BlConsolePrint(IN PUSHORT Format,
*/ */
XTCDECL XTCDECL
VOID VOID
BlConsoleWrite(IN PUSHORT String) BlConsoleWrite(IN PCWSTR String)
{ {
EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, String); EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, (PWSTR)String);
} }
/** /**
@@ -292,9 +292,9 @@ BlSetCursorPosition(IN ULONGLONG PosX,
*/ */
XTCDECL XTCDECL
XTSTATUS XTSTATUS
BlpConsolePutChar(IN USHORT Character) BlpConsolePutChar(IN WCHAR Character)
{ {
USHORT Buffer[2]; WCHAR Buffer[2];
/* Check if character is a newline ('\n') */ /* Check if character is a newline ('\n') */
if(Character == L'\n') if(Character == L'\n')

View File

@@ -24,7 +24,7 @@
*/ */
XTCDECL XTCDECL
VOID VOID
BlDebugPrint(IN PUSHORT Format, BlDebugPrint(IN PCWSTR Format,
IN ...) IN ...)
{ {
RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext; RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext;
@@ -71,17 +71,14 @@ BlDebugPrint(IN PUSHORT Format,
*/ */
XTCDECL XTCDECL
XTSTATUS XTSTATUS
BlpDebugPutChar(IN USHORT Character) BlpDebugPutChar(IN WCHAR Character)
{ {
USHORT Buffer[2]; WCHAR Buffer[2];
/* Write character to the serial console */ /* Write character to the serial console */
Buffer[0] = Character; Buffer[0] = Character;
Buffer[1] = 0; Buffer[1] = 0;
HlComPortPutByte(&BlpStatus.SerialPort, Buffer[0]); return HlComPortPutByte(&BlpStatus.SerialPort, Buffer[0]);
/* Return success */
return STATUS_EFI_SUCCESS;
} }
/** /**
@@ -105,7 +102,7 @@ BlpInitializeDebugConsole()
BaudRate = 0; BaudRate = 0;
/* Get debug configuration */ /* Get debug configuration */
DebugConfiguration = BlGetConfigValue(L"DEBUG"); BlGetConfigValue(L"DEBUG", &DebugConfiguration);
/* Make sure any debug options are provided and debug console is not initialized yet */ /* Make sure any debug options are provided and debug console is not initialized yet */
if(DebugConfiguration && BlpStatus.DebugPort == 0) if(DebugConfiguration && BlpStatus.DebugPort == 0)
@@ -232,18 +229,35 @@ BlpInitializeSerialPort(IN ULONG PortNumber,
EFI_STATUS EfiStatus; EFI_STATUS EfiStatus;
XTSTATUS Status; XTSTATUS Status;
/* Print debug message depending on port settings */ /* Check if custom COM port address supplied */
if(PortAddress) if(!PortAddress)
{ {
BlConsolePrint(L"Initializing serial console at COM port address: 0x%lX\n", PortAddress); /* We support only a pre-defined number of ports */
if(PortNumber > COMPORT_COUNT)
{
/* Fail if wrong/unsupported port used */
return STATUS_INVALID_PARAMETER;
}
/* Check if serial port is set */
if(PortNumber == 0)
{
/* Use COM1 by default */
PortNumber = 1;
}
/* Set custom port address based on the port number and print debug message */
PortAddress = BlComPortList[PortNumber - 1];
BlConsolePrint(L"Initializing serial console at port COM%d\n", PortNumber);
} }
else else
{ {
BlConsolePrint(L"Initializing serial console at port COM%d\n", PortNumber); /* Custom port address supplied, print debug message */
BlConsolePrint(L"Initializing serial console at COM port address: 0x%lX\n", PortAddress);
} }
/* Initialize COM port */ /* Initialize COM port */
Status = HlInitializeComPort(&BlpStatus.SerialPort, PortNumber, UlongToPtr(PortAddress), BaudRate); Status = HlInitializeComPort(&BlpStatus.SerialPort, UlongToPtr(PortAddress), BaudRate);
/* Port not found under supplied address */ /* Port not found under supplied address */
if(Status == STATUS_NOT_FOUND && PortAddress) if(Status == STATUS_NOT_FOUND && PortAddress)
@@ -254,7 +268,7 @@ BlpInitializeSerialPort(IN ULONG PortNumber,
{ {
/* Try to reinitialize COM port */ /* Try to reinitialize COM port */
BlConsolePrint(L"Enabled I/O space access for all PCI(E) serial controllers found\n"); BlConsolePrint(L"Enabled I/O space access for all PCI(E) serial controllers found\n");
Status = HlInitializeComPort(&BlpStatus.SerialPort, PortNumber, UlongToPtr(PortAddress), BaudRate); Status = HlInitializeComPort(&BlpStatus.SerialPort, UlongToPtr(PortAddress), BaudRate);
} }
} }

View File

@@ -12,12 +12,22 @@
/* XT Boot Loader registered boot protocol list */ /* XT Boot Loader registered boot protocol list */
LIST_ENTRY BlpBootProtocols; LIST_ENTRY BlpBootProtocols;
/* XT Boot Loader serial ports list */
ULONG BlComPortList[COMPORT_COUNT] = COMPORT_ADDRESS;
/* XT Boot Loader configuration list */ /* XT Boot Loader configuration list */
LIST_ENTRY BlpConfig; LIST_ENTRY BlpConfig;
/* XT Boot Loader loaded configuration */ /* XT Boot Loader loaded configuration */
LIST_ENTRY BlpConfigSections; LIST_ENTRY BlpConfigSections;
/* List of user-editable boot options */
PWCHAR BlpEditableConfigOptions[] = {
L"BootModules", L"SystemType", L"SystemPath",
L"KernelFile", L"InitrdFile", L"HalFile",
L"Parameters", NULL
};
/* XT Boot Loader protocol */ /* XT Boot Loader protocol */
XTBL_LOADER_PROTOCOL BlpLdrProtocol; XTBL_LOADER_PROTOCOL BlpLdrProtocol;
@@ -38,3 +48,4 @@ EFI_HANDLE EfiImageHandle;
/* EFI System Table */ /* EFI System Table */
PEFI_SYSTEM_TABLE EfiSystemTable; PEFI_SYSTEM_TABLE EfiSystemTable;

View File

@@ -15,12 +15,18 @@
/* XT Boot Loader registered boot protocol list */ /* XT Boot Loader registered boot protocol list */
EXTERN LIST_ENTRY BlpBootProtocols; EXTERN LIST_ENTRY BlpBootProtocols;
/* XT Boot Loader serial ports list */
EXTERN ULONG BlComPortList[COMPORT_COUNT];
/* XT Boot Loader configuration list */ /* XT Boot Loader configuration list */
EXTERN LIST_ENTRY BlpConfig; EXTERN LIST_ENTRY BlpConfig;
/* XT Boot Loader loaded configuration */ /* XT Boot Loader loaded configuration */
EXTERN LIST_ENTRY BlpConfigSections; EXTERN LIST_ENTRY BlpConfigSections;
/* List of user-editable boot options */
EXTERN PWCHAR BlpEditableConfigOptions[];
/* XT Boot Loader protocol */ /* XT Boot Loader protocol */
EXTERN XTBL_LOADER_PROTOCOL BlpLdrProtocol; EXTERN XTBL_LOADER_PROTOCOL BlpLdrProtocol;

View File

@@ -18,7 +18,8 @@
/* XTLDR routines forward references */ /* XTLDR routines forward references */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlAllocateMemoryPages(IN ULONGLONG Pages, BlAllocateMemoryPages(IN EFI_ALLOCATE_TYPE AllocationType,
IN ULONGLONG NumberOfPages,
OUT PEFI_PHYSICAL_ADDRESS Memory); OUT PEFI_PHYSICAL_ADDRESS Memory);
XTCDECL XTCDECL
@@ -50,16 +51,16 @@ BlCloseVolume(IN PEFI_HANDLE VolumeHandle);
XTCDECL XTCDECL
VOID VOID
BlConsolePrint(IN PUSHORT Format, BlConsolePrint(IN PCWSTR Format,
IN ...); IN ...);
XTCDECL XTCDECL
VOID VOID
BlConsoleWrite(IN PUSHORT String); BlConsoleWrite(IN PCWSTR String);
XTCDECL XTCDECL
VOID VOID
BlDebugPrint(IN PUSHORT Format, BlDebugPrint(IN PCWSTR Format,
IN ...); IN ...);
XTCDECL XTCDECL
@@ -70,6 +71,10 @@ XTCDECL
VOID VOID
BlDisplayBootMenu(); BlDisplayBootMenu();
XTCDECL
VOID
BlDisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry);
XTCDECL XTCDECL
VOID VOID
BlDisplayErrorDialog(IN PWCHAR Caption, BlDisplayErrorDialog(IN PWCHAR Caption,
@@ -121,26 +126,43 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlFreeMemoryPages(IN ULONGLONG Pages, BlFreeMemoryPages(IN ULONGLONG NumberOfPages,
IN EFI_PHYSICAL_ADDRESS Memory); IN EFI_PHYSICAL_ADDRESS Memory);
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlFreeMemoryPool(IN PVOID Memory); BlFreeMemoryPool(IN PVOID Memory);
XTCDECL
BOOLEAN
BlGetBooleanParameter(IN CONST PWCHAR Parameters,
IN CONST PWCHAR Needle);
XTCDECL
EFI_STATUS
BlGetBootOptionValue(IN PLIST_ENTRY Options,
IN CONST PWCHAR OptionName,
OUT PWCHAR *OptionValue);
XTCDECL XTCDECL
BOOLEAN BOOLEAN
BlGetConfigBooleanValue(IN CONST PWCHAR ConfigName); BlGetConfigBooleanValue(IN CONST PWCHAR ConfigName);
XTCDECL XTCDECL
PWCHAR EFI_STATUS
BlGetConfigValue(IN CONST PWCHAR ConfigName); BlGetConfigValue(IN CONST PWCHAR ConfigName,
OUT PWCHAR *ConfigValue);
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlGetConfigurationTable(IN PEFI_GUID TableGuid, BlGetConfigurationTable(IN PEFI_GUID TableGuid,
OUT PVOID *Table); OUT PVOID *Table);
XTCDECL
VOID
BlGetEditableOptions(OUT CONST PWCHAR **OptionsArray,
OUT PULONG OptionsCount);
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlGetEfiPath(IN PWCHAR SystemPath, BlGetEfiPath(IN PWCHAR SystemPath,
@@ -191,7 +213,8 @@ BlInitializeBootLoader();
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM *MenuEntries, BlInitializeBootMenuList(IN ULONG MaxNameLength,
OUT PXTBL_BOOTMENU_ITEM *MenuEntries,
OUT PULONG EntriesCount, OUT PULONG EntriesCount,
OUT PULONG DefaultId); OUT PULONG DefaultId);
@@ -249,9 +272,9 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlMapPage(IN PXTBL_PAGE_MAPPING PageMap, BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
IN UINT_PTR VirtualAddress, IN ULONG_PTR VirtualAddress,
IN UINT_PTR PhysicalAddress, IN ULONG_PTR PhysicalAddress,
IN UINT NumberOfPages); IN ULONG NumberOfPages);
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
@@ -325,6 +348,12 @@ XTCDECL
VOID VOID
BlResetConsoleInputBuffer(); BlResetConsoleInputBuffer();
XTCDECL
EFI_STATUS
BlSetBootOptionValue(IN PLIST_ENTRY Options,
IN CONST PWCHAR OptionName,
IN CONST PWCHAR OptionValue);
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlSetConfigValue(IN CONST PWCHAR ConfigName, BlSetConfigValue(IN CONST PWCHAR ConfigName,
@@ -389,11 +418,11 @@ BlpActivateSerialIOController();
XTCDECL XTCDECL
XTSTATUS XTSTATUS
BlpConsolePutChar(IN USHORT Character); BlpConsolePutChar(IN WCHAR Character);
XTCDECL XTCDECL
XTSTATUS XTSTATUS
BlpDebugPutChar(IN USHORT Character); BlpDebugPutChar(IN WCHAR Character);
XTCDECL XTCDECL
VOID VOID
@@ -449,6 +478,18 @@ VOID
BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle, BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle,
IN UCHAR Percentage); IN UCHAR Percentage);
XTCDECL
VOID
BlpDrawEditMenu(OUT PXTBL_DIALOG_HANDLE Handle);
XTCDECL
EFI_STATUS
BlpDrawEditMenuEntry(IN PXTBL_DIALOG_HANDLE Handle,
IN PWCHAR OptionName,
IN PWCHAR OptionValue,
IN UINT Position,
IN BOOLEAN Highlighted);
XTCDECL XTCDECL
PEFI_DEVICE_PATH_PROTOCOL PEFI_DEVICE_PATH_PROTOCOL
BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath); BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath);
@@ -462,10 +503,10 @@ XTCDECL
BOOLEAN BOOLEAN
BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices, BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices,
IN PEFI_BLOCK_DEVICE_DATA ChildNode, IN PEFI_BLOCK_DEVICE_DATA ChildNode,
OUT PEFI_BLOCK_DEVICE_DATA ParentNode); OUT PEFI_BLOCK_DEVICE_DATA *ParentNode);
XTCDECL XTCDECL
LOADER_MEMORY_TYPE LONG
BlpGetLoaderMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType); BlpGetLoaderMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType);
XTCDECL XTCDECL
@@ -484,9 +525,9 @@ BlpGetModuleInfoStrings(IN PWCHAR SectionData,
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
IN PHARDWARE_PTE PageTable, IN PVOID PageTable,
IN SIZE_T Entry, IN SIZE_T Entry,
OUT PHARDWARE_PTE *NextPageTable); OUT PVOID *NextPageTable);
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS

View File

@@ -12,7 +12,7 @@
/** /**
* This routine allocates one or more 4KB pages. * This routine allocates one or more 4KB pages.
* *
* @param Pages * @param NumberOfPages
* The number of contiguous 4KB pages to allocate. * The number of contiguous 4KB pages to allocate.
* *
* @param Memory * @param Memory
@@ -24,10 +24,11 @@
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlAllocateMemoryPages(IN ULONGLONG Pages, BlAllocateMemoryPages(IN EFI_ALLOCATE_TYPE AllocationType,
IN ULONGLONG NumberOfPages,
OUT PEFI_PHYSICAL_ADDRESS Memory) OUT PEFI_PHYSICAL_ADDRESS Memory)
{ {
return EfiSystemTable->BootServices->AllocatePages(AllocateAnyPages, EfiLoaderData, Pages, Memory); return EfiSystemTable->BootServices->AllocatePages(AllocationType, EfiLoaderData, NumberOfPages, Memory);
} }
/** /**
@@ -55,7 +56,7 @@ BlAllocateMemoryPool(IN UINT_PTR Size,
/** /**
* This routine frees memory pages. * This routine frees memory pages.
* *
* @param Pages * @param NumberOfPages
* The number of contiguous 4 KB pages to free. * The number of contiguous 4 KB pages to free.
* *
* @param Memory * @param Memory
@@ -67,10 +68,10 @@ BlAllocateMemoryPool(IN UINT_PTR Size,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlFreeMemoryPages(IN ULONGLONG Pages, BlFreeMemoryPages(IN ULONGLONG NumberOfPages,
IN EFI_PHYSICAL_ADDRESS Memory) IN EFI_PHYSICAL_ADDRESS Memory)
{ {
return EfiSystemTable->BootServices->FreePages(Memory, Pages); return EfiSystemTable->BootServices->FreePages(Memory, NumberOfPages);
} }
/** /**
@@ -292,7 +293,7 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
if(GetMemoryTypeRoutine == NULL) if(GetMemoryTypeRoutine == NULL)
{ {
/* Use default memory type routine */ /* Use default memory type routine */
GetMemoryTypeRoutine = (PBL_GET_MEMTYPE_ROUTINE)BlpGetLoaderMemoryType; GetMemoryTypeRoutine = BlpGetLoaderMemoryType;
} }
/* Allocate and zero-fill buffer for EFI memory map */ /* Allocate and zero-fill buffer for EFI memory map */
@@ -454,7 +455,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
Mapping1->MemoryType = MemoryType; Mapping1->MemoryType = MemoryType;
/* Calculate the end of the physical address */ /* Calculate the end of the physical address */
PhysicalAddressEnd = (PUCHAR)PhysicalAddress + (NumberOfPages * EFI_PAGE_SIZE) - 1; PhysicalAddressEnd = (PVOID)((ULONG_PTR)PhysicalAddress + (NumberOfPages * EFI_PAGE_SIZE) - 1);
/* Iterate through all the mappings already set to insert new mapping at the correct place */ /* Iterate through all the mappings already set to insert new mapping at the correct place */
ListEntry = PageMap->MemoryMap.Flink; ListEntry = PageMap->MemoryMap.Flink;
@@ -462,7 +463,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
{ {
/* Take a mapping from the list and calculate its end of physical address */ /* Take a mapping from the list and calculate its end of physical address */
Mapping2 = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry); Mapping2 = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);
PhysicalAddress2End = (PUCHAR)Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1 ; PhysicalAddress2End = (PVOID)((ULONG_PTR)Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1);
/* Check if new mapping is a subset of an existing mapping */ /* Check if new mapping is a subset of an existing mapping */
if(Mapping1->PhysicalAddress >= Mapping2->PhysicalAddress && PhysicalAddressEnd <= PhysicalAddress2End) if(Mapping1->PhysicalAddress >= Mapping2->PhysicalAddress && PhysicalAddressEnd <= PhysicalAddress2End)
@@ -508,7 +509,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
/* Calculate number of pages and the end of the physical address */ /* Calculate number of pages and the end of the physical address */
Mapping2->NumberOfPages = ((PUCHAR)PhysicalAddressEnd + 1 - Mapping2->NumberOfPages = ((PUCHAR)PhysicalAddressEnd + 1 -
(PUCHAR)Mapping2->PhysicalAddress) / EFI_PAGE_SIZE; (PUCHAR)Mapping2->PhysicalAddress) / EFI_PAGE_SIZE;
PhysicalAddress2End = (PUCHAR)Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1; PhysicalAddress2End = (PVOID)((ULONG_PTR)Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1);
} }
/* Check if they overlap */ /* Check if they overlap */
@@ -544,7 +545,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
/* Calculate number of pages and the end of the physical address */ /* Calculate number of pages and the end of the physical address */
Mapping2->NumberOfPages = ((PUCHAR)Mapping1->PhysicalAddress - Mapping2->NumberOfPages = ((PUCHAR)Mapping1->PhysicalAddress -
(PUCHAR)Mapping2->PhysicalAddress) / EFI_PAGE_SIZE; (PUCHAR)Mapping2->PhysicalAddress) / EFI_PAGE_SIZE;
PhysicalAddress2End = (PUCHAR)Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1; PhysicalAddress2End = (PVOID)((ULONG_PTR)Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1);
} }
/* Check if mapping is really needed */ /* Check if mapping is really needed */
@@ -659,16 +660,6 @@ BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap,
NextEntry = ListEntry->Flink; NextEntry = ListEntry->Flink;
/* Convert the address of this element to VirtualAddress */ /* Convert the address of this element to VirtualAddress */
if(ListEntry->Flink == ListHead)
{
/* Convert list head */
ListEntry->Flink = ListHead->Flink->Blink;
}
else
{
/* Convert list entry */
ListEntry->Flink = BlPhysicalAddressToVirtual(ListEntry->Flink, (PVOID)PhysicalBase, VirtualBase);
}
if(ListEntry->Blink == ListHead) if(ListEntry->Blink == ListHead)
{ {
/* Find virtual address of list head */ /* Find virtual address of list head */
@@ -679,14 +670,24 @@ BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap,
/* Convert list entry */ /* Convert list entry */
ListEntry->Blink = BlPhysicalAddressToVirtual(ListEntry->Blink, (PVOID)PhysicalBase, VirtualBase); ListEntry->Blink = BlPhysicalAddressToVirtual(ListEntry->Blink, (PVOID)PhysicalBase, VirtualBase);
} }
if(ListEntry->Flink == ListHead)
{
/* Convert list head */
ListEntry->Flink = ListHead->Flink->Blink;
}
else
{
/* Convert list entry */
ListEntry->Flink = BlPhysicalAddressToVirtual(ListEntry->Flink, (PVOID)PhysicalBase, VirtualBase);
}
/* Get to the next element*/ /* Get to the next element*/
ListEntry = NextEntry; ListEntry = NextEntry;
} }
/* Convert list head */ /* Convert list head */
ListHead->Flink = BlPhysicalAddressToVirtual(ListHead->Flink, (PVOID)PhysicalBase, VirtualBase);
ListHead->Blink = BlPhysicalAddressToVirtual(ListHead->Blink, (PVOID)PhysicalBase, VirtualBase); ListHead->Blink = BlPhysicalAddressToVirtual(ListHead->Blink, (PVOID)PhysicalBase, VirtualBase);
ListHead->Flink = BlPhysicalAddressToVirtual(ListHead->Flink, (PVOID)PhysicalBase, VirtualBase);
/* Return success */ /* Return success */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
@@ -703,7 +704,7 @@ BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap,
* @since XT 1.0 * @since XT 1.0
*/ */
XTCDECL XTCDECL
LOADER_MEMORY_TYPE LONG
BlpGetLoaderMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType) BlpGetLoaderMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType)
{ {
LOADER_MEMORY_TYPE MemoryType; LOADER_MEMORY_TYPE MemoryType;
@@ -739,75 +740,3 @@ BlpGetLoaderMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType)
/* Return XTLDR memory type */ /* Return XTLDR memory type */
return MemoryType; return MemoryType;
} }
/**
* Returns next level of the Page Table.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @param PageTable
* Supplies a pointer to the current Page Table.
*
* @param Entry
* Supplies an index of the current Page Table entry.
*
* @param NextPageTable
* Supplies a pointer to the memory area where the next Page Table level is returned.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
IN PHARDWARE_PTE PageTable,
IN SIZE_T Entry,
OUT PHARDWARE_PTE *NextPageTable)
{
EFI_PHYSICAL_ADDRESS Address;
ULONGLONG PmlPointer;
EFI_STATUS Status;
/* Check if this is a valid table */
if(PageTable[Entry].Valid)
{
/* Get PML pointer */
PmlPointer = PageTable[Entry].PageFrameNumber;
PmlPointer <<= EFI_PAGE_SHIFT;
}
else
{
/* Allocate pages for new PML entry */
Status = BlAllocateMemoryPages(1, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
return Status;
}
/* Add new memory mapping */
Status = BlMapVirtualMemory(PageMap, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
return Status;
}
/* Fill allocated memory with zeros */
RtlZeroMemory((PVOID)(ULONGLONG)Address, EFI_PAGE_SIZE);
/* Set paging entry settings */
PageTable[Entry].PageFrameNumber = Address / EFI_PAGE_SIZE;
PageTable[Entry].Valid = 1;
PageTable[Entry].Writable = 1;
PmlPointer = (ULONGLONG)Address;
}
/* Set next Page Map Level (PML) */
*NextPageTable = (PHARDWARE_PTE)(ULONGLONG)PmlPointer;
/* Return success */
return STATUS_EFI_SUCCESS;
}

View File

@@ -51,6 +51,126 @@ AcGetAcpiDescriptionPointer(OUT PVOID *AcpiTable)
return STATUS_EFI_NOT_FOUND; return STATUS_EFI_NOT_FOUND;
} }
/**
* Finds ACPI description table with given signature.
*
* @param Signature
* Supplies the signature of the desired ACPI table.
*
* @param PreviousTable
* Supplies a pointer to the table to start searching from.
*
* @param AcpiTable
* Supplies a pointer to memory area where ACPI table address will be stored, or NULL if not found.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
AcGetAcpiTable(IN CONST UINT Signature,
IN PVOID PreviousTable,
OUT PVOID *AcpiTable)
{
PACPI_DESCRIPTION_HEADER TableHeader;
SIZE_T RsdtIndex, TableIndex;
EFI_STATUS Status;
SIZE_T TableCount;
PACPI_RSDP Rsdp;
PACPI_RSDT Rsdt;
BOOLEAN Xsdp;
/* Return NULL address by default if requested table not found */
*AcpiTable = NULL;
/* Get Root System Description Table Pointer */
Status = AcGetAcpiDescriptionPointer((PVOID)&Rsdp);
if(Status != STATUS_EFI_SUCCESS)
{
/* ACPI tables not found, return error */
return Status;
}
/* Check if it is XSDP (ACPI 2.0) or RSDP (ACPI 1.0) */
if(Rsdp->Revision >= 2 && Rsdp->XsdtAddress)
{
/* XSDP (ACPI 2.0) */
Xsdp = TRUE;
Rsdt = (PACPI_RSDT)(UINT_PTR)Rsdp->XsdtAddress;
TableCount = (Rsdt->Header.Length - sizeof(ACPI_DESCRIPTION_HEADER)) / 8;
}
else
{
/* RSDP (ACPI 1.0) */
Xsdp = FALSE;
Rsdt = (PACPI_RSDT)(UINT_PTR)Rsdp->RsdtAddress;
TableCount = (Rsdt->Header.Length - sizeof(ACPI_DESCRIPTION_HEADER)) / 4;
}
/* Iterate over all ACPI tables */
for(TableIndex = 0; TableIndex < TableCount; TableIndex++)
{
/* Get table headers in reverse order */
RsdtIndex = TableCount - TableIndex - 1;
/* Check if XSDP or RSDT is used */
if(Xsdp)
{
/* Get table header from XSDT */
TableHeader = (PACPI_DESCRIPTION_HEADER)(ULONG_PTR)((PULONGLONG)Rsdt->Tables)[RsdtIndex];
}
else
{
/* Get table header from RSDT */
TableHeader = (PACPI_DESCRIPTION_HEADER)(ULONG_PTR)((PULONG)Rsdt->Tables)[RsdtIndex];
}
/* Check if previous table provided */
if(PreviousTable != NULL)
{
/* Check if this is a table previously found */
if(TableHeader == (PVOID)PreviousTable)
{
/* Unset previous table */
PreviousTable = NULL;
}
/* Skip to next ACPI table */
continue;
}
/* Verify table signature */
if((TableHeader->Signature == Signature))
{
/* Found requested ACPI table */
break;
}
}
/* Make sure table was found */
if(TableHeader->Signature != Signature)
{
/* ACPI table not found, return error */
return STATUS_EFI_NOT_FOUND;
}
/* Don't validate FADT on old, broken firmwares with ACPI 2.0 or older */
if(TableHeader->Signature != ACPI_FADT_SIGNATURE || TableHeader->Revision > 2)
{
/* Validate table checksum */
if(!AcpValidateAcpiTable(TableHeader, TableHeader->Length))
{
/* Checksum mismatch, return error */
return STATUS_EFI_CRC_ERROR;
}
}
/* Found valid ACPI table, return success */
*AcpiTable = TableHeader;
return STATUS_EFI_SUCCESS;
}
/** /**
* Gets the Advanced Programmable Interrupt Controller (APIC) base address. * Gets the Advanced Programmable Interrupt Controller (APIC) base address.
* *
@@ -65,19 +185,17 @@ XTCDECL
EFI_STATUS EFI_STATUS
AcGetApicBase(OUT PVOID *ApicBase) AcGetApicBase(OUT PVOID *ApicBase)
{ {
PCPUID_REGISTERS CpuRegisters = NULL; CPUID_REGISTERS CpuRegisters;
/* Get CPU features list */ /* Prepare CPUID registers to query for APIC support */
CpuRegisters->Leaf = CPUID_GET_CPU_FEATURES; RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters->SubLeaf = 0; CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
CpuRegisters->Eax = 0;
CpuRegisters->Ebx = 0; /* Query CPUID */
CpuRegisters->Ecx = 0; ArCpuId(&CpuRegisters);
CpuRegisters->Edx = 0;
ArCpuId(CpuRegisters);
/* Check if APIC present */ /* Check if APIC present */
if((CpuRegisters->Edx & CPUID_FEATURES_EDX_APIC) == 0) if((CpuRegisters.Edx & CPUID_FEATURES_EDX_APIC) == 0)
{ {
/* APIC is not supported by the CPU */ /* APIC is not supported by the CPU */
return STATUS_EFI_UNSUPPORTED; return STATUS_EFI_UNSUPPORTED;
@@ -110,7 +228,7 @@ AcGetRsdpTable(OUT PVOID *AcpiTable)
/* Get RSDP (ACPI 1.0) table from system configuration tables */ /* Get RSDP (ACPI 1.0) table from system configuration tables */
Status = XtLdrProtocol->Util.GetConfigurationTable(&AcpiGuid, &RsdpTable); Status = XtLdrProtocol->Util.GetConfigurationTable(&AcpiGuid, &RsdpTable);
if(Status != STATUS_EFI_SUCCESS || AcpChecksumTable(RsdpTable, 20) != 0) if(Status != STATUS_EFI_SUCCESS || !AcpValidateAcpiTable(RsdpTable, 20))
{ {
/* RSDP not found or checksum mismatch */ /* RSDP not found or checksum mismatch */
*AcpiTable = NULL; *AcpiTable = NULL;
@@ -142,7 +260,7 @@ AcGetSMBiosTable(OUT PVOID *SmBiosTable)
/* Get SMBIOS table from system configuration tables */ /* Get SMBIOS table from system configuration tables */
Status = XtLdrProtocol->Util.GetConfigurationTable(&SmBiosGuid, (PVOID)&SmBios); Status = XtLdrProtocol->Util.GetConfigurationTable(&SmBiosGuid, (PVOID)&SmBios);
if(Status != STATUS_EFI_SUCCESS || AcpChecksumTable(SmBios, SmBios->Length) != 0) if(Status != STATUS_EFI_SUCCESS || !AcpValidateAcpiTable(SmBios, SmBios->Length))
{ {
/* SMBIOS not found or checksum mismatch */ /* SMBIOS not found or checksum mismatch */
*SmBiosTable = NULL; *SmBiosTable = NULL;
@@ -174,7 +292,7 @@ AcGetSMBios3Table(OUT PVOID *SmBiosTable)
/* Get SMBIOS3 table from system configuration tables */ /* Get SMBIOS3 table from system configuration tables */
Status = XtLdrProtocol->Util.GetConfigurationTable(&SmBios3Guid, (PVOID)&SmBios); Status = XtLdrProtocol->Util.GetConfigurationTable(&SmBios3Guid, (PVOID)&SmBios);
if(Status != STATUS_EFI_SUCCESS || AcpChecksumTable(SmBios, SmBios->Length) != 0) if(Status != STATUS_EFI_SUCCESS || !AcpValidateAcpiTable(SmBios, SmBios->Length))
{ {
/* SMBIOS3 not found or checksum mismatch */ /* SMBIOS3 not found or checksum mismatch */
*SmBiosTable = NULL; *SmBiosTable = NULL;
@@ -206,7 +324,7 @@ AcGetXsdpTable(OUT PVOID *AcpiTable)
/* Get XSDP (ACPI 2.0) from system configuration tables */ /* Get XSDP (ACPI 2.0) from system configuration tables */
Status = XtLdrProtocol->Util.GetConfigurationTable(&AcpiGuid, &XsdpTable); Status = XtLdrProtocol->Util.GetConfigurationTable(&AcpiGuid, &XsdpTable);
if(Status != STATUS_EFI_SUCCESS || AcpChecksumTable(XsdpTable, 36) != 0) if(Status != STATUS_EFI_SUCCESS || !AcpValidateAcpiTable(XsdpTable, 36))
{ {
/* XSDP not found or checksum mismatch */ /* XSDP not found or checksum mismatch */
*AcpiTable = NULL; *AcpiTable = NULL;
@@ -219,7 +337,7 @@ AcGetXsdpTable(OUT PVOID *AcpiTable)
} }
/** /**
* Checksums a given ACPI table. * Validates given ACPI table by calculating its checksum.
* *
* @param Buffer * @param Buffer
* Supplies a pointer to the table to checksum. * Supplies a pointer to the table to checksum.
@@ -227,11 +345,13 @@ AcGetXsdpTable(OUT PVOID *AcpiTable)
* @param Size * @param Size
* Supplies the size of the table, in bytes. * Supplies the size of the table, in bytes.
* *
* @return This routine returns the calculated checksum. * @return This routine returns TRUE if the table is valid, or FALSE otherwise.
*
* @since XT 1.0
*/ */
XTCDECL XTCDECL
UCHAR BOOLEAN
AcpChecksumTable(IN PVOID Buffer, AcpValidateAcpiTable(IN PVOID Buffer,
IN UINT_PTR Size) IN UINT_PTR Size)
{ {
PUCHAR Pointer; PUCHAR Pointer;
@@ -250,7 +370,7 @@ AcpChecksumTable(IN PVOID Buffer,
} }
/* Return calculated checksum */ /* Return calculated checksum */
return Sum; return (Sum == 0) ? TRUE : FALSE;
} }
/** /**
@@ -284,6 +404,7 @@ XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
/* Set routines available via ACPI protocol */ /* Set routines available via ACPI protocol */
AcpAcpiProtocol.GetAcpiDescriptionPointer = AcGetAcpiDescriptionPointer; AcpAcpiProtocol.GetAcpiDescriptionPointer = AcGetAcpiDescriptionPointer;
AcpAcpiProtocol.GetAcpiTable = AcGetAcpiTable;
AcpAcpiProtocol.GetApicBase = AcGetApicBase; AcpAcpiProtocol.GetApicBase = AcGetApicBase;
AcpAcpiProtocol.GetRsdpTable = AcGetRsdpTable; AcpAcpiProtocol.GetRsdpTable = AcGetRsdpTable;
AcpAcpiProtocol.GetSMBiosTable = AcGetSMBiosTable; AcpAcpiProtocol.GetSMBiosTable = AcGetSMBiosTable;

View File

@@ -18,6 +18,12 @@ XTCDECL
EFI_STATUS EFI_STATUS
AcGetAcpiDescriptionPointer(OUT PVOID *AcpiTable); AcGetAcpiDescriptionPointer(OUT PVOID *AcpiTable);
XTCDECL
EFI_STATUS
AcGetAcpiTable(IN CONST UINT Signature,
IN PVOID PreviousTable,
OUT PVOID *AcpiTable);
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
AcGetApicBase(OUT PVOID *ApicBase); AcGetApicBase(OUT PVOID *ApicBase);
@@ -39,8 +45,8 @@ EFI_STATUS
AcGetXsdpTable(OUT PVOID *AcpiTable); AcGetXsdpTable(OUT PVOID *AcpiTable);
XTCDECL XTCDECL
UCHAR BOOLEAN
AcpChecksumTable(IN PVOID Buffer, AcpValidateAcpiTable(IN PVOID Buffer,
IN UINT_PTR Size); IN UINT_PTR Size);
XTCDECL XTCDECL

View File

@@ -196,6 +196,7 @@ XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable) IN PEFI_SYSTEM_TABLE SystemTable)
{ {
EFI_STATUS Status; EFI_STATUS Status;
PWCHAR Tune;
/* Open the XTLDR protocol */ /* Open the XTLDR protocol */
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol); Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
@@ -206,7 +207,8 @@ XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
} }
/* Play the tune set in the configuration */ /* Play the tune set in the configuration */
BpPlayTune(XtLdrProtocol->Config.GetValue(L"TUNE")); XtLdrProtocol->Config.GetValue(L"TUNE", &Tune);
BpPlayTune(Tune);
/* Return success */ /* Return success */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;

View File

@@ -47,7 +47,7 @@ ChBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
} }
/* Open EFI volume */ /* Open EFI volume */
Status = XtLdrProtocol->Disk.OpenVolume(NULL, &DiskHandle, &FsHandle); Status = XtLdrProtocol->Disk.OpenVolume(Parameters->DevicePath, &DiskHandle, &FsHandle);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to open a volume, return error code */ /* Failed to open a volume, return error code */

View File

@@ -524,8 +524,8 @@ FbpFindFramebufferAddress(OUT PEFI_PHYSICAL_ADDRESS Address)
* @param PixelBitMask * @param PixelBitMask
* Provides a pixel bit mask. * Provides a pixel bit mask.
* *
* @param ColorMask * @param ColorSize
* Supplies a pointer to the memory area where the color mask will be stored. * Supplies a pointer to the memory area where the color size will be stored.
* *
* @param ColorShift * @param ColorShift
* Supplies a pointer to the memory area where the color shift (position) will be stored. * Supplies a pointer to the memory area where the color shift (position) will be stored.
@@ -537,34 +537,37 @@ FbpFindFramebufferAddress(OUT PEFI_PHYSICAL_ADDRESS Address)
XTCDECL XTCDECL
VOID VOID
FbpGetColorMask(IN UINT PixelBitMask, FbpGetColorMask(IN UINT PixelBitMask,
OUT PUSHORT ColorMask, OUT PUSHORT ColorSize,
OUT PUSHORT ColorShift) OUT PUSHORT ColorShift)
{ {
UINT Index, Mask; UINT Shift, Size;
/* Initialize variables */ /* Initialize variables */
Index = 0; Shift = 0;
Mask = 1; Size = 0;
/* Make sure EfiMask is not zero */ /* Make sure EfiMask is not zero */
if(PixelBitMask) if(PixelBitMask)
{ {
while((Index < 32) && ((PixelBitMask & Mask) == 0)) /* Get color shift */
while((PixelBitMask & 1) == 0)
{ {
Index++; Shift++;
Mask <<= 1; PixelBitMask >>= 1;
}
/* Get color size */
while((PixelBitMask & 1) == 1)
{
Size++;
PixelBitMask >>= 1;
}
} }
/* Set color mask and shift */ /* Set color mask and shift */
*ColorShift = Index; *ColorShift = Shift;
*ColorMask = (Mask >> Index); *ColorSize = Size;
}
else
{
/* Set default color mask and shift */
*ColorMask = 0;
*ColorShift = 0;
}
} }
/** /**
@@ -672,26 +675,26 @@ FbpGetPixelInformation(IN PEFI_PIXEL_BITMASK PixelsBitMask)
case PixelBlueGreenRedReserved8BitPerColor: case PixelBlueGreenRedReserved8BitPerColor:
/* BGRR, 32 bits per pixel */ /* BGRR, 32 bits per pixel */
FbpDisplayInfo.ModeInfo.BitsPerPixel = 32; FbpDisplayInfo.ModeInfo.BitsPerPixel = 32;
FbpDisplayInfo.ModeInfo.PixelInformation.BlueMask = 0xFF;
FbpDisplayInfo.ModeInfo.PixelInformation.BlueShift = 0; FbpDisplayInfo.ModeInfo.PixelInformation.BlueShift = 0;
FbpDisplayInfo.ModeInfo.PixelInformation.GreenMask = 0xFF; FbpDisplayInfo.ModeInfo.PixelInformation.BlueSize = 8;
FbpDisplayInfo.ModeInfo.PixelInformation.GreenShift = 8; FbpDisplayInfo.ModeInfo.PixelInformation.GreenShift = 8;
FbpDisplayInfo.ModeInfo.PixelInformation.RedMask = 0xFF; FbpDisplayInfo.ModeInfo.PixelInformation.GreenSize = 8;
FbpDisplayInfo.ModeInfo.PixelInformation.RedShift = 16; FbpDisplayInfo.ModeInfo.PixelInformation.RedShift = 16;
FbpDisplayInfo.ModeInfo.PixelInformation.ReservedMask = 0xFF; FbpDisplayInfo.ModeInfo.PixelInformation.RedSize = 8;
FbpDisplayInfo.ModeInfo.PixelInformation.ReservedShift = 24; FbpDisplayInfo.ModeInfo.PixelInformation.ReservedShift = 24;
FbpDisplayInfo.ModeInfo.PixelInformation.ReservedSize = 8;
break; break;
case PixelRedGreenBlueReserved8BitPerColor: case PixelRedGreenBlueReserved8BitPerColor:
/* RGBR, 32 bits per pixel */ /* RGBR, 32 bits per pixel */
FbpDisplayInfo.ModeInfo.BitsPerPixel = 32; FbpDisplayInfo.ModeInfo.BitsPerPixel = 32;
FbpDisplayInfo.ModeInfo.PixelInformation.BlueMask = 0xFF;
FbpDisplayInfo.ModeInfo.PixelInformation.BlueShift = 16; FbpDisplayInfo.ModeInfo.PixelInformation.BlueShift = 16;
FbpDisplayInfo.ModeInfo.PixelInformation.GreenMask = 0xFF; FbpDisplayInfo.ModeInfo.PixelInformation.BlueSize = 8;
FbpDisplayInfo.ModeInfo.PixelInformation.GreenShift = 8; FbpDisplayInfo.ModeInfo.PixelInformation.GreenShift = 8;
FbpDisplayInfo.ModeInfo.PixelInformation.RedMask = 0xFF; FbpDisplayInfo.ModeInfo.PixelInformation.GreenSize = 8;
FbpDisplayInfo.ModeInfo.PixelInformation.RedShift = 0; FbpDisplayInfo.ModeInfo.PixelInformation.RedShift = 0;
FbpDisplayInfo.ModeInfo.PixelInformation.ReservedMask = 0xFF; FbpDisplayInfo.ModeInfo.PixelInformation.RedSize = 8;
FbpDisplayInfo.ModeInfo.PixelInformation.ReservedShift = 24; FbpDisplayInfo.ModeInfo.PixelInformation.ReservedShift = 24;
FbpDisplayInfo.ModeInfo.PixelInformation.ReservedSize = 8;
break; break;
case PixelBitMask: case PixelBitMask:
/* Assume 32 bits per pixel */ /* Assume 32 bits per pixel */
@@ -711,26 +714,26 @@ FbpGetPixelInformation(IN PEFI_PIXEL_BITMASK PixelsBitMask)
} }
/* Set pixel information */ /* Set pixel information */
FbpGetColorMask(PixelsBitMask->RedMask, &FbpDisplayInfo.ModeInfo.PixelInformation.RedMask, FbpGetColorMask(PixelsBitMask->RedMask, &FbpDisplayInfo.ModeInfo.PixelInformation.RedSize,
&FbpDisplayInfo.ModeInfo.PixelInformation.RedShift); &FbpDisplayInfo.ModeInfo.PixelInformation.RedShift);
FbpGetColorMask(PixelsBitMask->GreenMask, &FbpDisplayInfo.ModeInfo.PixelInformation.GreenMask, FbpGetColorMask(PixelsBitMask->GreenMask, &FbpDisplayInfo.ModeInfo.PixelInformation.GreenSize,
&FbpDisplayInfo.ModeInfo.PixelInformation.GreenShift); &FbpDisplayInfo.ModeInfo.PixelInformation.GreenShift);
FbpGetColorMask(PixelsBitMask->BlueMask, &FbpDisplayInfo.ModeInfo.PixelInformation.BlueMask, FbpGetColorMask(PixelsBitMask->BlueMask, &FbpDisplayInfo.ModeInfo.PixelInformation.BlueSize,
&FbpDisplayInfo.ModeInfo.PixelInformation.BlueShift); &FbpDisplayInfo.ModeInfo.PixelInformation.BlueShift);
FbpGetColorMask(PixelsBitMask->ReservedMask, &FbpDisplayInfo.ModeInfo.PixelInformation.ReservedMask, FbpGetColorMask(PixelsBitMask->ReservedMask, &FbpDisplayInfo.ModeInfo.PixelInformation.ReservedSize,
&FbpDisplayInfo.ModeInfo.PixelInformation.ReservedShift); &FbpDisplayInfo.ModeInfo.PixelInformation.ReservedShift);
break; break;
default: default:
/* Unknown pixel format */ /* Unknown pixel format */
FbpDisplayInfo.ModeInfo.BitsPerPixel = 0; FbpDisplayInfo.ModeInfo.BitsPerPixel = 0;
FbpDisplayInfo.ModeInfo.PixelInformation.BlueMask = 0x0;
FbpDisplayInfo.ModeInfo.PixelInformation.BlueShift = 0; FbpDisplayInfo.ModeInfo.PixelInformation.BlueShift = 0;
FbpDisplayInfo.ModeInfo.PixelInformation.GreenMask = 0x0; FbpDisplayInfo.ModeInfo.PixelInformation.BlueSize = 0;
FbpDisplayInfo.ModeInfo.PixelInformation.GreenShift = 0; FbpDisplayInfo.ModeInfo.PixelInformation.GreenShift = 0;
FbpDisplayInfo.ModeInfo.PixelInformation.RedMask = 0x0; FbpDisplayInfo.ModeInfo.PixelInformation.GreenSize = 0;
FbpDisplayInfo.ModeInfo.PixelInformation.RedShift = 0; FbpDisplayInfo.ModeInfo.PixelInformation.RedShift = 0;
FbpDisplayInfo.ModeInfo.PixelInformation.ReservedMask = 0x0; FbpDisplayInfo.ModeInfo.PixelInformation.RedSize = 0;
FbpDisplayInfo.ModeInfo.PixelInformation.ReservedShift = 0; FbpDisplayInfo.ModeInfo.PixelInformation.ReservedShift = 0;
FbpDisplayInfo.ModeInfo.PixelInformation.ReservedSize = 0;
break; break;
} }

View File

@@ -45,7 +45,7 @@ FbpFindFramebufferAddress(OUT PEFI_PHYSICAL_ADDRESS Address);
XTCDECL XTCDECL
VOID VOID
FbpGetColorMask(IN UINT EfiMask, FbpGetColorMask(IN UINT EfiMask,
OUT PUSHORT ColorMask, OUT PUSHORT ColorSize,
OUT PUSHORT ColorShift); OUT PUSHORT ColorShift);
XTCDECL XTCDECL

View File

@@ -409,7 +409,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
Pages = EFI_SIZE_TO_PAGES(ImageData->FileSize); Pages = EFI_SIZE_TO_PAGES(ImageData->FileSize);
/* Allocate pages */ /* Allocate pages */
Status = XtLdrProtocol->Memory.AllocatePages(Pages, &Address); Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, Pages, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Pages allocation failure */ /* Pages allocation failure */
@@ -472,7 +472,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
ImageData->ImagePages = EFI_SIZE_TO_PAGES(ImageData->ImageSize); ImageData->ImagePages = EFI_SIZE_TO_PAGES(ImageData->ImageSize);
/* Allocate image pages */ /* Allocate image pages */
Status = XtLdrProtocol->Memory.AllocatePages(ImageData->ImagePages, &Address); Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, ImageData->ImagePages, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Pages reallocation failure */ /* Pages reallocation failure */

View File

@@ -4,25 +4,204 @@
* FILE: xtldr/amd64/memory.c * FILE: xtldr/amd64/memory.c
* DESCRIPTION: EFI memory management for AMD64 target * DESCRIPTION: EFI memory management for AMD64 target
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/ */
#include <xtos.h> #include <xtos.h>
/**
* Determines the appropriate paging level (PML) for the AMD64 architecture.
*
* @param Parameters
* A pointer to the wide character string containing the kernel boot parameters.
*
* @return This routine returns the appropriate page map level (5 if LA57 is enabled, 4 otherwise).
*
* @since XT 1.0
*/
XTCDECL
ULONG
XtpDeterminePagingLevel(IN CONST PWCHAR Parameters)
{
CPUID_REGISTERS CpuRegisters;
/* Prepare CPUID registers to query for STD7 features */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
/* Query CPUID */
ArCpuId(&CpuRegisters);
/* Verify if the CPU supports the STD7 feature leaf (0x00000007) */
if(CpuRegisters.Eax >= CPUID_GET_STANDARD7_FEATURES)
{
/* Prepare CPUID registers to query for LA57 support */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_STANDARD7_FEATURES;
/* Query CPUID */
ArCpuId(&CpuRegisters);
/* Check if eXtended Physical Addressing (XPA) is enabled and if LA57 is supported by the CPU */
if((CpuRegisters.Ecx & CPUID_FEATURES_ECX_LA57) &&
!(XtLdrProtocol->BootUtil.GetBooleanParameter(Parameters, L"NOXPA")))
{
/* Enable LA57 (PML5) */
return 5;
}
}
/* Disable LA57 and use PML4 by default */
return 4;
}
/**
* Maps the page table for hardware layer addess space.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
{
PHARDWARE_PTE P5eBase, PdeBase, PpeBase, PxeBase;
EFI_PHYSICAL_ADDRESS Address;
EFI_STATUS Status;
if(PageMap->PageMapLevel == 5)
{
/* Get P5E (PML5) base address */
P5eBase = (PHARDWARE_PTE)PageMap->PtePointer;
/* Check if P5E entry already exists */
if(!P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].Valid)
{
/* No valid P5E, allocate memory */
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, return error */
return Status;
}
/* Zero fill memory used by P5E */
RtlZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
/* Make P5E valid */
P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].Valid = 1;
P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].PageFrameNumber = Address / EFI_PAGE_SIZE;
P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].Writable = 1;
/* Set PXE base address */
PxeBase = (PHARDWARE_PTE)(UINT_PTR)Address;
}
else
{
/* Set PXE base address based on existing P5E */
PxeBase = (PHARDWARE_PTE)((P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].PageFrameNumber) << EFI_PAGE_SHIFT);
}
}
else
{
/* Get PXE (PML4) base address */
PxeBase = (PHARDWARE_PTE)PageMap->PtePointer;
}
/* Check if PXE entry already exists */
if(!PxeBase[(MM_HARDWARE_VA_START >> MM_PXI_SHIFT) & 0x1FF].Valid)
{
/* No valid PXE, allocate memory */
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, return error */
return Status;
}
/* Zero fill memory used by PXE */
RtlZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
/* Make PXE valid */
PxeBase[(MM_HARDWARE_VA_START >> MM_PXI_SHIFT) & 0x1FF].Valid = 1;
PxeBase[(MM_HARDWARE_VA_START >> MM_PXI_SHIFT) & 0x1FF].PageFrameNumber = Address / EFI_PAGE_SIZE;
PxeBase[(MM_HARDWARE_VA_START >> MM_PXI_SHIFT) & 0x1FF].Writable = 1;
/* Set PPE base address */
PpeBase = (PHARDWARE_PTE)(UINT_PTR)Address;
}
else
{
/* Set PPE base address based on existing PXE */
PpeBase = (PHARDWARE_PTE)((PxeBase[(MM_HARDWARE_VA_START >> MM_PXI_SHIFT) & 0x1FF].PageFrameNumber) << EFI_PAGE_SHIFT);
}
/* Check if PPE entry already exists */
if(!PpeBase[(MM_HARDWARE_VA_START >> MM_PPI_SHIFT) & 0x1FF].Valid)
{
/* No valid PPE, allocate memory */
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, return error */
return Status;
}
/* Zero fill memory used by PPE */
RtlZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
/* Make PPE valid */
PpeBase[(MM_HARDWARE_VA_START >> MM_PPI_SHIFT) & 0x1FF].Valid = 1;
PpeBase[(MM_HARDWARE_VA_START >> MM_PPI_SHIFT) & 0x1FF].PageFrameNumber = Address / EFI_PAGE_SIZE;
PpeBase[(MM_HARDWARE_VA_START >> MM_PPI_SHIFT) & 0x1FF].Writable = 1;
/* Set PDE base address */
PdeBase = (PHARDWARE_PTE)Address;
}
else
{
/* Set PDE base address, based on existing PPE */
PdeBase = (PHARDWARE_PTE)((PpeBase[(MM_HARDWARE_VA_START >> MM_PPI_SHIFT) & 0x1FF].PageFrameNumber) << EFI_PAGE_SHIFT);
}
/* Loop through 2 PDE entries */
for(UINT Index = 0 ; Index < 2 ; Index++)
{
/* Check if PDE entry already exists */
if(!PdeBase[((MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF) + Index].Valid)
{
/* No valid PDE, allocate memory */
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, return error */
return Status;
}
/* Zero fill memory used by PDE */
RtlZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
/* Make PDE valid */
PdeBase[((MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF) + Index].Valid = 1;
PdeBase[((MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF) + Index].PageFrameNumber = Address / EFI_PAGE_SIZE;
PdeBase[((MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF) + Index].Writable = 1;
}
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
/** /**
* Builds the actual memory mapping page table and enables paging. This routine exits EFI boot services as well. * Builds the actual memory mapping page table and enables paging. This routine exits EFI boot services as well.
* *
* @param MemoryMappings * @param PageMap
* Supplies a pointer to linked list containing all memory mappings. * Supplies a pointer to the page mapping structure.
*
* @param VirtualAddress
* Supplies a pointer to the next valid, free and available virtual address.
*
* @param ImageProtocol
* A pointer to the EFI loaded image protocol with information about where in memory the loader code was placed.
*
* @param PtePointer
* Supplies a pointer to memory area containing a Page Table Entries (PTE).
* *
* @return This routine returns a status code. * @return This routine returns a status code.
* *
@@ -33,9 +212,12 @@ EFI_STATUS
XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap) XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS TrampolineAddress;
PXT_TRAMPOLINE_ENTRY TrampolineEntry;
ULONG_PTR TrampolineSize;
/* Build page map */ /* Build page map */
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, 0xFFFFF6FB7DBED000); Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, (PageMap->PageMapLevel > 4) ? MM_P5E_LA57_BASE : MM_PXE_BASE);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to build page map */ /* Failed to build page map */
@@ -43,6 +225,38 @@ XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
return Status; return Status;
} }
/* Map memory for hardware layer */
Status = XtpMapHardwareMemoryPool(PageMap);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to map memory for hardware layer */
XtLdrProtocol->Debug.Print(L"Failed to map memory for hardware leyer (Status code: %zX)\n", Status);
return Status;
}
/* Check the configured page map level to set the LA57 state accordingly */
if(PageMap->PageMapLevel == 5)
{
/* Set the address of the trampoline code below 1MB */
TrampolineAddress = MM_TRAMPOLINE_ADDRESS;
/* Calculate the size of the trampoline code */
TrampolineSize = (ULONG_PTR)ArEnableExtendedPhysicalAddressingEnd - (ULONG_PTR)ArEnableExtendedPhysicalAddressing;
/* Allocate pages for the trampoline */
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAddress, EFI_SIZE_TO_PAGES(TrampolineSize), &TrampolineAddress);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to allocate memory for trampoline code */
XtLdrProtocol->Debug.Print(L"Failed to allocate memory for trampoline code (Status code: %zX)\n", Status);
return Status;
}
/* Set the trampoline entry point and copy its code into the allocated buffer */
TrampolineEntry = (PXT_TRAMPOLINE_ENTRY)(UINT_PTR)TrampolineAddress;
RtlCopyMemory(TrampolineEntry, ArEnableExtendedPhysicalAddressing, TrampolineSize);
}
/* Exit EFI Boot Services */ /* Exit EFI Boot Services */
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n"); XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
Status = XtLdrProtocol->Util.ExitBootServices(); Status = XtLdrProtocol->Util.ExitBootServices();
@@ -53,8 +267,24 @@ XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
return STATUS_EFI_ABORTED; return STATUS_EFI_ABORTED;
} }
/* Write PML4 to CR3 */ /* Check the configured page map level to set the LA57 state accordingly */
if(PageMap->PageMapLevel == 5)
{
/* Enable Linear Address 57-bit (LA57) extension */
XtLdrProtocol->Debug.Print(L"Enabling Linear Address 57-bit (LA57)\n");
/* Execute the trampoline to enable LA57 and write PML5 to CR3 */
TrampolineEntry((UINT64)PageMap->PtePointer);
}
else
{
/* Disable Linear Address 57-bit (LA57) extension */
XtLdrProtocol->Debug.Print(L"Disabling Linear Address 57-bit (LA57)\n");
/* Write PML4 to CR3 and enable paging */
ArWriteControlRegister(3, (UINT_PTR)PageMap->PtePointer); ArWriteControlRegister(3, (UINT_PTR)PageMap->PtePointer);
ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_PG);
}
/* Return success */ /* Return success */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;

View File

@@ -9,20 +9,111 @@
#include <xtos.h> #include <xtos.h>
/**
* Determines the appropriate paging level (PML) for the i686 architecture.
*
* @param Parameters
* A pointer to the wide character string containing the kernel boot parameters.
*
* @return This routine returns the appropriate page map level (3 if PAE is enabled, 2 otherwise).
*
* @since XT 1.0
*/
XTCDECL
ULONG
XtpDeterminePagingLevel(IN CONST PWCHAR Parameters)
{
CPUID_REGISTERS CpuRegisters;
/* Prepare CPUID registers to query for PAE support */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
/* Query CPUID */
ArCpuId(&CpuRegisters);
/* Check if eXtended Physical Addressing (XPA) is enabled and if PAE is supported by the CPU */
if((CpuRegisters.Edx & CPUID_FEATURES_EDX_PAE) &&
!(XtLdrProtocol->BootUtil.GetBooleanParameter(Parameters, L"NOXPA")))
{
/* Enable PAE (PML3) */
return 3;
}
/* Disable PAE and use PML2 by default */
return 2;
}
/**
* Maps the page table for hardware layer addess space.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
{
EFI_PHYSICAL_ADDRESS Address;
PHARDWARE_LEGACY_PTE LegacyPdeBase;
PHARDWARE_MODERN_PTE PdeBase;
EFI_STATUS Status;
/* Allocate memory */
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, return error */
return Status;
}
/* Zero fill allocated memory */
RtlZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
/* Check if PAE is enabled (3-level paging) */
if(PageMap->PageMapLevel == 3)
{
/* Get PDE base address (PAE enabled) */
PdeBase = (PHARDWARE_MODERN_PTE)(((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[MM_HARDWARE_VA_START >> MM_PPI_SHIFT].PageFrameNumber << MM_PAGE_SHIFT);
/* Make PDE valid */
RtlZeroMemory(&PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF], sizeof(HARDWARE_MODERN_PTE));
PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF].PageFrameNumber = Address >> MM_PAGE_SHIFT;
PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF].Valid = 1;
PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF].Writable = 1;
}
else
{
/* Get PDE base address (PAE disabled) */
LegacyPdeBase = (PHARDWARE_LEGACY_PTE)PageMap->PtePointer;
/* Check for a conflicting PDE */
if(LegacyPdeBase[MM_HARDWARE_VA_START >> MM_PDI_LEGACY_SHIFT].Valid)
{
/* PDE already exists and is valid, nothing to do */
return STATUS_EFI_SUCCESS;
}
/* Make PDE valid */
RtlZeroMemory(&LegacyPdeBase[MM_HARDWARE_VA_START >> MM_PDI_LEGACY_SHIFT], sizeof(HARDWARE_LEGACY_PTE));
LegacyPdeBase[MM_HARDWARE_VA_START >> MM_PDI_LEGACY_SHIFT].Valid = 1;
LegacyPdeBase[MM_HARDWARE_VA_START >> MM_PDI_LEGACY_SHIFT].PageFrameNumber = Address >> MM_PAGE_SHIFT;
LegacyPdeBase[MM_HARDWARE_VA_START >> MM_PDI_LEGACY_SHIFT].Writable = 1;
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
/** /**
* Builds the actual memory mapping page table and enables paging. This routine exits EFI boot services as well. * Builds the actual memory mapping page table and enables paging. This routine exits EFI boot services as well.
* *
* @param MemoryMappings * @param PageMap
* Supplies a pointer to linked list containing all memory mappings. * Supplies a pointer to the page mapping structure.
*
* @param VirtualAddress
* Supplies a pointer to the next valid, free and available virtual address.
*
* @param ImageProtocol
* A pointer to the EFI loaded image protocol with information about where in memory the loader code was placed.
*
* @param PtePointer
* Supplies a pointer to memory area containing a Page Table Entries (PTE).
* *
* @return This routine returns a status code. * @return This routine returns a status code.
* *
@@ -32,30 +123,10 @@ XTCDECL
EFI_STATUS EFI_STATUS
XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap) XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
{ {
PCPUID_REGISTERS CpuRegisters = NULL;
EFI_STATUS Status; EFI_STATUS Status;
/* Prepare CPUID registers */
CpuRegisters->Leaf = CPUID_GET_CPU_FEATURES;
CpuRegisters->SubLeaf = 0;
CpuRegisters->Eax = 0;
CpuRegisters->Ebx = 0;
CpuRegisters->Ecx = 0;
CpuRegisters->Edx = 0;
/* Get CPUID */
ArCpuId(CpuRegisters);
/* Store PAE status from the CPUID results */
if(!(CpuRegisters->Edx & CPUID_FEATURES_EDX_PAE))
{
/* No PAE support */
XtLdrProtocol->Debug.Print(L"ERROR: PAE extension not supported by the CPU\n");
return STATUS_EFI_UNSUPPORTED;
}
/* Build page map */ /* Build page map */
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, 0xC0000000); Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, MM_PTE_BASE);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to build page map */ /* Failed to build page map */
@@ -63,6 +134,15 @@ XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
return Status; return Status;
} }
/* Map memory for hardware layer */
Status = XtpMapHardwareMemoryPool(PageMap);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to map memory for hardware layer */
XtLdrProtocol->Debug.Print(L"Failed to map memory for hardware layer (Status code: %zX)\n", Status);
return Status;
}
/* Exit EFI Boot Services */ /* Exit EFI Boot Services */
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n"); XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
Status = XtLdrProtocol->Util.ExitBootServices(); Status = XtLdrProtocol->Util.ExitBootServices();
@@ -73,8 +153,22 @@ XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
return STATUS_EFI_ABORTED; return STATUS_EFI_ABORTED;
} }
/* Disable paging */
ArWriteControlRegister(0, ArReadControlRegister(0) & ~CR0_PG);
/* Check the configured page map level to set the PAE state accordingly */
if(PageMap->PageMapLevel == 3)
{
/* Enable Physical Address Extension (PAE) */ /* Enable Physical Address Extension (PAE) */
XtLdrProtocol->Debug.Print(L"Enabling Physical Address Extension (PAE)\n");
ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_PAE); ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_PAE);
}
else
{
/* Disable Physical Address Extension (PAE) */
XtLdrProtocol->Debug.Print(L"Disabling Physical Address Extension (PAE)\n");
ArWriteControlRegister(4, ArReadControlRegister(4) & ~CR4_PAE);
}
/* Write page mappings to CR3 */ /* Write page mappings to CR3 */
ArWriteControlRegister(3, (UINT_PTR)PageMap->PtePointer); ArWriteControlRegister(3, (UINT_PTR)PageMap->PtePointer);

View File

@@ -29,9 +29,15 @@ typedef struct _XT_FRAMEBUFFER_PROTOCOL
/* EFI XT Loader Protocol */ /* EFI XT Loader Protocol */
EXTERN PXTBL_LOADER_PROTOCOL XtLdrProtocol; EXTERN PXTBL_LOADER_PROTOCOL XtLdrProtocol;
/* XTOS trampoline end address to calculate trampoline size */
EXTERN PVOID ArEnableExtendedPhysicalAddressingEnd[];
/* XTOS kernel entry point */ /* XTOS kernel entry point */
typedef VOID (XTAPI *PXT_ENTRY_POINT)(IN PKERNEL_INITIALIZATION_BLOCK BootParameters); typedef VOID (XTAPI *PXT_ENTRY_POINT)(IN PKERNEL_INITIALIZATION_BLOCK BootParameters);
/* XTOS trampoline entry point */
typedef VOID (*PXT_TRAMPOLINE_ENTRY)(UINT64 PageMap);
/* XTOS boot protocol related routines forward references */ /* XTOS boot protocol related routines forward references */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
@@ -49,6 +55,10 @@ XTCDECL
LOADER_MEMORY_TYPE LOADER_MEMORY_TYPE
XtConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType); XtConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType);
XTCDECL
ULONG
XtpDeterminePagingLevel(IN CONST PWCHAR Parameters);
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap); XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap);
@@ -96,6 +106,10 @@ XtpLoadModule(IN PEFI_FILE_HANDLE BootDir,
IN LOADER_MEMORY_TYPE MemoryType, IN LOADER_MEMORY_TYPE MemoryType,
OUT PPECOFF_IMAGE_CONTEXT *ImageContext); OUT PPECOFF_IMAGE_CONTEXT *ImageContext);
XTCDECL
EFI_STATUS
XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap);
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle, BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle,

View File

@@ -37,40 +37,51 @@ XTBL_BOOT_PROTOCOL XtBootProtocol;
*/ */
XTCDECL XTCDECL
VOID VOID
XtGetDisplayInformation(OUT PLOADER_GRAPHICS_INFORMATION_BLOCK InformationBlock, XtGetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource,
IN PEFI_PHYSICAL_ADDRESS FrameBufferBase, IN PEFI_PHYSICAL_ADDRESS FrameBufferBase,
IN PULONG_PTR FrameBufferSize, IN PULONG_PTR FrameBufferSize,
IN PXTBL_FRAMEBUFFER_MODE_INFORMATION FrameBufferModeInfo) IN PXTBL_FRAMEBUFFER_MODE_INFORMATION FrameBufferModeInfo)
{ {
InformationBlock->Initialized = TRUE; /* Fill in frame buffer resource */
InformationBlock->Address = (PVOID)*FrameBufferBase; FrameBufferResource->Header.PhysicalAddress = (PVOID)*FrameBufferBase;
InformationBlock->BufferSize = *FrameBufferSize; FrameBufferResource->Header.ResourceType = SystemResourceFrameBuffer;
InformationBlock->Width = FrameBufferModeInfo->Width; FrameBufferResource->Header.ResourceSize = sizeof(SYSTEM_RESOURCE_FRAMEBUFFER);
InformationBlock->Height = FrameBufferModeInfo->Height; FrameBufferResource->BufferSize = *FrameBufferSize;
InformationBlock->BitsPerPixel = FrameBufferModeInfo->BitsPerPixel; FrameBufferResource->Width = FrameBufferModeInfo->Width;
InformationBlock->PixelsPerScanLine = FrameBufferModeInfo->PixelsPerScanLine; FrameBufferResource->Height = FrameBufferModeInfo->Height;
InformationBlock->Pitch = FrameBufferModeInfo->Pitch; FrameBufferResource->Depth = FrameBufferModeInfo->Depth;
FrameBufferResource->BitsPerPixel = FrameBufferModeInfo->BitsPerPixel;
FrameBufferResource->PixelsPerScanLine = FrameBufferModeInfo->PixelsPerScanLine;
FrameBufferResource->Pitch = FrameBufferModeInfo->Pitch;
FrameBufferResource->Pixels.BlueShift = FrameBufferModeInfo->PixelInformation.BlueShift;
FrameBufferResource->Pixels.BlueSize = FrameBufferModeInfo->PixelInformation.BlueSize;
FrameBufferResource->Pixels.GreenShift = FrameBufferModeInfo->PixelInformation.GreenShift;
FrameBufferResource->Pixels.GreenSize = FrameBufferModeInfo->PixelInformation.GreenSize;
FrameBufferResource->Pixels.RedShift = FrameBufferModeInfo->PixelInformation.RedShift;
FrameBufferResource->Pixels.RedSize = FrameBufferModeInfo->PixelInformation.RedSize;
FrameBufferResource->Pixels.ReservedShift = FrameBufferModeInfo->PixelInformation.ReservedShift;
FrameBufferResource->Pixels.ReservedSize = FrameBufferModeInfo->PixelInformation.ReservedSize;
} }
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
XtGetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap, XtGetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID VirtualAddress, IN PVOID *VirtualAddress,
OUT PLIST_ENTRY MemoryDescriptorList) OUT PLIST_ENTRY MemoryDescriptorList)
{ {
EFI_PHYSICAL_ADDRESS Address; EFI_PHYSICAL_ADDRESS Address;
EFI_STATUS Status; EFI_STATUS Status;
ULONGLONG Pages; ULONGLONG Pages;
Pages = (ULONGLONG)EFI_SIZE_TO_PAGES((PageMap->MapSize + 1) * sizeof(LOADER_MEMORY_MAPPING)); Pages = (ULONGLONG)EFI_SIZE_TO_PAGES((PageMap->MapSize + 1) * sizeof(LOADER_MEMORY_DESCRIPTOR));
Status = XtLdrProtocol->Memory.AllocatePages(Pages, &Address); Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, Pages, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
return Status; return Status;
} }
Status = XtLdrProtocol->Memory.MapVirtualMemory(PageMap, VirtualAddress, (PVOID)Address, Pages, LoaderMemoryData); Status = XtLdrProtocol->Memory.MapVirtualMemory(PageMap, *VirtualAddress, (PVOID)Address, Pages, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
XtLdrProtocol->Memory.FreePages(Address, Pages); XtLdrProtocol->Memory.FreePages(Address, Pages);
@@ -84,7 +95,7 @@ XtGetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
while(ListEntry != &PageMap->MemoryMap) while(ListEntry != &PageMap->MemoryMap)
{ {
PXTBL_MEMORY_MAPPING MemoryMapping = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry); PXTBL_MEMORY_MAPPING MemoryMapping = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);
PLOADER_MEMORY_MAPPING MemoryDescriptor = (PLOADER_MEMORY_MAPPING)Address; PLOADER_MEMORY_DESCRIPTOR MemoryDescriptor = (PLOADER_MEMORY_DESCRIPTOR)Address;
MemoryDescriptor->MemoryType = MemoryMapping->MemoryType; MemoryDescriptor->MemoryType = MemoryMapping->MemoryType;
MemoryDescriptor->BasePage = (UINT_PTR)MemoryMapping->PhysicalAddress / EFI_PAGE_SIZE; MemoryDescriptor->BasePage = (UINT_PTR)MemoryMapping->PhysicalAddress / EFI_PAGE_SIZE;
@@ -92,11 +103,126 @@ XtGetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
RtlInsertTailList(MemoryDescriptorList, &MemoryDescriptor->ListEntry); RtlInsertTailList(MemoryDescriptorList, &MemoryDescriptor->ListEntry);
Address = Address + sizeof(LOADER_MEMORY_MAPPING); Address = Address + sizeof(LOADER_MEMORY_DESCRIPTOR);
ListEntry = ListEntry->Flink; ListEntry = ListEntry->Flink;
} }
XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, MemoryDescriptorList, PhysicalBase, VirtualAddress); XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, MemoryDescriptorList, PhysicalBase, *VirtualAddress);
return STATUS_EFI_SUCCESS;
}
XTCDECL
EFI_STATUS
XtGetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID *VirtualAddress,
OUT PLIST_ENTRY SystemResourcesList)
{
XTSTATUS Status;
EFI_HANDLE ProtocolHandle;
EFI_GUID AcpiGuid = XT_ACPI_PROTOCOL_GUID;
EFI_GUID FrameBufGuid = XT_FRAMEBUFFER_PROTOCOL_GUID;
PXTBL_ACPI_PROTOCOL AcpiProtocol;
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
XTBL_FRAMEBUFFER_MODE_INFORMATION FbModeInfo;
EFI_PHYSICAL_ADDRESS FbAddress;
ULONG_PTR FbSize;
UINT FrameBufferPages;
PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource;
PSYSTEM_RESOURCE_ACPI AcpiResource;
ULONGLONG Pages;
EFI_PHYSICAL_ADDRESS Address;
PVOID PhysicalBase, VirtualBase;
Pages = (ULONGLONG)EFI_SIZE_TO_PAGES(sizeof(SYSTEM_RESOURCE_ACPI) + sizeof(SYSTEM_RESOURCE_FRAMEBUFFER));
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, Pages, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
return Status;
}
Status = XtLdrProtocol->Memory.MapVirtualMemory(PageMap, *VirtualAddress, (PVOID)Address, Pages, LoaderFirmwarePermanent);
if(Status != STATUS_EFI_SUCCESS)
{
XtLdrProtocol->Memory.FreePages(Address, Pages);
return Status;
}
PhysicalBase = (PVOID)Address;
VirtualBase = *VirtualAddress;
/* Calculate next valid virtual address */
*VirtualAddress += (UINT_PTR)(Pages * EFI_PAGE_SIZE);
AcpiResource = (PSYSTEM_RESOURCE_ACPI)Address;
RtlZeroMemory(AcpiResource, sizeof(SYSTEM_RESOURCE_ACPI));
/* Load FrameBuffer protocol */
Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&AcpiProtocol, &AcpiGuid);
if(Status != STATUS_EFI_SUCCESS)
{
return Status;
}
AcpiResource->Header.ResourceType = SystemResourceAcpi;
AcpiResource->Header.ResourceSize = sizeof(SYSTEM_RESOURCE_ACPI);
/* Get APIC and XSDP/RSDP addresses */
AcpiProtocol->GetApicBase(&AcpiResource->ApicBase);
AcpiProtocol->GetAcpiDescriptionPointer(&AcpiResource->Header.PhysicalAddress);
/* No need to map ACPI */
AcpiResource->Header.VirtualAddress = 0;
RtlInsertTailList(SystemResourcesList, &AcpiResource->Header.ListEntry);
/* Close FrameBuffer protocol */
XtLdrProtocol->Protocol.Close(ProtocolHandle, &FrameBufGuid);
Address = Address + sizeof(SYSTEM_RESOURCE_ACPI);
FrameBufferResource = (PSYSTEM_RESOURCE_FRAMEBUFFER)Address;
RtlZeroMemory(FrameBufferResource, sizeof(SYSTEM_RESOURCE_FRAMEBUFFER));
/* Load FrameBuffer protocol */
Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&FrameBufProtocol, &FrameBufGuid);
if(Status == STATUS_EFI_SUCCESS)
{
/* Get FrameBuffer information */
Status = FrameBufProtocol->GetDisplayInformation(&FbAddress, &FbSize, &FbModeInfo);
if(Status == STATUS_EFI_SUCCESS)
{
/* Store information about FrameBuffer device */
XtGetDisplayInformation(FrameBufferResource, &FbAddress, &FbSize, &FbModeInfo);
}
}
if(Status != STATUS_EFI_SUCCESS)
{
return Status;
}
/* Calculate pages needed to map framebuffer */
FrameBufferPages = EFI_SIZE_TO_PAGES(FbSize);
/* Rewrite framebuffer address by using virtual address */
FrameBufferResource->Header.VirtualAddress = *VirtualAddress;
/* Map frame buffer memory */
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, FrameBufferResource->Header.VirtualAddress,
FrameBufferResource->Header.PhysicalAddress,
FrameBufferPages, LoaderFirmwarePermanent);
/* Close FrameBuffer protocol */
XtLdrProtocol->Protocol.Close(ProtocolHandle, &FrameBufGuid);
*VirtualAddress += (UINT_PTR)(FrameBufferPages * EFI_PAGE_SIZE);
RtlInsertTailList(SystemResourcesList, &FrameBufferResource->Header.ListEntry);
XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, SystemResourcesList, PhysicalBase, VirtualBase);
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
@@ -197,7 +323,7 @@ XtBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
Parameters->KernelFile, Parameters->Parameters); Parameters->KernelFile, Parameters->Parameters);
/* Open EFI volume */ /* Open EFI volume */
Status = XtLdrProtocol->Disk.OpenVolume(NULL, &DiskHandle, &FsHandle); Status = XtLdrProtocol->Disk.OpenVolume(Parameters->DevicePath, &DiskHandle, &FsHandle);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to open a volume */ /* Failed to open a volume */
@@ -284,7 +410,7 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir,
VirtualAddress = (PVOID)(KSEG0_BASE + KSEG0_KERNEL_BASE); VirtualAddress = (PVOID)(KSEG0_BASE + KSEG0_KERNEL_BASE);
/* Initialize virtual memory mappings */ /* Initialize virtual memory mappings */
XtLdrProtocol->Memory.InitializePageMap(&PageMap, 3, Size4K); XtLdrProtocol->Memory.InitializePageMap(&PageMap, XtpDeterminePagingLevel(Parameters->Parameters), Size4K);
Status = XtLdrProtocol->Memory.MapEfiMemory(&PageMap, &VirtualMemoryArea, NULL); Status = XtLdrProtocol->Memory.MapEfiMemory(&PageMap, &VirtualMemoryArea, NULL);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
@@ -416,22 +542,21 @@ XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID *VirtualAddress, IN PVOID *VirtualAddress,
IN PXTBL_BOOT_PARAMETERS Parameters) IN PXTBL_BOOT_PARAMETERS Parameters)
{ {
EFI_GUID FrameBufGuid = XT_FRAMEBUFFER_PROTOCOL_GUID;
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
XTBL_FRAMEBUFFER_MODE_INFORMATION FbModeInfo;
PKERNEL_INITIALIZATION_BLOCK LoaderBlock; PKERNEL_INITIALIZATION_BLOCK LoaderBlock;
EFI_PHYSICAL_ADDRESS Address, FbAddress; EFI_PHYSICAL_ADDRESS Address;
// PVOID RuntimeServices; // PVOID RuntimeServices;
ULONG_PTR FbSize;
EFI_STATUS Status; EFI_STATUS Status;
EFI_HANDLE ProtocolHandle; UINT BlockPages;
UINT BlockPages, FrameBufferPages; UINT ParametersSize;
/* Calculate size of parameters */
ParametersSize = (RtlWideStringLength(Parameters->Parameters, 0) + 1) * sizeof(WCHAR);
/* Calculate number of pages needed for initialization block */ /* Calculate number of pages needed for initialization block */
BlockPages = EFI_SIZE_TO_PAGES(sizeof(KERNEL_INITIALIZATION_BLOCK)); BlockPages = EFI_SIZE_TO_PAGES(sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize);
/* Allocate memory for kernel initialization block */ /* Allocate memory for kernel initialization block */
Status = XtLdrProtocol->Memory.AllocatePages(BlockPages, &Address); Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, BlockPages, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -440,7 +565,7 @@ XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
/* Initialize and zero-fill kernel initialization block */ /* Initialize and zero-fill kernel initialization block */
LoaderBlock = (PKERNEL_INITIALIZATION_BLOCK)(UINT_PTR)Address; LoaderBlock = (PKERNEL_INITIALIZATION_BLOCK)(UINT_PTR)Address;
RtlZeroMemory(LoaderBlock, sizeof(KERNEL_INITIALIZATION_BLOCK)); RtlZeroMemory(LoaderBlock, sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize);
/* Set basic loader block properties */ /* Set basic loader block properties */
LoaderBlock->BlockSize = sizeof(KERNEL_INITIALIZATION_BLOCK); LoaderBlock->BlockSize = sizeof(KERNEL_INITIALIZATION_BLOCK);
@@ -450,30 +575,6 @@ XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
/* Set LoaderInformation block properties */ /* Set LoaderInformation block properties */
LoaderBlock->LoaderInformation.DbgPrint = XtLdrProtocol->Debug.Print; LoaderBlock->LoaderInformation.DbgPrint = XtLdrProtocol->Debug.Print;
/* Load FrameBuffer protocol */
Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&FrameBufProtocol, &FrameBufGuid);
if(Status == STATUS_EFI_SUCCESS)
{
/* Get FrameBuffer information */
Status = FrameBufProtocol->GetDisplayInformation(&FbAddress, &FbSize, &FbModeInfo);
if(Status == STATUS_EFI_SUCCESS)
{
/* Store information about FrameBuffer device */
XtGetDisplayInformation(&LoaderBlock->LoaderInformation.FrameBuffer, &FbAddress, &FbSize, &FbModeInfo);
}
}
if(Status != STATUS_EFI_SUCCESS)
{
/* No FrameBuffer available */
LoaderBlock->LoaderInformation.FrameBuffer.Initialized = FALSE;
}
/* Store page map level */
LoaderBlock->LoaderInformation.PageMapLevel = 3;
/* Close FrameBuffer protocol */
XtLdrProtocol->Protocol.Close(ProtocolHandle, &FrameBufGuid);
/* Attempt to find virtual address of the EFI Runtime Services */ /* Attempt to find virtual address of the EFI Runtime Services */
// Status = XtLdrProtocol->GetVirtualAddress(MemoryMappings, &EfiSystemTable->RuntimeServices->Hdr, &RuntimeServices); // Status = XtLdrProtocol->GetVirtualAddress(MemoryMappings, &EfiSystemTable->RuntimeServices->Hdr, &RuntimeServices);
// if(Status == STATUS_EFI_SUCCESS) // if(Status == STATUS_EFI_SUCCESS)
@@ -490,8 +591,10 @@ XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
// } // }
/* Copy parameters to kernel initialization block */ /* Copy parameters to kernel initialization block */
RtlCopyMemory(LoaderBlock->KernelParameters, Parameters->Parameters, LoaderBlock->KernelParameters = (PWCHAR)((UINT_PTR)*VirtualAddress + sizeof(KERNEL_INITIALIZATION_BLOCK));
(RtlWideStringLength(Parameters->Parameters, 0) + 1) * sizeof(WCHAR)); RtlCopyMemory((PVOID)((UINT_PTR)LoaderBlock + sizeof(KERNEL_INITIALIZATION_BLOCK)),
Parameters->Parameters,
ParametersSize);
/* Map kernel initialization block */ /* Map kernel initialization block */
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, *VirtualAddress, (PVOID)LoaderBlock, XtLdrProtocol->Memory.MapVirtualMemory(PageMap, *VirtualAddress, (PVOID)LoaderBlock,
@@ -500,27 +603,12 @@ XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
/* Calculate next valid virtual address */ /* Calculate next valid virtual address */
*VirtualAddress += (UINT_PTR)(BlockPages * EFI_PAGE_SIZE); *VirtualAddress += (UINT_PTR)(BlockPages * EFI_PAGE_SIZE);
/* Check if framebuffer initialized */ RtlInitializeListHead(&LoaderBlock->SystemResourcesListHead);
if(LoaderBlock->LoaderInformation.FrameBuffer.Initialized) XtGetSystemResourcesList(PageMap, VirtualAddress, &LoaderBlock->SystemResourcesListHead);
{
/* Calculate pages needed to map framebuffer */
FrameBufferPages = EFI_SIZE_TO_PAGES(LoaderBlock->LoaderInformation.FrameBuffer.BufferSize);
/* Map frame buffer memory */
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, *VirtualAddress,
LoaderBlock->LoaderInformation.FrameBuffer.Address,
FrameBufferPages, LoaderFirmwarePermanent);
/* Rewrite framebuffer address by using virtual address */
LoaderBlock->LoaderInformation.FrameBuffer.Address = *VirtualAddress;
/* Calcualate next valid virtual address */
*VirtualAddress += (UINT_PTR)(FrameBufferPages * EFI_PAGE_SIZE);
}
/* Initialize memory descriptor list */ /* Initialize memory descriptor list */
RtlInitializeListHead(&LoaderBlock->MemoryDescriptorListHead); RtlInitializeListHead(&LoaderBlock->MemoryDescriptorListHead);
XtGetMemoryDescriptorList(PageMap, *VirtualAddress, &LoaderBlock->MemoryDescriptorListHead); XtGetMemoryDescriptorList(PageMap, VirtualAddress, &LoaderBlock->MemoryDescriptorListHead);
/* Return success */ /* Return success */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;

View File

@@ -749,100 +749,96 @@ BlpGetModuleInfoStrings(IN PWCHAR SectionData,
EFI_STATUS Status; EFI_STATUS Status;
PWCHAR *Array; PWCHAR *Array;
PWCHAR String; PWCHAR String;
ULONG DataSize;
/* Check input parameters */ /* Check input parameters */
InfoStrings = SectionData; InfoStrings = SectionData;
if(!InfoStrings || !SectionSize) if(!InfoStrings || !SectionSize)
{ {
/* Invalid input parameters */ /* Invalid input parameters */
*ModInfo = NULL;
*InfoCount = 0;
return STATUS_EFI_INVALID_PARAMETER; return STATUS_EFI_INVALID_PARAMETER;
} }
/* Skip zero padding */ /* Calculate the size of the data based on the size of the section */
while(InfoStrings[0] == L'\0' && SectionSize > 1) DataSize = SectionSize / sizeof(WCHAR);
/* Skip zero padding at the beginning */
while(DataSize > 0 && *InfoStrings == L'\0')
{ {
/* Get next character and decrement section size */
InfoStrings++; InfoStrings++;
SectionSize--; DataSize--;
} }
/* Make sure there is at least one string available */ /* Make sure there is at least one string available */
if(SectionSize <= 1) if(DataSize < 1)
{ {
/* No strings found */ /* No strings found */
*ModInfo = NULL;
*InfoCount = 0;
return STATUS_EFI_END_OF_FILE; return STATUS_EFI_END_OF_FILE;
} }
/* Count number of strings */ /* Count number of strings */
Index = 0; Index = 0;
Count = 0; Count = 0;
while(Index < SectionSize) while(Index < DataSize)
{ {
/* Get to the next string */ /* Found start of a new string */
if(InfoStrings[Index] != L'\0') Count++;
{
/* Get next character */
Index++;
continue;
}
/* Skip zero padding */ /* Go to the end of the string */
while(InfoStrings[Index] == L'\0' && Index < SectionSize) while(Index < DataSize && InfoStrings[Index] != L'\0')
{ {
/* Get next character */
Index++; Index++;
} }
/* Skip all null terminators */
/* New string found, increment counter */ while(Index < DataSize && InfoStrings[Index] == L'\0')
Count++;
}
/* Make sure there is no missing string */
if(InfoStrings[Index - 1] != L'\0')
{ {
/* One more string available */ Index++;
Count++; }
} }
/* Allocate memory for array of strings */ /* Allocate memory for the pointer array and the string data */
Status = BlAllocateMemoryPool(SectionSize + 1 + sizeof(PWCHAR) * (Count + 1), (PVOID *)&Array); Status = BlAllocateMemoryPool(sizeof(PWCHAR) * (Count + 1) + (DataSize + 1) * sizeof(WCHAR), (PVOID *)&Array);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to allocate memory */ /* Failed to allocate memory */
return STATUS_EFI_OUT_OF_RESOURCES; return STATUS_EFI_OUT_OF_RESOURCES;
} }
/* Allocate memory and copy strings read from '.modinfo' section */ /* The string buffer is located right after the pointer array */
BlAllocateMemoryPool(SectionSize, (PVOID*)&String); String = (PWCHAR)(Array + Count + 1);
RtlCopyMemory(String, InfoStrings, SectionSize);
/* Make sure last string is NULL-terminated */ /* Copy the raw string data */
RtlCopyMemory(String, InfoStrings, DataSize * sizeof(WCHAR));
/* Ensure the entire buffer is null-terminated for safety */
String[DataSize] = L'\0';
/* Set the last element of the pointer array to NULL */
Array[Count] = NULL; Array[Count] = NULL;
Array[0] = String;
/* Parse strings into array */ /* Populate the array with pointers to the strings within the buffer */
Index = 0; Index = 0;
ArrayIndex = 1; ArrayIndex = 0;
while(Index < SectionSize && ArrayIndex < Count) while(Index < DataSize && ArrayIndex < Count)
{ {
/* Get to the next string */ /* Set pointer to the beginning of the string */
if(String[Index] != L'\0') Array[ArrayIndex++] = &String[Index];
{
/* Get next character */
Index++;
continue;
}
/* Skip zero padding */ /* Find the end of the current string */
while(InfoStrings[Index] == L'\0' && Index < SectionSize) while(Index < DataSize && String[Index] != L'\0')
{ {
/* Get next character */
Index++; Index++;
} }
/* Push string into array */ /* Skip all null terminators to find the beginning of the next string */
Array[ArrayIndex] = &String[Index]; while(Index < DataSize && String[Index] == L'\0')
ArrayIndex++; {
Index++;
}
} }
/* Return array of strings and its size */ /* Return array of strings and its size */
@@ -872,8 +868,12 @@ BlpInstallXtLoaderProtocol()
BlpLdrProtocol.Boot.InvokeProtocol = BlInvokeBootProtocol; BlpLdrProtocol.Boot.InvokeProtocol = BlInvokeBootProtocol;
BlpLdrProtocol.Boot.RegisterMenu = BlRegisterBootMenu; BlpLdrProtocol.Boot.RegisterMenu = BlRegisterBootMenu;
BlpLdrProtocol.Boot.RegisterProtocol = BlRegisterBootProtocol; BlpLdrProtocol.Boot.RegisterProtocol = BlRegisterBootProtocol;
BlpLdrProtocol.BootUtil.GetBooleanParameter = BlGetBooleanParameter;
BlpLdrProtocol.Config.GetBooleanValue = BlGetConfigBooleanValue; BlpLdrProtocol.Config.GetBooleanValue = BlGetConfigBooleanValue;
BlpLdrProtocol.Config.GetBootOptionValue = BlGetBootOptionValue;
BlpLdrProtocol.Config.GetEditableOptions = BlGetEditableOptions;
BlpLdrProtocol.Config.GetValue = BlGetConfigValue; BlpLdrProtocol.Config.GetValue = BlGetConfigValue;
BlpLdrProtocol.Config.SetBootOptionValue = BlSetBootOptionValue;
BlpLdrProtocol.Console.ClearLine = BlClearConsoleLine; BlpLdrProtocol.Console.ClearLine = BlClearConsoleLine;
BlpLdrProtocol.Console.ClearScreen = BlClearConsoleScreen; BlpLdrProtocol.Console.ClearScreen = BlClearConsoleScreen;
BlpLdrProtocol.Console.DisableCursor = BlDisableConsoleCursor; BlpLdrProtocol.Console.DisableCursor = BlDisableConsoleCursor;

View File

@@ -4,6 +4,7 @@
* FILE: xtldr/textui.c * FILE: xtldr/textui.c
* DESCRIPTION: Text console User Interface (TUI) support for XT Boot Loader * DESCRIPTION: Text console User Interface (TUI) support for XT Boot Loader
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/ */
#include <xtldr.h> #include <xtldr.h>
@@ -22,7 +23,9 @@ BlDisplayBootMenu()
{ {
XTBL_DIALOG_HANDLE Handle; XTBL_DIALOG_HANDLE Handle;
PXTBL_BOOTMENU_ITEM MenuEntries = NULL; PXTBL_BOOTMENU_ITEM MenuEntries = NULL;
ULONG Index, NumberOfEntries, HighligtedEntryId; ULONG Index;
ULONG HighligtedEntryId, OldHighligtedEntryId, NumberOfEntries, TopVisibleEntry, VisibleEntries;
BOOLEAN RedrawBootMenu, RedrawEntries;
UINT_PTR EventIndex; UINT_PTR EventIndex;
EFI_EVENT Events[2]; EFI_EVENT Events[2];
EFI_INPUT_KEY Key; EFI_INPUT_KEY Key;
@@ -31,16 +34,30 @@ BlDisplayBootMenu()
LONG TimeOut; LONG TimeOut;
PWCHAR TimeOutString; PWCHAR TimeOutString;
/* Draw boot menu */
BlpDrawBootMenu(&Handle);
/* Initialize boot menu list */ /* Initialize boot menu list */
Status = BlInitializeBootMenuList(&MenuEntries, &NumberOfEntries, &HighligtedEntryId); TopVisibleEntry = 0;
Status = BlInitializeBootMenuList(Handle.Width - 4, &MenuEntries, &NumberOfEntries, &HighligtedEntryId);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to initialize boot menu list, exit into XTLDR shell */ /* Failed to initialize boot menu list, exit into XTLDR shell */
return; return;
} }
/* Calculate how many entries can be visible in the menu box */
VisibleEntries = Handle.Height - 2;
/* Adjust the view if the default entry is not initially visible */
if(HighligtedEntryId >= VisibleEntries)
{
/* Scroll the view to make the highlighted entry the last visible one */
TopVisibleEntry = HighligtedEntryId - VisibleEntries + 1;
}
/* Get timeout from the configuration */ /* Get timeout from the configuration */
TimeOutString = BlGetConfigValue(L"TIMEOUT"); BlGetConfigValue(L"TIMEOUT", &TimeOutString);
TimeOut = -1; TimeOut = -1;
/* Check if timeout is specified */ /* Check if timeout is specified */
@@ -56,26 +73,43 @@ BlDisplayBootMenu()
} }
} }
/* Set redraw flags to not redraw the menu itself, but fill it with entries */
RedrawBootMenu = FALSE;
RedrawEntries = TRUE;
/* Infinite boot menu loop */ /* Infinite boot menu loop */
while(TRUE) while(TRUE)
{ {
/* Draw boot menu */ /* Redraw boot menu frame if requested */
BlpDrawBootMenu(&Handle); if(RedrawBootMenu)
/* Check if there is anything to show in the boot menu */
if(NumberOfEntries > 0) {
/* Check if all menu entries will fit into the menu box */
if(NumberOfEntries > Handle.Height - 2)
{ {
/* Too many menu entries, limit entries to match box height (-2 for upper and bottom borders) */ BlpDrawBootMenu(&Handle);
NumberOfEntries = Handle.Height - 2; RedrawBootMenu = FALSE;
RedrawEntries = TRUE;
} }
/* Sanity check to ensure we do not display more entries than possible */
if(VisibleEntries > NumberOfEntries)
{
VisibleEntries = NumberOfEntries;
}
/* Check if there is anything to show in the boot menu */
if(NumberOfEntries > 0)
{
/* Check if we need to redraw boot menu entries */
if(RedrawEntries)
{
/* Iterate through all menu entries */ /* Iterate through all menu entries */
for(Index = 0; Index < NumberOfEntries; Index++) for(Index = 0; Index < VisibleEntries; Index++)
{ {
/* Draw menu entry */ /* Draw menu entry */
BlpDrawBootMenuEntry(&Handle, MenuEntries[Index].EntryName, Index, Index == HighligtedEntryId); BlpDrawBootMenuEntry(&Handle, MenuEntries[TopVisibleEntry + Index].EntryName,
Index, (TopVisibleEntry + Index) == HighligtedEntryId);
}
/* Clear redraw entries flag */
RedrawEntries = FALSE;
} }
} }
else else
@@ -109,6 +143,9 @@ BlDisplayBootMenu()
/* Flush keyboard buffer out of any keystrokes */ /* Flush keyboard buffer out of any keystrokes */
EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, FALSE); EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, FALSE);
/* Store old highlighted entry */
OldHighligtedEntryId = HighligtedEntryId;
/* Infinite boot menu event loop */ /* Infinite boot menu event loop */
while(TRUE) while(TRUE)
{ {
@@ -140,7 +177,7 @@ BlDisplayBootMenu()
BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor); BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor);
BlClearConsoleLine(Handle.PosY + Handle.Height + 4); BlClearConsoleLine(Handle.PosY + Handle.Height + 4);
BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4);
BlConsolePrint(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].EntryName); BlConsolePrint(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].FullName);
/* Boot the highlighted (chosen) OS */ /* Boot the highlighted (chosen) OS */
Status = BlInvokeBootProtocol(MenuEntries[HighligtedEntryId].ShortName, Status = BlInvokeBootProtocol(MenuEntries[HighligtedEntryId].ShortName,
@@ -149,8 +186,9 @@ BlDisplayBootMenu()
{ {
/* Failed to boot OS */ /* Failed to boot OS */
BlDebugPrint(L"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\n", BlDebugPrint(L"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\n",
MenuEntries[HighligtedEntryId].EntryName, Status); MenuEntries[HighligtedEntryId].FullName, Status);
BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System.");
RedrawBootMenu = TRUE;
} }
/* Break from boot menu event loop to redraw whole boot menu */ /* Break from boot menu event loop to redraw whole boot menu */
@@ -162,11 +200,23 @@ BlDisplayBootMenu()
if(HighligtedEntryId > 0) if(HighligtedEntryId > 0)
{ {
/* Highlight previous entry */ /* Highlight previous entry */
OldHighligtedEntryId = HighligtedEntryId;
HighligtedEntryId--; HighligtedEntryId--;
BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId + 1].EntryName,
HighligtedEntryId + 1, FALSE); /* Check if we need to scroll the view */
if(HighligtedEntryId < TopVisibleEntry)
{
/* Scroll the view */
TopVisibleEntry = HighligtedEntryId;
RedrawEntries = TRUE;
break;
}
/* Redraw new highlighted entry and the old one */
BlpDrawBootMenuEntry(&Handle, MenuEntries[OldHighligtedEntryId].EntryName,
OldHighligtedEntryId - TopVisibleEntry, FALSE);
BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName,
HighligtedEntryId, TRUE); HighligtedEntryId - TopVisibleEntry, TRUE);
} }
} }
else if(Key.ScanCode == 0x02) else if(Key.ScanCode == 0x02)
@@ -175,11 +225,23 @@ BlDisplayBootMenu()
if(HighligtedEntryId < NumberOfEntries - 1) if(HighligtedEntryId < NumberOfEntries - 1)
{ {
/* Highlight next entry */ /* Highlight next entry */
OldHighligtedEntryId = HighligtedEntryId;
HighligtedEntryId++; HighligtedEntryId++;
BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId - 1].EntryName,
HighligtedEntryId - 1, FALSE); /* Check if we need to scroll the view */
if(HighligtedEntryId >= TopVisibleEntry + VisibleEntries)
{
/* Scroll the view */
TopVisibleEntry = HighligtedEntryId - VisibleEntries + 1;
RedrawEntries = TRUE;
break;
}
/* Redraw new highlighted entry and the old one */
BlpDrawBootMenuEntry(&Handle, MenuEntries[OldHighligtedEntryId].EntryName,
OldHighligtedEntryId - TopVisibleEntry, FALSE);
BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName,
HighligtedEntryId, TRUE); HighligtedEntryId - TopVisibleEntry, TRUE);
} }
} }
else if(Key.ScanCode == 0x09) else if(Key.ScanCode == 0x09)
@@ -188,12 +250,10 @@ BlDisplayBootMenu()
if(HighligtedEntryId != 0) if(HighligtedEntryId != 0)
{ {
/* Highlight first entry */ /* Highlight first entry */
BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName,
HighligtedEntryId, FALSE);
BlpDrawBootMenuEntry(&Handle, MenuEntries[0].EntryName, 0, TRUE);
/* Update highlighted entry ID */
HighligtedEntryId = 0; HighligtedEntryId = 0;
TopVisibleEntry = 0;
RedrawEntries = TRUE;
break;
} }
} }
else if(Key.ScanCode == 0x0A) else if(Key.ScanCode == 0x0A)
@@ -202,13 +262,10 @@ BlDisplayBootMenu()
if(HighligtedEntryId != NumberOfEntries - 1) if(HighligtedEntryId != NumberOfEntries - 1)
{ {
/* Highlight last entry */ /* Highlight last entry */
BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName,
HighligtedEntryId, FALSE);
BlpDrawBootMenuEntry(&Handle, MenuEntries[NumberOfEntries - 1].EntryName,
NumberOfEntries - 1, TRUE);
/* Update highlighted entry ID */
HighligtedEntryId = NumberOfEntries - 1; HighligtedEntryId = NumberOfEntries - 1;
TopVisibleEntry = (NumberOfEntries > VisibleEntries) ? (NumberOfEntries - VisibleEntries) : 0;
RedrawEntries = TRUE;
break;
} }
} }
else if(Key.ScanCode == 0x0B) else if(Key.ScanCode == 0x0B)
@@ -231,6 +288,7 @@ BlDisplayBootMenu()
L"Visit https://exectos.eu.org/ for more information."); L"Visit https://exectos.eu.org/ for more information.");
/* Break from boot menu event loop to redraw whole boot menu */ /* Break from boot menu event loop to redraw whole boot menu */
RedrawBootMenu = TRUE;
break; break;
} }
else if(Key.ScanCode == 0x14) else if(Key.ScanCode == 0x14)
@@ -238,6 +296,7 @@ BlDisplayBootMenu()
/* F10 key pressed, reboot into UEFI setup interface */ /* F10 key pressed, reboot into UEFI setup interface */
BlEnterFirmwareSetup(); BlEnterFirmwareSetup();
BlDisplayErrorDialog(L"XTLDR", L"Reboot into firmware setup interface not supported!"); BlDisplayErrorDialog(L"XTLDR", L"Reboot into firmware setup interface not supported!");
RedrawBootMenu = TRUE;
/* Break from boot menu event loop to redraw whole boot menu */ /* Break from boot menu event loop to redraw whole boot menu */
break; break;
@@ -247,6 +306,7 @@ BlDisplayBootMenu()
/* F11 key pressed, reboot the machine */ /* F11 key pressed, reboot the machine */
BlRebootSystem(); BlRebootSystem();
BlDisplayErrorDialog(L"XTLDR", L"Failed to reboot the machine!"); BlDisplayErrorDialog(L"XTLDR", L"Failed to reboot the machine!");
RedrawBootMenu = TRUE;
/* Break from boot menu event loop to redraw whole boot menu */ /* Break from boot menu event loop to redraw whole boot menu */
break; break;
@@ -256,6 +316,7 @@ BlDisplayBootMenu()
/* F12 key pressed, shutdown the machine */ /* F12 key pressed, shutdown the machine */
BlShutdownSystem(); BlShutdownSystem();
BlDisplayErrorDialog(L"XTLDR", L"Failed to shutdown the machine!"); BlDisplayErrorDialog(L"XTLDR", L"Failed to shutdown the machine!");
RedrawBootMenu = TRUE;
/* Break from boot menu event loop to redraw whole boot menu */ /* Break from boot menu event loop to redraw whole boot menu */
break; break;
@@ -263,7 +324,8 @@ BlDisplayBootMenu()
else if(Key.UnicodeChar == 0x65) else if(Key.UnicodeChar == 0x65)
{ {
/* 'e' key pressed, edit the highlighted entry */ /* 'e' key pressed, edit the highlighted entry */
BlDisplayErrorDialog(L"XTLDR", L"Editing boot menu entries is not implemented yet!"); BlDisplayEditMenu(&MenuEntries[HighligtedEntryId]);
RedrawBootMenu = TRUE;
/* Break from boot menu event loop to redraw whole boot menu */ /* Break from boot menu event loop to redraw whole boot menu */
break; break;
@@ -292,7 +354,7 @@ BlDisplayBootMenu()
BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor); BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor);
BlClearConsoleLine(Handle.PosY + Handle.Height + 4); BlClearConsoleLine(Handle.PosY + Handle.Height + 4);
BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4);
BlConsolePrint(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].EntryName); BlConsolePrint(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].FullName);
/* Disable the timer just in case booting OS fails */ /* Disable the timer just in case booting OS fails */
TimeOut = -1; TimeOut = -1;
@@ -304,8 +366,9 @@ BlDisplayBootMenu()
{ {
/* Failed to boot OS */ /* Failed to boot OS */
BlDebugPrint(L"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\n", BlDebugPrint(L"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\n",
MenuEntries[HighligtedEntryId].EntryName, Status); MenuEntries[HighligtedEntryId].FullName, Status);
BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System.");
RedrawBootMenu = TRUE;
} }
break; break;
} }
@@ -314,6 +377,254 @@ BlDisplayBootMenu()
} }
} }
/**
* Displays a simple TUI-based edit menu.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BlDisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry)
{
ULONG HighligtedOptionId, Index, NumberOfOptions, OldHighligtedOptionId, TopVisibleEntry, VisibleEntries;
XTBL_DIALOG_HANDLE Handle;
BOOLEAN RedrawEditMenu, RedrawEntries;
EFI_INPUT_KEY Key;
UINT_PTR EventIndex;
PWCHAR NewValue, OptionName, OriginalValue, Value, ValueToEdit;
CONST PWCHAR *EditableOptions;
EFI_STATUS Status;
/* Draw edit menu */
BlpDrawEditMenu(&Handle);
/* Get the list of user editable options */
BlGetEditableOptions(&EditableOptions, &NumberOfOptions);
/* Calculate how many entries can be visible in the menu box */
VisibleEntries = Handle.Height - 2;
/* Assume the first option is highlighted by default */
HighligtedOptionId = 0;
OldHighligtedOptionId = 0;
TopVisibleEntry = 0;
/* Set redraw flags to not redraw the menu itself, but fill it with entries */
RedrawEditMenu = FALSE;
RedrawEntries = TRUE;
/* Infinite edit menu loop */
while(TRUE)
{
/* Redraw edit menu frame if requested */
if(RedrawEditMenu)
{
BlpDrawEditMenu(&Handle);
RedrawEditMenu = FALSE;
RedrawEntries = TRUE;
}
/* Sanity check to ensure we do not display more entries than possible */
if(VisibleEntries > NumberOfOptions)
{
VisibleEntries = NumberOfOptions;
}
/* Check if we need to redraw boot menu entries */
if(RedrawEntries)
{
/* Iterate through all menu entries */
for(Index = 0; Index < VisibleEntries; Index++)
{
/* Draw menu entry */
BlGetBootOptionValue(MenuEntry->Options, EditableOptions[TopVisibleEntry + Index], &Value);
BlpDrawEditMenuEntry(&Handle, EditableOptions[TopVisibleEntry + Index], Value, Index,
(TopVisibleEntry + Index) == HighligtedOptionId);
/* Free allocated value string if needed */
if(Value != NULL)
{
BlFreeMemoryPool(Value);
}
}
/* Clear redraw entries flag */
RedrawEntries = FALSE;
}
/* Wait for EFI event and read key stroke */
BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &EventIndex);
BlReadKeyStroke(&Key);
/* Check key press scan code */
if(Key.UnicodeChar == 0x0D || Key.UnicodeChar == 0x65)
{
/* ENTER or 'e' key pressed, edit the highlighted option */
OptionName = EditableOptions[HighligtedOptionId];
BlGetBootOptionValue(MenuEntry->Options, OptionName, &OriginalValue);
/* If the original value is NULL, use an empty string for editing */
if(OriginalValue == NULL)
{
ValueToEdit = L"";
}
else
{
ValueToEdit = OriginalValue;
}
/* Display input dialog to edit the option value */
NewValue = ValueToEdit;
BlDisplayInputDialog(OptionName, L"Enter new value:", &NewValue);
/* Check if the value was changed */
if(NewValue != ValueToEdit)
{
/* Update the boot option with the new value and free the old value */
BlSetBootOptionValue(MenuEntry->Options, OptionName, NewValue);
BlFreeMemoryPool(NewValue);
}
/* Free the original value if it was allocated */
if(OriginalValue != NULL)
{
BlFreeMemoryPool(OriginalValue);
}
/* Mark the edit menu for redraw */
RedrawEditMenu = TRUE;
}
else if(Key.ScanCode == 0x01)
{
/* UpArrow key pressed, go to previous entry if possible */
if(HighligtedOptionId > 0)
{
/* Highlight previous entry */
OldHighligtedOptionId = HighligtedOptionId;
HighligtedOptionId--;
/* Check if we need to scroll the view */
if(HighligtedOptionId < TopVisibleEntry)
{
/* Scroll the view */
TopVisibleEntry = HighligtedOptionId;
RedrawEntries = TRUE;
continue;
}
/* Redraw old highlighted entry */
BlGetBootOptionValue(MenuEntry->Options, EditableOptions[OldHighligtedOptionId], &Value);
BlpDrawEditMenuEntry(&Handle, EditableOptions[OldHighligtedOptionId], Value, OldHighligtedOptionId - TopVisibleEntry, FALSE);
/* Free allocated value string if needed */
if(Value != NULL)
{
BlFreeMemoryPool(Value);
}
/* Redraw new highlighted entry */
BlGetBootOptionValue(MenuEntry->Options, EditableOptions[HighligtedOptionId], &Value);
BlpDrawEditMenuEntry(&Handle, EditableOptions[HighligtedOptionId], Value, HighligtedOptionId - TopVisibleEntry, TRUE);
/* Free allocated value string if needed */
if(Value != NULL)
{
BlFreeMemoryPool(Value);
}
}
}
else if(Key.ScanCode == 0x02)
{
/* DownArrow key pressed, go to next entry if possible */
if(HighligtedOptionId < NumberOfOptions - 1)
{
/* Highlight next entry */
OldHighligtedOptionId = HighligtedOptionId;
HighligtedOptionId++;
/* Check if we need to scroll the view */
if(HighligtedOptionId >= TopVisibleEntry + VisibleEntries)
{
/* Scroll the view */
TopVisibleEntry = HighligtedOptionId - VisibleEntries + 1;
RedrawEntries = TRUE;
continue;
}
/* Redraw old highlighted entry */
BlGetBootOptionValue(MenuEntry->Options, EditableOptions[OldHighligtedOptionId], &Value);
BlpDrawEditMenuEntry(&Handle, EditableOptions[OldHighligtedOptionId], Value, OldHighligtedOptionId - TopVisibleEntry, FALSE);
/* Free allocated value string if needed */
if(Value != NULL)
{
BlFreeMemoryPool(Value);
}
/* Redraw new highlighted entry */
BlGetBootOptionValue(MenuEntry->Options, EditableOptions[HighligtedOptionId], &Value);
BlpDrawEditMenuEntry(&Handle, EditableOptions[HighligtedOptionId], Value, HighligtedOptionId - TopVisibleEntry, TRUE);
/* Free allocated value string if needed */
if(Value != NULL)
{
BlFreeMemoryPool(Value);
}
}
}
else if(Key.ScanCode == 0x09)
{
/* PageUp key pressed, go to top entry */
if(HighligtedOptionId != 0)
{
/* Highlight first entry */
HighligtedOptionId = 0;
TopVisibleEntry = 0;
RedrawEntries = TRUE;
}
}
else if(Key.ScanCode == 0x0A)
{
/* PageDown key pressed, go to bottom entry */
if(HighligtedOptionId != NumberOfOptions - 1)
{
/* Highlight last entry */
HighligtedOptionId = NumberOfOptions - 1;
TopVisibleEntry = (NumberOfOptions > VisibleEntries) ? (NumberOfOptions - VisibleEntries) : 0;
RedrawEntries = TRUE;
}
}
else if(Key.UnicodeChar == 0x02)
{
/* CTRL-B key pressed, boot the OS */
BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor);
BlClearConsoleLine(Handle.PosY + Handle.Height + 4);
BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4);
BlConsolePrint(L"Booting '%S' now...\n", MenuEntry->FullName);
/* Boot the OS */
Status = BlInvokeBootProtocol(MenuEntry->ShortName, MenuEntry->Options);
if(Status != STATUS_SUCCESS)
{
/* Failed to boot OS */
BlDebugPrint(L"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\n", MenuEntry->FullName, Status);
BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System.");
RedrawEditMenu = TRUE;
}
/* Return to the edit menu */
continue;
}
else if(Key.ScanCode == 0x17)
{
/* ESC key pressed, exit edit menu */
break;
}
}
}
/** /**
* Displays a red error dialog box with the specified caption and message. * Displays a red error dialog box with the specified caption and message.
* *
@@ -440,12 +751,11 @@ XTCDECL
VOID VOID
BlDisplayInputDialog(IN PWCHAR Caption, BlDisplayInputDialog(IN PWCHAR Caption,
IN PWCHAR Message, IN PWCHAR Message,
IN PWCHAR *InputFieldText) IN OUT PWCHAR *InputFieldText)
{ {
SIZE_T InputFieldLength, TextCursorPosition, TextIndex, TextPosition; SIZE_T InputFieldLength, TextCursorPosition, TextIndex, TextPosition;
XTBL_DIALOG_HANDLE Handle; XTBL_DIALOG_HANDLE Handle;
PWCHAR InputFieldBuffer; PWCHAR InputFieldBuffer;
SIZE_T BufferLength;
EFI_INPUT_KEY Key; EFI_INPUT_KEY Key;
EFI_STATUS Status; EFI_STATUS Status;
UINT_PTR Index; UINT_PTR Index;
@@ -470,9 +780,11 @@ BlDisplayInputDialog(IN PWCHAR Caption,
Key.ScanCode = 0; Key.ScanCode = 0;
Key.UnicodeChar = 0; Key.UnicodeChar = 0;
/* Get initial input text length and allocate a buffer */ /* Determine input field length */
BufferLength = RtlWideStringLength(*InputFieldText, 0); InputFieldLength = RtlWideStringLength(*InputFieldText, 0);
Status = BlAllocateMemoryPool(BufferLength * sizeof(WCHAR), (PVOID *)&InputFieldBuffer);
/* Allocate a buffer for storing the input field text */
Status = BlAllocateMemoryPool(2048 * sizeof(WCHAR), (PVOID *)&InputFieldBuffer);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure, print error message and return */ /* Memory allocation failure, print error message and return */
@@ -482,15 +794,8 @@ BlDisplayInputDialog(IN PWCHAR Caption,
} }
/* Copy input text into edit buffer */ /* Copy input text into edit buffer */
RtlCopyMemory(InputFieldBuffer, *InputFieldText, BufferLength * sizeof(WCHAR)); RtlCopyMemory(InputFieldBuffer, *InputFieldText, InputFieldLength * sizeof(WCHAR));
InputFieldBuffer[BufferLength] = L'\0'; InputFieldBuffer[InputFieldLength] = L'\0';
/* Determine input field length */
InputFieldLength = BufferLength;
if(InputFieldLength > Handle.Width - 8)
{
InputFieldLength = Handle.Width - 8;
}
/* Start at first character */ /* Start at first character */
TextPosition = 0; TextPosition = 0;
@@ -502,7 +807,6 @@ BlDisplayInputDialog(IN PWCHAR Caption,
/* Wait for key press and read key stroke */ /* Wait for key press and read key stroke */
BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index);
BlReadKeyStroke(&Key); BlReadKeyStroke(&Key);
BlResetConsoleInputBuffer();
/* Check key press scan code */ /* Check key press scan code */
if(Key.ScanCode == 0x17) if(Key.ScanCode == 0x17)
@@ -553,12 +857,16 @@ BlDisplayInputDialog(IN PWCHAR Caption,
/* DELETE key pressed, delete character */ /* DELETE key pressed, delete character */
if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT)
{ {
/* Check if buffer is not empty */
if(InputFieldLength > 0 && TextPosition < InputFieldLength) if(InputFieldLength > 0 && TextPosition < InputFieldLength)
{ {
/* Delete character */
RtlMoveMemory(InputFieldBuffer + TextPosition, InputFieldBuffer + TextPosition + 1, RtlMoveMemory(InputFieldBuffer + TextPosition, InputFieldBuffer + TextPosition + 1,
(InputFieldLength - TextPosition) * sizeof(WCHAR)); (InputFieldLength - TextPosition) * sizeof(WCHAR));
/* Decrement length and null terminate string */
InputFieldLength--; InputFieldLength--;
InputFieldBuffer[InputFieldLength] = 0; InputFieldBuffer[InputFieldLength] = L'\0';
} }
} }
} }
@@ -567,13 +875,17 @@ BlDisplayInputDialog(IN PWCHAR Caption,
/* BACKSPACE key pressed, delete character */ /* BACKSPACE key pressed, delete character */
if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT)
{ {
/* Check if buffer is not empty */
if(InputFieldLength > 0 && TextPosition > 0 && TextPosition <= InputFieldLength) if(InputFieldLength > 0 && TextPosition > 0 && TextPosition <= InputFieldLength)
{ {
/* Move memory to overwrite the character to the left of the cursor */
RtlMoveMemory(InputFieldBuffer + TextPosition - 1, InputFieldBuffer + TextPosition,
(InputFieldLength - TextPosition + 1) * sizeof(WCHAR));
/* Decrement length, position and null terminate string */
TextPosition--; TextPosition--;
RtlMoveMemory(InputFieldBuffer + TextPosition, InputFieldBuffer + TextPosition + 1,
(InputFieldLength - TextPosition) * sizeof(WCHAR));
InputFieldLength--; InputFieldLength--;
InputFieldBuffer[InputFieldLength] = 0; InputFieldBuffer[InputFieldLength] = L'\0';
} }
} }
} }
@@ -588,15 +900,23 @@ BlDisplayInputDialog(IN PWCHAR Caption,
/* Other key pressed, add character to the buffer */ /* Other key pressed, add character to the buffer */
if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT && Key.UnicodeChar != 0) if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT && Key.UnicodeChar != 0)
{ {
/* Check if buffer is full */
if(InputFieldLength < 2047)
{
/* Insert character at current position */
RtlMoveMemory(InputFieldBuffer + TextPosition + 1, InputFieldBuffer + TextPosition, RtlMoveMemory(InputFieldBuffer + TextPosition + 1, InputFieldBuffer + TextPosition,
(InputFieldLength - TextPosition) * sizeof(WCHAR)); (InputFieldLength - TextPosition) * sizeof(WCHAR));
InputFieldBuffer[TextPosition] = Key.UnicodeChar; InputFieldBuffer[TextPosition] = Key.UnicodeChar;
/* Increment length, position and null terminate string */
TextPosition++; TextPosition++;
InputFieldLength++; InputFieldLength++;
InputFieldBuffer[InputFieldLength] = 0; InputFieldBuffer[InputFieldLength] = L'\0';
}
} }
} }
/* Calculate text index and cursor position */
if(TextPosition > (Handle.Width - 9)) if(TextPosition > (Handle.Width - 9))
{ {
TextIndex = TextPosition - (Handle.Width - 9); TextIndex = TextPosition - (Handle.Width - 9);
@@ -612,6 +932,7 @@ BlDisplayInputDialog(IN PWCHAR Caption,
BlpDrawDialogButton(&Handle); BlpDrawDialogButton(&Handle);
BlpDrawDialogInputField(&Handle, &InputFieldBuffer[TextIndex]); BlpDrawDialogInputField(&Handle, &InputFieldBuffer[TextIndex]);
/* Set cursor position if input field is active */
if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT)
{ {
BlSetCursorPosition(Handle.PosX + 4 + TextCursorPosition, Handle.PosY + Handle.Height - 4); BlSetCursorPosition(Handle.PosX + 4 + TextCursorPosition, Handle.PosY + Handle.Height - 4);
@@ -870,8 +1191,8 @@ BlpDrawBootMenu(OUT PXTBL_DIALOG_HANDLE Handle)
BlSetCursorPosition(0, Handle->PosY + Handle->Height); BlSetCursorPosition(0, Handle->PosY + Handle->Height);
BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
BlConsolePrint(L" Use cursors to change the selection. Press ENTER key to boot the chosen\n" BlConsolePrint(L" Use cursors to change the selection. Press ENTER key to boot the chosen\n"
" Operating System, 'e' to edit it before booting or 's' for XTLDR shell.\n" L" Operating System, 'e' to edit it before booting or 's' for XTLDR shell.\n"
" Additional help available after pressing F1 key."); L" Additional help available after pressing F1 key.");
} }
/** /**
@@ -1330,3 +1651,164 @@ BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle,
BlDisableConsoleCursor(); BlDisableConsoleCursor();
BlConsoleWrite(ProgressBar); BlConsoleWrite(ProgressBar);
} }
/**
* Draws a text-based boot edition menu.
*
* @param Handle
* Supplies a pointer to the edition menu handle.
*
* @return This function does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BlpDrawEditMenu(OUT PXTBL_DIALOG_HANDLE Handle)
{
/* Query console screen resolution */
BlQueryConsoleMode(&Handle->ResX, &Handle->ResY);
/* Set boot menu parameters */
Handle->Attributes = 0;
Handle->DialogColor = EFI_TEXT_BGCOLOR_BLACK;
Handle->TextColor = EFI_TEXT_FGCOLOR_LIGHTGRAY;
Handle->PosX = 3;
Handle->PosY = 3;
Handle->Width = Handle->ResX - 6;
Handle->Height = Handle->ResY - 10;
/* Clear screen and disable cursor */
BlSetConsoleAttributes(Handle->DialogColor | Handle->TextColor);
BlClearConsoleScreen();
BlDisableConsoleCursor();
/* Check if debugging enabled */
if(DEBUG)
{
/* Print debug version of XTLDR banner */
BlSetCursorPosition((Handle->ResX - 44) / 2, 1);
BlConsolePrint(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 banner */
BlSetCursorPosition((Handle->ResX - 22) / 2, 1);
BlConsolePrint(L"XTLDR Boot Loader v%d.%d\n", XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR);
}
/* Draw empty dialog box for boot menu */
BlpDrawDialogBox(Handle, L"Edit Options", NULL);
/* Print help message below the edit menu */
BlSetCursorPosition(0, Handle->PosY + Handle->Height);
BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
BlConsolePrint(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 CTRL-B to boot.\n");
}
/**
* Draws edit menu entry at the specified position.
*
* @param Handle
* Supplies a pointer to the boot menu handle.
*
* @param OptionName
* Supplies a pointer to the buffer containing a part of the menu entry name (an option name).
*
* @param OptionValue
* Supplies a pointer to the buffer containing a part of the menu entry name (an option value).
*
* @param Position
* Specifies entry position on the list in the boot menu.
*
* @param Highlighted
* Specifies whether this entry should be highlighted or not.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlpDrawEditMenuEntry(IN PXTBL_DIALOG_HANDLE Handle,
IN PWCHAR OptionName,
IN PWCHAR OptionValue,
IN UINT Position,
IN BOOLEAN Highlighted)
{
BOOLEAN Allocation;
PWCHAR DisplayValue, ShortValue;
UINT Index;
ULONG OptionNameLength, OptionValueLength, OptionWidth;
EFI_STATUS Status;
/* Assume no allocation was made */
Allocation = FALSE;
/* Set display value depending on input */
DisplayValue = (OptionValue != NULL) ? OptionValue : L"";
/* Determine lengths */
OptionNameLength = RtlWideStringLength(OptionName, 0);
OptionValueLength = RtlWideStringLength(DisplayValue, 0);
OptionWidth = Handle->Width - 4 - (OptionNameLength + 2);
/* Check if value needs to be truncated */
if(OptionValueLength > OptionWidth)
{
/* Allocate buffer for new, shortened value */
Status = BlAllocateMemoryPool((OptionWidth + 1) * sizeof(WCHAR), (PVOID *)&ShortValue);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, print debug message and return */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status);
return Status;
}
/* Copy a desired value length into the allocated buffer and append "..." */
RtlCopyMemory(ShortValue, DisplayValue, (OptionWidth - 3) * sizeof(WCHAR));
RtlCopyMemory(ShortValue + OptionWidth - 3, L"...", 3 * sizeof(WCHAR));
ShortValue[OptionWidth] = L'\0';
/* Mark that allocation was made and set new display value */
Allocation = TRUE;
DisplayValue = ShortValue;
}
/* Move cursor to the right position */
BlSetCursorPosition(5, 4 + Position);
/* Check whether this entry should be highlighted */
if(Highlighted)
{
/* Highlight this entry */
BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_LIGHTGRAY | EFI_TEXT_FGCOLOR_BLACK);
}
else
{
/* Set default colors */
BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
}
/* Clear menu entry */
for(Index = 0; Index < Handle->Width - 4; Index++)
{
BlConsolePrint(L" ");
}
/* Print menu entry */
BlSetCursorPosition(5, 4 + Position);
BlConsolePrint(L"%S: %S", OptionName, DisplayValue);
/* Check if allocation was made */
if(Allocation)
{
/* Free allocated memory */
BlFreeMemoryPool(DisplayValue);
}
/* Return success */
return STATUS_EFI_SUCCESS;
}

View File

@@ -4,6 +4,7 @@
* FILE: xtldr/volume.c * FILE: xtldr/volume.c
* DESCRIPTION: XTLDR volume support * DESCRIPTION: XTLDR volume support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/ */
#include <xtldr.h> #include <xtldr.h>
@@ -47,7 +48,11 @@ XTCDECL
EFI_STATUS EFI_STATUS
BlEnumerateBlockDevices() BlEnumerateBlockDevices()
{ {
PEFI_DEVICE_PATH_PROTOCOL LastNode = NULL; EFI_GUID LoadedImageProtocolGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
EFI_GUID BlockIoGuid = EFI_BLOCK_IO_PROTOCOL_GUID;
EFI_HANDLE BootDeviceHandle = NULL, DeviceHandle = NULL;
EFI_LOADED_IMAGE_PROTOCOL* LoadedImage;
PEFI_DEVICE_PATH_PROTOCOL DevicePath = NULL, LastNode = NULL;
PEFI_BLOCK_DEVICE_DATA ParentNode = NULL; PEFI_BLOCK_DEVICE_DATA ParentNode = NULL;
PEFI_BLOCK_DEVICE_DATA BlockDeviceData; PEFI_BLOCK_DEVICE_DATA BlockDeviceData;
PEFI_BLOCK_DEVICE BlockDevice; PEFI_BLOCK_DEVICE BlockDevice;
@@ -62,6 +67,18 @@ BlEnumerateBlockDevices()
USHORT DriveType; USHORT DriveType;
ULONG CDCount = 0, FDCount = 0, HDCount = 0, RDCount = 0; ULONG CDCount = 0, FDCount = 0, HDCount = 0, RDCount = 0;
/* Get the device handle of the image that is running */
Status = EfiSystemTable->BootServices->HandleProtocol(EfiImageHandle, &LoadedImageProtocolGuid, (VOID**)&LoadedImage);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get boot device handle */
BlDebugPrint(L"ERROR: Failed to get boot device handle (Status Code: 0x%zX)\n", Status);
return Status;
}
/* Save the boot device handle */
BootDeviceHandle = LoadedImage->DeviceHandle;
/* Initialize list entries */ /* Initialize list entries */
RtlInitializeListHead(&BlockDevices); RtlInitializeListHead(&BlockDevices);
RtlInitializeListHead(&EfiBlockDevices); RtlInitializeListHead(&EfiBlockDevices);
@@ -78,21 +95,42 @@ BlEnumerateBlockDevices()
ListEntry = BlockDevices.Flink; ListEntry = BlockDevices.Flink;
while(ListEntry != &BlockDevices) while(ListEntry != &BlockDevices)
{ {
/* Take block device from the list */ /* Get data for the next discovered device. */
BlockDeviceData = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE_DATA, ListEntry); BlockDeviceData = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE_DATA, ListEntry);
PartitionGuid = NULL;
/* Find last node */ /* Find last node */
Status = BlpFindLastBlockDeviceNode(BlockDeviceData->DevicePath, &LastNode); Status = BlpFindLastBlockDeviceNode(BlockDeviceData->DevicePath, &LastNode);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Skip this device if its last node cannot be found, as it is required for classification */
BlDebugPrint(L"WARNING: Block device last node not found\n"); BlDebugPrint(L"WARNING: Block device last node not found\n");
ListEntry = ListEntry->Flink; ListEntry = ListEntry->Flink;
continue; continue;
} }
/* Set drive type to 'unknown' by default */ /* Initialize drive type before attempting to classify the device */
DriveType = XTBL_BOOT_DEVICE_UNKNOWN; DriveType = XTBL_BOOT_DEVICE_UNKNOWN;
/* Locate the parent for this block device to ensure it is not an orphaned entry */
if(!BlpFindParentBlockDevice(&BlockDevices, BlockDeviceData, &ParentNode))
{
/* Orphaned device found. Log a warning and skip it as it cannot be properly classified */
BlDebugPrint(L"WARNING: No parent device found, skipping orphaned media device path\n");
ListEntry = ListEntry->Flink;
continue;
}
/* Verify that media information is available, as some devices may not report it */
if(!BlockDeviceData->BlockIo->Media)
{
/* The device is unusable without media info, log a warning and skip it */
BlDebugPrint(L"WARNING: Block device is missing media information\n");
ListEntry = ListEntry->Flink;
continue;
}
Media = BlockDeviceData->BlockIo->Media;
/* Check last node type */ /* Check last node type */
if(LastNode->Type == EFI_ACPI_DEVICE_PATH && LastNode->SubType == EFI_ACPI_DP) if(LastNode->Type == EFI_ACPI_DEVICE_PATH && LastNode->SubType == EFI_ACPI_DP)
{ {
@@ -101,7 +139,6 @@ BlEnumerateBlockDevices()
if(AcpiDevice->HID == 0x60441D0 || AcpiDevice->HID == 0x70041D0 || AcpiDevice->HID == 0x70141D1) if(AcpiDevice->HID == 0x60441D0 || AcpiDevice->HID == 0x70041D0 || AcpiDevice->HID == 0x70141D1)
{ {
/* Floppy drive found */ /* Floppy drive found */
Media = BlockDeviceData->BlockIo->Media;
DriveType = XTBL_BOOT_DEVICE_FLOPPY; DriveType = XTBL_BOOT_DEVICE_FLOPPY;
DriveNumber = FDCount++; DriveNumber = FDCount++;
PartitionNumber = 0; PartitionNumber = 0;
@@ -111,13 +148,12 @@ BlEnumerateBlockDevices()
DriveNumber, Media->MediaPresent, Media->ReadOnly); DriveNumber, Media->MediaPresent, Media->ReadOnly);
} }
} }
else if(LastNode->Type == EFI_MEDIA_DEVICE_PATH) else if((LastNode->Type == EFI_MEDIA_DEVICE_PATH && LastNode->SubType == EFI_MEDIA_CDROM_DP) ||
{ (LastNode->Type == EFI_MESSAGING_DEVICE_PATH &&
/* Media device path found */ (LastNode->SubType == EFI_MESSAGING_ATAPI_DP || LastNode->SubType == EFI_MESSAGING_SATA_DP) &&
if(LastNode->SubType == EFI_MEDIA_CDROM_DP) Media->MediaPresent && Media->RemovableMedia))
{ {
/* Optical drive found */ /* Optical drive found */
Media = BlockDeviceData->BlockIo->Media;
DriveType = XTBL_BOOT_DEVICE_CDROM; DriveType = XTBL_BOOT_DEVICE_CDROM;
DriveNumber = CDCount++; DriveNumber = CDCount++;
PartitionNumber = 0; PartitionNumber = 0;
@@ -126,26 +162,43 @@ BlEnumerateBlockDevices()
BlDebugPrint(L"Found CD-ROM drive (DriveNumber: %lu, MediaPresent: %u, RemovableMedia: %u, RO: %u)\n", BlDebugPrint(L"Found CD-ROM drive (DriveNumber: %lu, MediaPresent: %u, RemovableMedia: %u, RO: %u)\n",
DriveNumber, Media->MediaPresent, Media->RemovableMedia, Media->ReadOnly); DriveNumber, Media->MediaPresent, Media->RemovableMedia, Media->ReadOnly);
} }
else if(LastNode->SubType == EFI_MEDIA_HARDDRIVE_DP) else if(LastNode->Type == EFI_MEDIA_DEVICE_PATH && LastNode->SubType == EFI_MEDIA_HARDDRIVE_DP)
{ {
/* Hard disk partition found */ /* Hard disk partition found */
Media = BlockDeviceData->BlockIo->Media;
HDPath = (PEFI_HARDDRIVE_DEVICE_PATH)LastNode; HDPath = (PEFI_HARDDRIVE_DEVICE_PATH)LastNode;
DriveType = XTBL_BOOT_DEVICE_HARDDISK; DriveType = XTBL_BOOT_DEVICE_HARDDISK;
DriveNumber = (HDPath->PartitionNumber == 1) ? HDCount++ : HDCount - 1; DriveNumber = (HDPath->PartitionNumber == 1) ? HDCount++ : HDCount - 1;
PartitionNumber = HDPath->PartitionNumber; PartitionNumber = HDPath->PartitionNumber;
PartitionGuid = (PEFI_GUID)HDPath->Signature; PartitionGuid = (PEFI_GUID)HDPath->Signature;
/* Check if this is the EFI System Partition (ESP) */
if(BootDeviceHandle != NULL)
{
/* Allocate memory for device path */
DevicePath = BlpDuplicateDevicePath(BlockDeviceData->DevicePath);
if(DevicePath != NULL)
{
/* Check if this is the boot device */
Status = EfiSystemTable->BootServices->LocateDevicePath(&BlockIoGuid, &DevicePath,
&DeviceHandle);
if(Status == STATUS_EFI_SUCCESS && DeviceHandle == BootDeviceHandle)
{
/* Mark partition as ESP */
DriveType |= XTBL_BOOT_DEVICE_ESP;
}
}
}
/* Print debug message */ /* Print debug message */
BlDebugPrint(L"Found Hard Disk partition (DiskNumber: %lu, PartNumber: %lu, " BlDebugPrint(L"Found Hard Disk partition (DiskNumber: %lu, PartNumber: %lu, "
L"MBRType: %u, GUID: {%V}, PartSize: %uB)\n", L"MBRType: %u, GUID: {%V}, PartSize: %lluB) %S\n",
DriveNumber, PartitionNumber, HDPath->MBRType, DriveNumber, PartitionNumber, HDPath->MBRType,
PartitionGuid, HDPath->PartitionSize * Media->BlockSize); PartitionGuid, HDPath->PartitionSize * Media->BlockSize,
(DriveType & XTBL_BOOT_DEVICE_ESP) ? L"(ESP)" : L"");
} }
else if(LastNode->SubType == EFI_MEDIA_RAMDISK_DP) else if(LastNode->Type == EFI_MEDIA_DEVICE_PATH && LastNode->SubType == EFI_MEDIA_RAMDISK_DP)
{ {
/* RAM disk found */ /* RAM disk found */
Media = BlockDeviceData->BlockIo->Media;
DriveType = XTBL_BOOT_DEVICE_RAMDISK; DriveType = XTBL_BOOT_DEVICE_RAMDISK;
DriveNumber = RDCount++; DriveNumber = RDCount++;
PartitionNumber = 0; PartitionNumber = 0;
@@ -155,13 +208,6 @@ BlEnumerateBlockDevices()
DriveNumber, Media->MediaPresent); DriveNumber, Media->MediaPresent);
} }
if(!BlpFindParentBlockDevice(&BlockDevices, BlockDeviceData, ParentNode))
{
BlDebugPrint(L"WARNING: No parent device found, skipping orphaned media device path\n");
continue;
}
}
/* Make sure the device found has valid type set */ /* Make sure the device found has valid type set */
if(DriveType != XTBL_BOOT_DEVICE_UNKNOWN) if(DriveType != XTBL_BOOT_DEVICE_UNKNOWN)
{ {
@@ -418,20 +464,34 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath,
{ {
/* Check if this is the volume we are looking for */ /* Check if this is the volume we are looking for */
Device = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE, ListEntry); Device = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE, ListEntry);
if((Device->DriveType == DriveType && Device->DriveNumber == DriveNumber && if(DriveType == XTBL_BOOT_DEVICE_ESP)
Device->PartitionNumber == PartNumber)) {
/* ESP requested, verify if flag is set for this device */
if((Device->DriveType & XTBL_BOOT_DEVICE_ESP) != 0)
{ {
/* Found volume */ /* Found volume */
*DevicePath = Device->DevicePath; *DevicePath = Device->DevicePath;
break; break;
} }
}
else
{
if(((Device->DriveType & DriveType) == DriveType) &&
(Device->DriveNumber == DriveNumber) &&
(Device->PartitionNumber == PartNumber))
{
/* Found volume */
*DevicePath = Device->DevicePath;
break;
}
}
ListEntry = ListEntry->Flink; ListEntry = ListEntry->Flink;
} }
/* Check if volume was found */ /* Check if volume was found */
if(*DevicePath == NULL) if(*DevicePath == NULL)
{ {
/* Failed to find volume */ /* Volume not found */
BlDebugPrint(L"ERROR: Volume (DriveType: %u, DriveNumber: %lu, PartNumber: %lu) not found\n", BlDebugPrint(L"ERROR: Volume (DriveType: %u, DriveNumber: %lu, PartNumber: %lu) not found\n",
DriveType, DriveNumber, PartNumber); DriveType, DriveNumber, PartNumber);
return STATUS_EFI_NOT_FOUND; return STATUS_EFI_NOT_FOUND;
@@ -606,7 +666,7 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
Pages = EFI_SIZE_TO_PAGES(FileInfo->FileSize); Pages = EFI_SIZE_TO_PAGES(FileInfo->FileSize);
/* Allocate pages */ /* Allocate pages */
Status = BlAllocateMemoryPages(Pages, &Address); Status = BlAllocateMemoryPages(AllocateAnyPages, Pages, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Pages allocation failure */ /* Pages allocation failure */
@@ -776,6 +836,12 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath,
ArcLength = 10; ArcLength = 10;
*DriveType = XTBL_BOOT_DEVICE_RAMDISK; *DriveType = XTBL_BOOT_DEVICE_RAMDISK;
} }
else if(RtlCompareWideStringInsensitive(SystemPath, L"multi(0)esp(0)", 0) == 0)
{
/* This is ESP */
ArcLength = 14;
*DriveType = XTBL_BOOT_DEVICE_ESP;
}
else if(RtlCompareWideStringInsensitive(SystemPath, L"multi(0)disk(0)", 0) == 0) else if(RtlCompareWideStringInsensitive(SystemPath, L"multi(0)disk(0)", 0) == 0)
{ {
/* This is a multi-disk port */ /* This is a multi-disk port */
@@ -917,17 +983,25 @@ BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath)
EFI_STATUS Status; EFI_STATUS Status;
UINT Length = 0; UINT Length = 0;
/* Check if the input device path is NULL */
if(!DevicePath)
{
/* Nothing to duplicate */
return NULL;
}
/* Start iterating from the beginning of the device path */
DevicePathNode = DevicePath; DevicePathNode = DevicePath;
/* Get the device path length */ /* Get the device path length */
while(TRUE) while(TRUE)
{ {
Length += *(PUSHORT)DevicePath->Length; Length += *(PUSHORT)DevicePathNode->Length;
if(DevicePathNode->Type == EFI_END_DEVICE_PATH) if(DevicePathNode->Type == EFI_END_DEVICE_PATH)
{ {
break; break;
} }
DevicePathNode = (PEFI_DEVICE_PATH_PROTOCOL)((PUCHAR)DevicePathNode + *(PUSHORT)DevicePath->Length); DevicePathNode = (PEFI_DEVICE_PATH_PROTOCOL)((PUCHAR)DevicePathNode + *(PUSHORT)DevicePathNode->Length);
} }
/* Check length */ /* Check length */
@@ -1016,7 +1090,7 @@ XTCDECL
BOOLEAN BOOLEAN
BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices, BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices,
IN PEFI_BLOCK_DEVICE_DATA ChildNode, IN PEFI_BLOCK_DEVICE_DATA ChildNode,
OUT PEFI_BLOCK_DEVICE_DATA ParentNode) OUT PEFI_BLOCK_DEVICE_DATA *ParentNode)
{ {
PEFI_DEVICE_PATH_PROTOCOL ChildDevicePath, ParentDevicePath; PEFI_DEVICE_PATH_PROTOCOL ChildDevicePath, ParentDevicePath;
PEFI_BLOCK_DEVICE_DATA BlockDeviceData; PEFI_BLOCK_DEVICE_DATA BlockDeviceData;
@@ -1029,6 +1103,14 @@ BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices,
/* Take block device from the list */ /* Take block device from the list */
BlockDeviceData = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE_DATA, ListEntry); BlockDeviceData = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE_DATA, ListEntry);
/* A device cannot be its own parent */
if (BlockDeviceData == ChildNode)
{
/* Move to the next device */
ListEntry = ListEntry->Flink;
continue;
}
ChildDevicePath = ChildNode->DevicePath; ChildDevicePath = ChildNode->DevicePath;
ParentDevicePath = BlockDeviceData->DevicePath; ParentDevicePath = BlockDeviceData->DevicePath;
@@ -1039,7 +1121,7 @@ BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices,
if(ParentDevicePath->Type == EFI_END_DEVICE_PATH) if(ParentDevicePath->Type == EFI_END_DEVICE_PATH)
{ {
/* Parent device is a match */ /* Parent device is a match */
ParentNode = BlockDeviceData; *ParentNode = BlockDeviceData;
return TRUE; return TRUE;
} }
@@ -1047,10 +1129,11 @@ BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices,
ChildLength = *(PUSHORT)ChildDevicePath->Length; ChildLength = *(PUSHORT)ChildDevicePath->Length;
ParentLength = *(PUSHORT)ParentDevicePath->Length; ParentLength = *(PUSHORT)ParentDevicePath->Length;
/* Check if lengths match */ /* Check if nodes match */
if(ChildLength != ParentLength) if((ChildLength != ParentLength) ||
(RtlCompareMemory(ChildDevicePath, ParentDevicePath, ParentLength) != ParentLength))
{ {
/* Lengths do not match, this is not a valid parent */ /* Nodes do not match, this is not a valid parent */
break; break;
} }

View File

@@ -90,16 +90,17 @@ BlInitializeBootLoader()
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM *MenuEntries, BlInitializeBootMenuList(IN ULONG MaxNameLength,
OUT PXTBL_BOOTMENU_ITEM *MenuEntries,
OUT PULONG EntriesCount, OUT PULONG EntriesCount,
OUT PULONG DefaultId) OUT PULONG DefaultId)
{ {
EFI_GUID VendorGuid = XT_BOOT_LOADER_PROTOCOL_GUID; EFI_GUID VendorGuid = XT_BOOT_LOADER_PROTOCOL_GUID;
PWCHAR DefaultMenuEntry, LastBooted, MenuEntryName; PWCHAR DefaultMenuEntry, LastBooted, MenuEntryName, VisibleName;
PLIST_ENTRY MenuEntrySectionList, MenuEntryList; PLIST_ENTRY MenuEntrySectionList, MenuEntryList;
PXTBL_CONFIG_SECTION MenuEntrySection; PXTBL_CONFIG_SECTION MenuEntrySection;
PXTBL_CONFIG_ENTRY MenuEntryOption; PXTBL_CONFIG_ENTRY MenuEntryOption;
ULONG DefaultOS, NumberOfEntries; ULONG DefaultOS, NameLength,NumberOfEntries;
PXTBL_BOOTMENU_ITEM OsList; PXTBL_BOOTMENU_ITEM OsList;
EFI_STATUS Status; EFI_STATUS Status;
@@ -108,7 +109,7 @@ BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM *MenuEntries,
NumberOfEntries = 0; NumberOfEntries = 0;
/* Get default menu entry from configuration */ /* Get default menu entry from configuration */
DefaultMenuEntry = BlGetConfigValue(L"DEFAULT"); BlGetConfigValue(L"DEFAULT", &DefaultMenuEntry);
/* Check if configuration allows to use last booted OS */ /* Check if configuration allows to use last booted OS */
if(BlGetConfigBooleanValue(L"KEEPLASTBOOT")) if(BlGetConfigBooleanValue(L"KEEPLASTBOOT"))
@@ -151,7 +152,8 @@ BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM *MenuEntries,
MenuEntrySection = CONTAIN_RECORD(MenuEntrySectionList, XTBL_CONFIG_SECTION, Flink); MenuEntrySection = CONTAIN_RECORD(MenuEntrySectionList, XTBL_CONFIG_SECTION, Flink);
/* Check if this is the default menu entry */ /* Check if this is the default menu entry */
if(RtlCompareWideStringInsensitive(MenuEntrySection->SectionName, DefaultMenuEntry, 0) == 0) if((RtlWideStringLength(MenuEntrySection->SectionName, 0) == RtlWideStringLength(DefaultMenuEntry, 0)) &&
(RtlCompareWideStringInsensitive(MenuEntrySection->SectionName, DefaultMenuEntry, 0) == 0))
{ {
/* Set default OS ID */ /* Set default OS ID */
DefaultOS = NumberOfEntries; DefaultOS = NumberOfEntries;
@@ -176,10 +178,36 @@ BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM *MenuEntries,
} }
/* Add OS to the boot menu list */ /* Add OS to the boot menu list */
OsList[NumberOfEntries].EntryName = MenuEntryName; OsList[NumberOfEntries].FullName = MenuEntryName;
OsList[NumberOfEntries].ShortName = MenuEntrySection->SectionName; OsList[NumberOfEntries].ShortName = MenuEntrySection->SectionName;
OsList[NumberOfEntries].Options = &MenuEntrySection->Options; OsList[NumberOfEntries].Options = &MenuEntrySection->Options;
/* Check if the menu entry name fits the maximum length */
NameLength = RtlWideStringLength(MenuEntryName, 0);
if(NameLength > MaxNameLength)
{
/* Menu entry name is too long, allocate memory for shorter name visible in the boot menu */
Status = BlAllocateMemoryPool((MaxNameLength + 1) * sizeof(WCHAR), (PVOID*)&VisibleName);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
return STATUS_EFI_OUT_OF_RESOURCES;
}
/* Copy shorter name and append "..." at the end */
RtlCopyMemory(VisibleName, MenuEntryName, (MaxNameLength - 3) * sizeof(WCHAR));
RtlCopyMemory(VisibleName + MaxNameLength - 3, L"...", 3 * sizeof(WCHAR));
VisibleName[MaxNameLength] = L'\0';
/* Set visible menu entry name */
OsList[NumberOfEntries].EntryName = VisibleName;
}
else
{
/* Menu entry name fits the maximum length, use it as is */
OsList[NumberOfEntries].EntryName = MenuEntryName;
}
/* Get next menu entry */ /* Get next menu entry */
MenuEntrySectionList = MenuEntrySectionList->Flink; MenuEntrySectionList = MenuEntrySectionList->Flink;
NumberOfEntries++; NumberOfEntries++;
@@ -363,6 +391,7 @@ EFI_STATUS
BlStartXtLoader(IN EFI_HANDLE ImageHandle, BlStartXtLoader(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable) IN PEFI_SYSTEM_TABLE SystemTable)
{ {
PWCHAR Modules;
EFI_STATUS Status; EFI_STATUS Status;
/* Set the system table and image handle */ /* Set the system table and image handle */
@@ -427,8 +456,9 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle,
return Status; return Status;
} }
/* Load boot loader modules */ /* Load all necessary modules */
Status = BlLoadModules(BlGetConfigValue(L"MODULES")); BlGetConfigValue(L"MODULES", &Modules);
Status = BlLoadModules(Modules);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to load modules */ /* Failed to load modules */

View File

@@ -1,4 +1,5 @@
# XT Kernel # XT Kernel and library
PROJECT(LIBXTOS)
PROJECT(XTOSKRNL) PROJECT(XTOSKRNL)
# Specify include directories # Specify include directories
@@ -6,42 +7,70 @@ include_directories(
${EXECTOS_SOURCE_DIR}/sdk/xtdk ${EXECTOS_SOURCE_DIR}/sdk/xtdk
${XTOSKRNL_SOURCE_DIR}/includes) ${XTOSKRNL_SOURCE_DIR}/includes)
# Specify list of source code files # Specify list of library source code files
list(APPEND LIBXTOS_SOURCE
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/boot.S
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.cc
${XTOSKRNL_SOURCE_DIR}/hl/cport.c
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.c
${XTOSKRNL_SOURCE_DIR}/rtl/globals.c
${XTOSKRNL_SOURCE_DIR}/rtl/guid.c
${XTOSKRNL_SOURCE_DIR}/rtl/math.c
${XTOSKRNL_SOURCE_DIR}/rtl/memory.c
${XTOSKRNL_SOURCE_DIR}/rtl/plist.c
${XTOSKRNL_SOURCE_DIR}/rtl/string.c
${XTOSKRNL_SOURCE_DIR}/rtl/widestr.c)
# 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}/cpufunc.c ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/boot.S
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/globals.c ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.cc
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/procsup.c ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/data.cc
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/traps.c ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/procsup.cc
${XTOSKRNL_SOURCE_DIR}/ex/rundown.c ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/traps.cc
${XTOSKRNL_SOURCE_DIR}/ex/exports.cc
${XTOSKRNL_SOURCE_DIR}/ex/rundown.cc
${XTOSKRNL_SOURCE_DIR}/hl/acpi.c
${XTOSKRNL_SOURCE_DIR}/hl/cport.c ${XTOSKRNL_SOURCE_DIR}/hl/cport.c
${XTOSKRNL_SOURCE_DIR}/hl/efifb.c ${XTOSKRNL_SOURCE_DIR}/hl/fbdev.c
${XTOSKRNL_SOURCE_DIR}/hl/globals.c ${XTOSKRNL_SOURCE_DIR}/hl/globals.c
${XTOSKRNL_SOURCE_DIR}/hl/init.c
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/cpu.c ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/cpu.c
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/pic.c ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/pic.c
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.c ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.c
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/runlevel.c ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/runlevel.c
${XTOSKRNL_SOURCE_DIR}/kd/dbginit.c
${XTOSKRNL_SOURCE_DIR}/kd/dbgio.c
${XTOSKRNL_SOURCE_DIR}/kd/globals.c
${XTOSKRNL_SOURCE_DIR}/ke/apc.c ${XTOSKRNL_SOURCE_DIR}/ke/apc.c
${XTOSKRNL_SOURCE_DIR}/ke/dpc.c ${XTOSKRNL_SOURCE_DIR}/ke/dpc.c
${XTOSKRNL_SOURCE_DIR}/ke/event.c ${XTOSKRNL_SOURCE_DIR}/ke/event.c
${XTOSKRNL_SOURCE_DIR}/ke/globals.c ${XTOSKRNL_SOURCE_DIR}/ke/globals.c
${XTOSKRNL_SOURCE_DIR}/ke/info.c
${XTOSKRNL_SOURCE_DIR}/ke/kprocess.c ${XTOSKRNL_SOURCE_DIR}/ke/kprocess.c
${XTOSKRNL_SOURCE_DIR}/ke/krnlinit.c ${XTOSKRNL_SOURCE_DIR}/ke/krnlinit.c
${XTOSKRNL_SOURCE_DIR}/ke/kthread.c ${XTOSKRNL_SOURCE_DIR}/ke/kthread.c
${XTOSKRNL_SOURCE_DIR}/ke/kubsan.c
${XTOSKRNL_SOURCE_DIR}/ke/panic.c ${XTOSKRNL_SOURCE_DIR}/ke/panic.c
${XTOSKRNL_SOURCE_DIR}/ke/runlevel.c ${XTOSKRNL_SOURCE_DIR}/ke/runlevel.c
${XTOSKRNL_SOURCE_DIR}/ke/semphore.c ${XTOSKRNL_SOURCE_DIR}/ke/semphore.c
${XTOSKRNL_SOURCE_DIR}/ke/spinlock.c ${XTOSKRNL_SOURCE_DIR}/ke/spinlock.c
${XTOSKRNL_SOURCE_DIR}/ke/sysres.c
${XTOSKRNL_SOURCE_DIR}/ke/timer.c ${XTOSKRNL_SOURCE_DIR}/ke/timer.c
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/irqs.c ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/irqs.c
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/krnlinit.c ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/krnlinit.c
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/kthread.c ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/kthread.c
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/proc.c ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/proc.c
${XTOSKRNL_SOURCE_DIR}/mm/globals.c ${XTOSKRNL_SOURCE_DIR}/mm/globals.c
${XTOSKRNL_SOURCE_DIR}/mm/hlpool.c
${XTOSKRNL_SOURCE_DIR}/mm/init.c ${XTOSKRNL_SOURCE_DIR}/mm/init.c
${XTOSKRNL_SOURCE_DIR}/mm/kpools.c ${XTOSKRNL_SOURCE_DIR}/mm/kpools.c
${XTOSKRNL_SOURCE_DIR}/mm/pages.c
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/globals.c
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/init.c ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/init.c
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pages.c ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pages.c
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pmap.c
${XTOSKRNL_SOURCE_DIR}/po/idle.c ${XTOSKRNL_SOURCE_DIR}/po/idle.c
${XTOSKRNL_SOURCE_DIR}/rtl/atomic.c ${XTOSKRNL_SOURCE_DIR}/rtl/atomic.c
${XTOSKRNL_SOURCE_DIR}/rtl/bitmap.c ${XTOSKRNL_SOURCE_DIR}/rtl/bitmap.c
@@ -61,7 +90,7 @@ list(APPEND XTOSKRNL_SOURCE
set_specfile(xtoskrnl.spec xtoskrnl.exe) set_specfile(xtoskrnl.spec xtoskrnl.exe)
# Link static XTOS library # Link static XTOS library
add_library(libxtos ${XTOSKRNL_SOURCE}) add_library(libxtos ${LIBXTOS_SOURCE})
# Link kernel executable # Link kernel executable
add_executable(xtoskrnl add_executable(xtoskrnl

View File

@@ -1,58 +1,68 @@
## XTOSKRNL ## XTOSKRNL
XTOSKRNL is an XT system kernel executable, providing the kernel and executive layers for XTOS kernel space. It is XTOSKRNL is the core kernel executable for ExectOS, providing the fundamental kernel and executive layers that operate
a fundamental part of ExectOS, responsible for various core services like hardware abstraction or memory management. within the XTOS kernel space. It is responsible for various core services, such as hardware abstraction, memory
This kernel, contains the scheduler (called sometimes as Dispatcher), cache, object and memory managers, security management, and process scheduling. The kernel contains the scheduler (sometimes referred to as the Dispatcher), the
manager and other kernel executives described below. cache, object, and memory managers, the security manager, and other executive components described below.
All routines in kernel are prefixed to indicate the kernel subsystem they belong and put inside separate directory. All routines in the kernel are prefixed to indicate the subsystem they belong to, and their source code is organized
This is a list of them: into corresponding directories. These subsystems include:
* Ar - Architecture library * Ar - Architecture-specific Library
* Ex - Kernel Executive * Ex - Kernel Executive
* Hl - Hardware Abstraction Layer (HAL) * Hl - Hardware Layer
* Ke - Core kernel library * Kd - Kernel Debugger
* Mm - Memory manager * Ke - Core Kernel Library
* Mm - Memory Manager
* Po - Plug&Play and Power Manager * Po - Plug&Play and Power Manager
* Rtl - Runtime library * Rtl - Runtime library
### AR: Architecture Library ### AR: Architecture Library
This module contains processor architecture specific functions. This includes enabling and disabling interrupts at This module contains functions specific to the processor architecture. These include routines for enabling and disabling
the processor, getting the address of a page fault, getting CPUID information, and performing very early processor interrupts, retrieving the faulting address on a page fault, querying CPUID information, and performing very early
initialization. This module does not contain any manufacturer or board-specific code, only CPU architecture specific processor initialization. This module contains only CPU architecture-specific code, with no manufacturer or
code. board-specific implementations.
### EX: Kernel Executive ### EX: Kernel Executive
The kernel executive supplies heap management, including support for allocating system memory from paged/non-paged The Kernel Executive provides services for allocating system memory from paged and non-paged pools. It also supplies
pools, as well as synchronization primitives like push locks and fast mutexes, interlocked memory access, and worker synchronization primitives such as pushlocks and fast mutexes, routines for interlocked memory access, and support for
threads. worker threads.
### HL: Hardware Abstraction Layer ### HL: Hardware Layer
Hardware Abstraction Layer (HAL), is a layer between the physical hardware of the computer and the rest of the operating The Hardware Layer is an abstraction layer between the physical hardware and the rest of the operating system. It is
system. It was designed to hide differences in hardware and therefore it provides a consistent platform on which designed to abstract away hardware differences, providing a consistent platform on which the kernel and applications
the system and applications may run. can run.
### KD: Kernel Debugger
The Kernel Debugger (KD) subsystem provides debugging support for the kernel. The KD is initialized early in the boot
process to facilitate debugging from the very beginning of the kernel's execution.
### KE: Kernel Library ### KE: Kernel Library
The kernel implements its core functionality that everything else in the system depends upon. This includes basic The Core Kernel Library implements the core functionality upon which the rest of the system depends. This includes
low-level operations such as routing hardware interrupts. fundamental low-level operations, such as routing hardware interrupts and managing dispatcher objects.
### MM: Memory Manager ### MM: Memory Manager
Memory Manager is one of core subsystems. It manages virtual memory, controls memory protection and the paging of memory The Memory Manager is one of the core subsystems. It manages virtual memory, controls memory protection, and
in and out of physical memory to secondary storage. It also implements a general-purpose allocator of physical memory. handles paging memory between physical RAM and secondary storage. It also implements a general-purpose allocator for
physical memory.
### PO: Plug&Play and Power Manager ### PO: Plug&Play and Power Manager
This subsystem deals with power events, such as power-off, stand-by, or hibernate. It also handles Plug&Play and This subsystem handles power management events, such as shutdown or standby. It also manages Plug and Play (PnP),
supports device detection and installation at boot time. It is responsible for starting and stopping devices on demand. supporting device detection and installation at boot time. Furthermore, it is responsible for starting and stopping
devices on demand.
### RTL: Runtime Library ### RTL: Runtime Library
This is a required static copy of C runtime objects. It includes many utility functions that can be used by native The Runtime Library provides a kernel-mode implementation of common C library functions. It includes many utility
applications. routines, for use by other kernel components.
## Functions Naming Convention ## Function Naming Convention
When naming a kernel functions, certain conventions are used. The function name is usually structured with All kernel functions adhere to a strict naming convention to enhance code readability and maintainability. The structure
&lt;Prefix&gt;&lt;Operation&gt;&lt;Object&gt;. The prefix denotes the module to which it belongs, thus module of a function name is generally composed of three parts: &lt;Prefix&gt;&lt;Operation&gt;&lt;Object&gt;
can be identified simply by the name of the function. Additionally, the prefix identifies the function visibility
as well. Thus all private functions, that should not be used from outside of the module has added "p" suffix to The prefix identifies the component to which the function belongs. Additionally, the prefix indicates the function's
the prefix. For example, KepInitializeStack() routine: visibility. Private functions, which should not be called from outside their own module, have a 'p' appended to their
* Kep - prefix meaning this is private routine belonging to Kernel library (Ke) module, prefix.
* Initialize - operation this function does with the object,
* Stack - the object is stack. For example, consider the **KepInitializeStack()** routine:
* **Kep** - The prefix indicates a private (p) routine belonging to the Core Kernel Library (Ke).
* **Initialize** - The operation performed by the function.
* **Stack** - The object on which the operation is performed.

View File

@@ -13,7 +13,7 @@
/** /**
* This macro creates a trap handler for the specified vector. * Creates a trap handler for the specified vector.
* *
* @param Vector * @param Vector
* Supplies a trap vector number. * Supplies a trap vector number.
@@ -22,9 +22,9 @@
* *
* @since XT 1.0 * @since XT 1.0
*/ */
.macro ArpCreateTrapHandler Vector .macro ArCreateTrapHandler Vector
.global ArpTrap\Vector .global ArTrap\Vector
ArpTrap\Vector: ArTrap\Vector:
/* Push fake error code for non-error vectors */ /* Push fake error code for non-error vectors */
.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
@@ -113,7 +113,7 @@ KernelMode$\Vector:
/* Push Frame Pointer, clear direction flag and pass to trap dispatcher */ /* Push Frame Pointer, clear direction flag and pass to trap dispatcher */
mov %rsp, %rcx mov %rsp, %rcx
cld cld
call ArpDispatchTrap call ArDispatchTrap
/* Test previous mode and swapgs if needed */ /* Test previous mode and swapgs if needed */
testb $1, TrapPreviousMode(%rbp) testb $1, TrapPreviousMode(%rbp)
@@ -176,6 +176,6 @@ KernelModeReturn$\Vector:
/* Populate common 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
ArpCreateTrapHandler 0x\i\j ArCreateTrapHandler 0x\i\j
.endr .endr
.endr .endr

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

@@ -0,0 +1,133 @@
/**
* 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 <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:

View File

@@ -1,887 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/amd64/cpufunc.c
* DESCRIPTION: Routines to provide access to special AMD64 CPU instructions
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
/**
* Instructs the processor to clear the interrupt flag.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArClearInterruptFlag(VOID)
{
asm volatile("cli");
}
/**
* Retrieves a various amount of information about the CPU.
*
* @param Registers
* Supplies a pointer to the structure containing all the necessary registers and leafs for CPUID.
*
* @return TRUE if CPUID function could be executed, FALSE otherwise.
*
* @since XT 1.0
*/
XTCDECL
BOOLEAN
ArCpuId(IN OUT PCPUID_REGISTERS Registers)
{
UINT32 MaxLeaf;
/* Get highest function ID available */
asm volatile("cpuid"
: "=a" (MaxLeaf)
: "a" (Registers->Leaf & 0x80000000)
: "rbx",
"rcx",
"rdx");
/* Check if CPU supports this command */
if(Registers->Leaf > MaxLeaf)
{
/* Cannot call it, return FALSE */
return FALSE;
}
/* Execute CPUID function */
asm volatile("cpuid"
: "=a" (Registers->Eax),
"=b" (Registers->Ebx),
"=c" (Registers->Ecx),
"=d" (Registers->Edx)
: "a" (Registers->Leaf),
"c" (Registers->SubLeaf));
/* Return TRUE */
return TRUE;
}
/**
* Partially flushes the Translation Lookaside Buffer (TLB)
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArFlushTlb(VOID)
{
/* Flush the TLB by resetting the CR3 */
ArWriteControlRegister(3, ArReadControlRegister(3));
}
/**
* Gets the address of the current stack register.
*
* @return This routine returns the current stack pointer.
*
* @since XT 1.0
*/
XTASSEMBLY
XTCDECL
ULONG_PTR
ArGetStackPointer(VOID)
{
/* Get current stack pointer */
asm volatile("movq %%rsp, %%rax\n"
"retq\n"
:
:
:);
}
/**
* Halts the central processing unit (CPU).
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArHalt(VOID)
{
asm volatile("hlt");
}
/**
* Invalidates the TLB (Translation Lookaside Buffer) for specified virtual address.
*
* @param Address
* Suuplies a virtual address whose associated TLB entry will be invalidated.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArInvalidateTlbEntry(IN PVOID Address)
{
asm volatile("invlpg (%0)"
:
: "b" (Address)
: "memory");
}
/**
* Loads the value in the source operand into the global descriptor table register (GDTR).
*
* @param Source
* Specifies a memory location that contains the base address of GDT.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArLoadGlobalDescriptorTable(IN PVOID Source)
{
asm volatile("lgdt %0"
:
: "m" (*(PSHORT)Source)
: "memory");
}
/**
* Loads the value in the source operand into the interrupt descriptor table register (IDTR).
*
* @param Source
* Specifies a memory location that contains the base address of IDT.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArLoadInterruptDescriptorTable(IN PVOID Source)
{
asm volatile("lidt %0"
:
: "m" (*(PSHORT)Source)
: "memory");
}
/**
* Loads the value in the source operand into the local descriptor table register (LDTR).
*
* @param Source
* Specifies a selector value.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArLoadLocalDescriptorTable(IN USHORT Source)
{
asm volatile("lldtw %0"
:
: "g" (Source));
}
/**
* Loads the value in the source operand into the MXCSR register
*
* @param Source
* Supplies a source value to be loaded into the MXCSR register.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArLoadMxcsrRegister(IN ULONG Source)
{
asm volatile("ldmxcsr %0"
:
: "m" (Source));
}
/**
* Loads source data into specified segment.
*
* @param Segment
* Supplies a segment identification.
*
* @param Source
* Supplies a pointer to the memory area containing data that will be loaded into specified segment.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArLoadSegment(IN USHORT Segment,
IN ULONG Source)
{
switch(Segment)
{
case SEGMENT_CS:
/* Load CS Segment */
asm volatile("mov %0, %%rax\n"
"push %%rax\n"
"lea label(%%rip), %%rax\n"
"push %%rax\n"
"lretq\n"
"label:"
:
: "ri" ((ULONGLONG)Source)
: "rax");
break;
case SEGMENT_DS:
/* Load DS Segment */
asm volatile("movl %0, %%ds"
:
: "r" (Source));
break;
case SEGMENT_ES:
/* Load ES Segment */
asm volatile("movl %0, %%es"
:
: "r" (Source));
break;
case SEGMENT_FS:
/* Load FS Segment */
asm volatile("movl %0, %%fs"
:
: "r" (Source));
break;
case SEGMENT_GS:
/* Load GS Segment */
asm volatile("movl %0, %%gs"
:
: "r" (Source));
break;
/* Load SS Segment */
case SEGMENT_SS:
asm volatile("movl %0, %%ss"
:
: "r" (Source));
break;
}
}
/**
* Loads Task Register (TR) with a segment selector that points to TSS.
*
* @param Source
* Supplies the segment selector in the GDT describing the TSS.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArLoadTaskRegister(USHORT Source)
{
asm volatile("ltr %0"
:
: "rm" (Source));
}
/**
* Orders memory accesses as seen by other processors.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArMemoryBarrier(VOID)
{
LONG Barrier;
asm volatile("lock; orl $0, %0;"
:
: "m"(Barrier));
}
/**
* Reads the specified CPU control register and returns its value.
*
* @param ControlRegister
* Supplies a number of a control register which controls the general behavior of a CPU.
*
* @return The value stored in the control register.
*
* @since XT 1.0
*/
XTCDECL
ULONG_PTR
ArReadControlRegister(IN USHORT ControlRegister)
{
ULONG_PTR Value;
/* Read a value from specified CR register */
switch(ControlRegister)
{
case 0:
/* Read value from CR0 */
asm volatile("mov %%cr0, %0"
: "=r" (Value)
:
: "memory");
break;
case 2:
/* Read value from CR2 */
asm volatile("mov %%cr2, %0"
: "=r" (Value)
:
: "memory");
break;
case 3:
/* Read value from CR3 */
asm volatile("mov %%cr3, %0"
: "=r" (Value)
:
: "memory");
break;
case 4:
/* Read value from CR4 */
asm volatile("mov %%cr4, %0"
: "=r" (Value)
:
: "memory");
break;
case 8:
/* Read value from CR8 */
asm volatile("mov %%cr8, %0"
: "=r" (Value)
:
: "memory");
break;
default:
/* Invalid control register set */
Value = 0;
break;
}
/* Return value read from given CR register */
return Value;
}
/**
* Reads the specified CPU debug register and returns its value.
*
* @param DebugRegister
* Supplies a number of a debug register to read from.
*
* @return The value stored in the specified debug register.
*
* @since XT 1.0
*/
XTCDECL
ULONG_PTR
ArReadDebugRegister(IN USHORT DebugRegister)
{
ULONG_PTR Value;
/* Read a value from specified DR register */
switch(DebugRegister)
{
case 0:
/* Read value from DR0 */
asm volatile("mov %%dr0, %0"
: "=r" (Value));
break;
case 1:
/* Read value from DR1 */
asm volatile("mov %%dr1, %0"
: "=r" (Value));
break;
case 2:
/* Read value from DR2 */
asm volatile("mov %%dr2, %0"
: "=r" (Value));
break;
case 3:
/* Read value from DR3 */
asm volatile("mov %%dr3, %0"
: "=r" (Value));
break;
case 4:
/* Read value from DR4 */
asm volatile("mov %%dr4, %0"
: "=r" (Value));
break;
case 5:
/* Read value from DR5 */
asm volatile("mov %%dr5, %0"
: "=r" (Value));
break;
case 6:
/* Read value from DR6 */
asm volatile("mov %%dr6, %0"
: "=r" (Value));
break;
case 7:
/* Read value from DR7 */
asm volatile("mov %%dr7, %0"
: "=r" (Value));
break;
default:
/* Invalid debug register set */
Value = 0;
break;
}
/* Return value read from given DR register */
return Value;
}
/**
* Reads quadword from a memory location specified by an offset relative to the beginning of the GS segment.
*
* @param Offset
* Specifies the offset from the beginning of GS segment.
*
* @return Returns the value read from the specified memory location relative to GS segment.
*
* @since XT 1.0
*/
XTCDECL
ULONGLONG
ArReadGSQuadWord(ULONG Offset)
{
ULONGLONG Value;
/* Read quadword from GS segment */
asm volatile("movq %%gs:%a[Offset], %q[Value]"
: [Value] "=r" (Value)
: [Offset] "ir" (Offset));
return Value;
}
/**
* Reads a 64-bit value from the requested Model Specific Register (MSR).
*
* @param Register
* Supplies the MSR to read.
*
* @return This routine returns the 64-bit MSR value.
*
* @since XT 1.0
*/
XTCDECL
ULONGLONG
ArReadModelSpecificRegister(IN ULONG Register)
{
ULONG Low, High;
asm volatile("rdmsr"
: "=a" (Low),
"=d" (High)
: "c" (Register));
return ((ULONGLONG)High << 32) | Low;
}
/**
* Reads the contents of the MXCSR control/status register.
*
* @return This routine returns the contents of the MXCSR register as a 32-bit unsigned integer value.
*
* @since XT 1.0
*/
XTCDECL
UINT
ArReadMxCsrRegister(VOID)
{
return __builtin_ia32_stmxcsr();
}
/**
* Reads the current value of the CPU's time-stamp counter.
*
* @return This routine returns the current instruction cycle count since the processor was started.
*
* @since XT 1.0
*/
XTCDECL
ULONGLONG
ArReadTimeStampCounter(VOID)
{
ULONGLONG Low, High;
asm volatile("rdtsc"
: "=a" (Low),
"=d" (High));
return ((ULONGLONG)High << 32) | Low;
}
/**
* Orders memory accesses as seen by other processors, without fence.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArReadWriteBarrier(VOID)
{
asm volatile(""
:
:
: "memory");
}
/**
* Instructs the processor to set the interrupt flag.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArSetInterruptFlag(VOID)
{
asm volatile("sti");
}
/**
* Stores GDT register into the given memory area.
*
* @param Destination
* Supplies a pointer to the memory area where GDT will be stored.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArStoreGlobalDescriptorTable(OUT PVOID Destination)
{
asm volatile("sgdt %0"
: "=m" (*(PSHORT)Destination)
:
: "memory");
}
/**
* Stores IDT register into the given memory area.
*
* @param Destination
* Supplies a pointer to the memory area where IDT will be stored.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArStoreInterruptDescriptorTable(OUT PVOID Destination)
{
asm volatile("sidt %0"
: "=m" (*(PSHORT)Destination)
:
: "memory");
}
/**
* Stores LDT register into the given memory area.
*
* @param Destination
* Supplies a pointer to the memory area where LDT will be stored.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArStoreLocalDescriptorTable(OUT PVOID Destination)
{
asm volatile("sldt %0"
: "=m" (*(PSHORT)Destination)
:
: "memory");
}
/**
* Stores specified segment into the given memory area.
*
* @param Segment
* Supplies a segment identification.
*
* @param Destination
* Supplies a pointer to the memory area where segment data will be stored.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArStoreSegment(IN USHORT Segment,
OUT PVOID Destination)
{
switch(Segment)
{
case SEGMENT_CS:
asm volatile("movl %%cs, %0"
: "=r" (*(PUINT)Destination));
break;
case SEGMENT_DS:
asm volatile("movl %%ds, %0"
: "=r" (*(PUINT)Destination));
break;
case SEGMENT_ES:
asm volatile("movl %%es, %0"
: "=r" (*(PUINT)Destination));
break;
case SEGMENT_FS:
asm volatile("movl %%fs, %0"
: "=r" (*(PUINT)Destination));
break;
case SEGMENT_GS:
asm volatile("movl %%gs, %0"
: "=r" (*(PUINT)Destination));
break;
case SEGMENT_SS:
asm volatile("movl %%ss, %0"
: "=r" (*(PUINT)Destination));
break;
default:
Destination = NULL;
break;
}
}
/**
* Stores TR into the given memory area.
*
* @param Destination
* Supplies a pointer to the memory area where TR will be stores.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArStoreTaskRegister(OUT PVOID Destination)
{
asm volatile("str %0"
: "=m" (*(PULONG)Destination)
:
: "memory");
}
/**
* Writes a value to the specified CPU control register.
*
* @param ControlRegister
* Supplies a number of a control register which controls the general behavior of a CPU.
*
* @param Value
* Suplies a value to write to the CR register.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArWriteControlRegister(IN USHORT ControlRegister,
IN UINT_PTR Value)
{
/* Write a value into specified control register */
switch(ControlRegister)
{
case 0:
/* Write value to CR0 */
asm volatile("mov %0, %%cr0"
:
: "r"(Value)
: "memory");
break;
case 2:
/* Write value to CR2 */
asm volatile("mov %0, %%cr2"
:
: "r"(Value)
: "memory");
break;
case 3:
/* Write value to CR3 */
asm volatile("mov %0, %%cr3"
:
: "r"(Value)
: "memory");
break;
case 4:
/* Write value to CR4 */
asm volatile("mov %0, %%cr4"
:
: "r"(Value)
: "memory");
break;
case 8:
/* Write value to CR8 */
asm volatile("mov %0, %%cr8"
:
: "r"(Value)
: "memory");
break;
}
}
/**
* Writes a value to the specified CPU debug register.
*
* @param DebugRegister
* Supplies a number of a debug register for write operation.
*
* @param Value
* Suplies a value to write to the specified DR register.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArWriteDebugRegister(IN USHORT DebugRegister,
IN UINT_PTR Value)
{
/* Write a value into specified debug register */
switch(DebugRegister)
{
case 0:
/* Write value to DR0 */
asm volatile("mov %0, %%dr0"
:
: "r" (Value)
: "memory");
case 1:
/* Write value to DR1 */
asm volatile("mov %0, %%dr1"
:
: "r" (Value)
: "memory");
case 2:
/* Write value to DR2 */
asm volatile("mov %0, %%dr2"
:
: "r" (Value)
: "memory");
case 3:
/* Write value to DR3 */
asm volatile("mov %0, %%dr3"
:
: "r" (Value)
: "memory");
case 4:
/* Write value to DR4 */
asm volatile("mov %0, %%dr4"
:
: "r" (Value)
: "memory");
case 5:
/* Write value to DR5 */
asm volatile("mov %0, %%dr5"
:
: "r" (Value)
: "memory");
case 6:
/* Write value to DR6 */
asm volatile("mov %0, %%dr6"
:
: "r" (Value)
: "memory");
case 7:
/* Write value to DR7 */
asm volatile("mov %0, %%dr7"
:
: "r" (Value)
: "memory");
}
}
/**
* Writes the specified value to the program status and control (EFLAGS) register.
*
* @param Value
* The value to write to the EFLAGS register.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArWriteEflagsRegister(IN UINT_PTR Value)
{
asm volatile("push %0\n"
"popf"
:
: "rim" (Value));
}
/**
* Writes a 64-bit value to the requested Model Specific Register (MSR).
*
* @param Register
* Supplies the MSR register to write.
*
* @param Value
* Supplies the 64-bit value to write.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArWriteModelSpecificRegister(IN ULONG Register,
IN ULONGLONG Value)
{
ULONG Low = Value & 0xFFFFFFFF;
ULONG High = Value >> 32;
asm volatile("wrmsr"
:
: "c" (Register),
"a" (Low),
"d" (High));
}
/**
* Yields a current thread running on the processor.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArYieldProcessor(VOID)
{
asm volatile("pause"
:
:
: "memory");
}

1120
xtoskrnl/ar/amd64/cpufunc.cc Normal file

File diff suppressed because it is too large Load Diff

34
xtoskrnl/ar/amd64/data.cc Normal file
View File

@@ -0,0 +1,34 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/amd64/data.cc
* DESCRIPTION: AMD64 architecture-specific global and static data
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
/* Initial kernel boot stack */
UCHAR ProcSup::BootStack[KERNEL_STACK_SIZE] = {};
/* Initial kernel fault stack */
UCHAR ProcSup::FaultStack[KERNEL_STACK_SIZE] = {};
/* Initial GDT */
KGDTENTRY ProcSup::InitialGdt[GDT_ENTRIES] = {};
/* Initial IDT */
KIDTENTRY ProcSup::InitialIdt[IDT_ENTRIES] = {};
/* Initial Processor Block */
KPROCESSOR_BLOCK ProcSup::InitialProcessorBlock;
/* Initial TSS */
KTSS ProcSup::InitialTss;
} /* namespace */

View File

@@ -1,28 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/amd64/globals.c
* DESCRIPTION: XT architecture library global variables
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
/* Initial GDT */
KGDTENTRY ArInitialGdt[GDT_ENTRIES] = {0};
/* Initial IDT */
KIDTENTRY ArInitialIdt[IDT_ENTRIES] = {0};
/* Initial Processor Block */
KPROCESSOR_BLOCK ArInitialProcessorBlock;
/* Initial TSS */
KTSS ArInitialTss;
/* Initial kernel boot stack */
UCHAR ArKernelBootStack[KERNEL_STACK_SIZE] = {0};
/* Initial kernel fault stack */
UCHAR ArKernelFaultStack[KERNEL_STACK_SIZE] = {0};

View File

@@ -1,557 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/amd64/procsup.c
* DESCRIPTION: AMD64 processor functionality support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
/**
* Initializes AMD64 processor specific structures.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ArInitializeProcessor(VOID)
{
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
PKPROCESSOR_BLOCK ProcessorBlock;
PVOID KernelFaultStack;
PKGDTENTRY Gdt;
PKIDTENTRY Idt;
PKTSS Tss;
/* Use initial structures */
Gdt = ArInitialGdt;
Idt = ArInitialIdt;
Tss = &ArInitialTss;
KernelFaultStack = &ArKernelFaultStack;
/* Load processor block */
ProcessorBlock = CONTAIN_RECORD(&ArInitialProcessorBlock.Prcb, KPROCESSOR_BLOCK, Prcb);
/* Initialize processor block */
ArpInitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);
/* Initialize GDT, IDT and TSS */
ArpInitializeGdt(ProcessorBlock);
ArpInitializeTss(ProcessorBlock);
ArpInitializeIdt(ProcessorBlock);
/* 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 */
ArLoadGlobalDescriptorTable(&GdtDescriptor.Limit);
ArLoadInterruptDescriptorTable(&IdtDescriptor.Limit);
ArLoadTaskRegister((UINT)KGDT_SYS_TSS);
/* Enter passive IRQ level */
HlSetRunLevel(PASSIVE_LEVEL);
/* Initialize segment registers */
ArpInitializeSegments();
/* Set GS base */
ArWriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock);
ArWriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock);
/* Initialize processor registers */
ArpInitializeProcessorRegisters();
/* Identify processor */
ArpIdentifyProcessor();
}
/**
* Updates an existing AMD64 GDT entry with new base address.
*
* @param Gdt
* Supplies a pointer to the GDT.
*
* @param Selector
* Specifies a segment selector of the GDT entry.
*
* @param Base
* Specifies a base address value of the descriptor.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ArSetGdtEntryBase(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base)
{
PKGDTENTRY GdtEntry;
/* Get GDT entry */
GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK));
/* Set new GDT descriptor base */
GdtEntry->BaseLow = (Base & 0xFFFF);
GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF);
GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF);
GdtEntry->BaseUpper = (Base >> 32);
}
/**
* 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.
*
* @since XT 1.0
*/
XTAPI
VOID
ArpIdentifyProcessor(VOID)
{
PKPROCESSOR_CONTROL_BLOCK Prcb;
CPUID_REGISTERS CpuRegisters;
CPUID_SIGNATURE CpuSignature;
/* Not fully implemented yet */
UNIMPLEMENTED;
/* Get current processor control block */
Prcb = KeGetCurrentProcessorControlBlock();
/* Get CPU vendor by issueing CPUID instruction */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
ArCpuId(&CpuRegisters);
/* Store CPU vendor in processor control block */
Prcb->CpuId.Vendor = CpuRegisters.Ebx;
Prcb->CpuId.VendorName[0] = CpuRegisters.Ebx;
Prcb->CpuId.VendorName[4] = CpuRegisters.Edx;
Prcb->CpuId.VendorName[8] = CpuRegisters.Ecx;
Prcb->CpuId.VendorName[12] = '\0';
/* Get CPU features */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_CPU_FEATURES;
ArCpuId(&CpuRegisters);
/* Store CPU signature in processor control block */
CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax;
Prcb->CpuId.Family = CpuSignature.Family;
Prcb->CpuId.Model = CpuSignature.Model;
Prcb->CpuId.Stepping = CpuSignature.Stepping;
/* CPU vendor specific quirks */
if(Prcb->CpuId.Vendor == CPU_VENDOR_AMD)
{
/* AMD CPU */
Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
if(Prcb->CpuId.Model == 0xF)
{
Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
}
}
else if(Prcb->CpuId.Vendor == CPU_VENDOR_INTEL)
{
/* Intel CPU */
if(Prcb->CpuId.Family == 0xF)
{
Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
}
if((Prcb->CpuId.Family == 0xF) || (Prcb->CpuId.Family == 0x6))
{
Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
}
}
else
{
/* Unknown CPU vendor */
Prcb->CpuId.Vendor = CPU_VENDOR_UNKNOWN;
}
/* TODO: Store a list of CPU features in processor control block */
}
/**
* Initializes the kernel's Global Descriptor Table (GDT).
*
* @param Gdt
* Supplies a pointer to the GDT to use.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
{
/* Initialize GDT entries */
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 1);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 1);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_DATA, 0x0, 0x0, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 1);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMCODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_USER, 1);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONG_PTR)ProcessorBlock->TssBase, sizeof(KTSS), AMD64_TSS, KGDT_DPL_SYSTEM, 0);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMTEB, 0x0, 0x0FFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_ALIAS, (ULONG_PTR)ProcessorBlock->GdtBase, (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0);
}
/**
* Initializes the kernel's Interrupt Descriptor Table (IDT).
*
* @param ProcessorBlock
* Supplies a pointer to the processor block to use.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
{
UINT Vector;
/* Fill in all vectors */
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
{
/* Set the IDT to handle unexpected interrupts */
ArpSetIdtGate(ProcessorBlock->IdtBase, Vector, ArpHandleTrapFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
}
/* Setup IDT handlers for known interrupts and traps */
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x00, ArpTrap0x00, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x01, ArpTrap0x01, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x02, ArpTrap0x02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x03, ArpTrap0x03, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x04, ArpTrap0x04, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x05, ArpTrap0x05, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x06, ArpTrap0x06, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x07, ArpTrap0x07, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x08, ArpTrap0x08, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x09, ArpTrap0x09, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0A, ArpTrap0x0A, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0B, ArpTrap0x0B, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0C, ArpTrap0x0C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0D, ArpTrap0x0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0E, ArpTrap0x0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x10, ArpTrap0x10, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x11, ArpTrap0x11, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x12, ArpTrap0x12, KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x13, ArpTrap0x13, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x1F, ArpTrap0x1F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2C, ArpTrap0x2C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2D, ArpTrap0x2D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2F, ArpTrap0x2F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0xE1, ArpTrap0xE1, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
}
/**
* Initializes processor block.
*
* @param ProcessorBlock
* Supplies a pointer to the processor block to initialize.
*
* @param Gdt
* Supplies a pointer to the GDT for this processor block.
*
* @param Idt
* Supplies a pointer to the IDT for this processor block.
*
* @param Tss
* Supplies a pointer to the TSS for this processor block.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
IN PKGDTENTRY Gdt,
IN PKIDTENTRY Idt,
IN PKTSS Tss,
IN PVOID DpcStack)
{
/* Fill processor block with zeroes */
RtlZeroMemory(ProcessorBlock, sizeof(KPROCESSOR_BLOCK));
/* Set processor block and processor control block */
ProcessorBlock->Self = ProcessorBlock;
ProcessorBlock->CurrentPrcb = &ProcessorBlock->Prcb;
/* Set GDT, IDT and TSS descriptors */
ProcessorBlock->GdtBase = (PVOID)Gdt;
ProcessorBlock->IdtBase = Idt;
ProcessorBlock->TssBase = Tss;
ProcessorBlock->Prcb.RspBase = Tss->Rsp0;
/* Setup DPC stack */
ProcessorBlock->Prcb.DpcStack = DpcStack;
/* Setup processor control block */
ProcessorBlock->Prcb.Number = 0;
ProcessorBlock->Prcb.SetMember = 1ULL;
ProcessorBlock->Prcb.MultiThreadProcessorSet = 1ULL;
/* Clear DR6 and DR7 registers */
ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr6 = 0;
ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr7 = 0;
/* Set process and thread information */
ProcessorBlock->Prcb.CurrentThread = &KeInitialThread.ThreadControlBlock;
ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &KeInitialProcess.ProcessControlBlock;
ProcessorBlock->Prcb.IdleThread = &KeInitialThread.ThreadControlBlock;
ProcessorBlock->Prcb.NextThread = NULL;
/* Set initial MXCSR register value */
ProcessorBlock->Prcb.MxCsr = INITIAL_MXCSR;
/* Set initial runlevel */
ProcessorBlock->RunLevel = PASSIVE_LEVEL;
}
/**
* Initializes processor registers and other boot structures.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ArpInitializeProcessorRegisters(VOID)
{
ULONGLONG PatAttributes;
/* Enable FXSAVE restore */
ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_FXSR);
/* Enable XMMI exceptions */
ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_XMMEXCPT);
/* Set debugger extension */
ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_DE);
/* Enable large pages */
ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_PSE);
/* Enable write-protection */
ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_WP);
/* Set alignment mask */
ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_AM);
/* Disable FPU monitoring */
ArWriteControlRegister(0, ArReadControlRegister(0) & ~CR0_MP);
/* Disable x87 FPU exceptions */
ArWriteControlRegister(0, ArReadControlRegister(0) & ~CR0_NE);
/* Flush the TLB */
ArFlushTlb();
/* Initialize system calls MSR */
ArWriteModelSpecificRegister(X86_MSR_STAR, (((ULONG64)KGDT_R3_CMCODE | RPL_MASK) << 48) | ((ULONG64)KGDT_R0_CODE << 32));
ArWriteModelSpecificRegister(X86_MSR_CSTAR, (ULONG64)&ArpHandleSystemCall32);
ArWriteModelSpecificRegister(X86_MSR_LSTAR, (ULONG64)&ArpHandleSystemCall64);
ArWriteModelSpecificRegister(X86_MSR_FMASK, X86_EFLAGS_IF_MASK | X86_EFLAGS_TF_MASK);
/* Enable system call extensions (SCE) in EFER MSR */
ArWriteModelSpecificRegister(X86_MSR_EFER, ArReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_SCE);
/* Enable No-Execute (NXE) in EFER MSR */
ArWriteModelSpecificRegister(X86_MSR_EFER, ArReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_NXE);
/* Initialize Page Attribute Table */
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);
ArWriteModelSpecificRegister(X86_MSR_PAT, PatAttributes);
/* Initialize MXCSR register */
ArLoadMxcsrRegister(INITIAL_MXCSR);
}
/**
* Initializes segment registers.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ArpInitializeSegments(VOID)
{
/* Initialize segments */
ArLoadSegment(SEGMENT_CS, KGDT_R0_CODE);
ArLoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
ArLoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
ArLoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK);
ArLoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK);
ArLoadSegment(SEGMENT_SS, KGDT_R0_DATA);
}
/**
* Initializes the kernel's Task State Segment (TSS).
*
* @param Tss
* Supplies a pointer to the TSS to use.
*
* @param Gdt
* Supplies a pointer to the GDT to use.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock)
{
/* Fill TSS with zeroes */
RtlZeroMemory(ProcessorBlock->TssBase, sizeof(KTSS));
/* Setup I/O map and stacks for ring0 & traps */
ProcessorBlock->TssBase->IoMapBase = sizeof(KTSS);
ProcessorBlock->TssBase->Rsp0 = (ULONG_PTR)&ArKernelBootStack;
ProcessorBlock->TssBase->Ist[KIDT_IST_PANIC] = (ULONG_PTR)&ArKernelFaultStack;
ProcessorBlock->TssBase->Ist[KIDT_IST_MCA] = (ULONG_PTR)&ArKernelFaultStack;
}
/**
* Fills in an AMD64 GDT entry.
*
* @param Gdt
* Supplies a pointer to the GDT.
*
* @param Selector
* Specifies a segment selector of the GDT entry.
*
* @param Base
* Specifies a base address value of the descriptor.
*
* @param Limit
* Specifies a descriptor limit.
*
* @param Type
* Specifies a type of the descriptor.
*
* @param Dpl
* Specifies the descriptor privilege level.
*
* @param SegmentMode
* Specifies a segment mode of the descriptor.
*
* @return This routine does not return any value
*
* @since XT 1.0
*/
XTAPI
VOID
ArpSetGdtEntry(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base,
IN ULONG Limit,
IN UCHAR Type,
IN UCHAR Dpl,
IN UCHAR SegmentMode)
{
PKGDTENTRY GdtEntry;
UCHAR Granularity;
/* Set the granularity flag depending on descriptor limit */
if(Limit < 0x100000)
{
/* Limit is in 1B blocks */
Granularity = 0;
}
else
{
/* Limit is in 4KB blocks */
Granularity = 1;
Limit >>= 12;
}
/* Get GDT entry */
GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK));
/* Set GDT descriptor base */
GdtEntry->BaseLow = (Base & 0xFFFF);
GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF);
GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF);
GdtEntry->BaseUpper = (Base >> 32);
/* Set descriptor limit */
GdtEntry->LimitLow = (Limit & 0xFFFF);
GdtEntry->Bits.LimitHigh = ((Limit >> 16) & 0xF);
/* Initialize GDT entry */
GdtEntry->Bits.DefaultBig = !!(SegmentMode & 2);
GdtEntry->Bits.Dpl = (Dpl & 0x3);
GdtEntry->Bits.Granularity = Granularity;
GdtEntry->Bits.LongMode = !!(SegmentMode & 1);
GdtEntry->Bits.Present = (Type != 0);
GdtEntry->Bits.System = 0;
GdtEntry->Bits.Type = (Type & 0x1F);
GdtEntry->MustBeZero = 0;
}
/**
* Fills in a call, interrupt, task or trap gate entry.
*
* @param Idt
* Supplies a pointer to IDT structure, where gate is located.
*
* @param Vector
* Supplies a gate vector pointing to the interrupt gate in the IDT
*
* @param Handler
* Supplies a pointer to the interrupt handler of the specified gate.
*
* @param Selector
* Supplies the code selector the gate should run in.
*
* @param Ist
* Supplies the interrupt stack table entry the gate should run in.
*
* @param Access
* Supplies the gate access rights.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ArpSetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Access)
{
/* Setup the gate */
Idt[Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF);
Idt[Vector].OffsetMiddle = (((ULONG_PTR)Handler >> 16) & 0xFFFF);
Idt[Vector].OffsetHigh = (ULONG_PTR)Handler >> 32;
Idt[Vector].Dpl = Access;
Idt[Vector].IstIndex = Ist;
Idt[Vector].Present = 1;
Idt[Vector].Selector = Selector;
Idt[Vector].Type = 0xE;
}

View File

@@ -0,0 +1,659 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/amd64/procsup.cc
* DESCRIPTION: AMD64 processor functionality support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
/**
* Gets the base address of the kernel boot stack.
*
* @return This routine returns a pointer to the kernel boot stack.
*
* @since XT 1.0
*/
PVOID ProcSup::GetBootStack(VOID)
{
return (PVOID)BootStack;
}
/**
* 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.
*
* @since XT 1.0
*/
XTAPI
VOID
ProcSup::IdentifyProcessor(VOID)
{
PKPROCESSOR_CONTROL_BLOCK Prcb;
CPUID_REGISTERS CpuRegisters;
CPUID_SIGNATURE CpuSignature;
/* Not fully implemented yet */
UNIMPLEMENTED;
/* Get current processor control block */
Prcb = KeGetCurrentProcessorControlBlock();
/* Get CPU vendor by issueing CPUID instruction */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
CpuFunc::CpuId(&CpuRegisters);
/* Store CPU vendor in processor control block */
Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx;
*(PULONG)&Prcb->CpuId.VendorName[0] = CpuRegisters.Ebx;
*(PULONG)&Prcb->CpuId.VendorName[4] = CpuRegisters.Edx;
*(PULONG)&Prcb->CpuId.VendorName[8] = CpuRegisters.Ecx;
Prcb->CpuId.VendorName[12] = '\0';
/* Get CPU standard features */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
CpuFunc::CpuId(&CpuRegisters);
/* Store CPU signature in processor control block */
CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax;
Prcb->CpuId.Family = CpuSignature.Family;
Prcb->CpuId.Model = CpuSignature.Model;
Prcb->CpuId.Stepping = CpuSignature.Stepping;
/* CPU vendor specific quirks */
if(Prcb->CpuId.Vendor == CPU_VENDOR_AMD)
{
/* AMD CPU */
if(Prcb->CpuId.Family >= 0xF)
{
Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
}
}
else if(Prcb->CpuId.Vendor == CPU_VENDOR_INTEL)
{
/* Intel CPU */
if(Prcb->CpuId.Family == 0xF)
{
Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
}
if((Prcb->CpuId.Family == 0x6) || (Prcb->CpuId.Family == 0xF))
{
Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
}
}
else
{
/* Unknown CPU vendor */
Prcb->CpuId.Vendor = CPU_VENDOR_UNKNOWN;
}
/* TODO: Store a list of CPU features in processor control block */
}
/**
* Initializes AMD64 processor specific structures.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
{
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
PVOID KernelBootStack, KernelFaultStack;
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);
/* Use global IDT */
Idt = InitialIdt;
}
else
{
/* Use initial structures */
Gdt = InitialGdt;
Idt = InitialIdt;
Tss = &InitialTss;
KernelBootStack = &BootStack;
KernelFaultStack = &FaultStack;
ProcessorBlock = &InitialProcessorBlock;
}
/* Initialize processor block */
InitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);
/* Initialize GDT, IDT and TSS */
InitializeGdt(ProcessorBlock);
InitializeIdt(ProcessorBlock);
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack);
/* 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 */
CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS);
/* Enter passive IRQ level */
HlSetRunLevel(PASSIVE_LEVEL);
/* Initialize segment registers */
InitializeSegments();
/* Set GS base */
CpuFunc::WriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock);
CpuFunc::WriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock);
/* Initialize processor registers */
InitializeProcessorRegisters();
/* Identify processor */
IdentifyProcessor();
}
/**
* Initializes the kernel's Global Descriptor Table (GDT).
*
* @param Gdt
* Supplies a pointer to the GDT to use.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
{
/* Initialize GDT entries */
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 1);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 1);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_DATA, 0x0, 0x0, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 1);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMCODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_USER, 1);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONG_PTR)ProcessorBlock->TssBase,
sizeof(KTSS) - 1, AMD64_TSS, KGDT_DPL_SYSTEM, 0);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMTEB, 0x0, 0x0FFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, 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);
}
/**
* Initializes the kernel's Interrupt Descriptor Table (IDT).
*
* @param ProcessorBlock
* Supplies a pointer to the processor block to use.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
{
UINT Vector;
/* Fill in all vectors */
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
{
/* Set the IDT to handle unexpected interrupts */
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
}
/* Setup IDT handlers for known interrupts and traps */
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x1F, (PVOID)ArTrap0x1F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrap0x2F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArTrap0xE1, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
}
/**
* Initializes processor block.
*
* @param ProcessorBlock
* Supplies a pointer to the processor block to initialize.
*
* @param Gdt
* Supplies a pointer to the GDT for this processor block.
*
* @param Idt
* Supplies a pointer to the IDT for this processor block.
*
* @param Tss
* Supplies a pointer to the TSS for this processor block.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
IN PKGDTENTRY Gdt,
IN PKIDTENTRY Idt,
IN PKTSS Tss,
IN PVOID DpcStack)
{
/* Set processor block and processor control block */
ProcessorBlock->Self = ProcessorBlock;
ProcessorBlock->CurrentPrcb = &ProcessorBlock->Prcb;
/* Set GDT, IDT and TSS descriptors */
ProcessorBlock->GdtBase = (PKGDTENTRY)(PVOID)Gdt;
ProcessorBlock->IdtBase = Idt;
ProcessorBlock->TssBase = Tss;
ProcessorBlock->Prcb.RspBase = Tss->Rsp0;
/* Setup DPC stack */
ProcessorBlock->Prcb.DpcStack = DpcStack;
/* Setup processor control block */
ProcessorBlock->Prcb.CpuNumber = ProcessorBlock->CpuNumber;
ProcessorBlock->Prcb.SetMember = 1ULL << ProcessorBlock->CpuNumber;
ProcessorBlock->Prcb.MultiThreadProcessorSet = 1ULL << ProcessorBlock->CpuNumber;
/* Clear DR6 and DR7 registers */
ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr6 = 0;
ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr7 = 0;
/* Set process and thread information */
ProcessorBlock->Prcb.CurrentThread = &KeInitialThread.ThreadControlBlock;
ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &KeInitialProcess.ProcessControlBlock;
ProcessorBlock->Prcb.IdleThread = &KeInitialThread.ThreadControlBlock;
ProcessorBlock->Prcb.NextThread = nullptr;
/* Set initial MXCSR register value */
ProcessorBlock->Prcb.MxCsr = INITIAL_MXCSR;
/* Set initial runlevel */
ProcessorBlock->RunLevel = PASSIVE_LEVEL;
}
/**
* Initializes processor registers and other boot structures.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ProcSup::InitializeProcessorRegisters(VOID)
{
ULONGLONG PatAttributes;
/* Enable FXSAVE restore */
CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_FXSR);
/* Enable XMMI exceptions */
CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_XMMEXCPT);
/* Set debugger extension */
CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_DE);
/* Enable large pages */
CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_PSE);
/* Enable write-protection */
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_WP);
/* Set alignment mask */
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_AM);
/* Disable FPU monitoring */
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) & ~CR0_MP);
/* Disable x87 FPU exceptions */
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) & ~CR0_NE);
/* Flush the TLB */
CpuFunc::FlushTlb();
/* Initialize system call MSRs */
Traps::InitializeSystemCallMsrs();
/* Enable No-Execute (NXE) in EFER MSR */
CpuFunc::WriteModelSpecificRegister(X86_MSR_EFER, CpuFunc::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_NXE);
/* Initialize Page Attribute Table */
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);
CpuFunc::WriteModelSpecificRegister(X86_MSR_PAT, PatAttributes);
/* Initialize MXCSR register */
CpuFunc::LoadMxcsrRegister(INITIAL_MXCSR);
}
/**
* Initializes i686 processor specific structures with provided memory buffer.
*
* @param ProcessorStructures
* Supplies a pointer to the allocated buffer with processor structures.
*
* @param Gdt
* Supplies a pointer to the GDT.
*
* @param Tss
* Supplies a pointer to the TSS.
*
* @param ProcessorBlock
* Supplies a pointer to the processor block.
*
* @param KernelBootStack
* Supplies a pointer to the kernel boot stack.
*
* @param KernelFaultStack
* Supplies a pointer to the kernel fault stack.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
OUT PKGDTENTRY *Gdt,
OUT PKTSS *Tss,
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
OUT PVOID *KernelBootStack,
OUT PVOID *KernelFaultStack)
{
UINT_PTR Address;
/* Align address to page size boundary and move to kernel boot stack */
Address = ROUND_UP((UINT_PTR)ProcessorStructures, MM_PAGE_SIZE) + KERNEL_STACK_SIZE;
/* Assign a space for kernel boot stack and advance */
*KernelBootStack = (PVOID)Address;
Address += KERNEL_STACK_SIZE;
/* Assign a space for kernel fault stack, no advance needed as stack grows down */
*KernelFaultStack = (PVOID)Address;
/* Assign a space for GDT and advance */
*Gdt = (PKGDTENTRY)(PVOID)Address;
Address += sizeof(InitialGdt);
/* Assign a space for Processor Block and advance */
*ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address;
Address += sizeof(InitialProcessorBlock);
/* Assign a space for TSS */
*Tss = (PKTSS)(PVOID)Address;
}
/**
* Initializes segment registers.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ProcSup::InitializeSegments(VOID)
{
/* Initialize segments */
CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK);
CpuFunc::LoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK);
CpuFunc::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);
}
/**
* Initializes the kernel's Task State Segment (TSS).
*
* @param Tss
* Supplies a pointer to the TSS to use.
*
* @param Gdt
* Supplies a pointer to the GDT to use.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelBootStack,
IN PVOID KernelFaultStack)
{
/* Fill TSS with zeroes */
RtlZeroMemory(ProcessorBlock->TssBase, sizeof(KTSS));
/* Setup I/O map and stacks for ring0 & traps */
ProcessorBlock->TssBase->IoMapBase = sizeof(KTSS);
ProcessorBlock->TssBase->Rsp0 = (ULONG_PTR)KernelBootStack;
ProcessorBlock->TssBase->Ist[KIDT_IST_PANIC] = (ULONG_PTR)KernelFaultStack;
ProcessorBlock->TssBase->Ist[KIDT_IST_MCA] = (ULONG_PTR)KernelFaultStack;
}
/**
* Fills in an AMD64 GDT entry.
*
* @param Gdt
* Supplies a pointer to the GDT.
*
* @param Selector
* Specifies a segment selector of the GDT entry.
*
* @param Base
* Specifies a base address value of the descriptor.
*
* @param Limit
* Specifies a descriptor limit.
*
* @param Type
* Specifies a type of the descriptor.
*
* @param Dpl
* Specifies the descriptor privilege level.
*
* @param SegmentMode
* Specifies a segment mode of the descriptor.
*
* @return This routine does not return any value
*
* @since XT 1.0
*/
XTAPI
VOID
ProcSup::SetGdtEntry(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base,
IN ULONG Limit,
IN UCHAR Type,
IN UCHAR Dpl,
IN UCHAR SegmentMode)
{
PKGDTENTRY GdtEntry;
UCHAR Granularity;
/* Set the granularity flag depending on descriptor limit */
if(Limit < 0x100000)
{
/* Limit is in 1B blocks */
Granularity = 0;
}
else
{
/* Limit is in 4KB blocks */
Granularity = 1;
Limit >>= 12;
}
/* Get GDT entry */
GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK));
/* Set GDT descriptor base */
GdtEntry->BaseLow = (Base & 0xFFFF);
GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF);
GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF);
GdtEntry->BaseUpper = (Base >> 32);
/* Set descriptor limit */
GdtEntry->LimitLow = (Limit & 0xFFFF);
GdtEntry->Bits.LimitHigh = ((Limit >> 16) & 0xF);
/* Initialize GDT entry */
GdtEntry->Bits.DefaultBig = !!(SegmentMode & 2);
GdtEntry->Bits.Dpl = (Dpl & 0x3);
GdtEntry->Bits.Granularity = Granularity;
GdtEntry->Bits.LongMode = !!(SegmentMode & 1);
GdtEntry->Bits.Present = (Type != 0);
GdtEntry->Bits.System = 0;
GdtEntry->Bits.Type = (Type & 0x1F);
GdtEntry->MustBeZero = 0;
}
/**
* Updates an existing AMD64 GDT entry with new base address.
*
* @param Gdt
* Supplies a pointer to the GDT.
*
* @param Selector
* Specifies a segment selector of the GDT entry.
*
* @param Base
* Specifies a base address value of the descriptor.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base)
{
PKGDTENTRY GdtEntry;
/* Get GDT entry */
GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK));
/* Set new GDT descriptor base */
GdtEntry->BaseLow = (Base & 0xFFFF);
GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF);
GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF);
GdtEntry->BaseUpper = (Base >> 32);
}
/**
* Fills in a call, interrupt, task or trap gate entry.
*
* @param Idt
* Supplies a pointer to IDT structure, where gate is located.
*
* @param Vector
* Supplies a gate vector pointing to the interrupt gate in the IDT
*
* @param Handler
* Supplies a pointer to the interrupt handler of the specified gate.
*
* @param Selector
* Supplies the code selector the gate should run in.
*
* @param Ist
* Supplies the interrupt stack table entry the gate should run in.
*
* @param Access
* Supplies the gate access rights.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Access)
{
/* Setup the gate */
Idt[Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF);
Idt[Vector].OffsetMiddle = (((ULONG_PTR)Handler >> 16) & 0xFFFF);
Idt[Vector].OffsetHigh = (ULONG_PTR)Handler >> 32;
Idt[Vector].Dpl = Access;
Idt[Vector].IstIndex = Ist;
Idt[Vector].Present = 1;
Idt[Vector].Selector = Selector;
Idt[Vector].Type = 0xE;
}
} /* namespace */
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTAPI
PVOID
ArGetBootStack(VOID)
{
return AR::ProcSup::GetBootStack();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTAPI
VOID
ArInitializeProcessor(IN PVOID ProcessorStructures)
{
AR::ProcSup::InitializeProcessor(ProcessorStructures);
}

View File

@@ -1,14 +1,18 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/amd64/traps.c * FILE: xtoskrnl/ar/amd64/traps.cc
* DESCRIPTION: AMD64 system traps * DESCRIPTION: AMD64 system traps
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
/** /**
* Dispatches the trap provided by common trap handler. * Dispatches the trap provided by common trap handler.
* *
@@ -21,124 +25,138 @@
*/ */
XTCDECL XTCDECL
VOID VOID
ArpDispatchTrap(IN PKTRAP_FRAME TrapFrame) Traps::DispatchTrap(IN PKTRAP_FRAME TrapFrame)
{ {
/* Check vector and call appropriate handler */ /* Check vector and call appropriate handler */
switch(TrapFrame->Vector) switch(TrapFrame->Vector)
{ {
case 0x00: case 0x00:
/* Divide By Zero exception */ /* Divide By Zero exception */
ArpHandleTrap00(TrapFrame); HandleTrap00(TrapFrame);
break; break;
case 0x01: case 0x01:
/* Debug exception */ /* Debug exception */
ArpHandleTrap01(TrapFrame); HandleTrap01(TrapFrame);
break; break;
case 0x02: case 0x02:
/* Non-Maskable Interrupt (NMI) */ /* Non-Maskable Interrupt (NMI) */
ArpHandleTrap02(TrapFrame); HandleTrap02(TrapFrame);
break; break;
case 0x03: case 0x03:
/* INT3 instruction executed */ /* INT3 instruction executed */
ArpHandleTrap03(TrapFrame); HandleTrap03(TrapFrame);
break; break;
case 0x04: case 0x04:
/* Overflow exception */ /* Overflow exception */
ArpHandleTrap04(TrapFrame); HandleTrap04(TrapFrame);
break; break;
case 0x05: case 0x05:
/* Bound Range Exceeded exception */ /* Bound Range Exceeded exception */
ArpHandleTrap05(TrapFrame); HandleTrap05(TrapFrame);
break; break;
case 0x06: case 0x06:
/* Invalid Opcode exception */ /* Invalid Opcode exception */
ArpHandleTrap06(TrapFrame); HandleTrap06(TrapFrame);
break; break;
case 0x07: case 0x07:
/* Device Not Available exception */ /* Device Not Available exception */
ArpHandleTrap07(TrapFrame); HandleTrap07(TrapFrame);
break; break;
case 0x08: case 0x08:
/* Double Fault exception */ /* Double Fault exception */
ArpHandleTrap08(TrapFrame); HandleTrap08(TrapFrame);
break; break;
case 0x09: case 0x09:
/* Segment Overrun exception */ /* Segment Overrun exception */
ArpHandleTrap09(TrapFrame); HandleTrap09(TrapFrame);
break; break;
case 0x0A: case 0x0A:
/* Invalid TSS exception */ /* Invalid TSS exception */
ArpHandleTrap0A(TrapFrame); HandleTrap0A(TrapFrame);
break; break;
case 0x0B: case 0x0B:
/* Segment Not Present exception */ /* Segment Not Present exception */
ArpHandleTrap0B(TrapFrame); HandleTrap0B(TrapFrame);
break; break;
case 0x0C: case 0x0C:
/* Stack Segment Fault exception */ /* Stack Segment Fault exception */
ArpHandleTrap0C(TrapFrame); HandleTrap0C(TrapFrame);
break; break;
case 0x0D: case 0x0D:
/* General Protection Fault (GPF) exception*/ /* General Protection Fault (GPF) exception*/
ArpHandleTrap0D(TrapFrame); HandleTrap0D(TrapFrame);
break; break;
case 0x0E: case 0x0E:
/* Page Fault exception */ /* Page Fault exception */
ArpHandleTrap0E(TrapFrame); HandleTrap0E(TrapFrame);
break; break;
case 0x10: case 0x10:
/* X87 Floating-Point exception */ /* X87 Floating-Point exception */
ArpHandleTrap10(TrapFrame); HandleTrap10(TrapFrame);
break; break;
case 0x11: case 0x11:
/* Alignment Check exception */ /* Alignment Check exception */
ArpHandleTrap11(TrapFrame); HandleTrap11(TrapFrame);
break; break;
case 0x12: case 0x12:
/* Machine Check exception */ /* Machine Check exception */
ArpHandleTrap12(TrapFrame); HandleTrap12(TrapFrame);
break; break;
case 0x13: case 0x13:
/* SIMD Floating-Point exception */ /* SIMD Floating-Point exception */
ArpHandleTrap13(TrapFrame); HandleTrap13(TrapFrame);
break; break;
case 0x1F: case 0x1F:
/* Software Interrupt at APC level */ /* Software Interrupt at APC level */
ArpHandleTrap1F(TrapFrame); HandleTrap1F(TrapFrame);
break; break;
case 0x2C: case 0x2C:
/* Assertion raised */ /* Assertion raised */
ArpHandleTrap2C(TrapFrame); HandleTrap2C(TrapFrame);
break; break;
case 0x2D: case 0x2D:
/* Debug-Service-Request raised */ /* Debug-Service-Request raised */
ArpHandleTrap2D(TrapFrame); HandleTrap2D(TrapFrame);
break; break;
case 0x2F: case 0x2F:
/* Software Interrupt at DISPATCH level */ /* Software Interrupt at DISPATCH level */
ArpHandleTrap2F(TrapFrame); HandleTrap2F(TrapFrame);
break; break;
case 0xE1: case 0xE1:
/* InterProcessor Interrupt (IPI) */ /* InterProcessor Interrupt (IPI) */
ArpHandleTrapE1(TrapFrame); HandleTrapE1(TrapFrame);
break; break;
default: default:
/* Unknown/Unexpected trap */ /* Unknown/Unexpected trap */
ArpHandleTrapFF(TrapFrame); HandleTrapFF(TrapFrame);
break; break;
} }
} }
/**
* Handles a 32-bit system call.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL XTCDECL
VOID VOID
ArpHandleSystemCall32(VOID) Traps::HandleSystemCall32(VOID)
{ {
DebugPrint(L"Handled 32-bit system call!\n"); DebugPrint(L"Handled 32-bit system call!\n");
} }
/**
* Handles a 64-bit system call.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL XTCDECL
VOID VOID
ArpHandleSystemCall64(VOID) Traps::HandleSystemCall64(VOID)
{ {
DebugPrint(L"Handled 64-bit system call!\n"); DebugPrint(L"Handled 64-bit system call!\n");
} }
@@ -155,7 +173,7 @@ ArpHandleSystemCall64(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap00(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Division-By-Zero Error (0x00)!\n"); DebugPrint(L"Handled Division-By-Zero Error (0x00)!\n");
for(;;); for(;;);
@@ -173,7 +191,7 @@ ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap01(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Debug exception (0x01)!\n"); DebugPrint(L"Handled Debug exception (0x01)!\n");
for(;;); for(;;);
@@ -191,7 +209,7 @@ ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n"); DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n");
for(;;); for(;;);
@@ -209,7 +227,7 @@ ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap03(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled INT3 (0x03)!\n"); DebugPrint(L"Handled INT3 (0x03)!\n");
for(;;); for(;;);
@@ -227,7 +245,7 @@ ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap04(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Overflow exception (0x04)!\n"); DebugPrint(L"Handled Overflow exception (0x04)!\n");
for(;;); for(;;);
@@ -245,7 +263,7 @@ ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap05(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Bound-Range-Exceeded exception (0x05)!\n"); DebugPrint(L"Handled Bound-Range-Exceeded exception (0x05)!\n");
for(;;); for(;;);
@@ -263,7 +281,7 @@ ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap06(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Invalid Opcode exception (0x06)!\n"); DebugPrint(L"Handled Invalid Opcode exception (0x06)!\n");
for(;;); for(;;);
@@ -281,7 +299,7 @@ ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap07(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Device Not Available exception (0x07)!\n"); DebugPrint(L"Handled Device Not Available exception (0x07)!\n");
for(;;); for(;;);
@@ -299,7 +317,7 @@ ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap08(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Double-Fault exception (0x08)!\n"); DebugPrint(L"Handled Double-Fault exception (0x08)!\n");
for(;;); for(;;);
@@ -317,7 +335,7 @@ ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap09(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Segment-Overrun exception (0x09)!\n"); DebugPrint(L"Handled Segment-Overrun exception (0x09)!\n");
for(;;); for(;;);
@@ -335,7 +353,7 @@ ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0A(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Invalid-TSS exception (0x0A)!\n"); DebugPrint(L"Handled Invalid-TSS exception (0x0A)!\n");
for(;;); for(;;);
@@ -353,7 +371,7 @@ ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0B(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Segment-Not-Present exception (0x0B)!\n"); DebugPrint(L"Handled Segment-Not-Present exception (0x0B)!\n");
for(;;); for(;;);
@@ -371,7 +389,7 @@ ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0C(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Stack-Segment-Fault exception (0x0C)!\n"); DebugPrint(L"Handled Stack-Segment-Fault exception (0x0C)!\n");
for(;;); for(;;);
@@ -389,7 +407,7 @@ ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0D(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled General-Protection-Fault (0x0D)!\n"); DebugPrint(L"Handled General-Protection-Fault (0x0D)!\n");
for(;;); for(;;);
@@ -407,7 +425,7 @@ ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0E(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Page-Fault exception (0x0E)!\n"); DebugPrint(L"Handled Page-Fault exception (0x0E)!\n");
for(;;); for(;;);
@@ -425,7 +443,7 @@ ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap10(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled x87 Floating-Point exception (0x10)!\n"); DebugPrint(L"Handled x87 Floating-Point exception (0x10)!\n");
for(;;); for(;;);
@@ -443,7 +461,7 @@ ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap11(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Alignment-Check exception (0x11)!\n"); DebugPrint(L"Handled Alignment-Check exception (0x11)!\n");
for(;;); for(;;);
@@ -461,7 +479,7 @@ ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap12(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Machine-Check exception (0x12)!\n"); DebugPrint(L"Handled Machine-Check exception (0x12)!\n");
for(;;); for(;;);
@@ -479,7 +497,7 @@ ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap13(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled SIMD Floating-Point exception (0x13)!\n"); DebugPrint(L"Handled SIMD Floating-Point exception (0x13)!\n");
for(;;); for(;;);
@@ -497,7 +515,7 @@ ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap1F(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap1F(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Unhandled software interrupt at APC level (0x1F)!\n"); DebugPrint(L"Unhandled software interrupt at APC level (0x1F)!\n");
} }
@@ -514,7 +532,7 @@ ArpHandleTrap1F(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap2C(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Assertion (0x2C)!\n"); DebugPrint(L"Handled Assertion (0x2C)!\n");
for(;;); for(;;);
@@ -532,7 +550,7 @@ ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap2D(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Debug-Service-Request (0x2D)!\n"); DebugPrint(L"Handled Debug-Service-Request (0x2D)!\n");
for(;;); for(;;);
@@ -550,7 +568,7 @@ ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap2F(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap2F(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Unhandled software interrupt at DISPATCH level (0x2F)!\n"); DebugPrint(L"Unhandled software interrupt at DISPATCH level (0x2F)!\n");
} }
@@ -567,7 +585,7 @@ ArpHandleTrap2F(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrapE1(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrapE1(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Unhandled IPI interrupt (0xE1)!\n"); DebugPrint(L"Unhandled IPI interrupt (0xE1)!\n");
} }
@@ -584,8 +602,49 @@ ArpHandleTrapE1(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrapFF(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrapFF(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Unexpected-Interrupt (0xFF)!\n"); DebugPrint(L"Handled Unexpected-Interrupt (0xFF)!\n");
for(;;); for(;;);
} }
/**
* Initializes system call MSRs.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
Traps::InitializeSystemCallMsrs(VOID)
{
/* Initialize system calls MSR */
CpuFunc::WriteModelSpecificRegister(X86_MSR_STAR, (((ULONG64)KGDT_R3_CMCODE | RPL_MASK) << 48) | ((ULONG64)KGDT_R0_CODE << 32));
CpuFunc::WriteModelSpecificRegister(X86_MSR_CSTAR, (ULONG64)&HandleSystemCall32);
CpuFunc::WriteModelSpecificRegister(X86_MSR_LSTAR, (ULONG64)&HandleSystemCall64);
CpuFunc::WriteModelSpecificRegister(X86_MSR_FMASK, X86_EFLAGS_IF_MASK | X86_EFLAGS_TF_MASK);
/* Enable system call extensions (SCE) in EFER MSR */
CpuFunc::WriteModelSpecificRegister(X86_MSR_EFER, CpuFunc::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_SCE);
}
} /* namespace */
/**
* C-linkage wrapper for dispatching the trap provided by common trap handler.
*
* @param TrapFrame
* Supplies a kernel trap frame pushed by common trap handler on the stack.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCLINK
XTCDECL
VOID
ArDispatchTrap(IN PKTRAP_FRAME TrapFrame)
{
AR::Traps::DispatchTrap(TrapFrame);
}

View File

@@ -22,9 +22,9 @@
* *
* @since XT 1.0 * @since XT 1.0
*/ */
.macro ArpCreateTrapHandler Vector .macro ArCreateTrapHandler Vector
.global _ArpTrap\Vector .global _ArTrap\Vector
_ArpTrap\Vector: _ArTrap\Vector:
/* Push fake error code for non-error vectors */ /* Push fake error code for non-error vectors */
.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
@@ -84,7 +84,7 @@ KernelMode$\Vector:
/* Push Frame Pointer, clear direction flag and pass to trap dispatcher */ /* Push Frame Pointer, clear direction flag and pass to trap dispatcher */
push %esp push %esp
cld cld
call _ArpDispatchTrap call _ArDispatchTrap
/* Clean up the stack */ /* Clean up the stack */
add $4, %esp add $4, %esp
@@ -121,6 +121,6 @@ KernelModeReturn$\Vector:
/* Populate common 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
ArpCreateTrapHandler 0x\i\j ArCreateTrapHandler 0x\i\j
.endr .endr
.endr .endr

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

@@ -0,0 +1,14 @@
/**
* 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 <amd64/asmsup.h>
.altmacro
.text

View File

@@ -1,846 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/i686/cpufunc.c
* DESCRIPTION: Routines to provide access to special i686 CPU instructions
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
/**
* Instructs the processor to clear the interrupt flag.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArClearInterruptFlag(VOID)
{
asm volatile("cli");
}
/**
* Retrieves a various amount of information about the CPU.
*
* @param Registers
* Supplies a pointer to the structure containing all the necessary registers and leafs for CPUID.
*
* @return TRUE if CPUID function could be executed, FALSE otherwise.
*
* @since XT 1.0
*/
XTCDECL
BOOLEAN
ArCpuId(IN OUT PCPUID_REGISTERS Registers)
{
UINT32 MaxLeaf;
/* Get highest function ID available */
asm volatile("cpuid"
: "=a" (MaxLeaf)
: "a" (Registers->Leaf & 0x80000000)
: "rbx",
"rcx",
"rdx");
/* Check if CPU supports this command */
if(Registers->Leaf > MaxLeaf)
{
/* Cannot call it, return FALSE */
return FALSE;
}
/* Execute CPUID function */
asm volatile("cpuid"
: "=a" (Registers->Eax),
"=b" (Registers->Ebx),
"=c" (Registers->Ecx),
"=d" (Registers->Edx)
: "a" (Registers->Leaf),
"c" (Registers->SubLeaf));
/* Return TRUE */
return TRUE;
}
/**
* Partially flushes the Translation Lookaside Buffer (TLB)
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArFlushTlb(VOID)
{
/* Flush the TLB by resetting the CR3 */
ArWriteControlRegister(3, ArReadControlRegister(3));
}
/**
* Gets the address of the current stack register.
*
* @return This routine returns the current stack pointer.
*
* @since XT 1.0
*/
XTASSEMBLY
XTCDECL
ULONG_PTR
ArGetStackPointer(VOID)
{
/* Get current stack pointer */
asm volatile("mov %%esp, %%eax\n"
"ret\n"
:
:
:);
}
/**
* Halts the central processing unit (CPU).
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArHalt(VOID)
{
asm volatile("hlt");
}
/**
* Invalidates the TLB (Translation Lookaside Buffer) for specified virtual address.
*
* @param Address
* Suuplies a virtual address whose associated TLB entry will be invalidated.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArInvalidateTlbEntry(PVOID Address)
{
asm volatile("invlpg (%0)"
:
: "b" (Address)
: "memory");
}
/**
* Loads the value in the source operand into the global descriptor table register (GDTR).
*
* @param Source
* Specifies a memory location that contains the base address of GDT.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArLoadGlobalDescriptorTable(IN PVOID Source)
{
asm volatile("lgdt %0"
:
: "m" (*(PSHORT)Source)
: "memory");
}
/**
* Loads the value in the source operand into the interrupt descriptor table register (IDTR).
*
* @param Source
* Specifies a memory location that contains the base address of IDT.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArLoadInterruptDescriptorTable(IN PVOID Source)
{
asm volatile("lidt %0"
:
: "m" (*(PSHORT)Source)
: "memory");
}
/**
* Loads the value in the source operand into the local descriptor table register (LDTR).
*
* @param Source
* Specifies a selector value.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArLoadLocalDescriptorTable(IN USHORT Source)
{
asm volatile("lldtw %0"
:
: "g" (Source));
}
/**
* Loads source data into specified segment.
*
* @param Segment
* Supplies a segment identification.
*
* @param Source
* Supplies a pointer to the memory area containing data that will be loaded into specified segment.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArLoadSegment(IN USHORT Segment,
IN ULONG Source)
{
switch(Segment)
{
case SEGMENT_CS:
/* Load CS Segment */
asm volatile("mov %0, %%eax\n"
"push %%eax\n"
"lea label, %%eax\n"
"push %%eax\n"
"lret\n"
"label:"
:
: "ri" (Source)
: "eax");
break;
case SEGMENT_DS:
/* Load DS Segment */
asm volatile("movl %0, %%ds"
:
: "r" (Source));
break;
case SEGMENT_ES:
/* Load ES Segment */
asm volatile("movl %0, %%es"
:
: "r" (Source));
break;
case SEGMENT_FS:
/* Load FS Segment */
asm volatile("movl %0, %%fs"
:
: "r" (Source));
break;
case SEGMENT_GS:
/* Load GS Segment */
asm volatile("movl %0, %%gs"
:
: "r" (Source));
break;
case SEGMENT_SS:
/* Load SS Segment */
asm volatile("movl %0, %%ss"
:
: "r" (Source));
break;
}
}
/**
* Loads Task Register (TR) with a segment selector that points to TSS.
*
* @param Source
* Supplies the segment selector in the GDT describing the TSS.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArLoadTaskRegister(USHORT Source)
{
asm volatile("ltr %0"
:
: "rm" (Source));
}
/**
* Orders memory accesses as seen by other processors.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArMemoryBarrier(VOID)
{
LONG Barrier;
asm volatile("xchg %%eax, %0"
:
: "m" (Barrier)
: "%eax");
}
/**
* Reads the specified CPU control register and returns its value.
*
* @param ControlRegister
* Supplies a number of a control register which controls the general behavior of a CPU.
*
* @return The value stored in the control register.
*
* @since XT 1.0
*/
XTCDECL
ULONG_PTR
ArReadControlRegister(IN USHORT ControlRegister)
{
ULONG_PTR Value;
/* Read a value from specified CR register */
switch(ControlRegister)
{
case 0:
/* Read value from CR0 */
asm volatile("mov %%cr0, %0"
: "=r" (Value)
:
: "memory");
break;
case 2:
/* Read value from CR2 */
asm volatile("mov %%cr2, %0"
: "=r" (Value)
:
: "memory");
break;
case 3:
/* Read value from CR3 */
asm volatile("mov %%cr3, %0"
: "=r" (Value)
:
: "memory");
break;
case 4:
/* Read value from CR4 */
asm volatile("mov %%cr4, %0"
: "=r" (Value)
:
: "memory");
break;
default:
/* Invalid control register set */
Value = 0;
break;
}
/* Return value read from given CR register */
return Value;
}
/**
* Reads the specified CPU debug register and returns its value.
*
* @param DebugRegister
* Supplies a number of a debug register to read from.
*
* @return The value stored in the specified debug register.
*
* @since XT 1.0
*/
XTCDECL
ULONG_PTR
ArReadDebugRegister(IN USHORT DebugRegister)
{
ULONG_PTR Value;
/* Read a value from specified DR register */
switch(DebugRegister)
{
case 0:
/* Read value from DR0 */
asm volatile("mov %%dr0, %0"
: "=r" (Value));
break;
case 1:
/* Read value from DR1 */
asm volatile("mov %%dr1, %0"
: "=r" (Value));
break;
case 2:
/* Read value from DR2 */
asm volatile("mov %%dr2, %0"
: "=r" (Value));
break;
case 3:
/* Read value from DR3 */
asm volatile("mov %%dr3, %0"
: "=r" (Value));
break;
case 4:
/* Read value from DR4 */
asm volatile("mov %%dr4, %0"
: "=r" (Value));
break;
case 5:
/* Read value from DR5 */
asm volatile("mov %%dr5, %0"
: "=r" (Value));
break;
case 6:
/* Read value from DR6 */
asm volatile("mov %%dr6, %0"
: "=r" (Value));
break;
case 7:
/* Read value from DR7 */
asm volatile("mov %%dr7, %0"
: "=r" (Value));
break;
default:
/* Invalid debug register set */
Value = 0;
break;
}
/* Return value read from given DR register */
return Value;
}
/**
* Reads dualword from a memory location specified by an offset relative to the beginning of the FS segment.
*
* @param Offset
* Specifies the offset from the beginning of FS segment.
*
* @return Returns the value read from the specified memory location relative to FS segment.
*
* @since XT 1.0
*/
XTCDECL
ULONG
ArReadFSDualWord(ULONG Offset)
{
ULONG Value;
asm volatile("movl %%fs:%a[Offset], %k[Value]"
: [Value] "=r" (Value)
: [Offset] "ir" (Offset));
return Value;
}
/**
* Reads a 64-bit value from the requested Model Specific Register (MSR).
*
* @param Register
* Supplies the MSR to read.
*
* @return This routine returns the 64-bit MSR value.
*
* @since XT 1.0
*/
XTCDECL
ULONGLONG
ArReadModelSpecificRegister(IN ULONG Register)
{
ULONGLONG Value;
asm volatile("rdmsr"
: "=A" (Value)
: "c" (Register));
return Value;
}
/**
* Reads the contents of the MXCSR control/status register.
*
* @return This routine returns the contents of the MXCSR register as a 32-bit unsigned integer value.
*
* @since XT 1.0
*/
XTCDECL
UINT
ArReadMxCsrRegister(VOID)
{
return __builtin_ia32_stmxcsr();
}
/**
* Reads the current value of the CPU's time-stamp counter.
*
* @return This routine returns the current instruction cycle count since the processor was started.
*
* @since XT 1.0
*/
XTCDECL
ULONGLONG
ArReadTimeStampCounter(VOID)
{
ULONGLONG Value;
asm volatile("rdtsc"
: "=A" (Value));
return Value;
}
/**
* Orders memory accesses as seen by other processors, without fence.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArReadWriteBarrier(VOID)
{
asm volatile(""
:
:
: "memory");
}
/**
* Instructs the processor to set the interrupt flag.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArSetInterruptFlag(VOID)
{
asm volatile("sti");
}
/**
* Stores GDT register into the given memory area.
*
* @param Destination
* Supplies a pointer to the memory area where GDT will be stored.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArStoreGlobalDescriptorTable(OUT PVOID Destination)
{
asm volatile("sgdt %0"
: "=m" (*(PSHORT)Destination)
:
: "memory");
}
/**
* Stores IDT register into the given memory area.
*
* @param Destination
* Supplies a pointer to the memory area where IDT will be stored.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArStoreInterruptDescriptorTable(OUT PVOID Destination)
{
asm volatile("sidt %0"
: "=m" (*(PSHORT)Destination)
:
: "memory");
}
/**
* Stores LDT register into the given memory area.
*
* @param Destination
* Supplies a pointer to the memory area where LDT will be stored.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArStoreLocalDescriptorTable(OUT PVOID Destination)
{
asm volatile("sldt %0"
: "=m" (*(PSHORT)Destination)
:
: "memory");
}
/**
* Stores specified segment into the given memory area.
*
* @param Segment
* Supplies a segment identification.
*
* @param Destination
* Supplies a pointer to the memory area where segment data will be stored.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArStoreSegment(IN USHORT Segment,
OUT PVOID Destination)
{
switch(Segment)
{
case SEGMENT_CS:
asm volatile("movl %%cs, %0"
: "=r" (*(PUINT)Destination));
break;
case SEGMENT_DS:
asm volatile("movl %%ds, %0"
: "=r" (*(PUINT)Destination));
break;
case SEGMENT_ES:
asm volatile("movl %%es, %0"
: "=r" (*(PUINT)Destination));
break;
case SEGMENT_FS:
asm volatile("movl %%fs, %0"
: "=r" (*(PUINT)Destination));
break;
case SEGMENT_GS:
asm volatile("movl %%gs, %0"
: "=r" (*(PUINT)Destination));
break;
case SEGMENT_SS:
asm volatile("movl %%ss, %0"
: "=r" (*(PUINT)Destination));
break;
default:
Destination = NULL;
break;
}
}
/**
* Stores TR into the given memory area.
*
* @param Destination
* Supplies a pointer to the memory area where TR will be stores.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArStoreTaskRegister(OUT PVOID Destination)
{
asm volatile("str %0"
: "=m" (*(PULONG)Destination)
:
: "memory");
}
/**
* Writes a value to the specified CPU control register.
*
* @param ControlRegister
* Supplies a number of a control register which controls the general behavior of a CPU.
*
* @param Value
* Suplies a value to write to the CR register.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArWriteControlRegister(IN USHORT ControlRegister,
IN UINT_PTR Value)
{
/* Write a value into specified control register */
switch(ControlRegister)
{
case 0:
/* Write value to CR0 */
asm volatile("mov %0, %%cr0"
:
: "r" (Value)
: "memory");
break;
case 2:
/* Write value to CR2 */
asm volatile("mov %0, %%cr2"
:
: "r" (Value)
: "memory");
break;
case 3:
/* Write value to CR3 */
asm volatile("mov %0, %%cr3"
:
: "r" (Value)
: "memory");
break;
case 4:
/* Write value to CR4 */
asm volatile("mov %0, %%cr4"
:
: "r" (Value)
: "memory");
break;
}
}
/**
* Writes a value to the specified CPU debug register.
*
* @param DebugRegister
* Supplies a number of a debug register for write operation.
*
* @param Value
* Suplies a value to write to the specified DR register.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArWriteDebugRegister(IN USHORT DebugRegister,
IN UINT_PTR Value)
{
/* Write a value into specified debug register */
switch(DebugRegister)
{
case 0:
/* Write value to DR0 */
asm volatile("mov %0, %%dr0"
:
: "r" (Value)
: "memory");
case 1:
/* Write value to DR1 */
asm volatile("mov %0, %%dr1"
:
: "r" (Value)
: "memory");
case 2:
/* Write value to DR2 */
asm volatile("mov %0, %%dr2"
:
: "r" (Value)
: "memory");
case 3:
/* Write value to DR3 */
asm volatile("mov %0, %%dr3"
:
: "r" (Value)
: "memory");
case 4:
/* Write value to DR4 */
asm volatile("mov %0, %%dr4"
:
: "r" (Value)
: "memory");
case 5:
/* Write value to DR5 */
asm volatile("mov %0, %%dr5"
:
: "r" (Value)
: "memory");
case 6:
/* Write value to DR6 */
asm volatile("mov %0, %%dr6"
:
: "r" (Value)
: "memory");
case 7:
/* Write value to DR7 */
asm volatile("mov %0, %%dr7"
:
: "r" (Value)
: "memory");
}
}
/**
* Writes the specified value to the program status and control (EFLAGS) register.
*
* @param Value
* The value to write to the EFLAGS register.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArWriteEflagsRegister(IN UINT_PTR Value)
{
asm volatile("push %0\n"
"popf"
:
: "rim" (Value));
}
/**
* Writes a 64-bit value to the requested Model Specific Register (MSR).
*
* @param Register
* Supplies the MSR register to write.
*
* @param Value
* Supplies the 64-bit value to write.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArWriteModelSpecificRegister(IN ULONG Register,
IN ULONGLONG Value)
{
asm volatile("wrmsr"
:
: "c" (Register),
"A" (Value));
}
/**
* Yields a current thread running on the processor.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArYieldProcessor(VOID)
{
asm volatile("pause"
:
:
: "memory");
}

1069
xtoskrnl/ar/i686/cpufunc.cc Normal file

File diff suppressed because it is too large Load Diff

40
xtoskrnl/ar/i686/data.cc Normal file
View File

@@ -0,0 +1,40 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/i686/data.cc
* DESCRIPTION: I686 architecture-specific global and static data
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
/* Initial kernel boot stack */
UCHAR ProcSup::BootStack[KERNEL_STACK_SIZE] = {};
/* Double Fault gate */
UCHAR ProcSup::DoubleFaultTss[KTSS_IO_MAPS];
/* Initial kernel fault stack */
UCHAR ProcSup::FaultStack[KERNEL_STACK_SIZE] = {};
/* Initial GDT */
KGDTENTRY ProcSup::InitialGdt[GDT_ENTRIES] = {};
/* Initial IDT */
KIDTENTRY ProcSup::InitialIdt[IDT_ENTRIES] = {};
/* Initial Processor Block */
KPROCESSOR_BLOCK ProcSup::InitialProcessorBlock;
/* Initial TSS */
KTSS ProcSup::InitialTss;
/* NMI task gate */
UCHAR ProcSup::NonMaskableInterruptTss[KTSS_IO_MAPS];
} /* namespace */

View File

@@ -1,32 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/i686/globals.c
* DESCRIPTION: XT architecture library global variables
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
/* Initial GDT */
KGDTENTRY ArInitialGdt[GDT_ENTRIES] = {0};
/* Initial IDT */
KIDTENTRY ArInitialIdt[IDT_ENTRIES] = {0};
/* Initial Processor Block */
KPROCESSOR_BLOCK ArInitialProcessorBlock;
/* Initial TSS */
KTSS ArInitialTss;
/* Double Fault and NMI task gates */
UCHAR ArpDoubleFaultTss[KTSS_IO_MAPS];
UCHAR ArpNonMaskableInterruptTss[KTSS_IO_MAPS];
/* Initial kernel boot stack */
UCHAR ArKernelBootStack[KERNEL_STACK_SIZE] = {0};
/* Initial kernel fault stack */
UCHAR ArKernelFaultStack[KERNEL_STACK_SIZE] = {0};

View File

@@ -1,104 +1,28 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/i686/procsup.c * FILE: xtoskrnl/ar/i686/procsup.cc
* DESCRIPTION: I686 processor functionality support * DESCRIPTION: I686 processor functionality support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
/** /**
* Initializes i686 processor specific structures. * Gets the base address of the kernel boot stack.
* *
* @return This routine does not return any value. * @return This routine returns a pointer to the kernel boot stack.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
XTAPI PVOID ProcSup::GetBootStack(VOID)
VOID
ArInitializeProcessor(VOID)
{ {
KDESCRIPTOR GdtDescriptor, IdtDescriptor; return (PVOID)BootStack;
PKPROCESSOR_BLOCK ProcessorBlock;
PVOID KernelFaultStack;
PKGDTENTRY Gdt;
PKIDTENTRY Idt;
PKTSS Tss;
/* Use initial structures */
Gdt = ArInitialGdt;
Idt = ArInitialIdt;
Tss = &ArInitialTss;
KernelFaultStack = &ArKernelFaultStack;
/* Load processor block */
ProcessorBlock = CONTAIN_RECORD(&ArInitialProcessorBlock.Prcb, KPROCESSOR_BLOCK, Prcb);
/* Initialize processor block */
ArpInitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);
/* Initialize GDT, IDT and TSS */
ArpInitializeGdt(ProcessorBlock);
ArpInitializeTss(ProcessorBlock);
ArpInitializeIdt(ProcessorBlock);
/* 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 */
ArLoadGlobalDescriptorTable(&GdtDescriptor.Limit);
ArLoadInterruptDescriptorTable(&IdtDescriptor.Limit);
ArLoadTaskRegister((UINT)KGDT_SYS_TSS);
/* Enter passive IRQ level */
HlSetRunLevel(PASSIVE_LEVEL);
/* Initialize segment registers */
ArpInitializeSegments();
/* Initialize processor registers */
ArpInitializeProcessorRegisters();
/* Identify processor */
ArpIdentifyProcessor();
}
/**
* Updates an existing i686 GDT entry with new base address.
*
* @param Gdt
* Supplies a pointer to the GDT.
*
* @param Selector
* Specifies a segment selector of the GDT entry.
*
* @param Base
* Specifies a base address value of the descriptor.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ArSetGdtEntryBase(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base)
{
PKGDTENTRY GdtEntry;
/* Get GDT entry */
GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK));
/* Set new GDT descriptor base */
GdtEntry->BaseLow = (Base & 0xFFFF);
GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF);
GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF);
} }
/** /**
@@ -111,7 +35,7 @@ ArSetGdtEntryBase(IN PKGDTENTRY Gdt,
*/ */
XTAPI XTAPI
VOID VOID
ArpIdentifyProcessor(VOID) ProcSup::IdentifyProcessor(VOID)
{ {
PKPROCESSOR_CONTROL_BLOCK Prcb; PKPROCESSOR_CONTROL_BLOCK Prcb;
CPUID_REGISTERS CpuRegisters; CPUID_REGISTERS CpuRegisters;
@@ -129,15 +53,15 @@ ArpIdentifyProcessor(VOID)
ArCpuId(&CpuRegisters); ArCpuId(&CpuRegisters);
/* Store CPU vendor in processor control block */ /* Store CPU vendor in processor control block */
Prcb->CpuId.Vendor = CpuRegisters.Ebx; Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx;
Prcb->CpuId.VendorName[0] = CpuRegisters.Ebx; *(PULONG)&Prcb->CpuId.VendorName[0] = CpuRegisters.Ebx;
Prcb->CpuId.VendorName[4] = CpuRegisters.Edx; *(PULONG)&Prcb->CpuId.VendorName[4] = CpuRegisters.Edx;
Prcb->CpuId.VendorName[8] = CpuRegisters.Ecx; *(PULONG)&Prcb->CpuId.VendorName[8] = CpuRegisters.Ecx;
Prcb->CpuId.VendorName[12] = '\0'; Prcb->CpuId.VendorName[12] = '\0';
/* Get CPU features */ /* Get CPU standard features */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_CPU_FEATURES; CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
ArCpuId(&CpuRegisters); ArCpuId(&CpuRegisters);
/* Store CPU signature in processor control block */ /* Store CPU signature in processor control block */
@@ -150,9 +74,9 @@ ArpIdentifyProcessor(VOID)
if(Prcb->CpuId.Vendor == CPU_VENDOR_AMD) if(Prcb->CpuId.Vendor == CPU_VENDOR_AMD)
{ {
/* AMD CPU */ /* AMD CPU */
Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily; if(Prcb->CpuId.Family >= 0xF)
if(Prcb->CpuId.Model == 0xF)
{ {
Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4); Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
} }
} }
@@ -164,7 +88,7 @@ ArpIdentifyProcessor(VOID)
Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily; Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
} }
if((Prcb->CpuId.Family == 0xF) || (Prcb->CpuId.Family == 0x6)) if((Prcb->CpuId.Family == 0x6) || (Prcb->CpuId.Family == 0xF))
{ {
Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4); Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
} }
@@ -178,6 +102,77 @@ ArpIdentifyProcessor(VOID)
/* TODO: Store a list of CPU features in processor control block */ /* TODO: Store a list of CPU features in processor control block */
} }
/**
* Initializes i686 processor specific structures.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
{
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
PVOID KernelBootStack, KernelFaultStack;
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);
/* Use global IDT */
Idt = InitialIdt;
}
else
{
/* Use initial structures */
Gdt = InitialGdt;
Idt = InitialIdt;
Tss = &InitialTss;
KernelBootStack = &BootStack;
KernelFaultStack = &FaultStack;
ProcessorBlock = &InitialProcessorBlock;
}
/* Initialize processor block */
InitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);
/* Initialize GDT, IDT and TSS */
InitializeGdt(ProcessorBlock);
InitializeIdt(ProcessorBlock);
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack);
/* 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 */
CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS);
/* Enter passive IRQ level */
HlSetRunLevel(PASSIVE_LEVEL);
/* Initialize segment registers */
InitializeSegments();
/* Initialize processor registers */
InitializeProcessorRegisters();
/* Identify processor */
IdentifyProcessor();
}
/** /**
* Initializes the kernel's Global Descriptor Table (GDT). * Initializes the kernel's Global Descriptor Table (GDT).
* *
@@ -190,23 +185,23 @@ ArpIdentifyProcessor(VOID)
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock) ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
{ {
/* Initialize GDT entries */ /* Initialize GDT entries */
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 2); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 2);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONG_PTR)ProcessorBlock->TssBase, sizeof(KTSS) - 1, I686_TSS, KGDT_DPL_SYSTEM, 0); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONG_PTR)ProcessorBlock->TssBase, sizeof(KTSS) - 1, I686_TSS, KGDT_DPL_SYSTEM, 0);
ArpSetGdtEntry(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);
ArpSetGdtEntry(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);
ArpSetGdtEntry(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);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0);
ArpSetGdtEntry(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);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_NMI_TSS, 0x20000, 0xFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NMI_TSS, 0x20000, 0xFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0);
ArpSetGdtEntry(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);
ArpSetGdtEntry(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);
} }
/** /**
@@ -221,7 +216,7 @@ ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock) ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
{ {
UINT Vector; UINT Vector;
@@ -229,34 +224,34 @@ ArpInitializeIdt(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 */
ArpSetIdtGate(ProcessorBlock->IdtBase, Vector, ArpHandleTrapFF, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
} }
/* Setup IDT handlers for known interrupts and traps */ /* Setup IDT handlers for known interrupts and traps */
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x00, ArpTrap0x00, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x01, ArpTrap0x01, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x02, ArpTrap0x02, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x03, ArpTrap0x03, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x04, ArpTrap0x04, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x05, ArpTrap0x05, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x06, ArpTrap0x06, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x07, ArpTrap0x07, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x08, ArpTrap0x08, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x09, ArpTrap0x09, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0A, ArpTrap0x0A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0B, ArpTrap0x0B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0C, ArpTrap0x0C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0D, ArpTrap0x0D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0E, ArpTrap0x0E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x10, ArpTrap0x10, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x11, ArpTrap0x11, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x12, ArpTrap0x12, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x13, ArpTrap0x13, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2A, ArpTrap0x2A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrap0x2A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2B, ArpTrap0x2B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrap0x2B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2C, ArpTrap0x2C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2D, ArpTrap0x2D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2E, ArpTrap0x2E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrap0x2E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
} }
/** /**
@@ -280,21 +275,18 @@ ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
IN PKGDTENTRY Gdt, IN PKGDTENTRY Gdt,
IN PKIDTENTRY Idt, IN PKIDTENTRY Idt,
IN PKTSS Tss, IN PKTSS Tss,
IN PVOID DpcStack) IN PVOID DpcStack)
{ {
/* Fill processor block with zeroes */
RtlZeroMemory(ProcessorBlock, sizeof(KPROCESSOR_BLOCK));
/* Set processor block and processor control block */ /* Set processor block and processor control block */
ProcessorBlock->Self = ProcessorBlock; ProcessorBlock->Self = ProcessorBlock;
ProcessorBlock->CurrentPrcb = &ProcessorBlock->Prcb; ProcessorBlock->CurrentPrcb = &ProcessorBlock->Prcb;
/* Set GDT, IDT and TSS descriptors */ /* Set GDT, IDT and TSS descriptors */
ProcessorBlock->GdtBase = Gdt; ProcessorBlock->GdtBase = (PKGDTENTRY)(PVOID)Gdt;
ProcessorBlock->IdtBase = Idt; ProcessorBlock->IdtBase = Idt;
ProcessorBlock->TssBase = Tss; ProcessorBlock->TssBase = Tss;
@@ -302,9 +294,9 @@ ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
ProcessorBlock->Prcb.DpcStack = DpcStack; ProcessorBlock->Prcb.DpcStack = DpcStack;
/* Setup processor control block */ /* Setup processor control block */
ProcessorBlock->Prcb.Number = 0; ProcessorBlock->Prcb.CpuNumber = ProcessorBlock->CpuNumber;
ProcessorBlock->Prcb.SetMember = 1; ProcessorBlock->Prcb.SetMember = 1 << ProcessorBlock->CpuNumber;
ProcessorBlock->Prcb.MultiThreadProcessorSet = 1; ProcessorBlock->Prcb.MultiThreadProcessorSet = 1 << ProcessorBlock->CpuNumber;
/* Clear DR6 and DR7 registers */ /* Clear DR6 and DR7 registers */
ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr6 = 0; ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr6 = 0;
@@ -314,7 +306,7 @@ ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
ProcessorBlock->Prcb.CurrentThread = &KeInitialThread.ThreadControlBlock; ProcessorBlock->Prcb.CurrentThread = &KeInitialThread.ThreadControlBlock;
ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &KeInitialProcess.ProcessControlBlock; ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &KeInitialProcess.ProcessControlBlock;
ProcessorBlock->Prcb.IdleThread = &KeInitialThread.ThreadControlBlock; ProcessorBlock->Prcb.IdleThread = &KeInitialThread.ThreadControlBlock;
ProcessorBlock->Prcb.NextThread = NULL; ProcessorBlock->Prcb.NextThread = nullptr;
/* Set initial runlevel */ /* Set initial runlevel */
ProcessorBlock->RunLevel = PASSIVE_LEVEL; ProcessorBlock->RunLevel = PASSIVE_LEVEL;
@@ -329,13 +321,71 @@ ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeProcessorRegisters(VOID) ProcSup::InitializeProcessorRegisters(VOID)
{ {
/* Clear EFLAGS register */ /* Clear EFLAGS register */
ArWriteEflagsRegister(0); CpuFunc::WriteEflagsRegister(0);
/* Enable write-protection */ /* Enable write-protection */
ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_WP); CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_WP);
}
/**
* Initializes i686 processor specific structures with provided memory buffer.
*
* @param ProcessorStructures
* Supplies a pointer to the allocated buffer with processor structures.
*
* @param Gdt
* Supplies a pointer to the GDT.
*
* @param Tss
* Supplies a pointer to the TSS.
*
* @param ProcessorBlock
* Supplies a pointer to the processor block.
*
* @param KernelBootStack
* Supplies a pointer to the kernel boot stack.
*
* @param KernelFaultStack
* Supplies a pointer to the kernel fault stack.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
OUT PKGDTENTRY *Gdt,
OUT PKTSS *Tss,
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
OUT PVOID *KernelBootStack,
OUT PVOID *KernelFaultStack)
{
UINT_PTR Address;
/* Align address to page size boundary and move to kernel boot stack */
Address = ROUND_UP((UINT_PTR)ProcessorStructures, MM_PAGE_SIZE) + KERNEL_STACK_SIZE;
/* Assign a space for kernel boot stack and advance */
*KernelBootStack = (PVOID)Address;
Address += KERNEL_STACK_SIZE;
/* Assign a space for kernel fault stack, no advance needed as stack grows down */
*KernelFaultStack = (PVOID)Address;
/* Assign a space for GDT and advance */
*Gdt = (PKGDTENTRY)(PVOID)Address;
Address += sizeof(ArInitialGdt);
/* Assign a space for Processor Block and advance */
*ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address;
Address += sizeof(ArInitialProcessorBlock);
/* Assign a space for TSS */
*Tss = (PKTSS)(PVOID)Address;
} }
/** /**
@@ -347,13 +397,13 @@ ArpInitializeProcessorRegisters(VOID)
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeSegments(VOID) ProcSup::InitializeSegments(VOID)
{ {
/* Initialize segments */ /* Initialize segments */
ArLoadSegment(SEGMENT_CS, KGDT_R0_CODE); CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
ArLoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK); CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
ArLoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK); CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
ArLoadSegment(SEGMENT_FS, KGDT_R0_PB); CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R0_PB);
} }
/** /**
@@ -368,7 +418,9 @@ ArpInitializeSegments(VOID)
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock) ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelBootStack,
IN PVOID KernelFaultStack)
{ {
/* 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);
@@ -391,6 +443,7 @@ ArpInitializeTss(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 LDT and SS */ /* Set LDT and SS */
@@ -398,8 +451,8 @@ ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock)
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 */
ArpSetDoubleFaultTssEntry(ProcessorBlock); SetDoubleFaultTssEntry(ProcessorBlock, KernelFaultStack);
ArpSetNonMaskableInterruptTssEntry(ProcessorBlock); SetNonMaskableInterruptTssEntry(ProcessorBlock, KernelFaultStack);
} }
/** /**
@@ -414,7 +467,8 @@ ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock)
*/ */
XTAPI XTAPI
VOID VOID
ArpSetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock) ProcSup::SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelFaultStack)
{ {
PKGDTENTRY TaskGateEntry, TssEntry; PKGDTENTRY TaskGateEntry, TssEntry;
PKTSS Tss; PKTSS Tss;
@@ -427,20 +481,20 @@ ArpSetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock)
((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_DF_TSS; ((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_DF_TSS;
/* Initialize DoubleFault TSS and set initial state */ /* Initialize DoubleFault TSS and set initial state */
Tss = (PKTSS)ArpDoubleFaultTss; Tss = (PKTSS)DoubleFaultTss;
Tss->IoMapBase = sizeof(KTSS); Tss->IoMapBase = sizeof(KTSS);
Tss->Flags = 0; Tss->Flags = 0;
Tss->LDT = KGDT_R0_LDT; Tss->LDT = KGDT_R0_LDT;
Tss->CR3 = ArReadControlRegister(3); Tss->CR3 = CpuFunc::ReadControlRegister(3);
Tss->Esp = (ULONG_PTR)&ArKernelFaultStack; Tss->Esp = (ULONG_PTR)KernelFaultStack;
Tss->Esp0 = (ULONG_PTR)&ArKernelFaultStack; Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
Tss->Eip = PtrToUlong(ArpHandleTrap08); 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->Ss0 = KGDT_R0_DATA; Tss->Ss0 = KGDT_R0_DATA;
ArStoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss); 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)]));
@@ -484,7 +538,7 @@ ArpSetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock)
*/ */
XTAPI XTAPI
VOID VOID
ArpSetGdtEntry(IN PKGDTENTRY Gdt, ProcSup::SetGdtEntry(IN PKGDTENTRY Gdt,
IN USHORT Selector, IN USHORT Selector,
IN ULONG_PTR Base, IN ULONG_PTR Base,
IN ULONG Limit, IN ULONG Limit,
@@ -530,6 +584,39 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt,
GdtEntry->Bits.Type = (Type & 0x1F); GdtEntry->Bits.Type = (Type & 0x1F);
} }
/**
* Updates an existing i686 GDT entry with new base address.
*
* @param Gdt
* Supplies a pointer to the GDT.
*
* @param Selector
* Specifies a segment selector of the GDT entry.
*
* @param Base
* Specifies a base address value of the descriptor.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base)
{
PKGDTENTRY GdtEntry;
/* Get GDT entry */
GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK));
/* Set new GDT descriptor base */
GdtEntry->BaseLow = (Base & 0xFFFF);
GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF);
GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF);
}
/** /**
* Fills in a call, interrupt, task or trap gate entry. * Fills in a call, interrupt, task or trap gate entry.
* *
@@ -557,7 +644,7 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt,
*/ */
XTAPI XTAPI
VOID VOID
ArpSetIdtGate(IN PKIDTENTRY Idt, ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector, IN USHORT Vector,
IN PVOID Handler, IN PVOID Handler,
IN USHORT Selector, IN USHORT Selector,
@@ -583,7 +670,8 @@ ArpSetIdtGate(IN PKIDTENTRY Idt,
*/ */
XTAPI XTAPI
VOID VOID
ArpSetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock) ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelFaultStack)
{ {
PKGDTENTRY TaskGateEntry, TssEntry; PKGDTENTRY TaskGateEntry, TssEntry;
PKTSS Tss; PKTSS Tss;
@@ -596,19 +684,19 @@ ArpSetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock)
((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_NMI_TSS; ((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_NMI_TSS;
/* Initialize NMI TSS and set initial state */ /* Initialize NMI TSS and set initial state */
Tss = (PKTSS)ArpNonMaskableInterruptTss; Tss = (PKTSS)NonMaskableInterruptTss;
Tss->IoMapBase = sizeof(KTSS); Tss->IoMapBase = sizeof(KTSS);
Tss->Flags = 0; Tss->Flags = 0;
Tss->LDT = KGDT_R0_LDT; Tss->LDT = KGDT_R0_LDT;
Tss->CR3 = ArReadControlRegister(3); Tss->CR3 = ArReadControlRegister(3);
Tss->Esp = (ULONG_PTR)&ArKernelFaultStack; Tss->Esp = (ULONG_PTR)KernelFaultStack;
Tss->Esp0 = (ULONG_PTR)&ArKernelFaultStack; Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
Tss->Eip = PtrToUlong(ArpHandleTrap02); 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;
ArStoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss); CpuFunc::StoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss);
/* 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)]));
@@ -621,3 +709,24 @@ ArpSetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock)
TssEntry->Bits.Present = 1; TssEntry->Bits.Present = 1;
TssEntry->Bits.Type = I686_TSS; TssEntry->Bits.Type = I686_TSS;
} }
} /* namespace */
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTAPI
PVOID
ArGetBootStack(VOID)
{
return AR::ProcSup::GetBootStack();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTAPI
VOID
ArInitializeProcessor(IN PVOID ProcessorStructures)
{
AR::ProcSup::InitializeProcessor(ProcessorStructures);
}

View File

@@ -1,14 +1,18 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/i686/traps.c * FILE: xtoskrnl/ar/i686/traps.cc
* DESCRIPTION: I686 system traps * DESCRIPTION: I686 system traps
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
/** /**
* Dispatches the trap provided by common trap handler. * Dispatches the trap provided by common trap handler.
* *
@@ -21,110 +25,110 @@
*/ */
XTCDECL XTCDECL
VOID VOID
ArpDispatchTrap(IN PKTRAP_FRAME TrapFrame) Traps::DispatchTrap(IN PKTRAP_FRAME TrapFrame)
{ {
/* Check vector and call appropriate handler */ /* Check vector and call appropriate handler */
switch(TrapFrame->Vector) switch(TrapFrame->Vector)
{ {
case 0x00: case 0x00:
/* Divide By Zero exception */ /* Divide By Zero exception */
ArpHandleTrap00(TrapFrame); HandleTrap00(TrapFrame);
break; break;
case 0x01: case 0x01:
/* Debug exception */ /* Debug exception */
ArpHandleTrap01(TrapFrame); HandleTrap01(TrapFrame);
break; break;
case 0x02: case 0x02:
/* Non-Maskable Interrupt (NMI) */ /* Non-Maskable Interrupt (NMI) */
ArpHandleTrap02(TrapFrame); HandleTrap02(TrapFrame);
break; break;
case 0x03: case 0x03:
/* INT3 instruction executed */ /* INT3 instruction executed */
ArpHandleTrap03(TrapFrame); HandleTrap03(TrapFrame);
break; break;
case 0x04: case 0x04:
/* Overflow exception */ /* Overflow exception */
ArpHandleTrap04(TrapFrame); HandleTrap04(TrapFrame);
break; break;
case 0x05: case 0x05:
/* Bound Range Exceeded exception */ /* Bound Range Exceeded exception */
ArpHandleTrap05(TrapFrame); HandleTrap05(TrapFrame);
break; break;
case 0x06: case 0x06:
/* Invalid Opcode exception */ /* Invalid Opcode exception */
ArpHandleTrap06(TrapFrame); HandleTrap06(TrapFrame);
break; break;
case 0x07: case 0x07:
/* Device Not Available exception */ /* Device Not Available exception */
ArpHandleTrap07(TrapFrame); HandleTrap07(TrapFrame);
break; break;
case 0x08: case 0x08:
/* Double Fault exception */ /* Double Fault exception */
ArpHandleTrap08(TrapFrame); HandleTrap08(TrapFrame);
break; break;
case 0x09: case 0x09:
/* Segment Overrun exception */ /* Segment Overrun exception */
ArpHandleTrap09(TrapFrame); HandleTrap09(TrapFrame);
break; break;
case 0x0A: case 0x0A:
/* Invalid TSS exception */ /* Invalid TSS exception */
ArpHandleTrap0A(TrapFrame); HandleTrap0A(TrapFrame);
break; break;
case 0x0B: case 0x0B:
/* Segment Not Present exception */ /* Segment Not Present exception */
ArpHandleTrap0B(TrapFrame); HandleTrap0B(TrapFrame);
break; break;
case 0x0C: case 0x0C:
/* Stack Segment Fault exception */ /* Stack Segment Fault exception */
ArpHandleTrap0C(TrapFrame); HandleTrap0C(TrapFrame);
break; break;
case 0x0D: case 0x0D:
/* General Protection Fault (GPF) exception*/ /* General Protection Fault (GPF) exception*/
ArpHandleTrap0D(TrapFrame); HandleTrap0D(TrapFrame);
break; break;
case 0x0E: case 0x0E:
/* Page Fault exception */ /* Page Fault exception */
ArpHandleTrap0E(TrapFrame); HandleTrap0E(TrapFrame);
break; break;
case 0x10: case 0x10:
/* X87 Floating-Point exception */ /* X87 Floating-Point exception */
ArpHandleTrap10(TrapFrame); HandleTrap10(TrapFrame);
break; break;
case 0x11: case 0x11:
/* Alignment Check exception */ /* Alignment Check exception */
ArpHandleTrap11(TrapFrame); HandleTrap11(TrapFrame);
break; break;
case 0x12: case 0x12:
/* Machine Check exception */ /* Machine Check exception */
ArpHandleTrap12(TrapFrame); HandleTrap12(TrapFrame);
break; break;
case 0x13: case 0x13:
/* SIMD Floating-Point exception */ /* SIMD Floating-Point exception */
ArpHandleTrap13(TrapFrame); HandleTrap13(TrapFrame);
break; break;
case 0x2A: case 0x2A:
/* Tick Count service request */ /* Tick Count service request */
ArpHandleTrap2A(TrapFrame); HandleTrap2A(TrapFrame);
break; break;
case 0x2B: case 0x2B:
/* User-mode callback return */ /* User-mode callback return */
ArpHandleTrap2B(TrapFrame); HandleTrap2B(TrapFrame);
break; break;
case 0x2C: case 0x2C:
/* Assertion raised */ /* Assertion raised */
ArpHandleTrap2C(TrapFrame); HandleTrap2C(TrapFrame);
break; break;
case 0x2D: case 0x2D:
/* Debug-Service-Request raised */ /* Debug-Service-Request raised */
ArpHandleTrap2D(TrapFrame); HandleTrap2D(TrapFrame);
break; break;
case 0x2E: case 0x2E:
/* System call service request */ /* System call service request */
ArpHandleTrap2E(TrapFrame); HandleTrap2E(TrapFrame);
break; break;
default: default:
/* Unknown/Unexpected trap */ /* Unknown/Unexpected trap */
ArpHandleTrapFF(TrapFrame); HandleTrapFF(TrapFrame);
break; break;
} }
} }
@@ -141,7 +145,7 @@ ArpDispatchTrap(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap00(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Division-By-Zero Error (0x00)!\n"); DebugPrint(L"Handled Division-By-Zero Error (0x00)!\n");
for(;;); for(;;);
@@ -159,7 +163,7 @@ ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap01(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Debug exception (0x01)!\n"); DebugPrint(L"Handled Debug exception (0x01)!\n");
for(;;); for(;;);
@@ -177,7 +181,7 @@ ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n"); DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n");
for(;;); for(;;);
@@ -195,7 +199,7 @@ ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap03(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled INT3 (0x03)!\n"); DebugPrint(L"Handled INT3 (0x03)!\n");
for(;;); for(;;);
@@ -213,7 +217,7 @@ ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap04(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Overflow exception (0x04)!\n"); DebugPrint(L"Handled Overflow exception (0x04)!\n");
for(;;); for(;;);
@@ -231,7 +235,7 @@ ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap05(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Bound-Range-Exceeded exception (0x05)!\n"); DebugPrint(L"Handled Bound-Range-Exceeded exception (0x05)!\n");
for(;;); for(;;);
@@ -249,7 +253,7 @@ ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap06(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Invalid Opcode exception (0x06)!\n"); DebugPrint(L"Handled Invalid Opcode exception (0x06)!\n");
for(;;); for(;;);
@@ -267,7 +271,7 @@ ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap07(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Device Not Available exception (0x07)!\n"); DebugPrint(L"Handled Device Not Available exception (0x07)!\n");
for(;;); for(;;);
@@ -285,7 +289,7 @@ ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap08(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Double-Fault exception (0x08)!\n"); DebugPrint(L"Handled Double-Fault exception (0x08)!\n");
for(;;); for(;;);
@@ -303,7 +307,7 @@ ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap09(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Segment-Overrun exception (0x09)!\n"); DebugPrint(L"Handled Segment-Overrun exception (0x09)!\n");
for(;;); for(;;);
@@ -321,7 +325,7 @@ ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0A(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Invalid-TSS exception (0x0A)!\n"); DebugPrint(L"Handled Invalid-TSS exception (0x0A)!\n");
for(;;); for(;;);
@@ -339,7 +343,7 @@ ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0B(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Segment-Not-Present exception (0x0B)!\n"); DebugPrint(L"Handled Segment-Not-Present exception (0x0B)!\n");
for(;;); for(;;);
@@ -357,7 +361,7 @@ ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0C(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Stack-Segment-Fault exception (0x0C)!\n"); DebugPrint(L"Handled Stack-Segment-Fault exception (0x0C)!\n");
for(;;); for(;;);
@@ -375,7 +379,7 @@ ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0D(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled General-Protection-Fault (0x0D)!\n"); DebugPrint(L"Handled General-Protection-Fault (0x0D)!\n");
for(;;); for(;;);
@@ -393,7 +397,7 @@ ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0E(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Page-Fault exception (0x0E)!\n"); DebugPrint(L"Handled Page-Fault exception (0x0E)!\n");
for(;;); for(;;);
@@ -411,7 +415,7 @@ ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap10(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled x87 Floating-Point exception (0x10)!\n"); DebugPrint(L"Handled x87 Floating-Point exception (0x10)!\n");
for(;;); for(;;);
@@ -429,7 +433,7 @@ ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap11(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Alignment-Check exception (0x11)!\n"); DebugPrint(L"Handled Alignment-Check exception (0x11)!\n");
for(;;); for(;;);
@@ -447,7 +451,7 @@ ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap12(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Machine-Check exception (0x12)!\n"); DebugPrint(L"Handled Machine-Check exception (0x12)!\n");
for(;;); for(;;);
@@ -465,7 +469,7 @@ ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap13(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled SIMD Floating-Point exception (0x13)!\n"); DebugPrint(L"Handled SIMD Floating-Point exception (0x13)!\n");
for(;;); for(;;);
@@ -483,7 +487,7 @@ ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap2A(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap2A(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Unhandled Tick Count service request (0x2A)!\n"); DebugPrint(L"Unhandled Tick Count service request (0x2A)!\n");
} }
@@ -500,7 +504,7 @@ ArpHandleTrap2A(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap2B(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap2B(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Unhandled Callback return service request (0x2B)!\n"); DebugPrint(L"Unhandled Callback return service request (0x2B)!\n");
} }
@@ -517,7 +521,7 @@ ArpHandleTrap2B(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap2C(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Assertion (0x2C)!\n"); DebugPrint(L"Handled Assertion (0x2C)!\n");
for(;;); for(;;);
@@ -535,7 +539,7 @@ ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap2D(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Debug-Service-Request (0x2D)!\n"); DebugPrint(L"Handled Debug-Service-Request (0x2D)!\n");
for(;;); for(;;);
@@ -553,7 +557,7 @@ ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap2E(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap2E(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Unhandled system call (0x2E)!\n"); DebugPrint(L"Unhandled system call (0x2E)!\n");
} }
@@ -570,8 +574,28 @@ ArpHandleTrap2E(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrapFF(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrapFF(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Unexpected-Interrupt (0xFF)!\n"); DebugPrint(L"Handled Unexpected-Interrupt (0xFF)!\n");
for(;;); for(;;);
} }
} /* namespace */
/**
* C-linkage wrapper for dispatching the trap provided by common trap handler.
*
* @param TrapFrame
* Supplies a kernel trap frame pushed by common trap handler on the stack.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCLINK
XTCDECL
VOID
ArDispatchTrap(IN PKTRAP_FRAME TrapFrame)
{
AR::Traps::DispatchTrap(TrapFrame);
}

112
xtoskrnl/ex/exports.cc Normal file
View File

@@ -0,0 +1,112 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ex/exports.cc
* DESCRIPTION: C-compatible API wrappers for exported kernel functions
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
/**
* Acquires the rundown protection for given descriptor.
*
* @param Descriptor
* Supplies a pointer to the rundown block descriptor.
*
* @return This routine returns TRUE if protection acquired successfully, or FALSE otherwise.
*
* @since NT 5.1
*/
XTFASTCALL
BOOLEAN
ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{
return EX::Rundown::AcquireProtection(Descriptor);
}
/**
* Marks the rundown descriptor as completed.
*
* @param Descriptor
* Supplies a pointer to the descriptor to be completed.
*
* @return This routine does not return any value.
*
* @since NT 5.1
*/
XTFASTCALL
VOID
ExCompleteRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{
EX::Rundown::CompleteProtection(Descriptor);
}
/**
* Initializes the rundown protection descriptor.
*
* @param Descriptor
* Supplies a pointer to the descriptor to be initialized.
*
* @return This routine does not return any value.
*
* @since NT 5.1
*/
XTFASTCALL
VOID
ExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{
EX::Rundown::InitializeProtection(Descriptor);
}
/**
* Reinitializes the rundown protection structure after it has been completed.
*
* @param Descriptor
* Supplies a pointer to the descriptor to be reinitialized.
*
* @return This routine does not return any value.
*
* @since NT 5.1
*/
XTFASTCALL
VOID
ExReInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{
EX::Rundown::ReInitializeProtection(Descriptor);
}
/**
* Releases the rundown protection for given descriptor.
*
* @param Descriptor
* Supplies a pointer to the descriptor to be initialized.
*
* @return This routine does not return any value.
*
* @since NT 5.1
*/
XTFASTCALL
VOID
ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{
EX::Rundown::ReleaseProtection(Descriptor);
}
/**
* Waits until rundown protection calls are completed.
*
* @param Descriptor
* Supplies a pointer to the rundown block descriptor.
*
* @return This routine does not return any value.
*
* @since NT 5.1
*/
XTFASTCALL
VOID
ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor)
{
EX::Rundown::WaitForProtectionRelease(Descriptor);
}

View File

@@ -1,14 +1,17 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ex/rundown.c * FILE: xtoskrnl/ex/rundown.cc
* DESCRIPTION: Rundown protection mechanism * DESCRIPTION: Rundown protection mechanism
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
namespace EX
{
/** /**
* Acquires the rundown protection for given descriptor. * Acquires the rundown protection for given descriptor.
* *
@@ -21,7 +24,7 @@
*/ */
XTFASTCALL XTFASTCALL
BOOLEAN BOOLEAN
ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) Rundown::AcquireProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{ {
ULONG_PTR CurrentValue, NewValue; ULONG_PTR CurrentValue, NewValue;
@@ -69,7 +72,7 @@ ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
ExCompleteRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) Rundown::CompleteProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{ {
RtlAtomicExchangePointer(&Descriptor->Ptr, (PVOID)EX_RUNDOWN_ACTIVE); RtlAtomicExchangePointer(&Descriptor->Ptr, (PVOID)EX_RUNDOWN_ACTIVE);
} }
@@ -86,7 +89,7 @@ ExCompleteRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
ExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) Rundown::InitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{ {
/* Reset descriptor counter */ /* Reset descriptor counter */
Descriptor->Count = 0; Descriptor->Count = 0;
@@ -104,7 +107,7 @@ ExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
ExReInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) Rundown::ReInitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{ {
RtlAtomicExchangePointer(&Descriptor->Ptr, NULL); RtlAtomicExchangePointer(&Descriptor->Ptr, NULL);
} }
@@ -121,7 +124,7 @@ ExReInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) Rundown::ReleaseProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{ {
ULONG_PTR CurrentValue, NewValue; ULONG_PTR CurrentValue, NewValue;
PEX_RUNDOWN_WAIT_BLOCK WaitBlock; PEX_RUNDOWN_WAIT_BLOCK WaitBlock;
@@ -172,7 +175,9 @@ ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor) Rundown::WaitForProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
} }
} /* namespace */

774
xtoskrnl/hl/acpi.c Normal file
View File

@@ -0,0 +1,774 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/hl/x86/acpi.c
* DESCRIPTION: Advanced Configuration and Power Interface (ACPI) support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
/**
* Gets a pointer to the ACPI system description pointer (RSDP).
*
* @param Rsdp
* Supplies a pointer to the memory area, where RSDP virtual address will be stored.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
HlGetAcpiSystemDescriptionPointer(OUT PACPI_RSDP *Rsdp)
{
/* Get RSDP and return success */
*Rsdp = HlpAcpiRsdp;
return STATUS_SUCCESS;
}
/**
* Gets an ACPI description table with given signature, available in the XSDT/RSDT.
*
* @param Signature
* Supplies the signature of the desired ACPI table.
*
* @param AcpiTable
* Supplies a pointer to memory area where ACPI table virtual address will be stored.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
HlGetAcpiTable(IN ULONG Signature,
OUT PACPI_DESCRIPTION_HEADER *AcpiTable)
{
PACPI_DESCRIPTION_HEADER Table;
XTSTATUS Status;
/* Assume ACPI table not found */
*AcpiTable = NULL;
/* Attempt to get ACPI table from the cache */
Status = HlpQueryAcpiCache(Signature, &Table);
if(Status != STATUS_SUCCESS)
{
/* Table not found in the cache, query ACPI tables */
Status = HlpQueryAcpiTables(Signature, &Table);
if(Status != STATUS_SUCCESS)
{
/* ACPI table not found, return error */
return STATUS_NOT_FOUND;
}
}
/* Store ACPI table and return success */
*AcpiTable = Table;
return STATUS_SUCCESS;
}
/**
* Stores given ACPI table in the kernel local cache.
*
* @param AcpiTable
* Supplies a pointer to ACPI table that will be stored in the cache.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HlpCacheAcpiTable(IN PACPI_DESCRIPTION_HEADER AcpiTable)
{
PACPI_CACHE_LIST AcpiCache;
/* Create new ACPI table cache entry */
AcpiCache = CONTAIN_RECORD(AcpiTable, ACPI_CACHE_LIST, Header);
RtlInsertTailList(&HlpAcpiCacheList, &AcpiCache->ListEntry);
}
/**
* Performs an initialization of the ACPI subsystem.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
HlpInitializeAcpi(VOID)
{
PACPI_FADT Fadt;
XTSTATUS Status;
/* Initialize ACPI cache */
Status = HlpInitializeAcpiCache();
if(Status != STATUS_SUCCESS)
{
/* ACPI cache initialization failed, return error */
return Status;
}
/* Get Fixed ACPI Description Table (FADT) */
Status = HlGetAcpiTable(ACPI_FADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Fadt);
if(Status != STATUS_SUCCESS || !Fadt)
{
/* Failed to get FADT, return error */
return STATUS_NOT_FOUND;
}
/* Initialize ACPI timer */
HlpInitializeAcpiTimer();
/* Return success */
return STATUS_SUCCESS;
}
/**
* Initializes the kernel's local ACPI cache storage.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
HlpInitializeAcpiCache(VOID)
{
PACPI_DESCRIPTION_HEADER Rsdt;
XTSTATUS Status;
/* Initialize ACPI cache list */
RtlInitializeListHead(&HlpAcpiCacheList);
/* Get XSDT/RSDT */
Status = HlpInitializeAcpiSystemDescriptionTable(&Rsdt);
if(Status != STATUS_SUCCESS)
{
/* Failed to get XSDT/RSDT, return error */
return Status;
}
/* Cache XSDT/RSDT table */
HlpCacheAcpiTable(Rsdt);
/* Return success */
return STATUS_SUCCESS;
}
/**
* Initializes ACPI System Description Table (XSDT/RSDT) by finding proper table and mapping its virtual address.
*
* @param AcpiTable
* Supplies a pointer to memory area where ACPI table virtual address will be stored.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
HlpInitializeAcpiSystemDescriptionTable(OUT PACPI_DESCRIPTION_HEADER *AcpiTable)
{
PHYSICAL_ADDRESS RsdpAddress, RsdtAddress;
PSYSTEM_RESOURCE_HEADER ResourceHeader;
PSYSTEM_RESOURCE_ACPI AcpiResource;
ULONG RsdtPages;
PACPI_RSDT Rsdt;
XTSTATUS Status;
/* Assume ACPI table not found */
*AcpiTable = NULL;
/* Get ACPI system resource */
Status = KeGetSystemResource(SystemResourceAcpi, &ResourceHeader);
if(Status != STATUS_SUCCESS)
{
/* Resource not found */
return STATUS_NOT_FOUND;
}
/* Cast system resource to ACPI resource and store RSDP physical address */
AcpiResource = (PSYSTEM_RESOURCE_ACPI)ResourceHeader;
RsdpAddress.QuadPart = (LONGLONG)AcpiResource->Header.PhysicalAddress;
/* Map RSDP and mark it as CD/WT to avoid delays in write-back cache */
Status = MmMapHardwareMemory(RsdpAddress, 1, TRUE, (PVOID *)&HlpAcpiRsdp);
MmMarkHardwareMemoryWriteThrough(HlpAcpiRsdp, 1);
/* Validate RSDP signature */
if(Status != STATUS_SUCCESS || HlpAcpiRsdp->Signature != ACPI_RSDP_SIGNATURE)
{
/* Not mapped correctly or invalid RSDP signature, return error */
return STATUS_INVALID_PARAMETER;
}
/* Check RSDP revision to determine RSDT/XSDT address */
if(HlpAcpiRsdp->Revision >= 2)
{
/* Get XSDT address */
RsdtAddress.QuadPart = (LONGLONG)HlpAcpiRsdp->XsdtAddress;
}
else
{
/* Get RSDT address */
RsdtAddress.QuadPart = (LONGLONG)HlpAcpiRsdp->RsdtAddress;
}
/* Map RSDT/XSDT as CD/WT */
Status = MmMapHardwareMemory(RsdtAddress, 2, TRUE, (PVOID *)&Rsdt);
MmMarkHardwareMemoryWriteThrough(Rsdt, 2);
/* Validate RSDT/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, return error */
return STATUS_INVALID_PARAMETER;
}
/* 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;
if(RsdtPages != 2)
{
/* RSDT/XSDT needs less or more than 2 pages, remap it */
MmUnmapHardwareMemory(Rsdt, 2, TRUE);
Status = MmMapHardwareMemory(RsdtAddress, RsdtPages, TRUE, (PVOID *)&Rsdt);
MmMarkHardwareMemoryWriteThrough(Rsdt, RsdtPages);
/* Make sure remapping was successful */
if(Status != STATUS_SUCCESS)
{
/* Remapping failed, return error */
return STATUS_INSUFFICIENT_RESOURCES;
}
}
/* Get ACPI table header and return success */
*AcpiTable = &Rsdt->Header;
return STATUS_SUCCESS;
}
/**
* Initializes System Information structure based on the ACPI provided data.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
HlpInitializeAcpiSystemInformation(VOID)
{
PACPI_MADT_LOCAL_X2APIC LocalX2Apic;
PACPI_MADT_LOCAL_APIC LocalApic;
ULONG_PTR MadtTable;
PACPI_MADT Madt;
XTSTATUS Status;
USHORT CpuCount;
/* Allocate memory for ACPI system information structure */
Status = HlpInitializeAcpiSystemStructure();
if(Status != STATUS_SUCCESS)
{
/* Failed to allocate memory, return error */
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Get Multiple APIC Description Table (MADT) */
Status = HlGetAcpiTable(ACPI_MADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Madt);
if(Status != STATUS_SUCCESS)
{
/* Failed to get MADT, return error */
return STATUS_NOT_FOUND;
}
/* Set APIC table traverse pointer and initialize number of CPUs */
MadtTable = (ULONG_PTR)Madt->ApicTables;
CpuCount = 0;
/* Traverse all MADT tables to get system information */
while(MadtTable <= ((ULONG_PTR)Madt + Madt->Header.Length))
{
/* Check if this is a local APIC subtable */
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 */
LocalApic = (PACPI_MADT_LOCAL_APIC)MadtTable;
/* Make sure, this CPU can be enabled */
if(LocalApic->Flags & ACPI_MADT_PLAOC_ENABLED)
{
/* Store CPU number, APIC ID and CPU ID */
HlpSystemInfo.CpuInfo[CpuCount].AcpiId = LocalApic->AcpiId;
HlpSystemInfo.CpuInfo[CpuCount].ApicId = LocalApic->ApicId;
HlpSystemInfo.CpuInfo[CpuCount].CpuNumber = CpuCount;
/* Increment number of CPUs */
CpuCount++;
}
/* Go to the next MADT table */
MadtTable += ((PACPI_SUBTABLE_HEADER)MadtTable)->Length;
}
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 */
LocalX2Apic = (PACPI_MADT_LOCAL_X2APIC)MadtTable;
/* Make sure, this CPU can be enabled */
if(LocalX2Apic->Flags & ACPI_MADT_PLAOC_ENABLED)
{
/* Store CPU number, APIC ID and CPU ID */
HlpSystemInfo.CpuInfo[CpuCount].AcpiId = LocalX2Apic->AcpiId;
HlpSystemInfo.CpuInfo[CpuCount].ApicId = LocalX2Apic->ApicId;
HlpSystemInfo.CpuInfo[CpuCount].CpuNumber = CpuCount;
/* Increment number of CPUs */
CpuCount++;
}
/* Go to the next MADT table */
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 */
HlpSystemInfo.CpuCount = CpuCount;
/* Return success */
return STATUS_SUCCESS;
}
/**
* Initializes ACPI System Information data structure based on the size of available ACPI data.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
HlpInitializeAcpiSystemStructure(VOID)
{
PHYSICAL_ADDRESS PhysicalAddress;
PFN_NUMBER PageCount;
ULONG_PTR MadtTable;
PACPI_MADT Madt;
XTSTATUS Status;
ULONG CpuCount;
/* Get Multiple APIC Description Table (MADT) */
Status = HlGetAcpiTable(ACPI_MADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Madt);
if(Status != STATUS_SUCCESS)
{
/* Failed to get MADT, return error */
return STATUS_NOT_FOUND;
}
/* Set APIC table traverse pointer and initialize number of CPUs */
MadtTable = (ULONG_PTR)Madt->ApicTables;
CpuCount = 0;
/* Traverse all MADT tables to get number of processors */
while(MadtTable <= ((ULONG_PTR)Madt + Madt->Header.Length))
{
/* Check if this is a local APIC subtable */
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 */
if(((PACPI_MADT_LOCAL_APIC)MadtTable)->Flags & ACPI_MADT_PLAOC_ENABLED)
{
/* Increment number of CPUs */
CpuCount++;
}
/* Go to the next MADT table */
MadtTable += ((PACPI_SUBTABLE_HEADER)MadtTable)->Length;
}
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 */
if(((PACPI_MADT_LOCAL_X2APIC)MadtTable)->Flags & ACPI_MADT_PLAOC_ENABLED)
{
/* Increment number of CPUs */
CpuCount++;
}
/* Go to the next MADT table */
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 */
RtlZeroMemory(&HlpSystemInfo, sizeof(ACPI_SYSTEM_INFO));
/* Calculate number of pages needed to store CPU information */
PageCount = SIZE_TO_PAGES(CpuCount * sizeof(PROCESSOR_IDENTITY));
/* Allocate memory for CPU information */
Status = MmAllocateHardwareMemory(PageCount, TRUE, &PhysicalAddress);
if(Status != STATUS_SUCCESS)
{
/* Failed to allocate memory, return error */
return Status;
}
/* Map physical address to the virtual memory area */
Status = MmMapHardwareMemory(PhysicalAddress, PageCount, TRUE, (PVOID *)&HlpSystemInfo.CpuInfo);
if(Status != STATUS_SUCCESS)
{
/* Failed to map memory, return error */
return Status;
}
/* Zero the CPU information structure */
RtlZeroMemory(HlpSystemInfo.CpuInfo, PAGES_TO_SIZE(PageCount));
/* Return success */
return STATUS_SUCCESS;
}
/**
* Initializes the ACPI Timer.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
HlpInitializeAcpiTimer(VOID)
{
PACPI_FADT Fadt;
XTSTATUS Status;
/* Get Fixed ACPI Description Table (FADT) */
Status = HlGetAcpiTable(ACPI_FADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Fadt);
if(Status != STATUS_SUCCESS || !Fadt)
{
/* Failed to get FADT, return error */
return STATUS_NOT_FOUND;
}
/* Set ACPI timer port address */
HlpAcpiTimerInfo.TimerPort = Fadt->PmTmrBlkIoPort;
/* Determine whether 32-bit or 24-bit timer is used */
if(Fadt->Flags & ACPI_FADT_32BIT_TIMER)
{
/* 32-bit timer */
HlpAcpiTimerInfo.MsbMask = ACPI_FADT_TIMER_32BIT;
}
else
{
/* 24-bit timer */
HlpAcpiTimerInfo.MsbMask = ACPI_FADT_TIMER_24BIT;
}
/* Return success */
return STATUS_SUCCESS;
}
/**
* Queries kernel local ACPI cache in attempt to find a requested ACPI table.
*
* @param Signature
* Supplies the signature of the desired ACPI table.
*
* @param AcpiTable
* Supplies a pointer to memory area where ACPI table virtual address will be stored.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
HlpQueryAcpiCache(IN ULONG Signature,
OUT PACPI_DESCRIPTION_HEADER *AcpiTable)
{
PACPI_DESCRIPTION_HEADER TableHeader;
PACPI_CACHE_LIST AcpiCache;
PLIST_ENTRY ListEntry;
/* Initialize variables */
TableHeader = NULL;
/* Iterate through ACPI tables cache list */
ListEntry = HlpAcpiCacheList.Flink;
while(ListEntry != &HlpAcpiCacheList)
{
/* Get cached ACPI table header */
AcpiCache = CONTAIN_RECORD(ListEntry, ACPI_CACHE_LIST, ListEntry);
/* Check if ACPI table signature matches */
if(AcpiCache->Header.Signature == Signature)
{
/* ACPI table found in cache, return it */
TableHeader = &AcpiCache->Header;
break;
}
/* Go to the next cache entry */
ListEntry = ListEntry->Flink;
}
/* Check if the requested ACPI table was found in the cache */
if(TableHeader == NULL)
{
/* ACPI table not found in cache, return error */
return STATUS_NOT_FOUND;
}
/* Return table header and status code */
*AcpiTable = TableHeader;
return STATUS_SUCCESS;
}
/**
* Queries XSDT/RSDT in order to find a requested ACPI table.
* Once the desired ACPI table is found, it is being mapped and cached.
*
* @param Signature
* Supplies the signature of the desired ACPI table.
*
* @param AcpiTable
* Supplies a pointer to memory area where ACPI table virtual address will be stored.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
HlpQueryAcpiTables(IN ULONG Signature,
OUT PACPI_DESCRIPTION_HEADER *AcpiTable)
{
ULONG TableCount, TableIndex, TablePages;
PACPI_DESCRIPTION_HEADER TableHeader;
PHYSICAL_ADDRESS TableAddress;
PACPI_FADT Fadt;
PACPI_RSDT Rsdt;
PACPI_XSDT Xsdt;
XTSTATUS Status;
/* Check if requesting a valid ACPI table */
if(Signature == ACPI_RSDT_SIGNATURE || Signature == ACPI_XSDT_SIGNATURE)
{
/* Cannot provide RSDP/XSDP table, it should be cached; return error */
return STATUS_INVALID_PARAMETER;
}
/* Ensure that table header is not set before attempting to find ACPI table */
TableHeader = NULL;
/* Check if DSDT or FACS table requested */
if(Signature == ACPI_DSDT_SIGNATURE || Signature == ACPI_FACS_SIGNATURE)
{
/* Get FADT as it contains a pointer to DSDT and FACS */
Status = HlGetAcpiTable(ACPI_FADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Fadt);
if(Status != STATUS_SUCCESS)
{
/* Failed to get FADT, return error */
return Status;
}
/* Check if DSDT or FACS table requested */
if(Signature == ACPI_DSDT_SIGNATURE)
{
/* Get DSDT address */
TableAddress.LowPart = Fadt->Dsdt;
}
else
{
/* Get FACS address */
TableAddress.LowPart = Fadt->FirmwareCtrl;
}
/* Fill in high part of ACPI table address */
TableAddress.HighPart = 0;
/* Map table using hardware memory pool */
Status = MmMapHardwareMemory(TableAddress, 2, TRUE, (PVOID*)&TableHeader);
if(Status != STATUS_SUCCESS)
{
/* Failed to map table, return error */
return Status;
}
}
else
{
/* Query cache for XSDP table */
Status = HlpQueryAcpiCache(ACPI_XSDT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Xsdt);
if(Status != STATUS_SUCCESS)
{
/* XSDP not found, query cache for RSDP table */
Status = HlpQueryAcpiCache(ACPI_RSDT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Rsdt);
}
/* Check if XSDT or RSDT table found */
if(Status != STATUS_SUCCESS)
{
/* Failed to get XSDT/RSDT, return error */
return Status;
}
/* Get table count depending on root table type */
if(Xsdt != NULL)
{
/* Get table count from XSDT */
TableCount = (Xsdt->Header.Length - sizeof(ACPI_DESCRIPTION_HEADER)) / 8;
}
else
{
/* Get table count from RSDT */
TableCount = (Rsdt->Header.Length - sizeof(ACPI_DESCRIPTION_HEADER)) / 4;
}
/* Iterate over all ACPI tables */
for(TableIndex = 0; TableIndex < TableCount; TableIndex++)
{
/* Check if XSDP or RSDT is used */
if(Xsdt != NULL)
{
/* Get table header physical address from XSDT */
TableAddress.QuadPart = Xsdt->Tables[TableIndex];
}
else
{
/* Get table header physical address from RSDT */
TableAddress.LowPart = Rsdt->Tables[TableIndex];
TableAddress.HighPart = 0;
}
/* Check whether some table is already mapped */
if(TableHeader != NULL)
{
/* Unmap previous table */
MmUnmapHardwareMemory(TableHeader, 2, TRUE);
}
/* Map table using hardware memory pool */
Status = MmMapHardwareMemory(TableAddress, 2, TRUE, (PVOID*)&TableHeader);
if(Status != STATUS_SUCCESS)
{
/* Failed to map table, return error */
return Status;
}
/* Verify table signature */
if(TableHeader->Signature == Signature)
{
/* Found requested ACPI table */
break;
}
}
}
/* Make sure table was found */
if(TableHeader->Signature != Signature)
{
/* ACPI table not found, check if cleanup is needed */
if(TableHeader != NULL)
{
/* Unmap non-matching ACPI table */
MmUnmapHardwareMemory(TableHeader, 2, TRUE);
}
/* Return error */
return STATUS_NOT_FOUND;
}
/* Don't validate FADT on old, broken firmwares with ACPI 2.0 or older */
if(TableHeader->Signature != ACPI_FADT_SIGNATURE || TableHeader->Revision > 2)
{
/* Validate table checksum */
if(!HlpValidateAcpiTable(TableHeader, TableHeader->Length))
{
/* Checksum mismatch, unmap table and return error */
MmUnmapHardwareMemory(TableHeader, 2, TRUE);
return STATUS_CRC_ERROR;
}
}
/* Calculate the length of ACPI table and remap it if needed */
TablePages = (((ULONG_PTR)TableHeader & (MM_PAGE_SIZE - 1)) + TableHeader->Length + (MM_PAGE_SIZE - 1)) >> MM_PAGE_SHIFT;
if(TablePages != 2)
{
/* ACPI table needs less or more than 2 pages, remap it */
MmUnmapHardwareMemory(TableHeader, 2, FALSE);
Status = MmMapHardwareMemory(TableAddress, TablePages, TRUE, (PVOID*)&TableHeader);
/* Make sure remapping was successful */
if(Status != STATUS_SUCCESS)
{
/* Remapping failed, return error */
return STATUS_INSUFFICIENT_RESOURCES;
}
}
/* Mark table as write through and store it in local cache */
MmMarkHardwareMemoryWriteThrough(TableHeader, TablePages);
HlpCacheAcpiTable(TableHeader);
/* Store ACPI table and return success */
*AcpiTable = TableHeader;
return STATUS_SUCCESS;
}
/**
* Validates given ACPI table by calculating its checksum.
*
* @param Buffer
* Supplies a pointer to the table to checksum.
*
* @param Size
* Supplies the size of the table, in bytes.
*
* @return This routine returns TRUE if the table is valid, or FALSE otherwise.
*
* @since XT 1.0
*/
XTAPI
BOOLEAN
HlpValidateAcpiTable(IN PVOID Buffer,
IN UINT_PTR Size)
{
PUCHAR Pointer;
UCHAR Sum;
/* Initialize variables */
Sum = 0;
Pointer = Buffer;
/* Calculate checksum of given table */
while(Size != 0)
{
Sum = (UCHAR)(Sum + *Pointer);
Pointer += 1;
Size -= 1;
}
/* Return calculated checksum */
return (Sum == 0) ? TRUE : FALSE;
}

View File

@@ -24,7 +24,7 @@ UCHAR
HlIoPortInByte(IN USHORT Port) HlIoPortInByte(IN USHORT Port)
{ {
UCHAR Value; UCHAR Value;
asm volatile("inb %1, %0" __asm__ volatile("inb %1, %0"
: "=a" (Value) : "=a" (Value)
: "Nd" (Port)); : "Nd" (Port));
return Value; return Value;
@@ -45,7 +45,7 @@ ULONG
HlIoPortInLong(IN USHORT Port) HlIoPortInLong(IN USHORT Port)
{ {
ULONG Value; ULONG Value;
asm volatile("inl %1, %0" __asm__ volatile("inl %1, %0"
: "=a" (Value) : "=a" (Value)
: "Nd" (Port)); : "Nd" (Port));
return Value; return Value;
@@ -66,7 +66,7 @@ USHORT
HlIoPortInShort(IN USHORT Port) HlIoPortInShort(IN USHORT Port)
{ {
USHORT Value; USHORT Value;
asm volatile("inw %1, %0" __asm__ volatile("inw %1, %0"
: "=a" (Value) : "=a" (Value)
: "Nd" (Port)); : "Nd" (Port));
return Value; return Value;
@@ -90,7 +90,7 @@ VOID
HlIoPortOutByte(IN USHORT Port, HlIoPortOutByte(IN USHORT Port,
IN UCHAR Value) IN UCHAR Value)
{ {
asm volatile("outb %0, %1" __asm__ volatile("outb %0, %1"
: :
: "a" (Value), : "a" (Value),
"Nd" (Port)); "Nd" (Port));
@@ -114,7 +114,7 @@ VOID
HlIoPortOutLong(IN USHORT Port, HlIoPortOutLong(IN USHORT Port,
IN ULONG Value) IN ULONG Value)
{ {
asm volatile("outl %0, %1" __asm__ volatile("outl %0, %1"
: :
: "a" (Value), : "a" (Value),
"Nd" (Port)); "Nd" (Port));
@@ -138,7 +138,7 @@ VOID
HlIoPortOutShort(IN USHORT Port, HlIoPortOutShort(IN USHORT Port,
IN USHORT Value) IN USHORT Value)
{ {
asm volatile("outw %0, %1" __asm__ volatile("outw %0, %1"
: :
: "a" (Value), : "a" (Value),
"Nd" (Port)); "Nd" (Port));

View File

@@ -9,9 +9,6 @@
#include <xtos.h> #include <xtos.h>
/* COM port I/O addresses */
ULONG ComPortAddress[] = COMPORT_ADDRESSES;
/** /**
* This routine gets a byte from serial port. * This routine gets a byte from serial port.
* *
@@ -168,7 +165,6 @@ HlComPortReadLsr(IN PCPPORT Port,
IN UCHAR Byte) IN UCHAR Byte)
{ {
UCHAR Lsr, Msr; UCHAR Lsr, Msr;
STATIC UCHAR RingFlag;
/* Read the Line Status Register (LSR) */ /* Read the Line Status Register (LSR) */
Lsr = HlIoPortInByte(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_LSR)); Lsr = HlIoPortInByte(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_LSR));
@@ -178,8 +174,8 @@ HlComPortReadLsr(IN PCPPORT Port,
{ {
/* Check Modem Status Register (MSR) for ring indicator */ /* Check Modem Status Register (MSR) for ring indicator */
Msr = HlIoPortInByte(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_MSR)); Msr = HlIoPortInByte(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_MSR));
RingFlag |= (Msr & COMPORT_MSR_RI) ? 1 : 2; Port->Ring |= (Msr & COMPORT_MSR_RI) ? 1 : 2;
if(RingFlag == 3) if(Port->Ring == 3)
{ {
/* Ring indicator toggled, use modem control */ /* Ring indicator toggled, use modem control */
Port->Flags |= COMPORT_FLAG_MC; Port->Flags |= COMPORT_FLAG_MC;
@@ -212,37 +208,16 @@ HlComPortReadLsr(IN PCPPORT Port,
XTCDECL XTCDECL
XTSTATUS XTSTATUS
HlInitializeComPort(IN OUT PCPPORT Port, HlInitializeComPort(IN OUT PCPPORT Port,
IN ULONG PortNumber,
IN PUCHAR PortAddress, IN PUCHAR PortAddress,
IN ULONG BaudRate) IN ULONG BaudRate)
{ {
USHORT Flags = 0; USHORT Flags;
UCHAR Byte = 0; UCHAR Byte;
PUCHAR Address;
ULONG Mode; ULONG Mode;
/* We support only a pre-defined number of ports */ /* Initialize variables */
if(PortNumber > ARRAY_SIZE(ComPortAddress)) Byte = 0;
{ Flags = 0;
/* Fail if wrong/unsupported port used */
return STATUS_INVALID_PARAMETER;
}
/* Check if serial port is set */
if(PortNumber == 0)
{
/* Check if port address supplied instead */
if(PortAddress)
{
/* Set custom port address */
ComPortAddress[PortNumber] = PtrToUlong(PortAddress);
}
else
{
/* Use COM1 by default */
PortNumber = 1;
}
}
/* Check if baud rate is set */ /* Check if baud rate is set */
if(BaudRate == 0) if(BaudRate == 0)
@@ -252,11 +227,8 @@ HlInitializeComPort(IN OUT PCPPORT Port,
Flags |= COMPORT_FLAG_DBR; Flags |= COMPORT_FLAG_DBR;
} }
/* Store COM pointer */
Address = UlongToPtr(ComPortAddress[PortNumber]);
/* Check whether this port is not already initialized */ /* Check whether this port is not already initialized */
if((Port->Address == Address) && (Port->Baud == BaudRate)) if((Port->Address == PortAddress) && (Port->Baud == BaudRate))
{ {
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@@ -265,8 +237,8 @@ HlInitializeComPort(IN OUT PCPPORT Port,
do do
{ {
/* Check whether the 16450/16550 scratch register exists */ /* Check whether the 16450/16550 scratch register exists */
HlIoPortOutByte(PtrToUshort(Address + (ULONG)COMPORT_REG_SR), Byte); HlIoPortOutByte(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_SR), Byte);
if(HlIoPortInByte(PtrToUshort(Address + (ULONG)COMPORT_REG_SR)) != Byte) if(HlIoPortInByte(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_SR)) != Byte)
{ {
return STATUS_NOT_FOUND; return STATUS_NOT_FOUND;
} }
@@ -274,42 +246,43 @@ HlInitializeComPort(IN OUT PCPPORT Port,
while(++Byte != 0); while(++Byte != 0);
/* Disable interrupts */ /* Disable interrupts */
HlIoPortOutByte(PtrToUshort(Address + (ULONG)COMPORT_REG_LCR), COMPORT_LSR_DIS); HlIoPortOutByte(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_LCR), COMPORT_LSR_DIS);
HlIoPortOutByte(PtrToUshort(Address + (ULONG)COMPORT_REG_IER), COMPORT_LSR_DIS); HlIoPortOutByte(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_IER), COMPORT_LSR_DIS);
/* Enable Divisor Latch Access Bit (DLAB) */ /* Enable Divisor Latch Access Bit (DLAB) */
HlIoPortOutByte(PtrToUshort(Address + (ULONG)COMPORT_REG_LCR), COMPORT_LCR_DLAB); HlIoPortOutByte(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_LCR), COMPORT_LCR_DLAB);
/* Set baud rate */ /* Set baud rate */
Mode = COMPORT_CLOCK_RATE / BaudRate; Mode = COMPORT_CLOCK_RATE / BaudRate;
HlIoPortOutByte(PtrToUshort(Address + (ULONG)COMPORT_DIV_DLL), (UCHAR)(Mode & 0xFF)); HlIoPortOutByte(PtrToUshort(PortAddress + (ULONG)COMPORT_DIV_DLL), (UCHAR)(Mode & 0xFF));
HlIoPortOutByte(PtrToUshort(Address + (ULONG)COMPORT_DIV_DLM), (UCHAR)((Mode >> 8) & 0xFF)); HlIoPortOutByte(PtrToUshort(PortAddress + (ULONG)COMPORT_DIV_DLM), (UCHAR)((Mode >> 8) & 0xFF));
/* Set 8 data bits, 1 stop bits, no parity (8n1) */ /* Set 8 data bits, 1 stop bits, no parity (8n1) */
HlIoPortOutByte(PtrToUshort(Address + (ULONG)COMPORT_REG_LCR), HlIoPortOutByte(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_LCR),
COMPORT_LCR_8DATA | COMPORT_LCR_1STOP | COMPORT_LCR_PARN); COMPORT_LCR_8DATA | COMPORT_LCR_1STOP | COMPORT_LCR_PARN);
/* Enable DTR, RTS and OUT2 */ /* Enable DTR, RTS and OUT2 */
HlIoPortOutByte(PtrToUshort(Address + (ULONG)COMPORT_REG_MCR), HlIoPortOutByte(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_MCR),
COMPORT_MCR_DTR | COMPORT_MCR_RTS | COMPORT_MCR_OUT2); COMPORT_MCR_DTR | COMPORT_MCR_RTS | COMPORT_MCR_OUT2);
/* Enable FIFO */ /* Enable FIFO */
HlIoPortOutByte(PtrToUshort(Address + (ULONG)COMPORT_REG_FCR), HlIoPortOutByte(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_FCR),
COMPORT_FCR_ENABLE | COMPORT_FCR_RCVR_RESET | COMPORT_FCR_TXMT_RESET); COMPORT_FCR_ENABLE | COMPORT_FCR_RCVR_RESET | COMPORT_FCR_TXMT_RESET);
/* Mark port as fully initialized */ /* Mark port as fully initialized */
Flags |= COMPORT_FLAG_INIT; Flags |= COMPORT_FLAG_INIT;
/* Make sure port works in Normal Operation Mode (NOM) */ /* Make sure port works in Normal Operation Mode (NOM) */
HlIoPortOutByte(PtrToUshort(Address + (ULONG)COMPORT_REG_MCR), COMPORT_MCR_NOM); HlIoPortOutByte(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_MCR), COMPORT_MCR_NOM);
/* Read junk data out of the Receive Buffer Register (RBR) */ /* Read junk data out of the Receive Buffer Register (RBR) */
HlIoPortInByte(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_RBR)); HlIoPortInByte(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_RBR));
/* Store port details */ /* Store port details */
Port->Address = Address; Port->Address = PortAddress;
Port->Baud = BaudRate; Port->Baud = BaudRate;
Port->Flags = Flags; Port->Flags = Flags;
Port->Ring = 0;
/* Return success */ /* Return success */
return STATUS_SUCCESS; return STATUS_SUCCESS;

View File

@@ -1,291 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/hl/efifb.c
* DESCRIPTION: EFI framebuffer support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
#include <xtfont.h>
/**
* Clears the screen by drawing a filled black box.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HlClearScreen(VOID)
{
SIZE_T Line, PositionX, PositionY;
PULONG FrameBuf;
/* Get pointer to frame buffer */
FrameBuf = HlpFrameBufferData.Address;
/* Fill the screen with a black box */
for(PositionY = 0; PositionY < HlpFrameBufferData.Height; PositionY++)
{
Line = PositionY * HlpFrameBufferData.PixelsPerScanLine;
for(PositionX = 0; PositionX < HlpFrameBufferData.Width; PositionX++)
{
FrameBuf[Line + PositionX] = 0x00000000;
}
}
}
/**
* Draw a pixel on the screen at the given position and color.
*
* @param PositionX
* Supplies the X coordinate of the pixel.
*
* @param PositionY
* Supplies the Y coordinate of the pixel.
*
* @param Color
* Specifies the color of the pixel.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HlDrawPixel(IN ULONG PositionX,
IN ULONG PositionY,
IN ULONG Color)
{
SIZE_T FrameBufferIndex;
/* Make sure frame buffer is already initialized */
if(HlpFrameBufferData.Initialized == FALSE)
{
/* Unable to operate on non-initialized frame buffer */
return;
}
/* Make sure point is not offscreen */
if(PositionX >= HlpFrameBufferData.Width || PositionY >= HlpFrameBufferData.Height || Color > 0xFFFFFFFF)
{
/* Invalid pixel position or color given */
return;
}
/* Calculate the index of the pixel in the frame buffer memory using the provided x and y coordinates */
FrameBufferIndex = 4 * HlpFrameBufferData.PixelsPerScanLine * PositionY + 4 * PositionX;
/* Set the color of the pixel by writing to the corresponding memory location */
*((PULONG)(HlpFrameBufferData.Address + FrameBufferIndex)) = Color;
}
/**
* Initializes frame buffer display.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
HlInitializeFrameBuffer(VOID)
{
/* Check if display already initialized */
if(HlpFrameBufferData.Initialized)
{
/* Nothing to do */
return STATUS_SUCCESS;
}
/* Check if framebuffer initialized by bootloader */
if(!KeInitializationBlock->LoaderInformation.FrameBuffer.Initialized ||
!KeInitializationBlock->LoaderInformation.FrameBuffer.Address)
{
/* Display not initialized */
return STATUS_DEVICE_NOT_READY;
}
/* Check if custom font provided by bootloader */
if(KeInitializationBlock->LoaderInformation.FrameBuffer.Font)
{
/* Use custom font */
HlpFrameBufferData.Font = KeInitializationBlock->LoaderInformation.FrameBuffer.Font;
}
else
{
/* Use default font */
HlpFrameBufferData.Font = (PVOID)&XtFbDefaultFont;
}
/* Save framebuffer information and mark display as initialized */
HlpFrameBufferData.Address = KeInitializationBlock->LoaderInformation.FrameBuffer.Address;
HlpFrameBufferData.Width = KeInitializationBlock->LoaderInformation.FrameBuffer.Width;
HlpFrameBufferData.Height = KeInitializationBlock->LoaderInformation.FrameBuffer.Height;
HlpFrameBufferData.BitsPerPixel = KeInitializationBlock->LoaderInformation.FrameBuffer.BitsPerPixel;
HlpFrameBufferData.PixelsPerScanLine = KeInitializationBlock->LoaderInformation.FrameBuffer.PixelsPerScanLine;
HlpFrameBufferData.Pitch = KeInitializationBlock->LoaderInformation.FrameBuffer.Pitch;
HlpFrameBufferData.Initialized = TRUE;
/* Clear screen */
HlClearScreen();
/* Return success */
return STATUS_SUCCESS;
}
/**
* Puts a wide character on the framebuffer at the given position and color using the SSFN font.
*
* @param PositionX
* Supplies the X coordinate of the character.
*
* @param PositionY
* Supplies the Y coordinate of the character.
*
* @param Color
* Supplies the font color.
*
* @param WideCharacter
* Supplies the wide character to be drawn on the framebuffer.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HlPutCharacter(IN ULONG PositionX,
IN ULONG PositionY,
IN ULONG Color,
IN WCHAR WideCharacter)
{
UINT CurrentFragment, Glyph, GlyphLimit, Index, Line, Mapping;
PUCHAR Character, CharacterMapping, Fragment;
UINT_PTR GlyphPixel, Pixel;
PSSFN_FONT_HEADER FbFont;
/* Get pointers to font data */
FbFont = (PSSFN_FONT_HEADER)HlpFrameBufferData.Font;
CharacterMapping = (PUCHAR)FbFont + FbFont->CharactersOffset;
/* Find the character in the font's character table */
Character = 0;
for(Index = 0; Index < 0x110000; Index++)
{
if(CharacterMapping[0] == 0xFF)
{
/* Skip 65535 code points */
Index += 65535;
CharacterMapping++;
}
else if((CharacterMapping[0] & 0xC0) == 0xC0)
{
/* Skip (N << 8 + additional byte) + 1 code points (up to 16128) */
Index += (((CharacterMapping[0] & 0x3F) << 8) | CharacterMapping[1]);
CharacterMapping += 2;
}
else if((CharacterMapping[0] & 0xC0) == 0x80)
{
/* Skip N + 1 code points (up to 64) */
Index += (CharacterMapping[0] & 0x3F);
CharacterMapping++;
}
else
{
/* There's a glyph for this character, check if it matches */
if(Index == WideCharacter)
{
/* Found the character, break loop */
Character = CharacterMapping;
break;
}
/* Move to next character table entry */
CharacterMapping += (6 + CharacterMapping[1] * (CharacterMapping[0] & 0x40 ? 6 : 5));
}
}
/* Make sure the character has been found in the font */
if(!Character)
{
/* Character not found, don't draw anything */
return;
}
/* Find the glyph position on the frame buffer */
GlyphPixel = (UINT_PTR)HlpFrameBufferData.Address + PositionY * HlpFrameBufferData.Pitch + PositionX * 4;
/* Check all kerning fragments */
Mapping = 0;
CharacterMapping = Character + 6;
for(Index = 0; Index < Character[1]; Index++)
{
/* Check if number of fragments is not exceeded */
if(CharacterMapping[0] == 255 && CharacterMapping[1] == 255)
{
/* Get next mapping */
continue;
}
/* Get pointer to fragment */
Fragment = (PUCHAR)FbFont + (CharacterMapping[2] |
(CharacterMapping[3] << 8) |
(CharacterMapping[4] << 16) |
((Character[0] & 0x40) ? (CharacterMapping[5] << 24) : 0));
/* Check if fragment is printable */
if((Fragment[0] & 0xE0) != 0x80)
{
/* Skip fragment */
continue;
}
/* Get initial glyph line */
GlyphPixel += (CharacterMapping[1] - Mapping) * HlpFrameBufferData.Pitch;
Mapping = CharacterMapping[1];
/* Extract glyph data from fragments table and advance */
Glyph = ((Fragment[0] & 0x1F) + 1) << 3;
GlyphLimit = Fragment[1] + 1;
Fragment += 2;
/* Look for kerning group for next code point */
CurrentFragment = 1;
while(GlyphLimit--)
{
Pixel = GlyphPixel;
for(Line = 0; Line < Glyph; Line++)
{
/* Decode compressed offsets */
if(CurrentFragment > 0x80)
{
/* Advance to next fragment */
Fragment++;
CurrentFragment = 1;
}
/* Check if pixel should be drawn */
if(*Fragment & CurrentFragment)
{
/* Draw glyph pixel */
*((PULONG)Pixel) = Color;
}
/* Advance pixel pointer */
Pixel += 4;
CurrentFragment <<= 1;
}
/* Advance to next line and increase mapping */
GlyphPixel += HlpFrameBufferData.Pitch;
Mapping++;
}
/* Get next mapping */
CharacterMapping += Character[0] & 0x40 ? 6 : 5;
}
}

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