167 Commits

Author SHA1 Message Date
b74c31f17c configure.ps1: Fix path handling and improve reliability
- Use $PSScriptRoot for reliable source directory detection
- Use Join-Path for proper path construction
- Validate BUILD_TYPE against Debug/Release
- Fix CMake argument quoting
- Use Write-Error for error messages
2025-10-10 16:26:28 +02:00
56a1a811b9 Fix multi-sector read using CHS mode 2025-10-10 15:10:42 +02:00
32bacdd228 Unify OVMF firmware and add WHPX targets 2025-10-10 11:00:11 +02:00
2d4c82cd29 Add initial WHPX support 2025-10-10 10:35:17 +02:00
e5611d8081 Add support for WHPX accelerator on Windows and introduce OVMF Pure EFI firmware 2025-10-09 17:35:03 +02:00
e52977fb63 Point contributors to gitea 2025-10-09 09:59:32 +02:00
11f096d9f3 Remove IDEAS and KNOWN_ISSUES migrated to Gitea 2025-10-09 09:57:30 +02:00
6e507be5e9 Add source directory include path for bootsector assembly 2025-10-09 09:25:50 +02:00
6a8a561484 Implement disk read and error handling in VBR 2025-10-07 20:09:36 +02:00
c5f522be4c Move XTLDR under boot directory 2025-10-06 12:08:36 +02:00
ce8041754b Document sdk/firmware directory 2025-10-05 22:41:32 +02:00
c4af89946b Restructure bootdata under boot directory 2025-10-05 22:37:03 +02:00
95fecfc095 Increase disk image size for FAT32 support 2025-10-05 22:01:12 +02:00
ec4e8c416c Switch disk image to FAT32 and install VBR 2025-10-05 18:48:42 +02:00
64733914f2 Add VBR stub 2025-10-05 17:24:25 +02:00
4e7baf302c Simplify and fix Print function 2025-10-02 12:24:05 +02:00
2f9a6b5548 Fix stack pointer setup 2025-10-02 11:52:27 +02:00
646e246ec6 Improve emulation targets and add BIOS variants 2025-10-01 18:26:27 +02:00
ae941d2761 Make use of 'diskimg' tool. This breaks compatibility with older versions of xtchain 2025-10-01 16:05:48 +02:00
b40db0d1dd Cleanup cmake functions 2025-09-29 20:05:14 +02:00
cf4c17df22 Switch bochs to use BIOS 2025-09-29 19:55:34 +02:00
f152e2bac7 Move MBR boot code to common, arch-independent place 2025-09-27 14:10:13 +02:00
f81e895fe1 Add MBR boot code 2025-09-27 14:07:17 +02:00
370a635ee2 Correctly handle CRLF line endings in config parser 2025-09-26 17:36:12 +02:00
4696faf86d Add support for building flat bootsector binaries 2025-09-25 18:32:27 +02:00
332e57f305 Add register dump to trap handler 2025-09-25 08:28:02 +02:00
4ee3daa8f8 Prune outdated ideas 2025-09-24 20:30:18 +02:00
ee82475aa3 Remove unused header 2025-09-24 20:27:27 +02:00
ff0caf93da Merge C to C++ migration changes 2025-09-24 20:18:35 +02:00
20fd950ef4 Update readme to reflect C++ namespaces and class-based naming 2025-09-23 22:54:41 +02:00
6e10089280 Drop unnecessary boolean casts after type refactor 2025-09-23 19:17:33 +02:00
9298aef87e Separate boolean definition for C and C++ 2025-09-23 19:06:18 +02:00
6c66028800 Document XTLDR methods 2025-09-22 14:54:27 +02:00
ed293c7e61 Finish moving global variables into classes 2025-09-22 09:56:58 +02:00
7791ca13e2 Partially move global variables into classes 2025-09-20 20:16:55 +02:00
d0aeaf1109 Unify XTLDR naming 2025-09-20 18:55:08 +02:00
c041457799 Refactor bootloader code into C++ classes 2025-09-20 18:47:36 +02:00
08a9a0273f Move trampoline handling code 2025-09-19 19:32:04 +02:00
ae4b95380a Fix AP startup symbol name 2025-09-19 19:23:39 +02:00
2b49b23d41 Add trampoline support and move assembler prototypes 2025-09-19 19:07:27 +02:00
38f1af025c Add missing calling convention 2025-09-19 17:21:20 +02:00
d0577611ca Move asm headers 2025-09-19 13:47:18 +02:00
7b357ebc54 Fix build after migration 2025-09-19 13:41:05 +02:00
4c380bae1c Fix build by replacing leftover Ar calls 2025-09-19 13:29:15 +02:00
1b0468f742 Fix build by replacing leftover Ar calls 2025-09-19 13:26:26 +02:00
e7425de523 Drop C wrappers and switch to C++ API 2025-09-19 12:56:06 +02:00
b2c8fa3e62 Use new C++ API 2025-09-19 10:49:07 +02:00
9bbac6d3c1 Migrate XTOS module to C++ 2025-09-18 21:54:11 +02:00
dcae0cbb91 Migrate XTLDR modules to C++ 2025-09-17 22:30:48 +02:00
57fbbf820c Remove stale comments and whitespace 2025-09-17 16:10:36 +02:00
86fd2b4eea Migrate XTLDR to C++ 2025-09-17 15:56:41 +02:00
7117d76842 Switch UEFI interfaces to PWCHAR/BOOLEAN types for better compatibility with C++ 2025-09-17 08:17:48 +02:00
98ad2087de Replace remaining NULL occurrence with NULLPTR 2025-09-16 16:04:37 +02:00
fabf3a3a5e Replace all occurrences of NULL with NULLPTR for unified C and C++ null pointer handling 2025-09-16 15:59:56 +02:00
ba9e5b1b88 Migrate NTOSDRV to C++ 2025-09-16 15:13:54 +02:00
307ec1794c Clean up after migration to C++ 2025-09-16 14:20:20 +02:00
f86b63f68d Add missing documentation and fix formatting 2025-09-16 11:42:40 +02:00
2f25107d09 Replace legacy thread retrieval function calls 2025-09-16 09:20:59 +02:00
556e832056 Restore missing assembly headers 2025-09-16 08:50:11 +02:00
f4561c1f4f Remove leftover old headers and fix missed spots 2025-09-16 08:46:53 +02:00
ee97388981 Switch i686 processor structures setup to use class data 2025-09-15 22:50:52 +02:00
0a0fdffc46 Clean up kernel headers 2025-09-15 22:46:57 +02:00
e3898f28fc Refactor kernel to use MM namespace for memory management 2025-09-15 22:26:52 +02:00
52c4d2a346 Complete MM class definitions with missing fields 2025-09-15 22:17:46 +02:00
404595801d Migrate MM subsystem to C++ 2025-09-15 22:15:07 +02:00
3e097c260d Add stubs for C++ exception and purecall handlers 2025-09-15 20:52:40 +02:00
e0844b38cd Move dbg.hh into KD namespace 2025-09-14 01:40:21 +02:00
f321ca908b Refine and export kernel debugger printing 2025-09-14 01:25:56 +02:00
79ec28641a Migrate KD subsystem to C++ 2025-09-13 23:40:07 +02:00
4592955da1 Migrate HL subsystem to C++ 2025-09-13 19:15:13 +02:00
a2fe39defd Refine formatting 2025-09-13 00:12:57 +02:00
7cdfa8f79d Refactor KE subsystem 2025-09-12 13:11:15 +02:00
0647b853a6 Migrate PO subsystem to C++ 2025-09-11 22:52:40 +02:00
3a11d536d5 Refactor AR subsystem 2025-09-11 20:23:51 +02:00
96043f3d70 Build SDK 2025-09-11 20:09:21 +02:00
5f44458e64 Fix calling conventions 2025-09-11 19:44:00 +02:00
cc632c5ef9 Update kernel exports 2025-09-11 19:35:38 +02:00
631c260280 Update SpinLock and DPC to use C++ helpers 2025-09-11 19:23:19 +02:00
1357e92627 Update EX subsystem to use C++ RTL api 2025-09-11 19:15:52 +02:00
3395934330 Match renamed I/O register helpers 2025-09-11 19:08:20 +02:00
744fffdd8a Clean up atomic routine declarations 2025-09-11 19:05:12 +02:00
0a3450f649 Add missing header files 2025-09-11 18:58:43 +02:00
7d5eab1a8e Remove redundant source list and reuse XTOSKRNL_SOURCE for libxtos 2025-09-11 18:55:31 +02:00
7674196cc1 Unify sdk library output path 2025-09-11 18:53:58 +02:00
c160e5ddf2 Improve CMake SDK output handling and linker configuration 2025-09-11 18:48:22 +02:00
9518e7da8e Migrate RTL subsystem to C++ 2025-09-11 18:28:24 +02:00
e507dd0390 Clean up cmake output directory configuration 2025-09-11 14:07:20 +02:00
510dccc5dc Add missing forward reference to KeGetInitializationBlock 2025-09-10 15:38:30 +02:00
17712883c5 Include new KE headers 2025-09-09 23:24:43 +02:00
5cb6474ade Sync CMakeLists with source tree 2025-09-09 23:22:37 +02:00
4947f788d5 Migrate KE subsystem to C++ 2025-09-09 23:20:50 +02:00
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
e8771dfc5b Use __asm__ to comply with disabled GNU extensions 2025-08-15 00:32:56 +02:00
325 changed files with 20185 additions and 13260 deletions

View File

@@ -28,7 +28,7 @@ jobs:
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 }}-${{ 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 }}-${{ 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 }}-${{ 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 }}-${{ matrix.build }}-sdk.tar.gz -C build-${{ matrix.arch }}-${{ matrix.build }}/output/sdk .
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 . 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 }}-${{ matrix.build }}/output/disk.img > ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}-${{ matrix.build }}.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 }}-${{ matrix.build }}*.gz" ExectOS artifact_publish "ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}-${{ matrix.build }}*.gz" ExectOS

View File

@@ -55,18 +55,15 @@ add_definitions(-D__XTOS__)
add_definitions(-DXTOS_SOURCE_DIR="${EXECTOS_SOURCE_DIR}") add_definitions(-DXTOS_SOURCE_DIR="${EXECTOS_SOURCE_DIR}")
add_definitions(-DXTOS_BINARY_DIR="${EXECTOS_BINARY_DIR}") add_definitions(-DXTOS_BINARY_DIR="${EXECTOS_BINARY_DIR}")
# Set libraries target directory
set(LIBRARY_OUTPUT_PATH ${EXECTOS_BINARY_DIR}/output/library CACHE PATH "Build directory" FORCE)
# Compute __FILE__ definition # Compute __FILE__ definition
file(RELATIVE_PATH _PATH_PREFIX ${EXECTOS_BINARY_DIR} ${EXECTOS_SOURCE_DIR}) file(RELATIVE_PATH _PATH_PREFIX ${EXECTOS_BINARY_DIR} ${EXECTOS_SOURCE_DIR})
add_compiler_flags(-D__RELFILE__="&__FILE__[__FILE__[0] == '.' ? sizeof \\\"${_PATH_PREFIX}\\\" - 1 : sizeof XTOS_SOURCE_DIR]") add_compiler_flags(-D__RELFILE__="&__FILE__[__FILE__[0] == '.' ? sizeof \\\"${_PATH_PREFIX}\\\" - 1 : sizeof XTOS_SOURCE_DIR]")
# Set the virtual disk image size (in MiB) # Set the virtual disk image size (in MiB)
set_disk_image_size(32) set_disk_image_size(48)
# Build all subprojects # Build all subprojects
add_subdirectory(bootdata) add_subdirectory(boot)
add_subdirectory(drivers) add_subdirectory(drivers)
add_subdirectory(xtldr) add_subdirectory(sdk)
add_subdirectory(xtoskrnl) add_subdirectory(xtoskrnl)

View File

@@ -9,8 +9,7 @@ porting drivers, fixing bugs, writing tests, creating documentation, or helping
love the help. love the help.
## Wish List ## Wish List
If you are looking for a way to contribute, but you are not sure where to start, check our [IDEAS](IDEAS.md) and If you are looking for a way to contribute, but you are not sure where to start, check our list of
[KNOWN ISSUES](KNOWN_ISSUES.md) pages for suggestions. We try to keep them up to date. You can also check a list of
[open issues](https://git.codingworkshop.eu.org/xt-sys/exectos/issues). If you find interesting task and you are serious [open issues](https://git.codingworkshop.eu.org/xt-sys/exectos/issues). If you find interesting task and you are serious
about tackling one, feel free to contact us. We will be able to provide a more detailed information and suggestions about tackling one, feel free to contact us. We will be able to provide a more detailed information and suggestions
towards getting started. towards getting started.

View File

@@ -1,23 +0,0 @@
## ExectOS Ideas
This is a list of ideas that migh but not must be realized.
### SDK
- [ ] Currently XT Development Kit (XTDK) is a garbage. It should be cleaned up the way, it contains all structures
and definitions, as well as all routines that are exported and can be used by other components or software
dynamically linked. All other routines should be available as well in some form, as some libraries can share
code with others (eg. XTLDR calls routines exported by XTOSKRNL). This is partially done, as XTDK has been
cleaned up, but still there are routines used by XTLDR.
### XTLDR
- [ ] 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
the addressable virtual memory from 256TB to 128PB. This is partially done.
- [ ] Implement editing boot menu entries directly from the boot menu. Changes should be runtime only (not stored on
disk).
### XTOSKRNL
- [ ] 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.
- [ ] 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
terminals and switch between them) and work on top of FB. It should define ANSI colors and scrollback buffer.

View File

@@ -1,6 +0,0 @@
## ExectOS Known Issues
This is a list of well known bugs that exists in all master branch builds.
### XTLDR
- [ ] EFI Runtime Services are not mapped properly into higher half. They are mapped itself, but all pointers inside
that structure point to some physical address that is unavailable after paging is enabled.

View File

@@ -58,15 +58,17 @@ design, it requires a modern EFI enabled hardware. It is not possible currently
# Source structure # Source structure
| Directory | Description | | Directory | Description |
|-------------|----------------------------------------------------------| |------------------|--------------------------------------------------------------|
| bootdata | default configuration and data needed to boot XTOS | | boot/bootdata | default configuration and data needed to boot XTOS |
| boot/bootsect | boot sector code (MBR & VBR) initializing the boot process |
| boot/xtldr | XTOS boot loader source code |
| drivers | XT native drivers source code | | drivers | XT native drivers source code |
| sdk/cmake | Host toolchain configuration and build-related functions | | sdk/cmake | host toolchain configuration and build-related functions |
| sdk/firmware | firmware enabling XTOS to boot on virtual machines |
| sdk/xtdk | XT Software Development Kit headers | | sdk/xtdk | XT Software Development Kit headers |
| services | integral subsystems services source code | | services | integral subsystems services source code |
| subsystems | environment subsystems source code | | subsystems | environment subsystems source code |
| xtoskrnl | XTOS kernel source code | | xtoskrnl | XTOS kernel source code |
| xtldr | XTOS boot loader source code |
# Build # Build
XTOS can only be built using [XTchain](https://git.codingworkshop.eu.org/xt-sys/xtchain), a dedicated toolchain designed XTOS can only be built using [XTchain](https://git.codingworkshop.eu.org/xt-sys/xtchain), a dedicated toolchain designed

3
boot/CMakeLists.txt Normal file
View File

@@ -0,0 +1,3 @@
add_subdirectory(bootdata)
add_subdirectory(bootsect)
add_subdirectory(xtldr)

View File

@@ -40,6 +40,14 @@ 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] [ExectOS_NOXPA]
SystemName="ExectOS Operating System (NOXPA)" SystemName="ExectOS Operating System (NOXPA)"
SystemType=XTOS SystemType=XTOS
@@ -48,6 +56,14 @@ SystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOS
KernelFile=xtoskrnl.exe KernelFile=xtoskrnl.exe
Parameters=DEBUG=COM1,115200 NOXPA 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

View File

@@ -0,0 +1,6 @@
# XT Boot Sector
PROJECT(BOOTSECT)
# Compile boot sectors
compile_bootsector(mbrboot ${BOOTSECT_SOURCE_DIR}/mbrboot.S 0x7C00 Start)
compile_bootsector(espboot ${BOOTSECT_SOURCE_DIR}/espboot.S 0x7C00 Start)

276
boot/bootsect/espboot.S Normal file
View File

@@ -0,0 +1,276 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: boot/bootsect/espboot.S
* DESCRIPTION: XT Boot Loader ESP boot code (FAT32)
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
.text
.code16
.global Start
Start:
/* Jump to the real start to omit the BPB (BIOS Parameter Block) */
jmp RealStart
nop
/* BIOS Parameter Block */
OsName:
.ascii "XTOS "
OsVersion:
.ascii "1.0"
BytesPerSector:
.word 512
SectorsPerCluster:
.byte 2
ReservedSectors:
.word 8
FatCopies:
.byte 1
RootDirEntries:
.word 1024
TotalSectors:
.word 0
MediaType:
.byte 0xF8
SectorsPerFat:
.word 0
SectorsPerTrack:
.word 17
NumberOfHeads:
.word 0
HiddenSectors:
.long 0
TotalBigSectors:
.long 0x200000
BigSectorsPerFat:
.long 0x1FE0
ExtendedFlags:
.word 0
FsVersion:
.word 0
RootDirStartCluster:
.long 0
FSInfoSector:
.word 0
BackupBootSector:
.word 6
Reserved:
.fill 12, 1, 0
DriveNumber:
.byte 0x80
CurrentHead:
.byte 0
Signature:
.byte 0x29
SerialNumber:
.long 0
VolumeLabel:
.ascii "NO NAME "
FileSystem:
.ascii "FAT32 "
RealStart:
/* Set segments and stack */
cli
cld
xorw %ax, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
movw $0x7C00, %bp
leaw -16(%bp), %sp
sti
/* Get drive number */
cmpb $0xFF, DriveNumber - Start(%bp)
jne GetDriveParameters
movb %dl, DriveNumber - Start(%bp)
GetDriveParameters:
/* Get drive parameters from the BIOS */
movb DriveNumber - Start(%bp), %dl
movb $0x08, %ah
movb $0x00, %al
int $0x13
jnc GetDriveSize
movw $0xFFFF, %cx
movb %cl, %dh
GetDriveSize:
/* Get drive size from the BIOS */
movzbl %dh, %eax
incw %ax
movzbl %cl, %edx
andb $0x3F, %dl
mulw %dx
xchgb %cl, %ch
shrb $0x06, %ch
incw %cx
movzwl %cx, %ecx
mull %ecx
movl %eax, %edi
VerifyBiosParameterBlock:
/* Verify the FAT32 BPB */
cmpw $0x00, SectorsPerFat - Start(%bp)
jne FsError
cmpw $0x00, FsVersion - Start(%bp)
ja FsError
ReadExtraCode:
/* Read second VBR sector with extra boot code */
movl HiddenSectors - Start(%bp), %eax
addl $0x02, %eax
movw $0x01, %cx
xorw %bx, %bx
movw %bx, %es
movw $0x7E00, %bx
call ReadSectors
jmp StartSectors
ReadSectors:
/* Check for extended BIOS functions and use it only if available */
pushw %es
pushal
movb $0x41, %ah
movw $0x55AA, %bx
movb DriveNumber - Start(%bp), %dl
int $0x13
jc ReadCHS
cmpw $0xAA55, %bx
jne ReadCHS
testb $0x01, %cl
jz ReadCHS
/* Verify drive size and determine whether to use CHS or LBA */
cmpl %edi, %eax
jnb ReadLBA
ReadCHS:
/* Read sectors using CHS */
pushw %cx
pushal
xorl %edx, %edx
movzwl SectorsPerTrack - Start(%bp), %ecx
divl %ecx
incb %dl
movb %dl, %cl
movl %eax, %edx
shrl $0x10, %edx
divw NumberOfHeads - Start(%bp)
movb %dl, %dh
movb DriveNumber - Start(%bp), %dl
movb %al, %ch
rorb $0x01, %ah
rorb $0x01, %ah
orb %ah, %cl
movw $0x0201, %ax
int $0x13
popal
popw %cx
jc DiskError
incl %eax
movw %es, %dx
addw $0x20, %dx
movw %dx, %es
loop ReadCHS
popw %es
ret
ReadLBA:
/* Prepare DAP packet and read sectors using LBA */
popal
pushw %cx
pushal
pushw $0x00
pushw $0x00
pushl %eax
pushw %es
pushw %bx
pushw %cx
pushw $0x10
movw %sp, %si
movb DriveNumber - Start(%bp), %dl
movb $0x42, %ah
int $0x13
jc DiskError
addw $0x10, %sp
popal
popw %si
pushw %bx
movzwl %si, %ebx
addl %ebx, %eax
shll $0x05, %ebx
movw %es, %dx
addw %bx, %dx
movw %dx, %es
popw %bx
subw %si, %cx
jnz ReadLBA
popw %es
ret
DiskError:
/* Display disk error message and reboot */
movw $msgDiskError, %si
call Print
jmp Reboot
FsError:
/* Display FS error message and reboot */
movw $msgFsError, %si
call Print
jmp Reboot
Print:
/* Simple routine to print messages */
lodsb
orb %al, %al
jz DonePrint
movb $0x0E, %ah
movw $0x07, %bx
int $0x10
jmp Print
DonePrint:
retw
Reboot:
/* Display a message, wait for a key press and reboot */
movw $msgAnyKey, %si
call Print
xorw %ax, %ax
int $0x16
int $0x19
msgAnyKey:
.ascii "Press any key to restart\r\n"
msgDiskError:
.ascii "Disk error\r\n"
msgFsError:
.ascii "File system error\r\n"
/* Fill the rest of the VBR with zeros and add VBR signature at the end */
.fill (510 - (. - Start)), 1, 0
.word 0xAA55
StartSectors:
/* Print message */
movw $msgUnavailable, %si
call Print
/* Wait for key press and reboot */
xorw %ax, %ax
int $0x16
int $0x19
msgUnavailable:
.ascii "XTLDR requires EFI-based system!\r\nPress any key to restart\r\n"
/* Fill the rest of the extra VBR with zeros */
.fill (1024 - (. - Start)), 1, 0

153
boot/bootsect/mbrboot.S Normal file
View File

@@ -0,0 +1,153 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: boot/bootsect/amd64/mbrboot.S
* DESCRIPTION: XT Boot Loader MBR boot code
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
.text
.code16
.global Start
Start:
/* Set segments and stack */
cli
cld
xorw %ax, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
movw $0x7C00, %bp
leaw -16(%bp), %sp
sti
/* Relocate MBR to 1FE0:7C00 */
movw $0x1FE0, %ax
movw %ax, %es
movw %bp, %si
movw %bp, %di
movw $256, %cx
rep movsw
/* Jump to the relocated MBR code */
jmp $0x1FE0, $RealStart
RealStart:
/* Set segments */
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
/* Print welcome message */
leaw msgXtosBoot, %si
call Print
/* Get BIOS boot drive and partition table offset */
lea 0x1BE(%bp), %si
movb %dl, .BootDrive
xorw %cx, %cx
FindActivePartition:
/* Look for active partition */
movb (%si), %al
cmpb $0x80, %al
je PartitionFound
addw $16, %si
incw %cx
cmpw $4, %cx
jne FindActivePartition
jmp PartitionNotFound
PartitionFound:
/* Save LBA start */
movl 8(%si), %eax
movl %eax, .LbaStart
/* Prepare Disk Address Packet (DAP) */
lea .Dap, %si
movb $0x10, 0(%si)
movb $0x00, 1(%si)
movw $1, 2(%si)
movw $0x7C00, 4(%si)
movw $0x0000, 6(%si)
movl .LbaStart, %eax
movl %eax, 8(%si)
/* Read Volume Boot Record (VBR) */
movb $0x42, %ah
movb .BootDrive, %dl
int $0x13
jc VbrReadFail
/* Verify VBR signature */
cmpw $0xAA55, (0x7C00 + 0x01FE)
jne InvalidSignature
/* Jump to the VBR code */
jmp $0x0000, $0x7C00
InvalidSignature:
/* Invalid signature error */
leaw msgInvalidSignature, %si
call Print
jmp HaltSystem
PartitionNotFound:
/* Active partition not found error */
leaw msgPartitionNotFound, %si
call Print
jmp HaltSystem
VbrReadFail:
/* VBR read failed error */
leaw msgVbrReadFail, %si
call Print
jmp HaltSystem
HaltSystem:
/* Disable interrupts and stop the CPU */
cli
hlt
jmp HaltSystem
Print:
/* Simple routine to print messages */
lodsb
orb %al, %al
jz DonePrint
movb $0x0E, %ah
movw $0x07, %bx
int $0x10
jmp Print
DonePrint:
retw
.BootDrive:
/* Storage for the boot drive number */
.byte 0
.Dap:
/* Storage for the Disk Address Packet (DAP) */
.fill 16, 1, 0
.LbaStart:
/* Storage for the LBA start */
.long 0
msgInvalidSignature:
.asciz "Invalid partition signature!"
msgPartitionNotFound:
.asciz "Bootable partition not found!"
msgVbrReadFail:
.asciz "VBR read failed!"
msgXtosBoot:
.asciz "Starting XTOS boot loader...\r\n"
/* Fill the rest of the MBR with zeros and add MBR signature at the end */
.fill (510 - (. - Start)), 1, 0
.word 0xAA55

View File

@@ -11,24 +11,23 @@ include_directories(
# Specify list of library source code files # Specify list of library source code files
list(APPEND LIBXTLDR_SOURCE list(APPEND LIBXTLDR_SOURCE
${XTLDR_SOURCE_DIR}/library/modproto.c) ${XTLDR_SOURCE_DIR}/library/modproto.cc)
# 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.cc
${XTLDR_SOURCE_DIR}/bootutil.c ${XTLDR_SOURCE_DIR}/bootutil.cc
${XTLDR_SOURCE_DIR}/config.c ${XTLDR_SOURCE_DIR}/config.cc
${XTLDR_SOURCE_DIR}/console.c ${XTLDR_SOURCE_DIR}/console.cc
${XTLDR_SOURCE_DIR}/debug.c ${XTLDR_SOURCE_DIR}/data.cc
${XTLDR_SOURCE_DIR}/efiutils.c ${XTLDR_SOURCE_DIR}/debug.cc
${XTLDR_SOURCE_DIR}/globals.c ${XTLDR_SOURCE_DIR}/efiutils.cc
${XTLDR_SOURCE_DIR}/hardware.c ${XTLDR_SOURCE_DIR}/memory.cc
${XTLDR_SOURCE_DIR}/memory.c ${XTLDR_SOURCE_DIR}/protocol.cc
${XTLDR_SOURCE_DIR}/protocol.c ${XTLDR_SOURCE_DIR}/shell.cc
${XTLDR_SOURCE_DIR}/shell.c ${XTLDR_SOURCE_DIR}/textui.cc
${XTLDR_SOURCE_DIR}/textui.c ${XTLDR_SOURCE_DIR}/volume.cc
${XTLDR_SOURCE_DIR}/volume.c ${XTLDR_SOURCE_DIR}/xtldr.cc)
${XTLDR_SOURCE_DIR}/xtldr.c)
# Link static XTLDR library # Link static XTLDR library
add_library(libxtldr ${LIBXTLDR_SOURCE}) add_library(libxtldr ${LIBXTLDR_SOURCE})

View File

@@ -1,13 +1,13 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/arch/amd64/memory.c * FILE: xtldr/arch/amd64/memory.cc
* 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> * Aiken Harris <harraiken91@gmail.com>
*/ */
#include <xtldr.h> #include <xtldr.hh>
/** /**
@@ -25,17 +25,19 @@
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress) IN ULONG_PTR SelfMapAddress)
{ {
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry; PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
PXTBL_MEMORY_MAPPING Mapping; PXTBL_MEMORY_MAPPING Mapping;
PXTBL_MODULE_INFO ModuleInfo; PXTBL_MODULE_INFO ModuleInfo;
EFI_PHYSICAL_ADDRESS Address; EFI_PHYSICAL_ADDRESS Address;
PVOID LoaderBase;
ULONGLONG LoaderSize;
EFI_STATUS Status; EFI_STATUS Status;
/* Allocate pages for the Page Map */ /* Allocate pages for the Page Map */
Status = BlAllocateMemoryPages(1, &Address); Status = AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -44,18 +46,27 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
/* Assign and zero-fill memory used by page mappings */ /* Assign and zero-fill memory used by page mappings */
PageMap->PtePointer = (PVOID)(UINT_PTR)Address; PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
RtlZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE); RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
/* Add page mapping itself to memory mapping */ /* Add page mapping itself to memory mapping */
Status = BlpSelfMapPml(PageMap, SelfMapAddress); Status = Memory::SelfMapPml(PageMap, SelfMapAddress);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* PML mapping failed */ /* PML mapping failed */
return Status; return Status;
} }
/* Map the trampoline code area */
Status = MapVirtualMemory(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 = Protocol::GetModulesList();
ModulesListEntry = ModulesList->Flink; ModulesListEntry = ModulesList->Flink;
while(ModulesListEntry != ModulesList) while(ModulesListEntry != ModulesList)
{ {
@@ -63,7 +74,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink); ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
/* Map module code */ /* Map module code */
Status = BlMapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase, Status = MapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase,
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary); EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
/* Check if mapping succeeded */ /* Check if mapping succeeded */
@@ -77,12 +88,15 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
ModulesListEntry = ModulesListEntry->Flink; ModulesListEntry = ModulesListEntry->Flink;
} }
/* Get boot loader image information */
XtLoader::GetLoaderImageInformation(&LoaderBase, &LoaderSize);
/* Make sure boot loader image base and size are set */ /* Make sure boot loader image base and size are set */
if(BlpStatus.LoaderBase && BlpStatus.LoaderSize) if(LoaderBase && LoaderSize)
{ {
/* Map boot loader code as well */ /* Map boot loader code as well */
Status = BlMapVirtualMemory(PageMap, BlpStatus.LoaderBase, BlpStatus.LoaderBase, Status = MapVirtualMemory(PageMap, LoaderBase, LoaderBase,
EFI_SIZE_TO_PAGES(BlpStatus.LoaderSize), LoaderFirmwareTemporary); EFI_SIZE_TO_PAGES(LoaderSize), LoaderFirmwareTemporary);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Mapping boot loader code failed */ /* Mapping boot loader code failed */
@@ -96,7 +110,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
} }
/* Iterate through and map all the mappings*/ /* Iterate through and map all the mappings*/
BlDebugPrint(L"Mapping and dumping EFI memory:\n"); Debug::Print(L"Mapping and dumping EFI memory:\n");
ListEntry = PageMap->MemoryMap.Flink; ListEntry = PageMap->MemoryMap.Flink;
while(ListEntry != &PageMap->MemoryMap) while(ListEntry != &PageMap->MemoryMap)
{ {
@@ -107,11 +121,11 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
if(Mapping->VirtualAddress) if(Mapping->VirtualAddress)
{ {
/* Dump memory mapping */ /* Dump memory mapping */
BlDebugPrint(L" Type=%02lu, PhysicalBase=%.16P, VirtualBase=%.16P, Pages=%llu\n", Mapping->MemoryType, Debug::Print(L" Type=%02lu, PhysicalBase=%.16P, VirtualBase=%.16P, Pages=%llu\n", Mapping->MemoryType,
Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages); Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages);
/* Map memory */ /* Map memory */
Status = BlMapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress, Status = MapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress,
(UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages); (UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
@@ -128,114 +142,6 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
/**
* Does the actual virtual memory mapping.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @param VirtualAddress
* Supplies a virtual address of the mapping.
*
* @param PhysicalAddress
* Supplies a physical address of the mapping.
*
* @param NumberOfPages
* Supplies a number of the pages of the mapping.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR VirtualAddress,
IN ULONG_PTR PhysicalAddress,
IN ULONG NumberOfPages)
{
PVOID Pml1, Pml2, Pml3, Pml4, Pml5;
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry, Pml4Entry, Pml5Entry;
PHARDWARE_PTE PmlTable;
SIZE_T PageFrameNumber;
EFI_STATUS Status;
/* Set the Page Frame Number (PFN) */
PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT;
/* Do the recursive mapping */
while(NumberOfPages > 0)
{
/* Calculate the indices in the various Page Tables from the virtual address */
Pml5Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_LA57_SHIFT)) >> MM_LA57_SHIFT;
Pml4Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PXI_SHIFT)) >> MM_PXI_SHIFT;
Pml3Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PPI_SHIFT)) >> MM_PPI_SHIFT;
Pml2Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PDI_SHIFT)) >> MM_PDI_SHIFT;
Pml1Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PTI_SHIFT)) >> MM_PTI_SHIFT;
/* Check page map level */
if(PageMap->PageMapLevel == 5)
{
/* Five level Page Map */
Pml5 = PageMap->PtePointer;
/* Get PML4 */
Status = BlpGetNextPageTable(PageMap, Pml5, Pml5Entry, &Pml4);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
return Status;
}
}
else
{
/* Four level Page Map */
Pml4 = PageMap->PtePointer;
}
/* Get PML3 */
Status = BlpGetNextPageTable(PageMap, Pml4, Pml4Entry, &Pml3);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
return Status;
}
/* Get PML 2 */
Status = BlpGetNextPageTable(PageMap, Pml3, Pml3Entry, &Pml2);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
return Status;
}
/* Get PML1 */
Status = BlpGetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
return Status;
}
/* Set paging entry settings */
PmlTable = (PHARDWARE_PTE)Pml1;
RtlZeroMemory(&PmlTable[Pml1Entry], sizeof(HARDWARE_PTE));
PmlTable[Pml1Entry].PageFrameNumber = PageFrameNumber;
PmlTable[Pml1Entry].Valid = 1;
PmlTable[Pml1Entry].Writable = 1;
/* Take next virtual address and PFN */
VirtualAddress += EFI_PAGE_SIZE;
PageFrameNumber++;
/* Decrease number of pages left */
NumberOfPages--;
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
/** /**
* Returns next level of the Page Table. * Returns next level of the Page Table.
* *
@@ -257,7 +163,7 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID PageTable, IN PVOID PageTable,
IN SIZE_T Entry, IN SIZE_T Entry,
OUT PVOID *NextPageTable) OUT PVOID *NextPageTable)
@@ -279,7 +185,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
else else
{ {
/* Allocate pages for new PML entry */ /* Allocate pages for new PML entry */
Status = BlAllocateMemoryPages(1, &Address); Status = AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -287,7 +193,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
} }
/* Add new memory mapping */ /* Add new memory mapping */
Status = BlMapVirtualMemory(PageMap, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData); Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory mapping failure */ /* Memory mapping failure */
@@ -295,7 +201,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
} }
/* Fill allocated memory with zeros */ /* Fill allocated memory with zeros */
RtlZeroMemory((PVOID)(ULONGLONG)Address, EFI_PAGE_SIZE); RTL::Memory::ZeroMemory((PVOID)(ULONGLONG)Address, EFI_PAGE_SIZE);
/* Set paging entry settings */ /* Set paging entry settings */
PmlTable[Entry].PageFrameNumber = Address / EFI_PAGE_SIZE; PmlTable[Entry].PageFrameNumber = Address / EFI_PAGE_SIZE;
@@ -311,6 +217,114 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
/**
* Does the actual virtual memory mapping.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @param VirtualAddress
* Supplies a virtual address of the mapping.
*
* @param PhysicalAddress
* Supplies a physical address of the mapping.
*
* @param NumberOfPages
* Supplies a number of the pages of the mapping.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
Memory::MapPage(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR VirtualAddress,
IN ULONG_PTR PhysicalAddress,
IN ULONG NumberOfPages)
{
PVOID Pml1, Pml2, Pml3, Pml4, Pml5;
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry, Pml4Entry, Pml5Entry;
PHARDWARE_PTE PmlTable;
SIZE_T PageFrameNumber;
EFI_STATUS Status;
/* Set the Page Frame Number (PFN) */
PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT;
/* Do the recursive mapping */
while(NumberOfPages > 0)
{
/* Calculate the indices in the various Page Tables from the virtual address */
Pml5Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_P5I_SHIFT)) >> MM_P5I_SHIFT;
Pml4Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PXI_SHIFT)) >> MM_PXI_SHIFT;
Pml3Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PPI_SHIFT)) >> MM_PPI_SHIFT;
Pml2Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PDI_SHIFT)) >> MM_PDI_SHIFT;
Pml1Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PTI_SHIFT)) >> MM_PTI_SHIFT;
/* Check page map level */
if(PageMap->PageMapLevel == 5)
{
/* Five level Page Map */
Pml5 = PageMap->PtePointer;
/* Get PML4 */
Status = GetNextPageTable(PageMap, Pml5, Pml5Entry, &Pml4);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
return Status;
}
}
else
{
/* Four level Page Map */
Pml4 = PageMap->PtePointer;
}
/* Get PML3 */
Status = GetNextPageTable(PageMap, Pml4, Pml4Entry, &Pml3);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
return Status;
}
/* Get PML 2 */
Status = GetNextPageTable(PageMap, Pml3, Pml3Entry, &Pml2);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
return Status;
}
/* Get PML1 */
Status = GetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
return Status;
}
/* Set paging entry settings */
PmlTable = (PHARDWARE_PTE)Pml1;
RTL::Memory::ZeroMemory(&PmlTable[Pml1Entry], sizeof(HARDWARE_PTE));
PmlTable[Pml1Entry].PageFrameNumber = PageFrameNumber;
PmlTable[Pml1Entry].Valid = 1;
PmlTable[Pml1Entry].Writable = 1;
/* Take next virtual address and PFN */
VirtualAddress += EFI_PAGE_SIZE;
PageFrameNumber++;
/* Decrease number of pages left */
NumberOfPages--;
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
/** /**
* Creates a recursive self mapping for all PML levels. * Creates a recursive self mapping for all PML levels.
* *
@@ -326,7 +340,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap, Memory::SelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress) IN ULONG_PTR SelfMapAddress)
{ {
PHARDWARE_PTE PmlBase; PHARDWARE_PTE PmlBase;
@@ -338,21 +352,20 @@ BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,
/* 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 >> MM_PXI_SHIFT) & 0x1FF; PmlIndex = (SelfMapAddress >> MM_PXI_SHIFT) & 0x1FF;
}
/* Add self-mapping for PML4 */ /* Add self-mapping */
RtlZeroMemory(&PmlBase[PmlIndex], sizeof(HARDWARE_PTE)); RTL::Memory::ZeroMemory(&PmlBase[PmlIndex], sizeof(HARDWARE_PTE));
PmlBase[PmlIndex].PageFrameNumber = (UINT_PTR)PageMap->PtePointer / EFI_PAGE_SIZE; PmlBase[PmlIndex].PageFrameNumber = (UINT_PTR)PageMap->PtePointer / EFI_PAGE_SIZE;
PmlBase[PmlIndex].Valid = 1; PmlBase[PmlIndex].Valid = 1;
PmlBase[PmlIndex].Writable = 1; PmlBase[PmlIndex].Writable = 1;
}
/* Return success */ /* Return success */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;

View File

@@ -1,13 +1,13 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/arch/i686/memory.c * FILE: xtldr/arch/i686/memory.cc
* 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> * Aiken Harris <harraiken91@gmail.com>
*/ */
#include <xtldr.h> #include <xtldr.hh>
/** /**
@@ -22,13 +22,15 @@
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress) IN ULONG_PTR SelfMapAddress)
{ {
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry; PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
EFI_PHYSICAL_ADDRESS Address, DirectoryAddress; EFI_PHYSICAL_ADDRESS Address, DirectoryAddress;
PXTBL_MODULE_INFO ModuleInfo; PXTBL_MODULE_INFO ModuleInfo;
PXTBL_MEMORY_MAPPING Mapping; PXTBL_MEMORY_MAPPING Mapping;
PVOID LoaderBase;
ULONGLONG LoaderSize;
EFI_STATUS Status; EFI_STATUS Status;
ULONG Index; ULONG Index;
@@ -36,7 +38,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
if(PageMap->PageMapLevel == 3) if(PageMap->PageMapLevel == 3)
{ {
/* Allocate a page for the 3-level page map structure (PAE enabled) */ /* Allocate a page for the 3-level page map structure (PAE enabled) */
Status = BlAllocateMemoryPages(1, &Address); Status = AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failed, cannot proceed with page map creation */ /* Memory allocation failed, cannot proceed with page map creation */
@@ -45,10 +47,10 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
/* Assign the allocated page to the page map and zero it out */ /* 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); RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
/* Allocate 4 pages for the Page Directories (PDs) */ /* Allocate 4 pages for the Page Directories (PDs) */
Status = BlAllocateMemoryPages(4, &DirectoryAddress); Status = AllocatePages(AllocateAnyPages, 4, &DirectoryAddress);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failed, cannot proceed with page map creation */ /* Memory allocation failed, cannot proceed with page map creation */
@@ -56,21 +58,21 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
} }
/* Zero-fill the allocated memory for the Page Directories */ /* Zero-fill the allocated memory for the Page Directories */
RtlZeroMemory((PVOID)DirectoryAddress, EFI_PAGE_SIZE * 4); RTL::Memory::ZeroMemory((PVOID)DirectoryAddress, EFI_PAGE_SIZE * 4);
/* Fill the PDPT with pointers to the Page Directories */ /* Fill the PDPT with pointers to the Page Directories */
for(Index = 0; Index < 4; Index++) for(Index = 0; Index < 4; Index++)
{ {
RtlZeroMemory(&((PHARDWARE_PTE)PageMap->PtePointer)[Index], sizeof(HARDWARE_PTE)); RTL::Memory::ZeroMemory(&((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;
DirectoryAddress += EFI_PAGE_SIZE; DirectoryAddress += EFI_PAGE_SIZE;
} }
} }
else else
{ {
/* Allocate a page for the 2-level page map structure (PAE disabled) */ /* Allocate a page for the 2-level page map structure (PAE disabled) */
Status = BlAllocateMemoryPages(1, &Address); Status = AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failed, cannot proceed with page map creation */ /* Memory allocation failed, cannot proceed with page map creation */
@@ -79,19 +81,28 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
/* Assign the allocated page to the page map and zero it out */ /* 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); RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
} }
/* Add page mapping itself to memory mapping */ /* Add page mapping itself to memory mapping */
Status = BlpSelfMapPml(PageMap, SelfMapAddress); Status = SelfMapPml(PageMap, SelfMapAddress);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* PML mapping failed */ /* PML mapping failed */
return Status; return Status;
} }
/* Map the trampoline code area */
Status = MapVirtualMemory(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 = Protocol::GetModulesList();
ModulesListEntry = ModulesList->Flink; ModulesListEntry = ModulesList->Flink;
while(ModulesListEntry != ModulesList) while(ModulesListEntry != ModulesList)
{ {
@@ -99,7 +110,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink); ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
/* Map module code */ /* Map module code */
Status = BlMapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase, Status = MapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase,
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary); EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
/* Check if mapping succeeded */ /* Check if mapping succeeded */
@@ -113,12 +124,15 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
ModulesListEntry = ModulesListEntry->Flink; ModulesListEntry = ModulesListEntry->Flink;
} }
/* Get boot loader image information */
XtLoader::GetLoaderImageInformation(&LoaderBase, &LoaderSize);
/* Make sure boot loader image base and size are set */ /* Make sure boot loader image base and size are set */
if(BlpStatus.LoaderBase && BlpStatus.LoaderSize) if(LoaderBase && LoaderSize)
{ {
/* Map boot loader code as well */ /* Map boot loader code as well */
Status = BlMapVirtualMemory(PageMap, BlpStatus.LoaderBase, BlpStatus.LoaderBase, Status = MapVirtualMemory(PageMap, LoaderBase, LoaderBase,
EFI_SIZE_TO_PAGES(BlpStatus.LoaderSize), LoaderFirmwareTemporary); EFI_SIZE_TO_PAGES(LoaderSize), LoaderFirmwareTemporary);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Mapping boot loader code failed */ /* Mapping boot loader code failed */
@@ -132,7 +146,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
} }
/* Iterate through and map all the mappings*/ /* Iterate through and map all the mappings*/
BlDebugPrint(L"Mapping and dumping EFI memory:\n"); Debug::Print(L"Mapping and dumping EFI memory:\n");
ListEntry = PageMap->MemoryMap.Flink; ListEntry = PageMap->MemoryMap.Flink;
while(ListEntry != &PageMap->MemoryMap) while(ListEntry != &PageMap->MemoryMap)
{ {
@@ -143,11 +157,11 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
if(Mapping->VirtualAddress) if(Mapping->VirtualAddress)
{ {
/* Dump memory mapping */ /* Dump memory mapping */
BlDebugPrint(L" Type=%02lu, PhysicalBase=%.8P, VirtualBase=%.8P, Pages=%llu\n", Mapping->MemoryType, Debug::Print(L" Type=%02lu, PhysicalBase=%.8P, VirtualBase=%.8P, Pages=%llu\n", Mapping->MemoryType,
Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages); Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages);
/* Map memory */ /* Map memory */
Status = BlMapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress, Status = MapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress,
(UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages); (UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
@@ -164,116 +178,6 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
/**
* Does the actual virtual memory mapping.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @param VirtualAddress
* Supplies a virtual address of the mapping.
*
* @param PhysicalAddress
* Supplies a physical address of the mapping.
*
* @param NumberOfPages
* Supplies a number of the pages of the mapping.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR VirtualAddress,
IN ULONG_PTR PhysicalAddress,
IN ULONG NumberOfPages)
{
SIZE_T PageFrameNumber;
PVOID Pml1, Pml2, Pml3;
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry;
PHARDWARE_PTE PmlTable;
PHARDWARE_LEGACY_PTE LegacyPmlTable;
EFI_STATUS Status;
/* Set the Page Frame Number (PFN) */
PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT;
/* Map all requested pages */
while(NumberOfPages > 0)
{
/* Check the paging mode to use the correct page table structure */
if(PageMap->PageMapLevel == 3)
{
/* Calculate the indices for PAE page tables */
Pml3Entry = (VirtualAddress >> 30) & 0x3;
Pml2Entry = (VirtualAddress >> 21) & 0x1FF;
Pml1Entry = (VirtualAddress >> 12) & 0x1FF;
/* Get Page Directory Pointer Table (PML3) */
Pml3 = PageMap->PtePointer;
/* Get Page Directory (PML2) */
Status = BlpGetNextPageTable(PageMap, Pml3, Pml3Entry, &Pml2);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get the Page Table, abort mapping */
return Status;
}
/* 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 64-bit PTE entry */
PmlTable = (PHARDWARE_PTE)Pml1;
RtlZeroMemory(&PmlTable[Pml1Entry], sizeof(HARDWARE_PTE));
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 */
VirtualAddress += EFI_PAGE_SIZE;
PageFrameNumber++;
/* Decrease number of pages left */
NumberOfPages--;
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
/** /**
* Returns next level of the Page Table. * Returns next level of the Page Table.
* *
@@ -295,7 +199,7 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID PageTable, IN PVOID PageTable,
IN SIZE_T Entry, IN SIZE_T Entry,
OUT PVOID *NextPageTable) OUT PVOID *NextPageTable)
@@ -304,14 +208,14 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
ULONGLONG PmlPointer = 0; ULONGLONG PmlPointer = 0;
EFI_STATUS Status; EFI_STATUS Status;
PHARDWARE_LEGACY_PTE LegacyPmlTable; PHARDWARE_LEGACY_PTE LegacyPmlTable;
PHARDWARE_PTE PmlTable; PHARDWARE_MODERN_PTE PmlTable;
BOOLEAN ValidPte = FALSE; BOOLEAN ValidPte = FALSE;
/* Check page map level to determine PTE size */ /* Check page map level to determine PTE size */
if(PageMap->PageMapLevel >= 3) if(PageMap->PageMapLevel >= 3)
{ {
/* 64-bit PTE for PML3 (PAE enabled) */ /* 64-bit PTE for PML3 (PAE enabled) */
PmlTable = (PHARDWARE_PTE)PageTable; PmlTable = (PHARDWARE_MODERN_PTE)PageTable;
if(PmlTable[Entry].Valid) if(PmlTable[Entry].Valid)
{ {
/* Get page frame number from page table entry */ /* Get page frame number from page table entry */
@@ -340,7 +244,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
else else
{ {
/* Allocate pages for new PML entry */ /* Allocate pages for new PML entry */
Status = BlAllocateMemoryPages(1, &Address); Status = AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -348,7 +252,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
} }
/* Add new memory mapping */ /* Add new memory mapping */
Status = BlMapVirtualMemory(PageMap, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData); Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory mapping failure */ /* Memory mapping failure */
@@ -356,13 +260,13 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
} }
/* Fill allocated memory with zeros */ /* Fill allocated memory with zeros */
RtlZeroMemory((PVOID)(ULONGLONG)Address, EFI_PAGE_SIZE); RTL::Memory::ZeroMemory((PVOID)(ULONGLONG)Address, EFI_PAGE_SIZE);
/* Set paging entry settings based on level */ /* Set paging entry settings based on level */
if(PageMap->PageMapLevel >= 3) if(PageMap->PageMapLevel >= 3)
{ {
/* 64-bit PTE for PML3 (PAE enabled) */ /* 64-bit PTE for PML3 (PAE enabled) */
PmlTable = (PHARDWARE_PTE)PageTable; PmlTable = (PHARDWARE_MODERN_PTE)PageTable;
PmlTable[Entry].PageFrameNumber = Address / EFI_PAGE_SIZE; PmlTable[Entry].PageFrameNumber = Address / EFI_PAGE_SIZE;
PmlTable[Entry].Valid = 1; PmlTable[Entry].Valid = 1;
PmlTable[Entry].Writable = 1; PmlTable[Entry].Writable = 1;
@@ -387,6 +291,116 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
/**
* Does the actual virtual memory mapping.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @param VirtualAddress
* Supplies a virtual address of the mapping.
*
* @param PhysicalAddress
* Supplies a physical address of the mapping.
*
* @param NumberOfPages
* Supplies a number of the pages of the mapping.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
Memory::MapPage(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR VirtualAddress,
IN ULONG_PTR PhysicalAddress,
IN ULONG NumberOfPages)
{
SIZE_T PageFrameNumber;
PVOID Pml1, Pml2, Pml3;
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry;
PHARDWARE_LEGACY_PTE LegacyPmlTable;
PHARDWARE_MODERN_PTE PmlTable;
EFI_STATUS Status;
/* Set the Page Frame Number (PFN) */
PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT;
/* Map all requested pages */
while(NumberOfPages > 0)
{
/* Check the paging mode to use the correct page table structure */
if(PageMap->PageMapLevel == 3)
{
/* Calculate the indices for PAE page tables */
Pml3Entry = (VirtualAddress >> 30) & 0x3;
Pml2Entry = (VirtualAddress >> 21) & 0x1FF;
Pml1Entry = (VirtualAddress >> 12) & 0x1FF;
/* Get Page Directory Pointer Table (PML3) */
Pml3 = PageMap->PtePointer;
/* Get Page Directory (PML2) */
Status = GetNextPageTable(PageMap, Pml3, Pml3Entry, &Pml2);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get the Page Table, abort mapping */
return Status;
}
/* Get Page Table (PML1) */
Status = GetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get the Page Table, abort mapping */
return Status;
}
/* Set the 64-bit PTE entry */
PmlTable = (PHARDWARE_MODERN_PTE)Pml1;
RTL::Memory::ZeroMemory(&PmlTable[Pml1Entry], sizeof(HARDWARE_MODERN_PTE));
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 = GetNextPageTable(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;
RTL::Memory::ZeroMemory(&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 */
VirtualAddress += EFI_PAGE_SIZE;
PageFrameNumber++;
/* Decrease number of pages left */
NumberOfPages--;
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
/** /**
* Creates a recursive self mapping for all PML levels. * Creates a recursive self mapping for all PML levels.
* *
@@ -402,11 +416,11 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap, Memory::SelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress) IN ULONG_PTR SelfMapAddress)
{ {
PHARDWARE_LEGACY_PTE LegacyPml; PHARDWARE_LEGACY_PTE LegacyPml;
PHARDWARE_PTE Pml; PHARDWARE_MODERN_PTE Pml;
ULONGLONG PmlIndex; ULONGLONG PmlIndex;
ULONG Index; ULONG Index;
@@ -417,13 +431,13 @@ BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,
PmlIndex = (SelfMapAddress >> MM_PDI_SHIFT) & 0x1FF; PmlIndex = (SelfMapAddress >> MM_PDI_SHIFT) & 0x1FF;
/* Get Page Directory */ /* Get Page Directory */
Pml = (PHARDWARE_PTE)(((PHARDWARE_PTE)PageMap->PtePointer)[SelfMapAddress >> MM_PPI_SHIFT].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++)
{ {
RtlZeroMemory(&Pml[PmlIndex + Index], sizeof(HARDWARE_PTE)); RTL::Memory::ZeroMemory(&Pml[PmlIndex + Index], sizeof(HARDWARE_MODERN_PTE));
Pml[PmlIndex + Index].PageFrameNumber = ((PHARDWARE_PTE)PageMap->PtePointer)[Index].PageFrameNumber; 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;
} }
@@ -436,7 +450,7 @@ BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,
PmlIndex = (SelfMapAddress >> MM_PDI_LEGACY_SHIFT); PmlIndex = (SelfMapAddress >> MM_PDI_LEGACY_SHIFT);
/* Add self-mapping for PML2 (PAE disabled) */ /* Add self-mapping for PML2 (PAE disabled) */
RtlZeroMemory(&LegacyPml[PmlIndex], sizeof(HARDWARE_LEGACY_PTE)); RTL::Memory::ZeroMemory(&LegacyPml[PmlIndex], sizeof(HARDWARE_LEGACY_PTE));
LegacyPml[PmlIndex].PageFrameNumber = (UINT_PTR)PageMap->PtePointer / EFI_PAGE_SIZE; LegacyPml[PmlIndex].PageFrameNumber = (UINT_PTR)PageMap->PtePointer / EFI_PAGE_SIZE;
LegacyPml[PmlIndex].Valid = 1; LegacyPml[PmlIndex].Valid = 1;
LegacyPml[PmlIndex].Writable = 1; LegacyPml[PmlIndex].Writable = 1;

View File

@@ -1,12 +1,12 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/bootutil.c * FILE: xtldr/bootutil.cc
* DESCRIPTION: Helper functions used by the boot protocol during system startup * DESCRIPTION: Helper functions used by the boot protocol during system startup
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com> * DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/ */
#include <xtldr.h> #include <xtldr.hh>
/** /**
@@ -24,21 +24,21 @@
*/ */
XTCDECL XTCDECL
BOOLEAN BOOLEAN
BlGetBooleanParameter(IN CONST PWCHAR Parameters, BootUtils::GetBooleanParameter(IN PCWSTR Parameters,
IN CONST PWCHAR Needle) IN PCWSTR Needle)
{ {
PWCHAR CurrentPosition, TokenEnd, TokenStart; PCWSTR CurrentPosition, TokenEnd, TokenStart;
SIZE_T NeedleLength, TokenLength; SIZE_T NeedleLength, TokenLength;
/* Validate input data and ensure the option is not an empty string */ /* Validate input data and ensure the option is not an empty string */
if(Parameters == NULL || Needle == NULL || *Needle == L'\0') if(Parameters == NULLPTR || Needle == NULLPTR || *Needle == L'\0')
{ {
/* One of the parameters was invalid */ /* One of the parameters was invalid */
return FALSE; return FALSE;
} }
CurrentPosition = Parameters; CurrentPosition = Parameters;
NeedleLength = RtlWideStringLength(Needle, 0); NeedleLength = RTL::WideString::WideStringLength(Needle, 0);
/* Iterate through the entire parameters string */ /* Iterate through the entire parameters string */
while(*CurrentPosition != L'\0') while(*CurrentPosition != L'\0')
@@ -71,7 +71,7 @@ BlGetBooleanParameter(IN CONST PWCHAR Parameters,
if(TokenLength == NeedleLength) if(TokenLength == NeedleLength)
{ {
/* Length matches, compare the strings */ /* Length matches, compare the strings */
if(RtlCompareWideStringInsensitive(TokenStart, Needle, NeedleLength) == 0) if(RTL::WideString::CompareWideStringInsensitive(TokenStart, Needle, NeedleLength) == 0)
{ {
/* A match was found */ /* A match was found */
return TRUE; return TRUE;

1052
boot/xtldr/config.cc Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,12 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/console.c * FILE: xtldr/console.cc
* DESCRIPTION: EFI console support * DESCRIPTION: EFI console support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtldr.h> #include <xtldr.hh>
/** /**
@@ -21,19 +21,19 @@
*/ */
XTCDECL XTCDECL
VOID VOID
BlClearConsoleLine(IN ULONGLONG LineNo) Console::ClearLine(IN ULONGLONG LineNo)
{ {
UINT_PTR Index, ResX, ResY; UINT_PTR Index, ResX, ResY;
/* Query console mode */ /* Query console mode */
BlQueryConsoleMode(&ResX, &ResY); QueryMode(&ResX, &ResY);
/* Set cursor position and clear line */ /* Set cursor position and clear line */
BlSetCursorPosition(0, LineNo); SetCursorPosition(0, LineNo);
for(Index = 0; Index < ResX; Index++) for(Index = 0; Index < ResX; Index++)
{ {
/* Clear line */ /* Clear line */
BlConsoleWrite(L" "); Write(L" ");
} }
} }
@@ -46,10 +46,10 @@ BlClearConsoleLine(IN ULONGLONG LineNo)
*/ */
XTCDECL XTCDECL
VOID VOID
BlClearConsoleScreen() Console::ClearScreen()
{ {
/* Clear screen */ /* Clear screen */
EfiSystemTable->ConOut->ClearScreen(EfiSystemTable->ConOut); XtLoader::GetEfiSystemTable()->ConOut->ClearScreen(XtLoader::GetEfiSystemTable()->ConOut);
} }
/** /**
@@ -61,9 +61,9 @@ BlClearConsoleScreen()
*/ */
XTCDECL XTCDECL
VOID VOID
BlDisableConsoleCursor() Console::DisableCursor()
{ {
EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, FALSE); XtLoader::GetEfiSystemTable()->ConOut->EnableCursor(XtLoader::GetEfiSystemTable()->ConOut, FALSE);
} }
/** /**
@@ -75,9 +75,39 @@ BlDisableConsoleCursor()
*/ */
XTCDECL XTCDECL
VOID VOID
BlEnableConsoleCursor() Console::EnableCursor()
{ {
EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, TRUE); XtLoader::GetEfiSystemTable()->ConOut->EnableCursor(XtLoader::GetEfiSystemTable()->ConOut, TRUE);
}
/**
* This routine initializes the EFI console.
*
* @return This routine returns status code.
*
* @since XT 1.0
*/
XTCDECL
VOID
Console::InitializeConsole()
{
/* Clear console buffers */
XtLoader::GetEfiSystemTable()->ConIn->Reset(XtLoader::GetEfiSystemTable()->ConIn, TRUE);
XtLoader::GetEfiSystemTable()->ConOut->Reset(XtLoader::GetEfiSystemTable()->ConOut, TRUE);
XtLoader::GetEfiSystemTable()->StdErr->Reset(XtLoader::GetEfiSystemTable()->StdErr, TRUE);
/* Make sure that current console mode is 80x25 characters, as some broken EFI implementations might
* set different mode that do not fit on the screen, causing a text to be displayed offscreen */
if(XtLoader::GetEfiSystemTable()->ConOut->Mode->Mode != 0)
{
/* Set console mode to 0, which is standard, 80x25 text mode */
SetMode(0);
}
/* Clear screen and enable cursor */
SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
ClearScreen();
EnableCursor();
} }
/** /**
@@ -95,30 +125,30 @@ BlEnableConsoleCursor()
*/ */
XTCDECL XTCDECL
VOID VOID
BlConsolePrint(IN PUSHORT Format, Console::Print(IN PCWSTR Format,
IN ...) IN ...)
{ {
RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext; RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext;
VA_LIST Arguments; VA_LIST Arguments;
/* Initialise the print contexts */ /* Initialise the print contexts */
ConsolePrintContext.WriteWideCharacter = BlpConsolePutChar; ConsolePrintContext.WriteWideCharacter = PutChar;
SerialPrintContext.WriteWideCharacter = BlpDebugPutChar; SerialPrintContext.WriteWideCharacter = Debug::PutChar;
/* Initialise the va_list */ /* Initialise the va_list */
VA_START(Arguments, Format); VA_START(Arguments, Format);
/* Format and print the string to the stdout */ /* Format and print the string to the stdout */
RtlFormatWideString(&ConsolePrintContext, (PWCHAR)Format, Arguments); RTL::WideString::FormatWideString(&ConsolePrintContext, (PWCHAR)Format, Arguments);
/* Print to serial console only if not running under OVMF */ /* Print to serial console only if not running under OVMF */
if(RtlCompareWideString(EfiSystemTable->FirmwareVendor, L"EDK II", 6) != 0) if(RTL::WideString::CompareWideString(XtLoader::GetEfiSystemTable()->FirmwareVendor, L"EDK II", 6) != 0)
{ {
/* Check if debugging enabled and if EFI serial port is fully initialized */ /* Check if debugging enabled and if EFI serial port is fully initialized */
if(DEBUG && (BlpStatus.SerialPort.Flags & COMPORT_FLAG_INIT)) if(DEBUG && Debug::SerialPortReady())
{ {
/* Format and print the string to the serial console */ /* Format and print the string to the serial console */
RtlFormatWideString(&SerialPrintContext, (PWCHAR)Format, Arguments); RTL::WideString::FormatWideString(&SerialPrintContext, (PWCHAR)Format, Arguments);
} }
} }
@@ -127,50 +157,35 @@ BlConsolePrint(IN PUSHORT Format,
} }
/** /**
* Displays the string on the device at the current cursor location. * Writes a character to the default EFI console.
* *
* @param String * @param Character
* The string to be displayed. * The integer promotion of the character to be written.
* *
* @return This routine does not return any value. * @return This routine returns a status code.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
XTCDECL XTCDECL
VOID XTSTATUS
BlConsoleWrite(IN PUSHORT String) Console::PutChar(IN WCHAR Character)
{ {
EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, String); WCHAR Buffer[2];
}
/** /* Check if character is a newline ('\n') */
* This routine initializes the EFI console. if(Character == L'\n')
*
* @return This routine returns status code.
*
* @since XT 1.0
*/
XTCDECL
VOID
BlInitializeConsole()
{
/* Clear console buffers */
EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, TRUE);
EfiSystemTable->ConOut->Reset(EfiSystemTable->ConOut, TRUE);
EfiSystemTable->StdErr->Reset(EfiSystemTable->StdErr, TRUE);
/* Make sure that current console mode is 80x25 characters, as some broken EFI implementations might
* set different mode that do not fit on the screen, causing a text to be displayed offscreen */
if(EfiSystemTable->ConOut->Mode->Mode != 0)
{ {
/* Set console mode to 0, which is standard, 80x25 text mode */ /* Print carriage return ('\r') as well */
BlSetConsoleMode(0); PutChar(L'\r');
} }
/* Clear screen and enable cursor */ /* Write character to the screen console */
BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); Buffer[0] = Character;
BlClearConsoleScreen(); Buffer[1] = 0;
BlEnableConsoleCursor(); XtLoader::GetEfiSystemTable()->ConOut->OutputString(XtLoader::GetEfiSystemTable()->ConOut, Buffer);
/* Return success */
return STATUS_SUCCESS;
} }
/** /**
@@ -188,10 +203,11 @@ BlInitializeConsole()
*/ */
XTCDECL XTCDECL
VOID VOID
BlQueryConsoleMode(OUT PUINT_PTR ResX, Console::QueryMode(OUT PUINT_PTR ResX,
OUT PUINT_PTR ResY) OUT PUINT_PTR ResY)
{ {
EfiSystemTable->ConOut->QueryMode(EfiSystemTable->ConOut, EfiSystemTable->ConOut->Mode->Mode, ResX, ResY); XtLoader::GetEfiSystemTable()->ConOut->QueryMode(XtLoader::GetEfiSystemTable()->ConOut,
XtLoader::GetEfiSystemTable()->ConOut->Mode->Mode, ResX, ResY);
} }
/** /**
@@ -206,9 +222,9 @@ BlQueryConsoleMode(OUT PUINT_PTR ResX,
*/ */
XTCDECL XTCDECL
VOID VOID
BlReadKeyStroke(OUT PEFI_INPUT_KEY Key) Console::ReadKeyStroke(OUT PEFI_INPUT_KEY Key)
{ {
EfiSystemTable->ConIn->ReadKeyStroke(EfiSystemTable->ConIn, Key); XtLoader::GetEfiSystemTable()->ConIn->ReadKeyStroke(XtLoader::GetEfiSystemTable()->ConIn, Key);
} }
/** /**
@@ -220,9 +236,9 @@ BlReadKeyStroke(OUT PEFI_INPUT_KEY Key)
*/ */
XTCDECL XTCDECL
VOID VOID
BlResetConsoleInputBuffer() Console::ResetInputBuffer()
{ {
EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, FALSE); XtLoader::GetEfiSystemTable()->ConIn->Reset(XtLoader::GetEfiSystemTable()->ConIn, FALSE);
} }
/** /**
@@ -237,26 +253,9 @@ BlResetConsoleInputBuffer()
*/ */
XTCDECL XTCDECL
VOID VOID
BlSetConsoleAttributes(IN ULONGLONG Attributes) Console::SetAttributes(IN ULONGLONG Attributes)
{ {
EfiSystemTable->ConOut->SetAttribute(EfiSystemTable->ConOut, Attributes); XtLoader::GetEfiSystemTable()->ConOut->SetAttribute(XtLoader::GetEfiSystemTable()->ConOut, Attributes);
}
/**
* Sets the output console device to the requested mode.
*
* @param Mode
* Supplies a text mode number to set.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlSetConsoleMode(IN ULONGLONG Mode)
{
return EfiSystemTable->ConOut->SetMode(EfiSystemTable->ConOut, Mode);
} }
/** /**
@@ -274,40 +273,42 @@ BlSetConsoleMode(IN ULONGLONG Mode)
*/ */
XTCDECL XTCDECL
VOID VOID
BlSetCursorPosition(IN ULONGLONG PosX, Console::SetCursorPosition(IN ULONGLONG PosX,
IN ULONGLONG PosY) IN ULONGLONG PosY)
{ {
EfiSystemTable->ConOut->SetCursorPosition(EfiSystemTable->ConOut, PosX, PosY); XtLoader::GetEfiSystemTable()->ConOut->SetCursorPosition(XtLoader::GetEfiSystemTable()->ConOut, PosX, PosY);
} }
/** /**
* Writes a character to the default EFI console. * Sets the output console device to the requested mode.
* *
* @param Character * @param Mode
* The integer promotion of the character to be written. * Supplies a text mode number to set.
* *
* @return This routine returns a status code. * @return This routine returns a status code.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
XTCDECL XTCDECL
XTSTATUS EFI_STATUS
BlpConsolePutChar(IN USHORT Character) Console::SetMode(IN ULONGLONG Mode)
{ {
USHORT Buffer[2]; return XtLoader::GetEfiSystemTable()->ConOut->SetMode(XtLoader::GetEfiSystemTable()->ConOut, Mode);
}
/* Check if character is a newline ('\n') */
if(Character == L'\n') /**
{ * Displays the string on the device at the current cursor location.
/* Print carriage return ('\r') as well */ *
BlpConsolePutChar(L'\r'); * @param String
} * The string to be displayed.
*
/* Write character to the screen console */ * @return This routine does not return any value.
Buffer[0] = Character; *
Buffer[1] = 0; * @since XT 1.0
EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, Buffer); */
XTCDECL
/* Return success */ VOID
return STATUS_SUCCESS; Console::Write(IN PCWSTR String)
{
XtLoader::GetEfiSystemTable()->ConOut->OutputString(XtLoader::GetEfiSystemTable()->ConOut, (PWSTR)String);
} }

60
boot/xtldr/data.cc Normal file
View File

@@ -0,0 +1,60 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/data.cc
* DESCRIPTION: XT Boot Loader global and static data
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/
#include <xtldr.hh>
/* XT Boot Loader menu list */
PLIST_ENTRY Configuration::BootMenuList = NULLPTR;
/* XT Boot Loader configuration list */
LIST_ENTRY Configuration::Config;
/* XT Boot Loader loaded configuration */
LIST_ENTRY Configuration::ConfigSections;
/* List of user-editable boot options */
PCWSTR Configuration::EditableConfigOptions[] = {
L"BootModules", L"SystemType", L"SystemPath",
L"KernelFile", L"InitrdFile", L"HalFile",
L"Parameters", NULLPTR
};
/* XT Boot Loader serial ports list */
ULONG Debug::ComPortList[COMPORT_COUNT] = COMPORT_ADDRESS;
/* A list of enabled debug ports */
ULONG Debug::EnabledDebugPorts;
/* XT Boot Loader serial port handle */
CPPORT Debug::SerialPort;
/* XT Boot Loader registered boot protocol list */
LIST_ENTRY Protocol::BootProtocols;
/* XT Boot Loader protocol */
XTBL_LOADER_PROTOCOL Protocol::LoaderProtocol;
/* XT Boot Loader loaded modules list */
LIST_ENTRY Protocol::LoadedModules;
/* List of available block devices */
LIST_ENTRY Volume::EfiBlockDevices;
/* Pointer to the boot menu callback routine */
PBL_XT_BOOT_MENU XtLoader::BootMenu = NULLPTR;
/* EFI Image Handle */
EFI_HANDLE XtLoader::EfiImageHandle;
/* EFI System Table */
PEFI_SYSTEM_TABLE XtLoader::EfiSystemTable;
/* XT Boot Loader status data */
XTBL_STATUS XtLoader::LoaderStatus = {0};

402
boot/xtldr/debug.cc Normal file
View File

@@ -0,0 +1,402 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/debug.cc
* DESCRIPTION: XT Boot Loader debugging support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtldr.hh>
/**
* Enables I/O space access to all serial controllers found on the PCI(E) root bridge.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
Debug::ActivateSerialIOController()
{
EFI_GUID PciGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL PciDev;
USHORT Bus, Device, Function, Command;
UINT_PTR Index, PciHandleSize;
PEFI_HANDLE PciHandle = NULLPTR;
PCI_COMMON_HEADER PciHeader;
EFI_STATUS Status;
ULONGLONG Address;
/* Allocate memory for single EFI_HANDLE, what should be enough in most cases */
PciHandleSize = sizeof(EFI_HANDLE);
Status = Memory::AllocatePool(PciHandleSize, (PVOID*)&PciHandle);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
return Status;
}
/* Get all instances of PciRootBridgeIo */
Status = XtLoader::GetEfiSystemTable()->BootServices->LocateHandle(ByProtocol, &PciGuid, NULLPTR,
&PciHandleSize, PciHandle);
if(Status == STATUS_EFI_BUFFER_TOO_SMALL)
{
/* Reallocate more memory as requested by UEFI */
Memory::FreePool(PciHandle);
Status = Memory::AllocatePool(PciHandleSize, (PVOID*)&PciHandle);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory reallocation failure */
return Status;
}
/* Second attempt to get instances of PciRootBridgeIo */
Status = XtLoader::GetEfiSystemTable()->BootServices->LocateHandle(ByProtocol, &PciGuid, NULLPTR,
&PciHandleSize, PciHandle);
}
/* Make sure successfully obtained PciRootBridgeIo instances */
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get PciRootBridgeIo instances */
return Status;
}
/* Enumerate all devices for each handle, which decides a segment and a bus number range */
for(Index = 0; Index < (PciHandleSize / sizeof(EFI_HANDLE)); Index++)
{
/* Get inferface from the protocol */
Status = XtLoader::GetEfiSystemTable()->BootServices->HandleProtocol(PciHandle[Index], &PciGuid, (PVOID*)&PciDev);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get interface */
return Status;
}
/* Enumerate whole PCI bridge */
for(Bus = 0; Bus <= PCI_MAX_BRIDGE_NUMBER; Bus++)
{
/* Enumerate all devices for each bus */
for(Device = 0; Device < PCI_MAX_DEVICES; Device++)
{
/* Enumerate all functions for each devices */
for(Function = 0; Function < PCI_MAX_FUNCTION; Function++)
{
/* Read configuration space */
Address = ((ULONGLONG)((((UINT_PTR) Bus) << 24) + (((UINT_PTR) Device) << 16) +
(((UINT_PTR) Function) << 8) + ((UINT_PTR) 0)));
PciDev->Pci.Read(PciDev, EfiPciIoWidthUint32, Address, sizeof (PciHeader) / sizeof (UINT), &PciHeader);
/* Check if device exists */
if(PciHeader.VendorId == PCI_INVALID_VENDORID)
{
/* Skip non-existen device */
continue;
}
/* Check if device is serial controller or multiport serial controller */
if(PciHeader.BaseClass == 0x07 && (PciHeader.SubClass == 0x00 || PciHeader.SubClass == 0x02))
{
/* Enable I/O space access */
Address |= 0x4;
Command = PCI_ENABLE_IO_SPACE;
Status = PciDev->Pci.Write(PciDev, EfiPciIoWidthUint16, Address, 1, &Command);
}
}
}
}
}
/* Return SUCCESS */
return STATUS_EFI_SUCCESS;
}
/**
* This routine initializes the XTLDR debug console.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
Debug::InitializeDebugConsole()
{
ULONG PortAddress, PortNumber, BaudRate;
PWCHAR DebugConfiguration, DebugPort, LastPort;
EFI_STATUS Status;
/* Set default serial port options */
PortAddress = 0;
PortNumber = 0;
BaudRate = 0;
/* Get debug configuration */
Configuration::GetValue(L"DEBUG", &DebugConfiguration);
/* Make sure any debug options are provided and debug console is not initialized yet */
if(DebugConfiguration && EnabledDebugPorts == 0)
{
/* Find all debug ports */
DebugPort = RTL::WideString::TokenizeWideString(DebugConfiguration, L";", &LastPort);
/* Iterate over all debug ports */
while(DebugPort != NULLPTR)
{
/* Check what port is set for debugging */
if(RTL::WideString::CompareWideStringInsensitive(DebugPort, L"COM", 3) == 0)
{
/* Read COM port number */
DebugPort += 3;
while(*DebugPort >= '0' && *DebugPort <= '9')
{
/* Get port number */
PortNumber *= 10;
PortNumber += *DebugPort - '0';
DebugPort++;
}
/* Check if custom COM port address supplied */
if(PortNumber == 0 && RTL::WideString::CompareWideStringInsensitive(DebugPort, L":0x", 3) == 0)
{
/* COM port address provided */
DebugPort += 3;
while((*DebugPort >= '0' && *DebugPort <= '9') ||
(*DebugPort >= 'A' && *DebugPort <= 'F') ||
(*DebugPort >= 'a' && *DebugPort <= 'f'))
{
/* Get port address */
PortAddress *= 16;
if(*DebugPort >= '0' && *DebugPort <= '9')
{
PortAddress += *DebugPort - '0';
}
else if(*DebugPort >= 'A' && *DebugPort <= 'F')
{
PortAddress += *DebugPort - 'A' + 10;
}
else if(*DebugPort >= 'a' && *DebugPort <= 'f')
{
PortAddress += *DebugPort - 'a' + 10;
}
DebugPort++;
}
}
/* Look for additional COM port parameters */
if(*DebugPort == ',')
{
/* Baud rate provided */
DebugPort++;
while(*DebugPort >= '0' && *DebugPort <= '9')
{
/* Get baud rate */
BaudRate *= 10;
BaudRate += *DebugPort - '0';
DebugPort++;
}
}
/* Enable debug port */
EnabledDebugPorts |= XTBL_DEBUGPORT_SERIAL;
}
else if(RTL::WideString::CompareWideStringInsensitive(DebugPort, L"SCREEN", 5) == 0)
{
/* Enable debug port */
EnabledDebugPorts |= XTBL_DEBUGPORT_SCREEN;
}
else
{
/* Unsupported debug port specified */
Console::Print(L"ERROR: Unsupported debug port ('%S') specified\n", DebugPort);
EfiUtils::SleepExecution(3000);
}
/* Take next debug port */
DebugPort = RTL::WideString::TokenizeWideString(NULLPTR, L";", &LastPort);
}
/* Check if serial debug port is enabled */
if(EnabledDebugPorts & XTBL_DEBUGPORT_SERIAL)
{
/* Try to initialize COM port */
Status = InitializeSerialPort(PortNumber, PortAddress, BaudRate);
if(Status != STATUS_EFI_SUCCESS)
{
/* Remove serial debug port, as COM port initialization failed and return */
EnabledDebugPorts &= ~XTBL_DEBUGPORT_SERIAL;
return Status;
}
}
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
/**
* This routine initializes the serial debug console.
*
* @param PortNumber
* Supplies a port number.
*
* @param PortAddress
* Supplies an address of the COM port.
*
* @param BaudRate
* Supplies an optional port baud rate.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
Debug::InitializeSerialPort(IN ULONG PortNumber,
IN ULONG PortAddress,
IN ULONG BaudRate)
{
EFI_STATUS EfiStatus;
XTSTATUS Status;
/* Check if custom COM port address supplied */
if(!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 = ComPortList[PortNumber - 1];
Console::Print(L"Initializing serial console at port COM%d\n", PortNumber);
}
else
{
/* Custom port address supplied, print debug message */
Console::Print(L"Initializing serial console at COM port address: 0x%lX\n", PortAddress);
}
/* Initialize COM port */
Status = HL::ComPort::InitializeComPort(&SerialPort, (PUCHAR)UlongToPtr(PortAddress), BaudRate);
/* Port not found under supplied address */
if(Status == STATUS_NOT_FOUND && PortAddress)
{
/* This might be PCI(E) serial controller, try to activate I/O space access first */
EfiStatus = ActivateSerialIOController();
if(EfiStatus == STATUS_EFI_SUCCESS)
{
/* Try to reinitialize COM port */
Console::Print(L"Enabled I/O space access for all PCI(E) serial controllers found\n");
Status = HL::ComPort::InitializeComPort(&SerialPort, (PUCHAR)UlongToPtr(PortAddress), BaudRate);
}
}
/* Check COM port initialization status code */
if(Status != STATUS_SUCCESS)
{
/* Serial port initialization failed, mark as not ready */
return STATUS_EFI_NOT_READY;
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
/**
* This routine formats the input string and prints it out to the debug ports.
*
* @param Format
* The formatted string that is to be written to the output.
*
* @param ...
* Depending on the format string, this routine might expect a sequence of additional arguments.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
Debug::Print(IN PCWSTR Format,
IN ...)
{
RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext;
VA_LIST Arguments;
/* Check if debugging enabled and if EFI serial port is fully initialized */
if(DEBUG)
{
/* Initialize the print contexts */
ConsolePrintContext.WriteWideCharacter = Console::PutChar;
SerialPrintContext.WriteWideCharacter = PutChar;
/* Initialise the va_list */
VA_START(Arguments, Format);
/* Check if serial debug port is enabled */
if((EnabledDebugPorts & XTBL_DEBUGPORT_SERIAL) && (SerialPort.Flags & COMPORT_FLAG_INIT))
{
/* Format and print the string to the serial console */
RTL::WideString::FormatWideString(&SerialPrintContext, (PWCHAR)Format, Arguments);
}
/* Check if screen debug port is enabled and Boot Services are still available */
if((EnabledDebugPorts & XTBL_DEBUGPORT_SCREEN) && (XtLoader::GetBootServicesStatus() == TRUE))
{
/* Format and print the string to the screen */
RTL::WideString::FormatWideString(&ConsolePrintContext, (PWCHAR)Format, Arguments);
}
/* Clean up the va_list */
VA_END(Arguments);
}
}
/**
* Writes a character to the serial console.
*
* @param Character
* The integer promotion of the character to be written.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
XTSTATUS
Debug::PutChar(IN WCHAR Character)
{
WCHAR Buffer[2];
/* Write character to the serial console */
Buffer[0] = Character;
Buffer[1] = 0;
return HL::ComPort::WriteComPort(&SerialPort, Buffer[0]);
}
/**
* Determines if the serial port has been successfully initialized and is ready for communication.
*
* @return This routine returns TRUE if the serial port is initialized and ready, FALSE otherwise.
*
* @since XT 1.0
*/
XTCDECL
BOOLEAN
Debug::SerialPortReady()
{
return (SerialPort.Flags & COMPORT_FLAG_INIT);
}

View File

@@ -1,12 +1,12 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/efiutils.c * FILE: xtldr/efiutils.cc
* DESCRIPTION: EFI related routines for XT Boot Loader * DESCRIPTION: EFI related routines for XT Boot Loader
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtldr.h> #include <xtldr.hh>
/** /**
@@ -18,29 +18,35 @@
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlEnterFirmwareSetup() EfiUtils::EnterFirmwareSetup()
{ {
EFI_GUID Guid = EFI_GLOBAL_VARIABLE_GUID; EFI_GUID Guid = EFI_GLOBAL_VARIABLE_GUID;
PULONGLONG SetupSupport; PULONGLONG SetupSupport = NULLPTR;
ULONGLONG Indications; ULONGLONG Indications;
EFI_STATUS Status; EFI_STATUS Status;
/* Check if booting into firmware interface is supported */ /* Check if booting into firmware interface is supported */
Status = BlGetEfiVariable(&Guid, L"OsIndicationsSupported", (PVOID*)&SetupSupport); Status = GetEfiVariable(&Guid, L"OsIndicationsSupported", (PVOID*)&SetupSupport);
if(Status != STATUS_EFI_SUCCESS || !(*SetupSupport & EFI_OS_INDICATIONS_BOOT_TO_FW_UI)) if(Status != STATUS_EFI_SUCCESS || !(*SetupSupport & EFI_OS_INDICATIONS_BOOT_TO_FW_UI))
{ {
/* Reboot into firmware setup is not supported */ /* Reboot into firmware setup is not supported */
BlDebugPrint(L"WARNING: Reboot into firmware setup interface not supported\n"); Debug::Print(L"WARNING: Reboot into firmware setup interface not supported\n");
if(SetupSupport)
{
Memory::FreePool((PVOID)SetupSupport);
}
return STATUS_EFI_UNSUPPORTED; return STATUS_EFI_UNSUPPORTED;
} }
Memory::FreePool((PVOID)SetupSupport);
/* Get the value of OsIndications variable */ /* Get the value of OsIndications variable */
Indications = 0; Indications = 0;
Status = BlGetEfiVariable(&Guid, L"OsIndications", (PVOID)&Indications); Status = GetEfiVariable(&Guid, L"OsIndications", (PVOID*)&Indications);
/* Enable FW setup on next boot */ /* Enable FW setup on next boot */
Indications |= EFI_OS_INDICATIONS_BOOT_TO_FW_UI; Indications |= EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
Status = BlSetEfiVariable(&Guid, L"OsIndications", (PVOID)&Indications, sizeof(Indications)); Status = SetEfiVariable(&Guid, L"OsIndications", (PVOID)&Indications, sizeof(Indications));
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to update OsIndications variable */ /* Failed to update OsIndications variable */
@@ -48,7 +54,7 @@ BlEnterFirmwareSetup()
} }
/* Reboot into firmware setup */ /* Reboot into firmware setup */
BlRebootSystem(); RebootSystem();
/* Must not reach this point, just make the compiler happy */ /* Must not reach this point, just make the compiler happy */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
@@ -63,33 +69,33 @@ BlEnterFirmwareSetup()
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlExitBootServices() EfiUtils::ExitBootServices()
{ {
PEFI_MEMORY_MAP MemoryMap; PEFI_MEMORY_MAP MemoryMap;
EFI_STATUS Status; EFI_STATUS Status;
ULONG Counter; ULONG Counter;
/* Boot Services might be partially shutdown, so mark them as unavailable */ /* Boot Services might be partially shutdown, so mark them as unavailable */
BlpStatus.BootServices = FALSE; XtLoader::DisableBootServices();
/* Allocate buffer for EFI memory map */ /* Allocate buffer for EFI memory map */
Status = BlAllocateMemoryPool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap); Status = Memory::AllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status);
return Status; return Status;
} }
/* Zero fill the buffer and initialize counter */ /* Zero fill the buffer and initialize counter */
RtlZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP)); RTL::Memory::ZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP));
Counter = 0xFF; Counter = 0xFF;
/* Attempt to exit boot services */ /* Attempt to exit boot services */
while(Counter > 0) while(Counter > 0)
{ {
/* Get memory map each time as it can change between two calls */ /* Get memory map each time as it can change between two calls */
Status = BlGetMemoryMap(MemoryMap); Status = Memory::GetMemoryMap(MemoryMap);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to get new memory map */ /* Failed to get new memory map */
@@ -97,7 +103,8 @@ BlExitBootServices()
} }
/* Exit boot services */ /* Exit boot services */
Status = EfiSystemTable->BootServices->ExitBootServices(EfiImageHandle, MemoryMap->MapKey); Status = XtLoader::GetEfiSystemTable()->BootServices->ExitBootServices(XtLoader::GetEfiImageHandle(),
MemoryMap->MapKey);
if(Status == STATUS_EFI_SUCCESS) if(Status == STATUS_EFI_SUCCESS)
{ {
break; break;
@@ -126,25 +133,26 @@ BlExitBootServices()
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlGetConfigurationTable(IN PEFI_GUID TableGuid, EfiUtils::GetConfigurationTable(IN PEFI_GUID TableGuid,
OUT PVOID *Table) OUT PVOID *Table)
{ {
SIZE_T Index; SIZE_T Index;
/* Iterate through all system configuration tables */ /* Iterate through all system configuration tables */
for(Index = 0; Index < EfiSystemTable->NumberOfTableEntries; Index++) for(Index = 0; Index < XtLoader::GetEfiSystemTable()->NumberOfTableEntries; Index++)
{ {
/* Check if this table matches requested table */ /* Check if this table matches requested table */
if(RtlCompareGuids((PGUID)&(EfiSystemTable->ConfigurationTable[Index].VendorGuid), (PGUID)TableGuid)) if(RTL::Guid::CompareGuids((PGUID)&(XtLoader::GetEfiSystemTable()->ConfigurationTable[Index].VendorGuid),
(PGUID)TableGuid))
{ {
/* Found requested table, return success */ /* Found requested table, return success */
*Table = EfiSystemTable->ConfigurationTable[Index].VendorTable; *Table = XtLoader::GetEfiSystemTable()->ConfigurationTable[Index].VendorTable;
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
} }
/* Table not found */ /* Table not found */
*Table = NULL; *Table = NULLPTR;
return STATUS_EFI_NOT_FOUND; return STATUS_EFI_NOT_FOUND;
} }
@@ -166,17 +174,17 @@ BlGetConfigurationTable(IN PEFI_GUID TableGuid,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlGetEfiVariable(IN PEFI_GUID Vendor, EfiUtils::GetEfiVariable(IN PEFI_GUID Vendor,
IN PWCHAR VariableName, IN PCWSTR VariableName,
OUT PVOID *VariableValue) OUT PVOID *VariableValue)
{ {
EFI_STATUS Status; EFI_STATUS Status;
PVOID Buffer; PVOID Buffer;
UINT_PTR Size; UINT_PTR Size = 0;
/* Allocate a buffer for storing a variable's value */ /* Allocate a buffer for storing a variable's value */
Size = EFI_MAXIMUM_VARIABLE_SIZE * sizeof(PWCHAR); Size = EFI_MAXIMUM_VARIABLE_SIZE * sizeof(PWCHAR);
Status = BlAllocateMemoryPool(Size, (PVOID*)&Buffer); Status = Memory::AllocatePool(Size, (PVOID*)&Buffer);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -184,7 +192,8 @@ BlGetEfiVariable(IN PEFI_GUID Vendor,
} }
/* Attempt to get variable value */ /* Attempt to get variable value */
Status = EfiSystemTable->RuntimeServices->GetVariable(VariableName, Vendor, NULL, &Size, Buffer); Status = XtLoader::GetEfiSystemTable()->RuntimeServices->GetVariable((PWCHAR)VariableName, Vendor, NULLPTR,
&Size, Buffer);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to get variable, probably not found such one */ /* Failed to get variable, probably not found such one */
@@ -210,7 +219,7 @@ BlGetEfiVariable(IN PEFI_GUID Vendor,
*/ */
XTCDECL XTCDECL
ULONGLONG ULONGLONG
BlGetRandomValue(IN OUT PULONGLONG RNGBuffer) EfiUtils::GetRandomValue(IN OUT PULONGLONG RNGBuffer)
{ {
/* Recalculate RNG buffer with XORSHIFT */ /* Recalculate RNG buffer with XORSHIFT */
*RNGBuffer ^= *RNGBuffer >> 12; *RNGBuffer ^= *RNGBuffer >> 12;
@@ -230,21 +239,21 @@ BlGetRandomValue(IN OUT PULONGLONG RNGBuffer)
*/ */
XTCDECL XTCDECL
INT_PTR INT_PTR
BlGetSecureBootStatus() EfiUtils::GetSecureBootStatus()
{ {
EFI_GUID VarGuid = EFI_GLOBAL_VARIABLE_GUID; EFI_GUID VarGuid = EFI_GLOBAL_VARIABLE_GUID;
INT_PTR SecureBootStatus = 0; INT_PTR SecureBootStatus = 0;
UCHAR VarValue = 0; INT_PTR VarValue = 0;
UINT_PTR Size; UINT_PTR Size;
Size = sizeof(VarValue); Size = sizeof(INT_PTR);
if(EfiSystemTable->RuntimeServices->GetVariable(L"SecureBoot", &VarGuid, if(XtLoader::GetEfiSystemTable()->RuntimeServices->GetVariable((PWCHAR)L"SecureBoot", &VarGuid,
NULL, &Size, &VarValue) == STATUS_EFI_SUCCESS) NULLPTR, &Size, &VarValue) == STATUS_EFI_SUCCESS)
{ {
SecureBootStatus = (INT_PTR)VarValue; SecureBootStatus = VarValue;
Size = sizeof(INT_PTR);
if((EfiSystemTable->RuntimeServices->GetVariable(L"SetupMode", &VarGuid, if((XtLoader::GetEfiSystemTable()->RuntimeServices->GetVariable((PWCHAR)L"SetupMode", &VarGuid,
NULL, &Size, &VarValue) == STATUS_EFI_SUCCESS) && VarValue != 0) NULLPTR, &Size, &VarValue) == STATUS_EFI_SUCCESS) && VarValue != 0)
{ {
SecureBootStatus = -1; SecureBootStatus = -1;
} }
@@ -266,7 +275,7 @@ BlGetSecureBootStatus()
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlInitializeEntropy(PULONGLONG RNGBuffer) EfiUtils::InitializeEntropy(PULONGLONG RNGBuffer)
{ {
EFI_GUID RngGuid = EFI_RNG_PROTOCOL_GUID; EFI_GUID RngGuid = EFI_RNG_PROTOCOL_GUID;
PEFI_RNG_PROTOCOL Rng; PEFI_RNG_PROTOCOL Rng;
@@ -274,11 +283,11 @@ BlInitializeEntropy(PULONGLONG RNGBuffer)
ULONGLONG Seed; ULONGLONG Seed;
/* Initialize variables */ /* Initialize variables */
Rng = NULL; Rng = NULLPTR;
Seed = 0; Seed = 0;
/* Locate RNG protocol */ /* Locate RNG protocol */
Status = EfiSystemTable->BootServices->LocateProtocol(&RngGuid, NULL, (PVOID *)&Rng); Status = XtLoader::GetEfiSystemTable()->BootServices->LocateProtocol(&RngGuid, NULLPTR, (PVOID *)&Rng);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to locate RNG protocol, return status code */ /* Failed to locate RNG protocol, return status code */
@@ -286,7 +295,7 @@ BlInitializeEntropy(PULONGLONG RNGBuffer)
} }
/* Get RNG value using the default algorithm */ /* Get RNG value using the default algorithm */
Status = Rng->GetRNG(Rng, NULL, 8, (PUCHAR)&Seed); Status = Rng->GetRNG(Rng, NULLPTR, 8, (PUCHAR)&Seed);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to get RNG value, return status code */ /* Failed to get RNG value, return status code */
@@ -319,13 +328,14 @@ BlInitializeEntropy(PULONGLONG RNGBuffer)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlLoadEfiImage(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, EfiUtils::LoadEfiImage(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
IN PVOID ImageData, IN PVOID ImageData,
IN SIZE_T ImageSize, IN SIZE_T ImageSize,
OUT PEFI_HANDLE ImageHandle) OUT PEFI_HANDLE ImageHandle)
{ {
/* Load EFI image */ /* Load EFI image */
return EfiSystemTable->BootServices->LoadImage(FALSE, EfiImageHandle, DevicePath, ImageData, ImageSize, ImageHandle); return XtLoader::GetEfiSystemTable()->BootServices->LoadImage(FALSE, XtLoader::GetEfiImageHandle(), DevicePath,
ImageData, ImageSize, ImageHandle);
} }
/** /**
@@ -337,10 +347,10 @@ BlLoadEfiImage(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlRebootSystem() EfiUtils::RebootSystem()
{ {
/* Reboot machine */ /* Reboot machine */
return EfiSystemTable->RuntimeServices->ResetSystem(EfiResetCold, STATUS_EFI_SUCCESS, 0, NULL); return XtLoader::GetEfiSystemTable()->RuntimeServices->ResetSystem(EfiResetCold, STATUS_EFI_SUCCESS, 0, NULLPTR);
} }
/** /**
@@ -364,8 +374,8 @@ BlRebootSystem()
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlSetEfiVariable(IN PEFI_GUID Vendor, EfiUtils::SetEfiVariable(IN PEFI_GUID Vendor,
IN PWCHAR VariableName, IN PCWSTR VariableName,
IN PVOID VariableValue, IN PVOID VariableValue,
IN UINT_PTR Size) IN UINT_PTR Size)
{ {
@@ -373,7 +383,8 @@ BlSetEfiVariable(IN PEFI_GUID Vendor,
/* Set EFI variable */ /* Set EFI variable */
Attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS; Attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
return EfiSystemTable->RuntimeServices->SetVariable(VariableName, Vendor, Attributes, Size, VariableValue); return XtLoader::GetEfiSystemTable()->RuntimeServices->SetVariable((PWCHAR)VariableName, Vendor, Attributes,
Size, VariableValue);
} }
/** /**
@@ -385,10 +396,10 @@ BlSetEfiVariable(IN PEFI_GUID Vendor,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlShutdownSystem() EfiUtils::ShutdownSystem()
{ {
/* Shutdown machine */ /* Shutdown machine */
return EfiSystemTable->RuntimeServices->ResetSystem(EfiResetShutdown, STATUS_EFI_SUCCESS, 0, NULL); return XtLoader::GetEfiSystemTable()->RuntimeServices->ResetSystem(EfiResetShutdown, STATUS_EFI_SUCCESS, 0, NULLPTR);
} }
/** /**
@@ -403,9 +414,9 @@ BlShutdownSystem()
*/ */
XTCDECL XTCDECL
VOID VOID
BlSleepExecution(IN ULONG_PTR Milliseconds) EfiUtils::SleepExecution(IN ULONG_PTR Milliseconds)
{ {
EfiSystemTable->BootServices->Stall(Milliseconds * 1000); XtLoader::GetEfiSystemTable()->BootServices->Stall(Milliseconds * 1000);
} }
/** /**
@@ -420,9 +431,9 @@ BlSleepExecution(IN ULONG_PTR Milliseconds)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlStartEfiImage(IN EFI_HANDLE ImageHandle) EfiUtils::StartEfiImage(IN EFI_HANDLE ImageHandle)
{ {
return EfiSystemTable->BootServices->StartImage(ImageHandle, NULL, NULL); return XtLoader::GetEfiSystemTable()->BootServices->StartImage(ImageHandle, NULLPTR, NULLPTR);
} }
/** /**
@@ -443,9 +454,9 @@ BlStartEfiImage(IN EFI_HANDLE ImageHandle)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlWaitForEfiEvent(IN UINT_PTR NumberOfEvents, EfiUtils::WaitForEfiEvent(IN UINT_PTR NumberOfEvents,
IN PEFI_EVENT Event, IN PEFI_EVENT Event,
OUT PUINT_PTR Index) OUT PUINT_PTR Index)
{ {
return EfiSystemTable->BootServices->WaitForEvent(NumberOfEvents, Event, Index); return XtLoader::GetEfiSystemTable()->BootServices->WaitForEvent(NumberOfEvents, Event, Index);
} }

View File

@@ -0,0 +1,142 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/includes/libxtos.hh
* DESCRIPTION: XT Loader to LIBXTOS interface
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTLDR_LIBXTOS_HH
#define __XTLDR_LIBXTOS_HH
#include <xtblapi.h>
/* Minimal forward references for AR classes used by XTLDR */
namespace AR
{
class CpuFunc
{
public:
STATIC XTCDECL BOOLEAN CpuId(IN OUT PCPUID_REGISTERS Registers);
STATIC XTCDECL ULONG_PTR ReadControlRegister(IN USHORT ControlRegister);
STATIC XTCDECL ULONGLONG ReadModelSpecificRegister(IN ULONG Register);
STATIC XTCDECL VOID WriteControlRegister(IN USHORT ControlRegister,
IN UINT_PTR Value);
};
class ProcSup
{
public:
STATIC XTAPI VOID GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
OUT PVOID *TrampolineCode,
OUT PULONG_PTR TrampolineSize);
};
}
/* Minimal forward references for HL classes used by XTLDR */
namespace HL
{
class ComPort
{
public:
STATIC XTCDECL XTSTATUS InitializeComPort(IN OUT PCPPORT Port,
IN PUCHAR PortAddress,
IN ULONG BaudRate);
STATIC XTCDECL XTSTATUS WriteComPort(IN PCPPORT Port,
IN UCHAR Byte);
};
class IoPort
{
public:
STATIC XTCDECL UCHAR ReadPort8(IN USHORT Port);
STATIC XTCDECL USHORT ReadPort16(IN USHORT Port);
STATIC XTCDECL ULONG ReadPort32(IN USHORT Port);
STATIC XTCDECL VOID WritePort8(IN USHORT Port,
IN UCHAR Value);
STATIC XTCDECL VOID WritePort16(IN USHORT Port,
IN USHORT Value);
STATIC XTCDECL VOID WritePort32(IN USHORT Port,
IN ULONG Value);
};
}
/* Minimal forward references for RTL classes used by XTLDR */
namespace RTL
{
class Guid
{
public:
STATIC XTAPI BOOLEAN CompareGuids(IN PGUID Guid1,
IN PGUID Guid2);
};
class LinkedList
{
public:
STATIC XTCDECL VOID InitializeListHead(IN PLIST_ENTRY ListHead);
STATIC XTCDECL VOID InsertHeadList(IN OUT PLIST_ENTRY ListHead,
IN PLIST_ENTRY Entry);
STATIC XTCDECL VOID InsertTailList(IN OUT PLIST_ENTRY ListHead,
IN PLIST_ENTRY Entry);
STATIC XTCDECL VOID RemoveEntryList(IN PLIST_ENTRY Entry);
};
class Memory
{
public:
STATIC XTAPI SIZE_T CompareMemory(IN PCVOID LeftBuffer,
IN PCVOID RightBuffer,
IN SIZE_T Length);
STATIC XTAPI VOID CopyMemory(OUT PVOID Destination,
IN PCVOID Source,
IN SIZE_T Length);
STATIC XTAPI VOID MoveMemory(OUT PVOID Destination,
IN PCVOID Source,
IN SIZE_T Length);
STATIC XTAPI VOID SetMemory(OUT PVOID Destination,
IN UCHAR Byte,
IN SIZE_T Length);
STATIC XTAPI VOID ZeroMemory(OUT PVOID Destination,
IN SIZE_T Length);
};
class String
{
public:
STATIC XTAPI SIZE_T CompareString(IN PCSTR String1,
IN PCSTR String2,
IN SIZE_T Length);
STATIC XTAPI SIZE_T StringLength(IN PCSTR String,
IN SIZE_T MaxLength);
STATIC XTAPI SIZE_T StringToWideString(OUT PWCHAR Destination,
IN PCSTR *Source,
IN SIZE_T Length);
STATIC XTAPI PCHAR TrimString(IN PCHAR String);
};
class WideString
{
public:
STATIC XTAPI SIZE_T CompareWideString(IN PCWSTR String1,
IN PCWSTR String2,
IN SIZE_T Length);
STATIC XTAPI SIZE_T CompareWideStringInsensitive(IN PCWSTR String1,
IN PCWSTR String2,
IN SIZE_T Length);
STATIC XTAPI PWCHAR ConcatenateWideString(OUT PWCHAR Destination,
IN PWCHAR Source,
IN SIZE_T Count);
STATIC XTAPI XTSTATUS FormatWideString(IN PRTL_PRINT_CONTEXT Context,
IN PCWSTR Format,
IN VA_LIST ArgumentList);
STATIC XTAPI PWCHAR TokenizeWideString(IN PWCHAR String,
IN PCWSTR Delimiter,
IN OUT PWCHAR *SavePtr);
STATIC XTAPI SIZE_T WideStringLength(IN PCWSTR String,
IN SIZE_T MaxLength);
};
}
#endif /* __XTLDR_LIBXTOS_HH */

View File

@@ -0,0 +1,351 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/includes/xtldr.hh
* DESCRIPTION: Top level header for XTLDR
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTLDR_XTLDR_HH
#define __XTLDR_XTLDR_HH
#include <xtblapi.h>
#include <xtver.h>
#include <libxtos.hh>
class BootUtils
{
public:
STATIC XTCDECL BOOLEAN GetBooleanParameter(IN PCWSTR Parameters,
IN PCWSTR Needle);
};
class Configuration
{
private:
STATIC PLIST_ENTRY BootMenuList;
STATIC LIST_ENTRY Config;
STATIC LIST_ENTRY ConfigSections;
STATIC PCWSTR EditableConfigOptions[];
public:
STATIC XTCDECL BOOLEAN GetBooleanValue(IN PCWSTR ConfigName);
STATIC XTCDECL EFI_STATUS GetBootOptionValue(IN PLIST_ENTRY Options,
IN PCWSTR OptionName,
OUT PWCHAR *OptionValue);
STATIC XTCDECL VOID GetEditableOptions(OUT PCWSTR **OptionsArray,
OUT PULONG OptionsCount);
STATIC XTCDECL EFI_STATUS GetValue(IN PCWSTR ConfigName,
OUT PWCHAR *ConfigValue);
STATIC XTCDECL EFI_STATUS InitializeBootMenuList(IN ULONG MaxNameLength,
OUT PXTBL_BOOTMENU_ITEM *MenuEntries,
OUT PULONG EntriesCount,
OUT PULONG DefaultId);
STATIC XTCDECL VOID InitializeConfiguration();
STATIC XTCDECL EFI_STATUS LoadConfiguration();
STATIC XTCDECL EFI_STATUS ParseCommandLine();
STATIC XTCDECL EFI_STATUS SetBootOptionValue(IN PLIST_ENTRY Options,
IN PCWSTR OptionName,
IN PCWSTR OptionValue);
private:
STATIC XTCDECL EFI_STATUS ParseConfigFile(IN CONST PCHAR RawConfig,
OUT PLIST_ENTRY Configuration);
STATIC XTCDECL EFI_STATUS ReadConfigFile(IN PCWSTR ConfigDirectory,
IN PCWSTR ConfigFile,
OUT PCHAR *ConfigData);
STATIC XTCDECL EFI_STATUS SetValue(IN PCWSTR ConfigName,
IN PCWSTR ConfigValue);
STATIC XTCDECL VOID UpdateConfiguration(IN PLIST_ENTRY NewConfig);
};
class Console
{
public:
STATIC XTCDECL VOID ClearLine(IN ULONGLONG LineNo);
STATIC XTCDECL VOID ClearScreen();
STATIC XTCDECL VOID DisableCursor();
STATIC XTCDECL VOID EnableCursor();
STATIC XTCDECL VOID InitializeConsole();
STATIC XTCDECL VOID Print(IN PCWSTR Format,
IN ...);
STATIC XTCDECL XTSTATUS PutChar(IN WCHAR Character);
STATIC XTCDECL VOID QueryMode(OUT PUINT_PTR ResX,
OUT PUINT_PTR ResY);
STATIC XTCDECL VOID ReadKeyStroke(OUT PEFI_INPUT_KEY Key);
STATIC XTCDECL VOID ResetInputBuffer();
STATIC XTCDECL VOID SetAttributes(IN ULONGLONG Attributes);
STATIC XTCDECL VOID SetCursorPosition(IN ULONGLONG PosX,
IN ULONGLONG PosY);
STATIC XTCDECL VOID Write(IN PCWSTR String);
private:
STATIC XTCDECL EFI_STATUS SetMode(IN ULONGLONG Mode);
};
class Debug
{
private:
STATIC ULONG ComPortList[COMPORT_COUNT];
STATIC ULONG EnabledDebugPorts;
STATIC CPPORT SerialPort;
public:
STATIC XTCDECL EFI_STATUS InitializeDebugConsole();
STATIC XTCDECL VOID Print(IN PCWSTR Format,
IN ...);
STATIC XTCDECL XTSTATUS PutChar(IN WCHAR Character);
STATIC XTCDECL BOOLEAN SerialPortReady();
private:
STATIC XTCDECL EFI_STATUS ActivateSerialIOController();
STATIC XTCDECL EFI_STATUS InitializeSerialPort(IN ULONG PortNumber,
IN ULONG PortAddress,
IN ULONG BaudRate);
};
class EfiUtils
{
public:
STATIC XTCDECL EFI_STATUS EnterFirmwareSetup();
STATIC XTCDECL EFI_STATUS ExitBootServices();
STATIC XTCDECL EFI_STATUS GetConfigurationTable(IN PEFI_GUID TableGuid,
OUT PVOID *Table);
STATIC XTCDECL EFI_STATUS GetEfiVariable(IN PEFI_GUID Vendor,
IN PCWSTR VariableName,
OUT PVOID *VariableValue);
STATIC XTCDECL ULONGLONG GetRandomValue(IN OUT PULONGLONG RNGBuffer);
STATIC XTCDECL INT_PTR GetSecureBootStatus();
STATIC XTCDECL EFI_STATUS InitializeEntropy(PULONGLONG RNGBuffer);
STATIC XTCDECL EFI_STATUS LoadEfiImage(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
IN PVOID ImageData,
IN SIZE_T ImageSize,
OUT PEFI_HANDLE ImageHandle);
STATIC XTCDECL EFI_STATUS RebootSystem();
STATIC XTCDECL EFI_STATUS SetEfiVariable(IN PEFI_GUID Vendor,
IN PCWSTR VariableName,
IN PVOID VariableValue,
IN UINT_PTR Size);
STATIC XTCDECL EFI_STATUS ShutdownSystem();
STATIC XTCDECL VOID SleepExecution(IN ULONG_PTR Milliseconds);
STATIC XTCDECL EFI_STATUS StartEfiImage(IN EFI_HANDLE ImageHandle);
STATIC XTCDECL EFI_STATUS WaitForEfiEvent(IN UINT_PTR NumberOfEvents,
IN PEFI_EVENT Event,
OUT PUINT_PTR Index);
};
class Memory
{
public:
STATIC XTCDECL EFI_STATUS AllocatePages(IN EFI_ALLOCATE_TYPE AllocationType,
IN ULONGLONG NumberOfPages,
OUT PEFI_PHYSICAL_ADDRESS Memory);
STATIC XTCDECL EFI_STATUS AllocatePool(IN UINT_PTR Size,
OUT PVOID *Memory);
STATIC XTCDECL EFI_STATUS BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress);
STATIC XTCDECL EFI_STATUS FreePages(IN ULONGLONG NumberOfPages,
IN EFI_PHYSICAL_ADDRESS Memory);
STATIC XTCDECL EFI_STATUS FreePool(IN PVOID Memory);
STATIC XTCDECL VOID GetMappingsCount(IN PXTBL_PAGE_MAPPING PageMap,
OUT PULONG NumberOfMappings);
STATIC XTCDECL EFI_STATUS GetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap);
STATIC XTCDECL PVOID GetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID PhysicalAddress);
STATIC XTCDECL VOID InitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap,
IN SHORT PageMapLevel,
IN PAGE_SIZE PageSize);
STATIC XTCDECL EFI_STATUS MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
IN OUT PVOID *MemoryMapAddress,
IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine);
STATIC XTCDECL EFI_STATUS MapPage(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR VirtualAddress,
IN ULONG_PTR PhysicalAddress,
IN ULONG NumberOfPages);
STATIC XTCDECL EFI_STATUS MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
IN PVOID VirtualAddress,
IN PVOID PhysicalAddress,
IN ULONGLONG NumberOfPages,
IN LOADER_MEMORY_TYPE MemoryType);
STATIC XTCDECL PVOID PhysicalAddressToVirtual(IN PVOID PhysicalAddress,
IN PVOID PhysicalBase,
IN PVOID VirtualBase);
STATIC XTCDECL EFI_STATUS PhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap,
IN OUT PLIST_ENTRY ListHead,
IN PVOID PhysicalBase,
IN PVOID VirtualBase);
private:
STATIC XTCDECL LOADER_MEMORY_TYPE GetLoaderMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType);
STATIC XTCDECL EFI_STATUS GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID PageTable,
IN SIZE_T Entry,
OUT PVOID *NextPageTable);
STATIC XTCDECL EFI_STATUS SelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress);
};
class Protocol
{
private:
STATIC LIST_ENTRY BootProtocols;
STATIC XTBL_LOADER_PROTOCOL LoaderProtocol;
STATIC LIST_ENTRY LoadedModules;
public:
STATIC XTCDECL EFI_STATUS CloseProtocol(IN PEFI_HANDLE Handle,
IN PEFI_GUID ProtocolGuid);
STATIC XTCDECL EFI_STATUS FindBootProtocol(IN PCWSTR SystemType,
OUT PEFI_GUID BootProtocolGuid);
STATIC XTCDECL PLIST_ENTRY GetModulesList();
STATIC XTCDECL EFI_STATUS InstallProtocol(IN PVOID Interface,
IN PEFI_GUID Guid);
STATIC XTCDECL VOID InitializeProtocol();
STATIC XTCDECL EFI_STATUS InvokeBootProtocol(IN PWCHAR ShortName,
IN PLIST_ENTRY OptionsList);
STATIC XTCDECL EFI_STATUS LoadModule(IN PWCHAR ModuleName);
STATIC XTCDECL EFI_STATUS LoadModules(IN PWCHAR ModulesList);
STATIC XTCDECL EFI_STATUS LocateProtocolHandles(OUT PEFI_HANDLE *Handles,
OUT PUINT_PTR Count,
IN PEFI_GUID ProtocolGuid);
STATIC XTCDECL EFI_STATUS OpenProtocol(OUT PEFI_HANDLE Handle,
OUT PVOID *ProtocolHandler,
IN PEFI_GUID ProtocolGuid);
STATIC XTCDECL EFI_STATUS OpenProtocolHandle(IN EFI_HANDLE Handle,
OUT PVOID *ProtocolHandler,
IN PEFI_GUID ProtocolGuid);
STATIC XTCDECL EFI_STATUS RegisterBootProtocol(IN PCWSTR SystemType,
IN PEFI_GUID BootProtocolGuid);
STATIC XTCDECL EFI_STATUS InstallXtLoaderProtocol();
private:
STATIC XTCDECL EFI_STATUS GetModuleInformation(IN PWCHAR SectionData,
IN ULONG SectionSize,
OUT PXTBL_MODULE_INFO ModuleInfo);
STATIC XTCDECL EFI_STATUS GetModuleInfoStrings(IN PWCHAR SectionData,
IN ULONG SectionSize,
OUT PWCHAR **ModInfo,
OUT PULONG InfoCount);
};
class Shell
{
public:
STATIC XTCDECL VOID StartLoaderShell();
private:
STATIC XTCDECL VOID PrintPrompt();
};
class TextUi
{
public:
STATIC XTCDECL VOID DisplayBootMenu();
STATIC XTCDECL VOID DisplayErrorDialog(IN PCWSTR Caption,
IN PCWSTR Message);
STATIC XTCDECL VOID DisplayInfoDialog(IN PCWSTR Caption,
IN PCWSTR Message);
STATIC XTCDECL VOID DisplayInputDialog(IN PCWSTR Caption,
IN PCWSTR Message,
IN OUT PWCHAR *InputFieldText);
STATIC XTCDECL XTBL_DIALOG_HANDLE DisplayProgressDialog(IN PCWSTR Caption,
IN PCWSTR Message,
IN UCHAR Percentage);
STATIC XTCDECL VOID UpdateProgressBar(IN PXTBL_DIALOG_HANDLE Handle,
IN PCWSTR Message,
IN UCHAR Percentage);
private:
STATIC XTCDECL VOID DetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle,
IN PCWSTR Message);
STATIC XTCDECL VOID DisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry);
STATIC XTCDECL VOID DrawBootMenu(OUT PXTBL_DIALOG_HANDLE Handle);
STATIC XTCDECL VOID DrawBootMenuEntry(IN PXTBL_DIALOG_HANDLE Handle,
IN PWCHAR MenuEntry,
IN UINT Position,
IN BOOLEAN Highlighted);
STATIC XTCDECL VOID DrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle,
IN PCWSTR Caption,
IN PCWSTR Message);
STATIC XTCDECL VOID DrawButton(IN PXTBL_DIALOG_HANDLE Handle);
STATIC XTCDECL VOID DrawInputField(IN PXTBL_DIALOG_HANDLE Handle,
IN PWCHAR InputFieldText);
STATIC XTCDECL VOID DrawMessage(IN PXTBL_DIALOG_HANDLE Handle,
IN PCWSTR Message);
STATIC XTCDECL VOID DrawProgressBar(IN PXTBL_DIALOG_HANDLE Handle,
IN UCHAR Percentage);
STATIC XTCDECL VOID DrawEditMenu(OUT PXTBL_DIALOG_HANDLE Handle);
STATIC XTCDECL EFI_STATUS DrawEditMenuEntry(IN PXTBL_DIALOG_HANDLE Handle,
IN PCWSTR OptionName,
IN PCWSTR OptionValue,
IN UINT Position,
IN BOOLEAN Highlighted);
};
class Volume
{
private:
STATIC LIST_ENTRY EfiBlockDevices;
public:
STATIC XTCDECL EFI_STATUS CloseVolume(IN PEFI_HANDLE VolumeHandle);
STATIC XTCDECL EFI_STATUS EnumerateBlockDevices();
STATIC XTCDECL EFI_STATUS FindDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,
IN CONST PWCHAR FileSystemPath,
OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath);
STATIC XTCDECL EFI_STATUS GetEfiPath(IN PWCHAR SystemPath,
OUT PWCHAR *EfiPath);
STATIC XTCDECL EFI_STATUS GetDevicePath(IN PWCHAR SystemPath,
OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath,
OUT PWCHAR *ArcName,
OUT PWCHAR *Path);
STATIC XTCDECL EFI_STATUS OpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
OUT PEFI_HANDLE DiskHandle,
OUT PEFI_FILE_HANDLE *FsHandle);
STATIC XTCDECL EFI_STATUS ReadFile(IN PEFI_FILE_HANDLE DirHandle,
IN PCWSTR FileName,
OUT PVOID *FileData,
OUT PSIZE_T FileSize);
private:
STATIC XTCDECL EFI_STATUS DiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices);
STATIC XTCDECL EFI_STATUS DissectArcPath(IN PWCHAR SystemPath,
OUT PWCHAR *ArcName,
OUT PWCHAR *Path,
OUT PUSHORT DriveType,
OUT PULONG DriveNumber,
OUT PULONG PartNumber);
STATIC XTCDECL PEFI_DEVICE_PATH_PROTOCOL DuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath);
STATIC XTCDECL EFI_STATUS FindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode);
STATIC XTCDECL BOOLEAN FindParentBlockDevice(IN PLIST_ENTRY BlockDevices,
IN PEFI_BLOCK_DEVICE_DATA ChildNode,
OUT PEFI_BLOCK_DEVICE_DATA *ParentNode);
};
class XtLoader
{
private:
STATIC PBL_XT_BOOT_MENU BootMenu;
STATIC EFI_HANDLE EfiImageHandle;
STATIC PEFI_SYSTEM_TABLE EfiSystemTable;
STATIC XTBL_STATUS LoaderStatus;
public:
STATIC XTCDECL VOID DisableBootServices();
STATIC XTCDECL BOOLEAN GetBootServicesStatus();
STATIC XTCDECL EFI_HANDLE GetEfiImageHandle();
STATIC XTCDECL PEFI_SYSTEM_TABLE GetEfiSystemTable();
STATIC XTCDECL VOID GetLoaderImageInformation(PVOID *LoaderBase,
PULONGLONG LoaderSize);
STATIC XTCDECL INT_PTR GetSecureBootStatus();
STATIC XTCDECL VOID InitializeBootLoader(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable);
STATIC XTCDECL VOID RegisterBootMenu(IN PVOID BootMenuRoutine);
STATIC XTCDECL VOID ShowBootMenu();
};
#endif /* __XTLDR_XTLDR_HH */

View File

@@ -1,12 +1,12 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/library/modproto.c * FILE: xtldr/library/modproto.cc
* DESCRIPTION: XT Boot Loader protocol support for XTLDR modules * DESCRIPTION: XT Boot Loader protocol support for XTLDR modules
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtldr.h> #include <xtldr.hh>
/** /**
@@ -25,6 +25,7 @@
* *
* @since XT 1.0 * @since XT 1.0
*/ */
XTCLINK
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable, BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable,
@@ -32,13 +33,13 @@ BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable,
OUT PXTBL_LOADER_PROTOCOL *ProtocolHandler) OUT PXTBL_LOADER_PROTOCOL *ProtocolHandler)
{ {
EFI_GUID ProtocolGuid = XT_BOOT_LOADER_PROTOCOL_GUID; EFI_GUID ProtocolGuid = XT_BOOT_LOADER_PROTOCOL_GUID;
PEFI_HANDLE Handles = NULL; PEFI_HANDLE Handles = NULLPTR;
EFI_STATUS Status; EFI_STATUS Status;
UINT_PTR Count; UINT_PTR Count;
UINT Index; UINT Index;
/* Try to locate the handles */ /* Try to locate the handles */
Status = SystemTable->BootServices->LocateHandleBuffer(ByProtocol, &ProtocolGuid, NULL, &Count, &Handles); Status = SystemTable->BootServices->LocateHandleBuffer(ByProtocol, &ProtocolGuid, NULLPTR, &Count, &Handles);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Unable to get handles */ /* Unable to get handles */
@@ -53,7 +54,7 @@ BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable,
{ {
/* Try to open protocol */ /* Try to open protocol */
Status = SystemTable->BootServices->OpenProtocol(Handles[Index], &ProtocolGuid, Status = SystemTable->BootServices->OpenProtocol(Handles[Index], &ProtocolGuid,
(PVOID*)ProtocolHandler, ImageHandle, NULL, (PVOID*)ProtocolHandler, ImageHandle, NULLPTR,
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
/* Check if successfully opened the loader protocol */ /* Check if successfully opened the loader protocol */
@@ -69,7 +70,7 @@ BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable,
SystemTable->BootServices->FreePool(Handles); SystemTable->BootServices->FreePool(Handles);
/* Make sure the loaded protocol has been found */ /* Make sure the loaded protocol has been found */
if(*ProtocolHandler == NULL) if(*ProtocolHandler == NULLPTR)
{ {
/* Protocol not found */ /* Protocol not found */
return STATUS_EFI_NOT_FOUND; return STATUS_EFI_NOT_FOUND;

View File

@@ -1,12 +1,12 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/memory.c * FILE: xtldr/memory.cc
* DESCRIPTION: XT Boot Loader memory management * DESCRIPTION: XT Boot Loader memory management
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtldr.h> #include <xtldr.hh>
/** /**
@@ -24,10 +24,12 @@
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlAllocateMemoryPages(IN ULONGLONG NumberOfPages, Memory::AllocatePages(IN EFI_ALLOCATE_TYPE AllocationType,
IN ULONGLONG NumberOfPages,
OUT PEFI_PHYSICAL_ADDRESS Memory) OUT PEFI_PHYSICAL_ADDRESS Memory)
{ {
return EfiSystemTable->BootServices->AllocatePages(AllocateAnyPages, EfiLoaderData, NumberOfPages, Memory); return XtLoader::GetEfiSystemTable()->BootServices->AllocatePages(AllocationType, EfiLoaderData,
NumberOfPages, Memory);
} }
/** /**
@@ -45,11 +47,11 @@ BlAllocateMemoryPages(IN ULONGLONG NumberOfPages,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlAllocateMemoryPool(IN UINT_PTR Size, Memory::AllocatePool(IN UINT_PTR Size,
OUT PVOID *Memory) OUT PVOID *Memory)
{ {
/* Allocate pool */ /* Allocate pool */
return EfiSystemTable->BootServices->AllocatePool(EfiLoaderData, Size, Memory); return XtLoader::GetEfiSystemTable()->BootServices->AllocatePool(EfiLoaderData, Size, Memory);
} }
/** /**
@@ -67,10 +69,10 @@ BlAllocateMemoryPool(IN UINT_PTR Size,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlFreeMemoryPages(IN ULONGLONG NumberOfPages, Memory::FreePages(IN ULONGLONG NumberOfPages,
IN EFI_PHYSICAL_ADDRESS Memory) IN EFI_PHYSICAL_ADDRESS Memory)
{ {
return EfiSystemTable->BootServices->FreePages(Memory, NumberOfPages); return XtLoader::GetEfiSystemTable()->BootServices->FreePages(Memory, NumberOfPages);
} }
/** /**
@@ -85,10 +87,58 @@ BlFreeMemoryPages(IN ULONGLONG NumberOfPages,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlFreeMemoryPool(IN PVOID Memory) Memory::FreePool(IN PVOID Memory)
{ {
/* Free pool */ /* Free pool */
return EfiSystemTable->BootServices->FreePool(Memory); return XtLoader::GetEfiSystemTable()->BootServices->FreePool(Memory);
}
/**
* Converts EFI memory type to XTLDR memory type.
*
* @param EfiMemoryType
* Specifies EFI memory type.
*
* @return This routine returns a mapped XTLDR memory type.
*
* @since XT 1.0
*/
XTCDECL
LOADER_MEMORY_TYPE
Memory::GetLoaderMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType)
{
LOADER_MEMORY_TYPE MemoryType;
/* Check EFI memory type and convert to XTLDR memory type */
switch(EfiMemoryType)
{
case EfiACPIMemoryNVS:
case EfiACPIReclaimMemory:
case EfiPalCode:
case EfiReservedMemoryType:
MemoryType = LoaderSpecialMemory;
break;
case EfiRuntimeServicesCode:
case EfiRuntimeServicesData:
case EfiMemoryMappedIO:
case EfiMemoryMappedIOPortSpace:
MemoryType = LoaderFirmwarePermanent;
break;
case EfiBootServicesData:
case EfiLoaderCode:
case EfiLoaderData:
MemoryType = LoaderFirmwareTemporary;
break;
case EfiUnusableMemory:
MemoryType = LoaderBad;
break;
default:
MemoryType = LoaderFree;
break;
}
/* Return XTLDR memory type */
return MemoryType;
} }
/** /**
@@ -106,7 +156,7 @@ BlFreeMemoryPool(IN PVOID Memory)
*/ */
XTCDECL XTCDECL
VOID VOID
BlGetMappingsCount(IN PXTBL_PAGE_MAPPING PageMap, Memory::GetMappingsCount(IN PXTBL_PAGE_MAPPING PageMap,
OUT PULONG NumberOfMappings) OUT PULONG NumberOfMappings)
{ {
/* Return number of mappings */ /* Return number of mappings */
@@ -125,24 +175,27 @@ BlGetMappingsCount(IN PXTBL_PAGE_MAPPING PageMap,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap) Memory::GetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap)
{ {
EFI_STATUS Status; EFI_STATUS Status;
if(MemoryMap == NULL) if(MemoryMap == NULLPTR)
{ {
return STATUS_EFI_INVALID_PARAMETER; return STATUS_EFI_INVALID_PARAMETER;
} }
MemoryMap->Map = NULL; MemoryMap->Map = NULLPTR;
MemoryMap->MapSize = 0; MemoryMap->MapSize = 0;
/* Get memory map */ /* Get memory map */
do do
{ {
/* Attempt do get EFI memory map */ /* Attempt do get EFI memory map */
Status = EfiSystemTable->BootServices->GetMemoryMap(&MemoryMap->MapSize, MemoryMap->Map, &MemoryMap->MapKey, Status = XtLoader::GetEfiSystemTable()->BootServices->GetMemoryMap(&MemoryMap->MapSize,
&MemoryMap->DescriptorSize, &MemoryMap->DescriptorVersion); MemoryMap->Map,
&MemoryMap->MapKey,
&MemoryMap->DescriptorSize,
&MemoryMap->DescriptorVersion);
if(Status == STATUS_EFI_SUCCESS) if(Status == STATUS_EFI_SUCCESS)
{ {
/* Go further if succeeded */ /* Go further if succeeded */
@@ -154,19 +207,19 @@ BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap)
if(MemoryMap->Map) if(MemoryMap->Map)
{ {
/* Free allocated memory */ /* Free allocated memory */
BlFreeMemoryPool(MemoryMap->Map); FreePool(MemoryMap->Map);
} }
return Status; return Status;
} }
/* Allocate the desired amount of memory */ /* Allocate the desired amount of memory */
MemoryMap->MapSize += 2 * MemoryMap->DescriptorSize; MemoryMap->MapSize += 2 * MemoryMap->DescriptorSize;
BlAllocateMemoryPool(MemoryMap->MapSize, (PVOID *)&MemoryMap->Map); AllocatePool(MemoryMap->MapSize, (PVOID *)&MemoryMap->Map);
} }
while(Status == STATUS_EFI_BUFFER_TOO_SMALL); while(Status == STATUS_EFI_BUFFER_TOO_SMALL);
/* Make sure memory map is set */ /* Make sure memory map is set */
if(MemoryMap->Map == NULL) if(MemoryMap->Map == NULLPTR)
{ {
/* Something went wrong */ /* Something went wrong */
return STATUS_EFI_NO_MAPPING; return STATUS_EFI_NO_MAPPING;
@@ -191,7 +244,7 @@ BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap)
*/ */
XTCDECL XTCDECL
PVOID PVOID
BlGetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap, Memory::GetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID PhysicalAddress) IN PVOID PhysicalAddress)
{ {
PXTBL_MEMORY_MAPPING Mapping; PXTBL_MEMORY_MAPPING Mapping;
@@ -208,11 +261,11 @@ BlGetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap,
if(Mapping->VirtualAddress) if(Mapping->VirtualAddress)
{ {
/* Check if provided physical address is in range of this mapping */ /* Check if provided physical address is in range of this mapping */
if((PhysicalAddress >= Mapping->PhysicalAddress) && if(((UINT_PTR)PhysicalAddress >= (UINT_PTR)Mapping->PhysicalAddress) &&
(PhysicalAddress < Mapping->PhysicalAddress + (Mapping->NumberOfPages * EFI_PAGE_SIZE))) ((UINT_PTR)PhysicalAddress < ((UINT_PTR)Mapping->PhysicalAddress + (Mapping->NumberOfPages * EFI_PAGE_SIZE))))
{ {
/* Calculate virtual address based on the mapping and return it */ /* Calculate virtual address based on the mapping and return it */
return PhysicalAddress - Mapping->PhysicalAddress + Mapping->VirtualAddress; return (PVOID)(((UINT_PTR)PhysicalAddress - (UINT_PTR)Mapping->PhysicalAddress) + (UINT_PTR)Mapping->VirtualAddress);
} }
} }
@@ -242,12 +295,12 @@ BlGetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap,
*/ */
XTCDECL XTCDECL
VOID VOID
BlInitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap, Memory::InitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap,
IN SHORT PageMapLevel, IN SHORT PageMapLevel,
IN PAGE_SIZE PageSize) IN PAGE_SIZE PageSize)
{ {
/* Initialize memory mappings */ /* Initialize memory mappings */
RtlInitializeListHead(&PageMap->MemoryMap); RTL::LinkedList::InitializeListHead(&PageMap->MemoryMap);
PageMap->MapSize = 0; PageMap->MapSize = 0;
/* Set page map size/level and memory map address */ /* Set page map size/level and memory map address */
@@ -273,7 +326,7 @@ BlInitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
IN OUT PVOID *MemoryMapAddress, IN OUT PVOID *MemoryMapAddress,
IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine) IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine)
{ {
@@ -286,21 +339,21 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
SIZE_T Index; SIZE_T Index;
/* Set virtual address as specified in argument */ /* Set virtual address as specified in argument */
VirtualAddress = *MemoryMapAddress; VirtualAddress = (PUCHAR)*MemoryMapAddress;
/* Check if custom memory type routine is specified */ /* Check if custom memory type routine is specified */
if(GetMemoryTypeRoutine == NULL) if(GetMemoryTypeRoutine == NULLPTR)
{ {
/* Use default memory type routine */ /* Use default memory type routine */
GetMemoryTypeRoutine = BlpGetLoaderMemoryType; GetMemoryTypeRoutine = GetLoaderMemoryType;
} }
/* Allocate and zero-fill buffer for EFI memory map */ /* Allocate and zero-fill buffer for EFI memory map */
BlAllocateMemoryPool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap); AllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap);
RtlZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP)); RTL::Memory::ZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP));
/* Get EFI memory map */ /* Get EFI memory map */
Status = BlGetMemoryMap(MemoryMap); Status = GetMemoryMap(MemoryMap);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to get EFI memory map */ /* Failed to get EFI memory map */
@@ -345,19 +398,19 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
} }
/* Convert EFI memory type into XTLDR memory type */ /* Convert EFI memory type into XTLDR memory type */
MemoryType = GetMemoryTypeRoutine(Descriptor->Type); MemoryType = GetMemoryTypeRoutine((EFI_MEMORY_TYPE)Descriptor->Type);
/* Do memory mappings depending on memory type */ /* Do memory mappings depending on memory type */
if(MemoryType == LoaderFirmwareTemporary) if(MemoryType == LoaderFirmwareTemporary)
{ {
/* Map EFI firmware code */ /* Map EFI firmware code */
Status = BlMapVirtualMemory(PageMap, (PVOID)Descriptor->PhysicalStart, Status = MapVirtualMemory(PageMap, (PVOID)Descriptor->PhysicalStart,
(PVOID)Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType); (PVOID)Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType);
} }
else if(MemoryType != LoaderFree) else if(MemoryType != LoaderFree)
{ {
/* Add any non-free memory mapping */ /* Add any non-free memory mapping */
Status = BlMapVirtualMemory(PageMap, VirtualAddress, (PVOID)Descriptor->PhysicalStart, Status = MapVirtualMemory(PageMap, VirtualAddress, (PVOID)Descriptor->PhysicalStart,
Descriptor->NumberOfPages, MemoryType); Descriptor->NumberOfPages, MemoryType);
/* Calculate next valid virtual address */ /* Calculate next valid virtual address */
@@ -366,7 +419,7 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
else else
{ {
/* Map all other memory as loader free */ /* Map all other memory as loader free */
Status = BlMapVirtualMemory(PageMap, NULL, (PVOID)Descriptor->PhysicalStart, Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)Descriptor->PhysicalStart,
Descriptor->NumberOfPages, LoaderFree); Descriptor->NumberOfPages, LoaderFree);
} }
@@ -383,7 +436,7 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
} }
/* Always map first page */ /* Always map first page */
Status = BlMapVirtualMemory(PageMap, NULL, (PVOID)0, 1, LoaderFirmwarePermanent); Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)0, 1, LoaderFirmwarePermanent);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Mapping failed */ /* Mapping failed */
@@ -391,7 +444,7 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
} }
/* Map BIOS ROM and VRAM */ /* Map BIOS ROM and VRAM */
Status = BlMapVirtualMemory(PageMap, NULL, (PVOID)0xA0000, 0x60, LoaderFirmwarePermanent); Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)0xA0000, 0x60, LoaderFirmwarePermanent);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Mapping failed */ /* Mapping failed */
@@ -427,7 +480,7 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
IN PVOID VirtualAddress, IN PVOID VirtualAddress,
IN PVOID PhysicalAddress, IN PVOID PhysicalAddress,
IN ULONGLONG NumberOfPages, IN ULONGLONG NumberOfPages,
@@ -440,7 +493,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
EFI_STATUS Status; EFI_STATUS Status;
/* Allocate memory for new mapping */ /* Allocate memory for new mapping */
Status = BlAllocateMemoryPool(sizeof(XTBL_MEMORY_MAPPING), (PVOID *)&Mapping1); Status = AllocatePool(sizeof(XTBL_MEMORY_MAPPING), (PVOID *)&Mapping1);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -490,7 +543,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
if(NumberOfMappedPages > 0) if(NumberOfMappedPages > 0)
{ {
/* Pages associated to the mapping, allocate memory for it */ /* Pages associated to the mapping, allocate memory for it */
Status = BlAllocateMemoryPool(sizeof(XTBL_MEMORY_MAPPING), (PVOID*)&Mapping3); Status = AllocatePool(sizeof(XTBL_MEMORY_MAPPING), (PVOID*)&Mapping3);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -499,10 +552,10 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
/* Set mapping fields and insert it on the top */ /* Set mapping fields and insert it on the top */
Mapping3->PhysicalAddress = (PUCHAR)PhysicalAddressEnd + 1; Mapping3->PhysicalAddress = (PUCHAR)PhysicalAddressEnd + 1;
Mapping3->VirtualAddress = NULL; Mapping3->VirtualAddress = NULLPTR;
Mapping3->NumberOfPages = NumberOfMappedPages; Mapping3->NumberOfPages = NumberOfMappedPages;
Mapping3->MemoryType = Mapping2->MemoryType; Mapping3->MemoryType = Mapping2->MemoryType;
RtlInsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry); RTL::LinkedList::InsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry);
} }
/* Calculate number of pages and the end of the physical address */ /* Calculate number of pages and the end of the physical address */
@@ -526,7 +579,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
if(NumberOfMappedPages > 0) if(NumberOfMappedPages > 0)
{ {
/* Pages associated to the mapping, allocate memory for it */ /* Pages associated to the mapping, allocate memory for it */
Status = BlAllocateMemoryPool(sizeof(XTBL_MEMORY_MAPPING), (PVOID*)&Mapping3); Status = AllocatePool(sizeof(XTBL_MEMORY_MAPPING), (PVOID*)&Mapping3);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -535,10 +588,10 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
/* Set mapping fields and insert it on the top */ /* Set mapping fields and insert it on the top */
Mapping3->PhysicalAddress = Mapping1->PhysicalAddress; Mapping3->PhysicalAddress = Mapping1->PhysicalAddress;
Mapping3->VirtualAddress = NULL; Mapping3->VirtualAddress = NULLPTR;
Mapping3->NumberOfPages = NumberOfMappedPages; Mapping3->NumberOfPages = NumberOfMappedPages;
Mapping3->MemoryType = Mapping2->MemoryType; Mapping3->MemoryType = Mapping2->MemoryType;
RtlInsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry); RTL::LinkedList::InsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry);
} }
/* Calculate number of pages and the end of the physical address */ /* Calculate number of pages and the end of the physical address */
@@ -562,8 +615,8 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
MappingListEntry = ListEntry->Flink; MappingListEntry = ListEntry->Flink;
/* Remove mapping from the list and free up it's memory */ /* Remove mapping from the list and free up it's memory */
RtlRemoveEntryList(&Mapping2->ListEntry); RTL::LinkedList::RemoveEntryList(&Mapping2->ListEntry);
Status = BlFreeMemoryPool(Mapping2); Status = FreePool(Mapping2);
ListEntry = MappingListEntry; ListEntry = MappingListEntry;
/* Go to the next mapping */ /* Go to the next mapping */
@@ -574,7 +627,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
if(Mapping2->PhysicalAddress > Mapping1->PhysicalAddress) if(Mapping2->PhysicalAddress > Mapping1->PhysicalAddress)
{ {
/* Insert new mapping in front */ /* Insert new mapping in front */
RtlInsertHeadList(Mapping2->ListEntry.Blink, &Mapping1->ListEntry); RTL::LinkedList::InsertHeadList(Mapping2->ListEntry.Blink, &Mapping1->ListEntry);
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
@@ -583,7 +636,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
} }
/* Insert new mapping to the list and increase page map size */ /* Insert new mapping to the list and increase page map size */
RtlInsertTailList(&PageMap->MemoryMap, &Mapping1->ListEntry); RTL::LinkedList::InsertTailList(&PageMap->MemoryMap, &Mapping1->ListEntry);
PageMap->MapSize++; PageMap->MapSize++;
/* Return success */ /* Return success */
@@ -608,7 +661,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
*/ */
XTCDECL XTCDECL
PVOID PVOID
BlPhysicalAddressToVirtual(IN PVOID PhysicalAddress, Memory::PhysicalAddressToVirtual(IN PVOID PhysicalAddress,
IN PVOID PhysicalBase, IN PVOID PhysicalBase,
IN PVOID VirtualBase) IN PVOID VirtualBase)
{ {
@@ -637,7 +690,7 @@ BlPhysicalAddressToVirtual(IN PVOID PhysicalAddress,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap, Memory::PhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap,
IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListHead,
IN PVOID PhysicalBase, IN PVOID PhysicalBase,
IN PVOID VirtualBase) IN PVOID VirtualBase)
@@ -662,12 +715,12 @@ BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap,
if(ListEntry->Blink == ListHead) if(ListEntry->Blink == ListHead)
{ {
/* Find virtual address of list head */ /* Find virtual address of list head */
ListEntry->Blink = BlGetVirtualAddress(PageMap, ListEntry->Blink); ListEntry->Blink = (PLIST_ENTRY)GetVirtualAddress(PageMap, ListEntry->Blink);
} }
else else
{ {
/* Convert list entry */ /* Convert list entry */
ListEntry->Blink = BlPhysicalAddressToVirtual(ListEntry->Blink, (PVOID)PhysicalBase, VirtualBase); ListEntry->Blink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListEntry->Blink, (PVOID)PhysicalBase, VirtualBase);
} }
if(ListEntry->Flink == ListHead) if(ListEntry->Flink == ListHead)
{ {
@@ -677,7 +730,7 @@ BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap,
else else
{ {
/* Convert list entry */ /* Convert list entry */
ListEntry->Flink = BlPhysicalAddressToVirtual(ListEntry->Flink, (PVOID)PhysicalBase, VirtualBase); ListEntry->Flink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListEntry->Flink, (PVOID)PhysicalBase, VirtualBase);
} }
/* Get to the next element*/ /* Get to the next element*/
@@ -685,57 +738,9 @@ BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap,
} }
/* Convert list head */ /* Convert list head */
ListHead->Blink = BlPhysicalAddressToVirtual(ListHead->Blink, (PVOID)PhysicalBase, VirtualBase); ListHead->Blink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListHead->Blink, (PVOID)PhysicalBase, VirtualBase);
ListHead->Flink = BlPhysicalAddressToVirtual(ListHead->Flink, (PVOID)PhysicalBase, VirtualBase); ListHead->Flink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListHead->Flink, (PVOID)PhysicalBase, VirtualBase);
/* Return success */ /* Return success */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
/**
* Converts EFI memory type to XTLDR memory type.
*
* @param EfiMemoryType
* Specifies EFI memory type.
*
* @return This routine returns a mapped XTLDR memory type.
*
* @since XT 1.0
*/
XTCDECL
LONG
BlpGetLoaderMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType)
{
LOADER_MEMORY_TYPE MemoryType;
/* Check EFI memory type and convert to XTLDR memory type */
switch(EfiMemoryType)
{
case EfiACPIMemoryNVS:
case EfiACPIReclaimMemory:
case EfiPalCode:
case EfiReservedMemoryType:
MemoryType = LoaderSpecialMemory;
break;
case EfiRuntimeServicesCode:
case EfiRuntimeServicesData:
case EfiMemoryMappedIO:
case EfiMemoryMappedIOPortSpace:
MemoryType = LoaderFirmwarePermanent;
break;
case EfiBootServicesData:
case EfiLoaderCode:
case EfiLoaderData:
MemoryType = LoaderFirmwareTemporary;
break;
case EfiUnusableMemory:
MemoryType = LoaderBad;
break;
default:
MemoryType = LoaderFree;
break;
}
/* Return XTLDR memory type */
return MemoryType;
}

View File

@@ -8,8 +8,8 @@ include_directories(
# Specify list of source code files # Specify list of source code files
list(APPEND XTLDR_ACPI_SOURCE list(APPEND XTLDR_ACPI_SOURCE
${XTLDR_ACPI_SOURCE_DIR}/acpi.c ${XTLDR_ACPI_SOURCE_DIR}/acpi.cc
${XTLDR_ACPI_SOURCE_DIR}/globals.c) ${XTLDR_ACPI_SOURCE_DIR}/data.cc)
# Link module executable # Link module executable
add_executable(acpi ${XTLDR_ACPI_SOURCE}) add_executable(acpi ${XTLDR_ACPI_SOURCE})

View File

@@ -1,20 +1,21 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/acpi/acpi.c * FILE: xtldr/modules/acpi/acpi.cc
* DESCRIPTION: XTLDR ACPI Support Module * DESCRIPTION: XTLDR ACPI Support Module
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <acpi.h> #include <acpi.hh>
/* Dummy module information */ /* ACPI module information */
MODULE_AUTHOR(L"Rafal Kupiec <belliash@codingworkshop.eu.org>"); MODULE_AUTHOR(L"Rafal Kupiec <belliash@codingworkshop.eu.org>");
MODULE_DESCRIPTION(L"ACPI support"); MODULE_DESCRIPTION(L"ACPI support");
MODULE_LICENSE(L"GPLv3"); MODULE_LICENSE(L"GPLv3");
MODULE_VERSION(L"0.1"); MODULE_VERSION(L"0.1");
/** /**
* Attempts to get XSDP. If it is not found or checksum mismatch, it will try to get RSDP instead. * Attempts to get XSDP. If it is not found or checksum mismatch, it will try to get RSDP instead.
* *
@@ -27,12 +28,12 @@ MODULE_VERSION(L"0.1");
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
AcGetAcpiDescriptionPointer(OUT PVOID *AcpiTable) Acpi::GetAcpiDescriptionPointer(OUT PVOID *AcpiTable)
{ {
PVOID Rsdp; PVOID Rsdp;
/* Try to get XSDP (ACPI 2.0) from system configuration tables */ /* Try to get XSDP (ACPI 2.0) from system configuration tables */
if(AcGetXsdpTable(&Rsdp) == STATUS_EFI_SUCCESS) if(GetXsdpTable(&Rsdp) == STATUS_EFI_SUCCESS)
{ {
/* XSDP found, return success */ /* XSDP found, return success */
*AcpiTable = Rsdp; *AcpiTable = Rsdp;
@@ -40,7 +41,7 @@ AcGetAcpiDescriptionPointer(OUT PVOID *AcpiTable)
} }
/* Try to get RSDP (ACPI 1.0) from system configuration tables */ /* Try to get RSDP (ACPI 1.0) from system configuration tables */
if(AcGetRsdpTable(&Rsdp) == STATUS_EFI_SUCCESS) if(GetRsdpTable(&Rsdp) == STATUS_EFI_SUCCESS)
{ {
/* RSDP found, return success */ /* RSDP found, return success */
*AcpiTable = Rsdp; *AcpiTable = Rsdp;
@@ -61,7 +62,7 @@ AcGetAcpiDescriptionPointer(OUT PVOID *AcpiTable)
* Supplies a pointer to the table to start searching from. * Supplies a pointer to the table to start searching from.
* *
* @param AcpiTable * @param AcpiTable
* Supplies a pointer to memory area where ACPI table address will be stored, or NULL if not found. * Supplies a pointer to memory area where ACPI table address will be stored, or NULLPTR if not found.
* *
* @return This routine returns a status code. * @return This routine returns a status code.
* *
@@ -69,7 +70,7 @@ AcGetAcpiDescriptionPointer(OUT PVOID *AcpiTable)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
AcGetAcpiTable(IN CONST UINT Signature, Acpi::GetAcpiTable(IN CONST UINT Signature,
IN PVOID PreviousTable, IN PVOID PreviousTable,
OUT PVOID *AcpiTable) OUT PVOID *AcpiTable)
{ {
@@ -81,11 +82,11 @@ AcGetAcpiTable(IN CONST UINT Signature,
PACPI_RSDT Rsdt; PACPI_RSDT Rsdt;
BOOLEAN Xsdp; BOOLEAN Xsdp;
/* Return NULL address by default if requested table not found */ /* Return NULLPTR by default if requested table not found */
*AcpiTable = NULL; *AcpiTable = NULLPTR;
/* Get Root System Description Table Pointer */ /* Get Root System Description Table Pointer */
Status = AcGetAcpiDescriptionPointer((PVOID)&Rsdp); Status = GetAcpiDescriptionPointer((PVOID*)&Rsdp);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* ACPI tables not found, return error */ /* ACPI tables not found, return error */
@@ -127,13 +128,13 @@ AcGetAcpiTable(IN CONST UINT Signature,
} }
/* Check if previous table provided */ /* Check if previous table provided */
if(PreviousTable != NULL) if(PreviousTable != NULLPTR)
{ {
/* Check if this is a table previously found */ /* Check if this is a table previously found */
if(TableHeader == (PVOID)PreviousTable) if(TableHeader == (PVOID)PreviousTable)
{ {
/* Unset previous table */ /* Unset previous table */
PreviousTable = NULL; PreviousTable = NULLPTR;
} }
/* Skip to next ACPI table */ /* Skip to next ACPI table */
@@ -159,7 +160,7 @@ AcGetAcpiTable(IN CONST UINT Signature,
if(TableHeader->Signature != ACPI_FADT_SIGNATURE || TableHeader->Revision > 2) if(TableHeader->Signature != ACPI_FADT_SIGNATURE || TableHeader->Revision > 2)
{ {
/* Validate table checksum */ /* Validate table checksum */
if(!AcpValidateAcpiTable(TableHeader, TableHeader->Length)) if(!ValidateAcpiTable(TableHeader, TableHeader->Length))
{ {
/* Checksum mismatch, return error */ /* Checksum mismatch, return error */
return STATUS_EFI_CRC_ERROR; return STATUS_EFI_CRC_ERROR;
@@ -183,16 +184,16 @@ AcGetAcpiTable(IN CONST UINT Signature,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
AcGetApicBase(OUT PVOID *ApicBase) Acpi::GetApicBase(OUT PVOID *ApicBase)
{ {
CPUID_REGISTERS CpuRegisters; CPUID_REGISTERS CpuRegisters;
/* Prepare CPUID registers to query for APIC support */ /* Prepare CPUID registers to query for APIC support */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); XtLdrProtocol->Memory.ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES; CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
/* Query CPUID */ /* Query CPUID */
ArCpuId(&CpuRegisters); XtLdrProtocol->Cpu.CpuId(&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)
@@ -202,7 +203,7 @@ AcGetApicBase(OUT PVOID *ApicBase)
} }
/* Get APIC base address */ /* Get APIC base address */
*ApicBase = (PVOID)((UINT_PTR)ArReadModelSpecificRegister(0x1B) & 0xFFFFF000); *ApicBase = (PVOID)((UINT_PTR)XtLdrProtocol->Cpu.ReadModelSpecificRegister(0x1B) & 0xFFFFF000);
/* Return success */ /* Return success */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
@@ -220,18 +221,18 @@ AcGetApicBase(OUT PVOID *ApicBase)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
AcGetRsdpTable(OUT PVOID *AcpiTable) Acpi::GetRsdpTable(OUT PVOID *AcpiTable)
{ {
EFI_GUID AcpiGuid = EFI_CONFIG_TABLE_ACPI_TABLE_GUID; EFI_GUID AcpiGuid = EFI_CONFIG_TABLE_ACPI_TABLE_GUID;
EFI_STATUS Status; EFI_STATUS Status;
PVOID RsdpTable; PVOID RsdpTable;
/* 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->Utils.GetConfigurationTable(&AcpiGuid, &RsdpTable);
if(Status != STATUS_EFI_SUCCESS || !AcpValidateAcpiTable(RsdpTable, 20)) if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(RsdpTable, 20))
{ {
/* RSDP not found or checksum mismatch */ /* RSDP not found or checksum mismatch */
*AcpiTable = NULL; *AcpiTable = NULLPTR;
return STATUS_EFI_NOT_FOUND; return STATUS_EFI_NOT_FOUND;
} }
@@ -252,18 +253,18 @@ AcGetRsdpTable(OUT PVOID *AcpiTable)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
AcGetSMBiosTable(OUT PVOID *SmBiosTable) Acpi::GetSMBiosTable(OUT PVOID *SmBiosTable)
{ {
EFI_GUID SmBiosGuid = EFI_CONFIG_TABLE_SMBIOS_TABLE_GUID; EFI_GUID SmBiosGuid = EFI_CONFIG_TABLE_SMBIOS_TABLE_GUID;
PSMBIOS_TABLE_HEADER SmBios; PSMBIOS_TABLE_HEADER SmBios;
EFI_STATUS Status; EFI_STATUS Status;
/* Get SMBIOS table from system configuration tables */ /* Get SMBIOS table from system configuration tables */
Status = XtLdrProtocol->Util.GetConfigurationTable(&SmBiosGuid, (PVOID)&SmBios); Status = XtLdrProtocol->Utils.GetConfigurationTable(&SmBiosGuid, (PVOID*)&SmBios);
if(Status != STATUS_EFI_SUCCESS || !AcpValidateAcpiTable(SmBios, SmBios->Length)) if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(SmBios, SmBios->Length))
{ {
/* SMBIOS not found or checksum mismatch */ /* SMBIOS not found or checksum mismatch */
*SmBiosTable = NULL; *SmBiosTable = NULLPTR;
return STATUS_EFI_NOT_FOUND; return STATUS_EFI_NOT_FOUND;
} }
@@ -284,18 +285,18 @@ AcGetSMBiosTable(OUT PVOID *SmBiosTable)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
AcGetSMBios3Table(OUT PVOID *SmBiosTable) Acpi::GetSMBios3Table(OUT PVOID *SmBiosTable)
{ {
EFI_GUID SmBios3Guid = EFI_CONFIG_TABLE_SMBIOS3_TABLE_GUID; EFI_GUID SmBios3Guid = EFI_CONFIG_TABLE_SMBIOS3_TABLE_GUID;
PSMBIOS3_TABLE_HEADER SmBios; PSMBIOS3_TABLE_HEADER SmBios;
EFI_STATUS Status; EFI_STATUS Status;
/* Get SMBIOS3 table from system configuration tables */ /* Get SMBIOS3 table from system configuration tables */
Status = XtLdrProtocol->Util.GetConfigurationTable(&SmBios3Guid, (PVOID)&SmBios); Status = XtLdrProtocol->Utils.GetConfigurationTable(&SmBios3Guid, (PVOID*)&SmBios);
if(Status != STATUS_EFI_SUCCESS || !AcpValidateAcpiTable(SmBios, SmBios->Length)) if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(SmBios, SmBios->Length))
{ {
/* SMBIOS3 not found or checksum mismatch */ /* SMBIOS3 not found or checksum mismatch */
*SmBiosTable = NULL; *SmBiosTable = NULLPTR;
return STATUS_EFI_NOT_FOUND; return STATUS_EFI_NOT_FOUND;
} }
@@ -316,18 +317,18 @@ AcGetSMBios3Table(OUT PVOID *SmBiosTable)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
AcGetXsdpTable(OUT PVOID *AcpiTable) Acpi::GetXsdpTable(OUT PVOID *AcpiTable)
{ {
EFI_GUID AcpiGuid = EFI_CONFIG_TABLE_ACPI20_TABLE_GUID; EFI_GUID AcpiGuid = EFI_CONFIG_TABLE_ACPI20_TABLE_GUID;
EFI_STATUS Status; EFI_STATUS Status;
PVOID XsdpTable; PVOID XsdpTable;
/* 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->Utils.GetConfigurationTable(&AcpiGuid, &XsdpTable);
if(Status != STATUS_EFI_SUCCESS || !AcpValidateAcpiTable(XsdpTable, 36)) if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(XsdpTable, 36))
{ {
/* XSDP not found or checksum mismatch */ /* XSDP not found or checksum mismatch */
*AcpiTable = NULL; *AcpiTable = NULLPTR;
return STATUS_EFI_NOT_FOUND; return STATUS_EFI_NOT_FOUND;
} }
@@ -336,6 +337,48 @@ AcGetXsdpTable(OUT PVOID *AcpiTable)
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
/**
* Initializes ACPI module by opening XTLDR protocol and installing ACPI protocol.
*
* @param ImageHandle
* Firmware-allocated handle that identifies the image.
*
* @param SystemTable
* Provides the EFI system table.
*
* @return This routine returns status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
Acpi::InitializeModule(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable)
{
EFI_GUID Guid = XT_ACPI_PROTOCOL_GUID;
EFI_STATUS Status;
/* Open the XTLDR protocol */
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open the protocol, return error */
return STATUS_EFI_PROTOCOL_ERROR;
}
/* Set routines available via ACPI protocol */
AcpiProtocol.GetAcpiDescriptionPointer = GetAcpiDescriptionPointer;
AcpiProtocol.GetAcpiTable = GetAcpiTable;
AcpiProtocol.GetApicBase = GetApicBase;
AcpiProtocol.GetRsdpTable = GetRsdpTable;
AcpiProtocol.GetSMBiosTable = GetSMBiosTable;
AcpiProtocol.GetSMBios3Table = GetSMBios3Table;
AcpiProtocol.GetXsdpTable = GetXsdpTable;
/* Install ACPI protocol */
return XtLdrProtocol->Protocol.Install(&AcpiProtocol, &Guid);
}
/** /**
* Validates given ACPI table by calculating its checksum. * Validates given ACPI table by calculating its checksum.
* *
@@ -351,7 +394,7 @@ AcGetXsdpTable(OUT PVOID *AcpiTable)
*/ */
XTCDECL XTCDECL
BOOLEAN BOOLEAN
AcpValidateAcpiTable(IN PVOID Buffer, Acpi::ValidateAcpiTable(IN PVOID Buffer,
IN UINT_PTR Size) IN UINT_PTR Size)
{ {
PUCHAR Pointer; PUCHAR Pointer;
@@ -359,7 +402,7 @@ AcpValidateAcpiTable(IN PVOID Buffer,
/* Initialize variables */ /* Initialize variables */
Sum = 0; Sum = 0;
Pointer = Buffer; Pointer = (PUCHAR)Buffer;
/* Calculate checksum of given table */ /* Calculate checksum of given table */
while(Size != 0) while(Size != 0)
@@ -391,26 +434,6 @@ EFI_STATUS
XtLdrModuleMain(IN EFI_HANDLE ImageHandle, XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable) IN PEFI_SYSTEM_TABLE SystemTable)
{ {
EFI_GUID Guid = XT_ACPI_PROTOCOL_GUID; /* Initialize ACPI module */
EFI_STATUS Status; return Acpi::InitializeModule(ImageHandle, SystemTable);
/* Open the XTLDR protocol */
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open the protocol, return error */
return STATUS_EFI_PROTOCOL_ERROR;
}
/* Set routines available via ACPI protocol */
AcpAcpiProtocol.GetAcpiDescriptionPointer = AcGetAcpiDescriptionPointer;
AcpAcpiProtocol.GetAcpiTable = AcGetAcpiTable;
AcpAcpiProtocol.GetApicBase = AcGetApicBase;
AcpAcpiProtocol.GetRsdpTable = AcGetRsdpTable;
AcpAcpiProtocol.GetSMBiosTable = AcGetSMBiosTable;
AcpAcpiProtocol.GetSMBios3Table = AcGetSMBios3Table;
AcpAcpiProtocol.GetXsdpTable = AcGetXsdpTable;
/* Install ACPI protocol */
return XtLdrProtocol->Protocol.Install(&AcpAcpiProtocol, &Guid);
} }

View File

@@ -1,16 +1,16 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/acpi/globals.c * FILE: xtldr/modules/acpi/data.cc
* DESCRIPTION: ACPI module global variables * DESCRIPTION: ACPI module global and static data
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtblapi.h> #include <acpi.hh>
/* ACPI Protocol */ /* ACPI Protocol */
XTBL_ACPI_PROTOCOL AcpAcpiProtocol; XTBL_ACPI_PROTOCOL Acpi::AcpiProtocol;
/* XTLDR protocol handler */ /* XTLDR protocol handler */
PXTBL_LOADER_PROTOCOL XtLdrProtocol; PXTBL_LOADER_PROTOCOL Acpi::XtLdrProtocol;

View File

@@ -0,0 +1,40 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/acpi/includes/acpi.hh
* DESCRIPTION: XTLDR ACPI module header file
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTLDR_ACPI_ACPI_HH
#define __XTLDR_ACPI_ACPI_HH
#include <xtblapi.h>
/* ACPI module for XTLDR */
class Acpi
{
private:
STATIC XTBL_ACPI_PROTOCOL AcpiProtocol;
STATIC PXTBL_LOADER_PROTOCOL XtLdrProtocol;
public:
STATIC XTCDECL EFI_STATUS GetAcpiDescriptionPointer(OUT PVOID *AcpiTable);
STATIC XTCDECL EFI_STATUS GetAcpiTable(IN CONST UINT Signature,
IN PVOID PreviousTable,
OUT PVOID *AcpiTable);
STATIC XTCDECL EFI_STATUS GetApicBase(OUT PVOID *ApicBase);
STATIC XTCDECL EFI_STATUS GetRsdpTable(OUT PVOID *AcpiTable);
STATIC XTCDECL EFI_STATUS GetSMBiosTable(OUT PVOID *SmBiosTable);
STATIC XTCDECL EFI_STATUS GetSMBios3Table(OUT PVOID *SmBiosTable);
STATIC XTCDECL EFI_STATUS GetXsdpTable(OUT PVOID *AcpiTable);
STATIC XTCDECL EFI_STATUS InitializeModule(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable);
private:
STATIC XTCDECL BOOLEAN ValidateAcpiTable(IN PVOID Buffer,
IN UINT_PTR Size);
};
#endif /* __XTLDR_ACPI_ACPI_HH */

View File

@@ -8,8 +8,8 @@ include_directories(
# Specify list of source code files # Specify list of source code files
list(APPEND XTLDR_BEEP_SOURCE list(APPEND XTLDR_BEEP_SOURCE
${XTLDR_BEEP_SOURCE_DIR}/beep.c ${XTLDR_BEEP_SOURCE_DIR}/beep.cc
${XTLDR_BEEP_SOURCE_DIR}/globals.c) ${XTLDR_BEEP_SOURCE_DIR}/data.cc)
# Link module executable # Link module executable
add_executable(beep ${XTLDR_BEEP_SOURCE}) add_executable(beep ${XTLDR_BEEP_SOURCE})

View File

@@ -1,12 +1,12 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/beep/beep.c * FILE: xtldr/modules/beep/beep.cc
* DESCRIPTION: XTLDR Beep Module * DESCRIPTION: XTLDR Beep Module
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <beep.h> #include <beep.hh>
/* Beep module information */ /* Beep module information */
@@ -15,6 +15,7 @@ MODULE_DESCRIPTION(L"Plays a GRUB compatible tune via PC speaker");
MODULE_LICENSE(L"GPLv3"); MODULE_LICENSE(L"GPLv3");
MODULE_VERSION(L"0.1"); MODULE_VERSION(L"0.1");
/** /**
* Disables the PC speaker. * Disables the PC speaker.
* *
@@ -24,13 +25,13 @@ MODULE_VERSION(L"0.1");
*/ */
XTCDECL XTCDECL
VOID VOID
BpDisableToneBeep() Beep::DisableToneBeep()
{ {
UCHAR Status; UCHAR Status;
/* Stop the PC speaker */ /* Stop the PC speaker */
Status = HlIoPortInByte(0x61); Status = XtLdrProtocol->IoPort.Read8(0x61);
HlIoPortOutByte(0x61, Status & 0xFC); XtLdrProtocol->IoPort.Write8(0x61, Status & 0xFC);
} }
/** /**
@@ -45,7 +46,7 @@ BpDisableToneBeep()
*/ */
XTCDECL XTCDECL
VOID VOID
BpEnableToneBeep(IN UINT Pitch) Beep::EnableToneBeep(IN UINT Pitch)
{ {
UINT Counter; UINT Counter;
UCHAR Status; UCHAR Status;
@@ -62,14 +63,51 @@ BpEnableToneBeep(IN UINT Pitch)
/* Set the desired frequency of the PIT clock */ /* Set the desired frequency of the PIT clock */
Counter = 0x1234DD / Pitch; Counter = 0x1234DD / Pitch;
HlIoPortOutByte(0x43, 0xB6); XtLdrProtocol->IoPort.Write8(0x43, 0xB6);
HlIoPortOutByte(0x43, 0xB6); XtLdrProtocol->IoPort.Write8(0x43, 0xB6);
HlIoPortOutByte(0x42, (UCHAR) Counter & 0xFF); XtLdrProtocol->IoPort.Write8(0x42, (UCHAR) Counter & 0xFF);
HlIoPortOutByte(0x42, (UCHAR) (Counter >> 8) & 0xFF); XtLdrProtocol->IoPort.Write8(0x42, (UCHAR) (Counter >> 8) & 0xFF);
/* Start the PC speaker */ /* Start the PC speaker */
Status = HlIoPortInByte(0x61); Status = XtLdrProtocol->IoPort.Read8(0x61);
HlIoPortOutByte(0x61, Status | 0x03); XtLdrProtocol->IoPort.Write8(0x61, Status | 0x03);
}
/**
* Initializes BEEP module by opening XTLDR protocol and playing the tune.
*
* @param ImageHandle
* Firmware-allocated handle that identifies the image.
*
* @param SystemTable
* Provides the EFI system table.
*
* @return This routine returns status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
Beep::InitializeModule(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable)
{
EFI_STATUS Status;
PWCHAR Tune;
/* Open the XTLDR protocol */
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open the protocol, return error */
return STATUS_EFI_PROTOCOL_ERROR;
}
/* Play the tune set in the configuration */
XtLdrProtocol->Config.GetValue(L"TUNE", &Tune);
PlayTune(Tune);
/* Return success */
return STATUS_EFI_SUCCESS;
} }
/** /**
@@ -84,7 +122,7 @@ BpEnableToneBeep(IN UINT Pitch)
*/ */
XTCDECL XTCDECL
VOID VOID
BpPlayTune(IN PWCHAR Arguments) Beep::PlayTune(IN PWCHAR Arguments)
{ {
LONG Pitch, Duration, Tempo; LONG Pitch, Duration, Tempo;
PWCHAR Argument, LastArgument; PWCHAR Argument, LastArgument;
@@ -95,41 +133,41 @@ BpPlayTune(IN PWCHAR Arguments)
Tempo = -1; Tempo = -1;
/* Tokenize provided list of arguments */ /* Tokenize provided list of arguments */
Argument = RtlTokenizeWideString(Arguments, L" ", &LastArgument); Argument = XtLdrProtocol->WideString.Tokenize(Arguments, L" ", &LastArgument);
/* Iterate over all arguments */ /* Iterate over all arguments */
while(Argument != NULL) while(Argument != NULLPTR)
{ {
/* Check if tempo, pitch and duration are set */ /* Check if tempo, pitch and duration are set */
if(Tempo < 0) if(Tempo < 0)
{ {
/* Set the tempo */ /* Set the tempo */
Tempo = BpWideStringToNumber(Argument); Tempo = WideStringToNumber(Argument);
} }
else if(Pitch < 0) else if(Pitch < 0)
{ {
/* Set the pitch */ /* Set the pitch */
Pitch = BpWideStringToNumber(Argument); Pitch = WideStringToNumber(Argument);
} }
else else
{ {
/* Set the duration */ /* Set the duration */
Duration = BpWideStringToNumber(Argument); Duration = WideStringToNumber(Argument);
/* Check pitch value */ /* Check pitch value */
if(Pitch > 0) if(Pitch > 0)
{ {
/* Emit the beep tone */ /* Emit the beep tone */
BpEnableToneBeep(Pitch); EnableToneBeep(Pitch);
} }
else else
{ {
/* Stop emitting beep tone */ /* Stop emitting beep tone */
BpDisableToneBeep(); DisableToneBeep();
} }
/* Wait for duration time */ /* Wait for duration time */
XtLdrProtocol->Util.SleepExecution(60000 * Duration / Tempo); XtLdrProtocol->Utils.SleepExecution(60000 * Duration / Tempo);
/* Reset pitch and duration */ /* Reset pitch and duration */
Pitch = -1; Pitch = -1;
@@ -137,11 +175,11 @@ BpPlayTune(IN PWCHAR Arguments)
} }
/* Get next argument */ /* Get next argument */
Argument = RtlTokenizeWideString(NULL, L" ", &LastArgument); Argument = XtLdrProtocol->WideString.Tokenize(NULLPTR, L" ", &LastArgument);
} }
/* Stop emitting beep tone */ /* Stop emitting beep tone */
BpDisableToneBeep(); DisableToneBeep();
} }
/** /**
@@ -156,7 +194,7 @@ BpPlayTune(IN PWCHAR Arguments)
*/ */
XTCDECL XTCDECL
UINT UINT
BpWideStringToNumber(IN PWCHAR String) Beep::WideStringToNumber(IN PWCHAR String)
{ {
ULONG Number = 0; ULONG Number = 0;
@@ -195,19 +233,6 @@ EFI_STATUS
XtLdrModuleMain(IN EFI_HANDLE ImageHandle, XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable) IN PEFI_SYSTEM_TABLE SystemTable)
{ {
EFI_STATUS Status; /* Initialize BEEP module */
return Beep::InitializeModule(ImageHandle, SystemTable);
/* Open the XTLDR protocol */
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open the protocol, return error */
return STATUS_EFI_PROTOCOL_ERROR;
}
/* Play the tune set in the configuration */
BpPlayTune(XtLdrProtocol->Config.GetValue(L"TUNE"));
/* Return success */
return STATUS_EFI_SUCCESS;
} }

View File

@@ -1,13 +1,13 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/beep/globals.c * FILE: xtldr/modules/beep/data.cc
* DESCRIPTION: Beep module global variables * DESCRIPTION: BEEP module global and static data
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtblapi.h> #include <beep.hh>
/* XTLDR protocol handler */ /* XTLDR protocol handler */
PXTBL_LOADER_PROTOCOL XtLdrProtocol; PXTBL_LOADER_PROTOCOL Beep::XtLdrProtocol;

View File

@@ -0,0 +1,32 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/beep/includes/beep.hh
* DESCRIPTION: XTLDR Beep Module header file
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTLDR_BEEP_BEEP_HH
#define __XTLDR_BEEP_BEEP_HH
#include <xtblapi.h>
/* BEEP module for XTLDR */
class Beep
{
private:
STATIC PXTBL_LOADER_PROTOCOL XtLdrProtocol;
public:
STATIC XTCDECL EFI_STATUS InitializeModule(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable);
STATIC XTCDECL VOID PlayTune(IN PWCHAR Arguments);
private:
STATIC XTCDECL VOID DisableToneBeep();
STATIC XTCDECL VOID EnableToneBeep(IN UINT Pitch);
STATIC XTCDECL UINT WideStringToNumber(IN PWCHAR String);
};
#endif /* __XTLDR_BEEP_BEEP_HH */

View File

@@ -8,8 +8,8 @@ include_directories(
# Specify list of source code files # Specify list of source code files
list(APPEND XTLDR_CHAINLDR_SOURCE list(APPEND XTLDR_CHAINLDR_SOURCE
${XTLDR_CHAINLDR_SOURCE_DIR}/chainldr.c ${XTLDR_CHAINLDR_SOURCE_DIR}/chainldr.cc
${XTLDR_CHAINLDR_SOURCE_DIR}/globals.c) ${XTLDR_CHAINLDR_SOURCE_DIR}/data.cc)
# Link module executable # Link module executable
add_executable(chainldr ${XTLDR_CHAINLDR_SOURCE}) add_executable(chainldr ${XTLDR_CHAINLDR_SOURCE})

View File

@@ -1,12 +1,12 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/chainldr/chainldr.c * FILE: xtldr/modules/chainldr/chainldr.cc
* DESCRIPTION: XTLDR Chain Loader * DESCRIPTION: XTLDR Chain Loader
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <chainldr.h> #include <chainldr.hh>
/* ChainLoader module information */ /* ChainLoader module information */
@@ -15,6 +15,7 @@ MODULE_DESCRIPTION(L"XTLDR Chain Loader");
MODULE_LICENSE(L"GPLv3"); MODULE_LICENSE(L"GPLv3");
MODULE_VERSION(L"0.1"); MODULE_VERSION(L"0.1");
/** /**
* Chainloads another boot loader. * Chainloads another boot loader.
* *
@@ -27,7 +28,7 @@ MODULE_VERSION(L"0.1");
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
ChBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters) ChainLoader::BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
{ {
EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
EFI_MEMMAP_DEVICE_PATH MemoryDevicePath[2]; EFI_MEMMAP_DEVICE_PATH MemoryDevicePath[2];
@@ -39,7 +40,7 @@ ChBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
PVOID LoaderData; PVOID LoaderData;
/* Check if image file is provided */ /* Check if image file is provided */
if(Parameters->KernelFile == NULL) if(Parameters->KernelFile == NULLPTR)
{ {
/* No image filename provided, return error code */ /* No image filename provided, return error code */
XtLdrProtocol->Debug.Print(L"ERROR: No EFI image filename provided\n"); XtLdrProtocol->Debug.Print(L"ERROR: No EFI image filename provided\n");
@@ -66,14 +67,14 @@ ChBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
XtLdrProtocol->Debug.Print(L"ERROR: Unable to open system boot directory (Status Code: 0x%zX)\n", Status); XtLdrProtocol->Debug.Print(L"ERROR: Unable to open system boot directory (Status Code: 0x%zX)\n", Status);
/* Close volume and return error code */ /* Close volume and return error code */
XtLdrProtocol->Disk.CloseVolume(DiskHandle); XtLdrProtocol->Disk.CloseVolume(&DiskHandle);
return Status; return Status;
} }
/* Read EFI image file from disk and close both directory and EFI volume */ /* Read EFI image file from disk and close both directory and EFI volume */
Status = XtLdrProtocol->Disk.ReadFile(BootDir, Parameters->KernelFile, &LoaderData, &LoaderSize); Status = XtLdrProtocol->Disk.ReadFile(BootDir, Parameters->KernelFile, &LoaderData, &LoaderSize);
BootDir->Close(BootDir); BootDir->Close(BootDir);
XtLdrProtocol->Disk.CloseVolume(DiskHandle); XtLdrProtocol->Disk.CloseVolume(&DiskHandle);
/* Setup device path for EFI image */ /* Setup device path for EFI image */
MemoryDevicePath[0].Header.Length[0] = sizeof(EFI_MEMMAP_DEVICE_PATH); MemoryDevicePath[0].Header.Length[0] = sizeof(EFI_MEMMAP_DEVICE_PATH);
@@ -89,7 +90,7 @@ ChBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
MemoryDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP; MemoryDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP;
/* Load EFI image */ /* Load EFI image */
Status = XtLdrProtocol->Util.LoadEfiImage((PEFI_DEVICE_PATH_PROTOCOL)MemoryDevicePath, Status = XtLdrProtocol->Utils.LoadEfiImage((PEFI_DEVICE_PATH_PROTOCOL)MemoryDevicePath,
LoaderData, LoaderSize, &LoaderHandle); LoaderData, LoaderSize, &LoaderHandle);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
@@ -112,7 +113,7 @@ ChBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
if(Parameters->Parameters) if(Parameters->Parameters)
{ {
/* Pass arguments to chainloaded image */ /* Pass arguments to chainloaded image */
LoadedImage->LoadOptionsSize = RtlWideStringLength(Parameters->Parameters, 0) * sizeof(WCHAR); LoadedImage->LoadOptionsSize = XtLdrProtocol->WideString.Length(Parameters->Parameters, 0) * sizeof(WCHAR);
LoadedImage->LoadOptions = Parameters->Parameters; LoadedImage->LoadOptions = Parameters->Parameters;
} }
@@ -120,7 +121,46 @@ ChBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
LoadedImage->DeviceHandle = DiskHandle; LoadedImage->DeviceHandle = DiskHandle;
/* Chainload EFI image */ /* Chainload EFI image */
return XtLdrProtocol->Util.StartEfiImage(LoaderHandle); return XtLdrProtocol->Utils.StartEfiImage(LoaderHandle);
}
/**
* Initializes CHAINLDR module by opening XTLDR protocol and installing CHAINLOADER protocol.
*
* @param ImageHandle
* Firmware-allocated handle that identifies the image.
*
* @param SystemTable
* Provides the EFI system table.
*
* @return This routine returns status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
ChainLoader::InitializeModule(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable)
{
EFI_GUID Guid = XT_CHAIN_BOOT_PROTOCOL_GUID;
EFI_STATUS Status;
/* Open the XTLDR protocol */
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open the protocol, return error */
return STATUS_EFI_PROTOCOL_ERROR;
}
/* Set routines available via ChainLoader boot protocol */
BootProtocol.BootSystem = BootSystem;
/* Register XTOS boot protocol */
XtLdrProtocol->Boot.RegisterProtocol(L"CHAINLOADER", &Guid);
/* Install XTOS protocol */
return XtLdrProtocol->Protocol.Install(&BootProtocol, &Guid);
} }
/** /**
@@ -141,23 +181,6 @@ EFI_STATUS
XtLdrModuleMain(IN EFI_HANDLE ImageHandle, XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable) IN PEFI_SYSTEM_TABLE SystemTable)
{ {
EFI_GUID Guid = XT_CHAIN_BOOT_PROTOCOL_GUID; /* Initialize CHAINLDR module */
EFI_STATUS Status; return ChainLoader::InitializeModule(ImageHandle, SystemTable);
/* Open the XTLDR protocol */
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open the protocol, return error */
return STATUS_EFI_PROTOCOL_ERROR;
}
/* Set routines available via ChainLoader boot protocol */
ChpBootProtocol.BootSystem = ChBootSystem;
/* Register XTOS boot protocol */
XtLdrProtocol->Boot.RegisterProtocol(L"CHAINLOADER", &Guid);
/* Install XTOS protocol */
return XtLdrProtocol->Protocol.Install(&ChpBootProtocol, &Guid);
} }

View File

@@ -1,16 +1,16 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/chainldr/globals.c * FILE: xtldr/modules/chainldr/data.cc
* DESCRIPTION: XTLDR Chain Loader global variables * DESCRIPTION: CHAINLDR module global and static data
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtblapi.h> #include <chainldr.hh>
/* ChainLoader Boot Protocol */ /* ChainLoader Boot Protocol */
XTBL_BOOT_PROTOCOL ChpBootProtocol; XTBL_BOOT_PROTOCOL ChainLoader::BootProtocol;
/* XTLDR protocol handler */ /* XTLDR protocol handler */
PXTBL_LOADER_PROTOCOL XtLdrProtocol; PXTBL_LOADER_PROTOCOL ChainLoader::XtLdrProtocol;

View File

@@ -0,0 +1,28 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/chainldr/includes/chainldr.hh
* DESCRIPTION: XTLDR Chain Loader header file
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTLDR_CHAINLDR_CHAINLDR_HH
#define __XTLDR_CHAINLDR_CHAINLDR_HH
#include <xtblapi.h>
/* CHAINLDR module for XTLDR */
class ChainLoader
{
private:
STATIC XTBL_BOOT_PROTOCOL BootProtocol;
STATIC PXTBL_LOADER_PROTOCOL XtLdrProtocol;
public:
STATIC XTCDECL EFI_STATUS BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters);
STATIC XTCDECL EFI_STATUS InitializeModule(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable);
};
#endif /* __XTLDR_CHAINLDR_CHAINLDR_HH */

View File

@@ -8,8 +8,8 @@ include_directories(
# Specify list of source code files # Specify list of source code files
list(APPEND XTLDR_DUMMY_SOURCE list(APPEND XTLDR_DUMMY_SOURCE
${XTLDR_DUMMY_SOURCE_DIR}/dummy.c ${XTLDR_DUMMY_SOURCE_DIR}/dummy.cc
${XTLDR_DUMMY_SOURCE_DIR}/globals.c) ${XTLDR_DUMMY_SOURCE_DIR}/data.cc)
# Link module executable # Link module executable
add_executable(dummy ${XTLDR_DUMMY_SOURCE}) add_executable(dummy ${XTLDR_DUMMY_SOURCE})

View File

@@ -1,16 +1,16 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/dummy/globals.c * FILE: xtldr/modules/dummy/data.cc
* DESCRIPTION: Dummy XTLDR module global variables * DESCRIPTION: Dummy XTLDR module global and static data
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <dummy.h> #include <dummy.hh>
/* XTLDR protocol handler */
PXTBL_LOADER_PROTOCOL XtLdrProtocol;
/* Dummy Boot Protocol handler */ /* Dummy Boot Protocol handler */
XTBL_BOOT_PROTOCOL BlpDummyProtocol; XTBL_BOOT_PROTOCOL Dummy::DummyProtocol;
/* XTLDR protocol handler */
PXTBL_LOADER_PROTOCOL Dummy::XtLdrProtocol;

View File

@@ -1,12 +1,12 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/dummy/dummy.c * FILE: xtldr/modules/dummy/dummy.cc
* DESCRIPTION: XTLDR Dummy Module * DESCRIPTION: XTLDR Dummy Module
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <dummy.h> #include <dummy.hh>
/* Dummy module information */ /* Dummy module information */
@@ -15,6 +15,7 @@ MODULE_DESCRIPTION(L"XTLDR Dummy Module");
MODULE_LICENSE(L"GPLv3"); MODULE_LICENSE(L"GPLv3");
MODULE_VERSION(L"0.1"); MODULE_VERSION(L"0.1");
/** /**
* Stub boot routine. * Stub boot routine.
* *
@@ -27,11 +28,50 @@ MODULE_VERSION(L"0.1");
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
DmBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters) Dummy::BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
{ {
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
/**
* Initializes DUMMY module by opening XTLDR protocol and installing DUMMY protocol.
*
* @param ImageHandle
* Firmware-allocated handle that identifies the image.
*
* @param SystemTable
* Provides the EFI system table.
*
* @return This routine returns status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
Dummy::InitializeModule(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable)
{
EFI_GUID DummyGuid = XT_DUMMY_BOOT_PROTOCOL_GUID;
EFI_STATUS Status;
/* Open the XTLDR protocol */
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open the protocol, return error */
return STATUS_EFI_PROTOCOL_ERROR;
}
/* Set boot protocol routines */
DummyProtocol.BootSystem = BootSystem;
/* Register XTOS boot protocol */
XtLdrProtocol->Boot.RegisterProtocol(L"DUMMYOS", &DummyGuid);
/* Register DUMMY protocol as XTOS boot protocol */
return XtLdrProtocol->Protocol.Install(&DummyProtocol, &DummyGuid);
}
/** /**
* This routine is the entry point of the XT EFI boot loader module. * This routine is the entry point of the XT EFI boot loader module.
* *
@@ -50,23 +90,6 @@ EFI_STATUS
XtLdrModuleMain(IN EFI_HANDLE ImageHandle, XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable) IN PEFI_SYSTEM_TABLE SystemTable)
{ {
EFI_GUID DummyGuid = XT_DUMMY_BOOT_PROTOCOL_GUID; /* Initialize DUMMY module */
EFI_STATUS Status; return Dummy::InitializeModule(ImageHandle, SystemTable);
/* Open the XTLDR protocol */
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open the protocol, return error */
return STATUS_EFI_PROTOCOL_ERROR;
}
/* Set boot protocol routines */
BlpDummyProtocol.BootSystem = DmBootSystem;
/* Register XTOS boot protocol */
XtLdrProtocol->Boot.RegisterProtocol(L"DUMMYOS", &DummyGuid);
/* Register DUMMY protocol as XTOS boot protocol */
return XtLdrProtocol->Protocol.Install(&BlpDummyProtocol, &DummyGuid);
} }

View File

@@ -0,0 +1,28 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/dummy/includes/dummy.hh
* DESCRIPTION: XTLDR Dummy Module header file
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTLDR_DUMMY_DUMMY_HH
#define __XTLDR_DUMMY_DUMMY_HH
#include <xtblapi.h>
/* DUMMY module for XTLDR */
class Dummy
{
private:
STATIC XTBL_BOOT_PROTOCOL DummyProtocol;
STATIC PXTBL_LOADER_PROTOCOL XtLdrProtocol;
public:
STATIC EFI_STATUS BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters);
STATIC EFI_STATUS InitializeModule(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable);
};
#endif/* __XTLDR_DUMMY_DUMMY_HH */

View File

@@ -8,8 +8,8 @@ include_directories(
# Specify list of source code files # Specify list of source code files
list(APPEND XTLDR_FRAMEBUF_SOURCE list(APPEND XTLDR_FRAMEBUF_SOURCE
${XTLDR_FRAMEBUF_SOURCE_DIR}/framebuf.c ${XTLDR_FRAMEBUF_SOURCE_DIR}/framebuf.cc
${XTLDR_FRAMEBUF_SOURCE_DIR}/globals.c) ${XTLDR_FRAMEBUF_SOURCE_DIR}/data.cc)
# Link bootloader executable # Link bootloader executable
add_executable(framebuf ${XTLDR_FRAMEBUF_SOURCE}) add_executable(framebuf ${XTLDR_FRAMEBUF_SOURCE})

View File

@@ -0,0 +1,19 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/framebuf/data.cc
* DESCRIPTION: EFI framebuffer module global and static data
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <framebuf.hh>
/* Framebuffer display information */
XTBL_FRAMEBUFFER_INFORMATION FrameBuffer::DisplayInfo;
/* Framebuffer protocol handler */
XTBL_FRAMEBUFFER_PROTOCOL FrameBuffer::FbProtocol;
/* XTLDR protocol handler */
PXTBL_LOADER_PROTOCOL FrameBuffer::XtLdrProtocol;

View File

@@ -0,0 +1,44 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/framebuf/includes/framebuf.hh
* DESCRIPTION: EFI Framebuffer support module header file
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTLDR_MODULES_FRAMEBUF_HH
#define __XTLDR_MODULES_FRAMEBUF_HH
#include <xtblapi.h>
class FrameBuffer
{
private:
STATIC XTBL_FRAMEBUFFER_INFORMATION DisplayInfo;
STATIC XTBL_FRAMEBUFFER_PROTOCOL FbProtocol;
STATIC PXTBL_LOADER_PROTOCOL XtLdrProtocol;
public:
STATIC XTCDECL EFI_STATUS GetDisplayDriver(OUT PEFI_GRAPHICS_PROTOCOL Protocol);
STATIC XTCDECL EFI_STATUS GetDisplayInformation(OUT PEFI_PHYSICAL_ADDRESS FrameBufferBase,
OUT PULONG_PTR FrameBufferSize,
OUT PXTBL_FRAMEBUFFER_MODE_INFORMATION ModeInfo);
STATIC XTCDECL EFI_STATUS GetPreferredScreenResolution(OUT PUINT PreferredWidth,
OUT PUINT PreferredHeight);
STATIC XTCDECL EFI_STATUS InitializeDisplay();
STATIC XTCDECL EFI_STATUS InitializeModule(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable);
STATIC XTCDECL EFI_STATUS SetScreenResolution(IN UINT Width,
IN UINT Height);
private:
STATIC EFI_STATUS FindFramebufferAddress(OUT PEFI_PHYSICAL_ADDRESS Address);
STATIC XTCDECL VOID GetColorMask(IN UINT EfiMask,
OUT PUSHORT ColorSize,
OUT PUSHORT ColorShift);
STATIC XTCDECL EFI_STATUS GetModeInformation();
STATIC XTCDECL VOID GetPixelInformation(IN PEFI_PIXEL_BITMASK PixelsBitMask);
};
#endif /* __XTLDR_MODULES_FRAMEBUF_HH */

View File

@@ -8,8 +8,8 @@ include_directories(
# Specify list of source code files # Specify list of source code files
list(APPEND XTLDR_PECOFF_SOURCE list(APPEND XTLDR_PECOFF_SOURCE
${XTLDR_PECOFF_SOURCE_DIR}/globals.c ${XTLDR_PECOFF_SOURCE_DIR}/data.cc
${XTLDR_PECOFF_SOURCE_DIR}/pecoff.c) ${XTLDR_PECOFF_SOURCE_DIR}/pecoff.cc)
# Link module executable # Link module executable
add_executable(pecoff ${XTLDR_PECOFF_SOURCE}) add_executable(pecoff ${XTLDR_PECOFF_SOURCE})

View File

@@ -0,0 +1,16 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/pecoff/globals.cc
* DESCRIPTION: Basic PE/COFF executable file format global and static data
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <pecoff.hh>
/* XTOS PE/COFF Image Protocol */
XTBL_EXECUTABLE_IMAGE_PROTOCOL PeCoff::PeProtocol;
/* EFI XT Loader Protocol */
PXTBL_LOADER_PROTOCOL PeCoff::XtLdrProtocol;

View File

@@ -0,0 +1,53 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/pecoff/includes/pecoff.hh
* DESCRIPTION: Basic PE/COFF executable file format support header
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTLDR_PECOFF_HH
#define __XTLDR_PECOFF_HH
#include <xtblapi.h>
/* PE/COFF module for XTLDR */
class PeCoff
{
private:
STATIC XTBL_EXECUTABLE_IMAGE_PROTOCOL PeProtocol;
STATIC PXTBL_LOADER_PROTOCOL XtLdrProtocol;
public:
STATIC XTCDECL EFI_STATUS GetEntryPoint(IN PVOID ImagePointer,
OUT PVOID *EntryPoint);
STATIC XTCDECL EFI_STATUS GetFileSize(IN PVOID ImagePointer,
OUT PULONGLONG FileSize);
STATIC XTCDECL EFI_STATUS GetImageSize(IN PVOID ImagePointer,
OUT PUINT ImageSize);
STATIC XTCDECL EFI_STATUS GetMachineType(IN PVOID ImagePointer,
OUT PUSHORT MachineType);
STATIC XTCDECL EFI_STATUS GetSection(IN PVOID ImagePointer,
IN PCHAR SectionName,
OUT PULONG *RawData);
STATIC XTCDECL EFI_STATUS GetSubSystem(IN PVOID ImagePointer,
OUT PUSHORT SubSystem);
STATIC XTCDECL EFI_STATUS GetVersion(IN PVOID ImagePointer,
OUT PUSHORT Version);
STATIC XTCDECL EFI_STATUS InitializeModule(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable);
STATIC XTCDECL EFI_STATUS LoadImage(IN PEFI_FILE_HANDLE FileHandle,
IN LOADER_MEMORY_TYPE MemoryType,
IN PVOID VirtualAddress,
OUT PVOID *ImagePointer);
STATIC XTCDECL EFI_STATUS RelocateImage(IN PVOID ImagePointer,
IN EFI_VIRTUAL_ADDRESS Address);
STATIC XTCDECL EFI_STATUS UnloadImage(IN PVOID ImagePointer);
STATIC XTCDECL EFI_STATUS VerifyImage(IN PVOID ImagePointer);
private:
STATIC XTCDECL EFI_STATUS RelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image);
};
#endif /* __XTLDR_PECOFF_HH */

View File

@@ -1,12 +1,12 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/pecoff/pecoff.c * FILE: xtldr/modules/pecoff/pecoff.cc
* DESCRIPTION: Basic PE/COFF executable file format support module * DESCRIPTION: Basic PE/COFF executable file format support module
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <pecoff.h> #include <pecoff.hh>
/* PE/COFF_O module information */ /* PE/COFF_O module information */
@@ -15,6 +15,7 @@ MODULE_DESCRIPTION(L"Basic PE/COFF executable file format support");
MODULE_LICENSE(L"GPLv3"); MODULE_LICENSE(L"GPLv3");
MODULE_VERSION(L"0.1"); MODULE_VERSION(L"0.1");
/** /**
* Returns the address of the entry point. * Returns the address of the entry point.
* *
@@ -30,10 +31,13 @@ MODULE_VERSION(L"0.1");
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
PeGetEntryPoint(IN PVOID ImagePointer, PeCoff::GetEntryPoint(IN PVOID ImagePointer,
OUT PVOID *EntryPoint) OUT PVOID *EntryPoint)
{ {
PPECOFF_IMAGE_CONTEXT Image = ImagePointer; PPECOFF_IMAGE_CONTEXT Image;
/* Get PE/COFF image pointer*/
Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;
/* Validate input data */ /* Validate input data */
if(!Image || !Image->PeHeader) if(!Image || !Image->PeHeader)
@@ -46,12 +50,12 @@ PeGetEntryPoint(IN PVOID ImagePointer,
if(Image->PeHeader->OptionalHeader32.Magic == PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC) if(Image->PeHeader->OptionalHeader32.Magic == PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC)
{ {
/* Get entry point from 64-bit optional header */ /* Get entry point from 64-bit optional header */
*EntryPoint = (PUINT8)Image->VirtualAddress + Image->PeHeader->OptionalHeader64.AddressOfEntryPoint; *EntryPoint = (PUCHAR)Image->VirtualAddress + Image->PeHeader->OptionalHeader64.AddressOfEntryPoint;
} }
else else
{ {
/* Get entry point from 32-bit optional header */ /* Get entry point from 32-bit optional header */
*EntryPoint = (PUINT8)Image->VirtualAddress + Image->PeHeader->OptionalHeader32.AddressOfEntryPoint; *EntryPoint = (PUCHAR)Image->VirtualAddress + Image->PeHeader->OptionalHeader32.AddressOfEntryPoint;
} }
/* Return success */ /* Return success */
@@ -73,13 +77,13 @@ PeGetEntryPoint(IN PVOID ImagePointer,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
PeGetFileSize(IN PVOID ImagePointer, PeCoff::GetFileSize(IN PVOID ImagePointer,
OUT PULONGLONG FileSize) OUT PULONGLONG FileSize)
{ {
PPECOFF_IMAGE_CONTEXT Image; PPECOFF_IMAGE_CONTEXT Image;
/* Get PE/COFF image pointer*/ /* Get PE/COFF image pointer*/
Image = ImagePointer; Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;
/* Validate input data */ /* Validate input data */
if(!Image || !Image->ImageSize) if(!Image || !Image->ImageSize)
@@ -108,13 +112,13 @@ PeGetFileSize(IN PVOID ImagePointer,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
PeGetImageSize(IN PVOID ImagePointer, PeCoff::GetImageSize(IN PVOID ImagePointer,
OUT PUINT ImageSize) OUT PUINT ImageSize)
{ {
PPECOFF_IMAGE_CONTEXT Image; PPECOFF_IMAGE_CONTEXT Image;
/* Get PE/COFF image pointer*/ /* Get PE/COFF image pointer*/
Image = ImagePointer; Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;
/* Validate input data */ /* Validate input data */
if(!Image || !Image->ImageSize) if(!Image || !Image->ImageSize)
@@ -143,10 +147,13 @@ PeGetImageSize(IN PVOID ImagePointer,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
PeGetMachineType(IN PVOID ImagePointer, PeCoff::GetMachineType(IN PVOID ImagePointer,
OUT PUSHORT MachineType) OUT PUSHORT MachineType)
{ {
PPECOFF_IMAGE_CONTEXT Image = ImagePointer; PPECOFF_IMAGE_CONTEXT Image;
/* Get PE/COFF image pointer*/
Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;
/* Validate input data */ /* Validate input data */
if(!Image || !Image->PeHeader) if(!Image || !Image->PeHeader)
@@ -178,7 +185,7 @@ PeGetMachineType(IN PVOID ImagePointer,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
PeGetSection(IN PVOID ImagePointer, PeCoff::GetSection(IN PVOID ImagePointer,
IN PCHAR SectionName, IN PCHAR SectionName,
OUT PULONG *RawData) OUT PULONG *RawData)
{ {
@@ -188,7 +195,7 @@ PeGetSection(IN PVOID ImagePointer,
USHORT SectionIndex; USHORT SectionIndex;
/* Get PE/COFF image pointer*/ /* Get PE/COFF image pointer*/
Image = ImagePointer; Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;
/* Validate input data */ /* Validate input data */
if(!Image || !Image->PeHeader) if(!Image || !Image->PeHeader)
@@ -212,16 +219,16 @@ PeGetSection(IN PVOID ImagePointer,
} }
/* Get section name length */ /* Get section name length */
SectionNameLength = RtlStringLength(SectionName, 0); SectionNameLength = XtLdrProtocol->String.Length(SectionName, 0);
/* Iterate through all image sections */ /* Iterate through all image sections */
for(SectionIndex = 0; SectionIndex < Image->PeHeader->FileHeader.NumberOfSections; SectionIndex++) for(SectionIndex = 0; SectionIndex < Image->PeHeader->FileHeader.NumberOfSections; SectionIndex++)
{ {
/* Check section name */ /* Check section name */
if(RtlCompareString((PCHAR)SectionHeader[SectionIndex].Name, SectionName, SectionNameLength) == 0) if(XtLdrProtocol->String.Compare((PCHAR)SectionHeader[SectionIndex].Name, SectionName, SectionNameLength) == 0)
{ {
/* Store section address and return */ /* Store section address and return */
*RawData = Image->Data + SectionHeader[SectionIndex].PointerToRawData; *RawData = (PULONG)((PUCHAR)Image->Data + SectionHeader[SectionIndex].PointerToRawData);
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
} }
@@ -245,10 +252,13 @@ PeGetSection(IN PVOID ImagePointer,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
PeGetSubSystem(IN PVOID ImagePointer, PeCoff::GetSubSystem(IN PVOID ImagePointer,
OUT PUSHORT SubSystem) OUT PUSHORT SubSystem)
{ {
PPECOFF_IMAGE_CONTEXT Image = ImagePointer; PPECOFF_IMAGE_CONTEXT Image;
/* Get PE/COFF image pointer*/
Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;
/* Validate input data */ /* Validate input data */
if(!Image || !Image->PeHeader) if(!Image || !Image->PeHeader)
@@ -288,10 +298,13 @@ PeGetSubSystem(IN PVOID ImagePointer,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
PeGetVersion(IN PVOID ImagePointer, PeCoff::GetVersion(IN PVOID ImagePointer,
OUT PUSHORT Version) OUT PUSHORT Version)
{ {
PPECOFF_IMAGE_CONTEXT Image = ImagePointer; PPECOFF_IMAGE_CONTEXT Image;
/* Get PE/COFF image pointer*/
Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;
/* Validate input data */ /* Validate input data */
if(!Image || !Image->PeHeader) if(!Image || !Image->PeHeader)
@@ -316,6 +329,52 @@ PeGetVersion(IN PVOID ImagePointer,
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
/**
* Initializes PECOFF module by opening XTLDR protocol and installing PECOFF protocol.
*
* @param ImageHandle
* Firmware-allocated handle that identifies the image.
*
* @param SystemTable
* Provides the EFI system table.
*
* @return This routine returns status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
PeCoff::InitializeModule(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable)
{
EFI_GUID Guid = XT_PECOFF_IMAGE_PROTOCOL_GUID;
EFI_STATUS Status;
/* Open the XTLDR protocol */
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open loader protocol */
return STATUS_EFI_PROTOCOL_ERROR;
}
/* Set routines available via PE/COFF image protocol */
PeProtocol.GetEntryPoint = GetEntryPoint;
PeProtocol.GetFileSize = GetFileSize;
PeProtocol.GetImageSize = GetImageSize;
PeProtocol.GetMachineType = GetMachineType;
PeProtocol.GetSection = GetSection;
PeProtocol.GetSubSystem = GetSubSystem;
PeProtocol.GetVersion = GetVersion;
PeProtocol.LoadImage = LoadImage;
PeProtocol.RelocateImage = RelocateImage;
PeProtocol.UnloadImage = UnloadImage;
PeProtocol.VerifyImage = VerifyImage;
/* Register PE/COFF protocol */
return XtLdrProtocol->Protocol.Install(&PeProtocol, &Guid);
}
/** /**
* Loads a PE/COFF image file. * Loads a PE/COFF image file.
* *
@@ -337,7 +396,7 @@ PeGetVersion(IN PVOID ImagePointer,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, PeCoff::LoadImage(IN PEFI_FILE_HANDLE FileHandle,
IN LOADER_MEMORY_TYPE MemoryType, IN LOADER_MEMORY_TYPE MemoryType,
IN PVOID VirtualAddress, IN PVOID VirtualAddress,
OUT PVOID *ImagePointer) OUT PVOID *ImagePointer)
@@ -400,7 +459,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
} }
/* Store file size and memory type, nullify data and free up memory */ /* Store file size and memory type, nullify data and free up memory */
ImageData->Data = NULL; ImageData->Data = NULLPTR;
ImageData->FileSize = FileInfo->FileSize; ImageData->FileSize = FileInfo->FileSize;
ImageData->MemoryType = MemoryType; ImageData->MemoryType = MemoryType;
XtLdrProtocol->Memory.FreePool(FileInfo); XtLdrProtocol->Memory.FreePool(FileInfo);
@@ -409,7 +468,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 */
@@ -433,10 +492,10 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
/* Extract DOS and PE headers */ /* Extract DOS and PE headers */
ImageData->DosHeader = (PPECOFF_IMAGE_DOS_HEADER)Data; ImageData->DosHeader = (PPECOFF_IMAGE_DOS_HEADER)Data;
ImageData->PeHeader = (PPECOFF_IMAGE_PE_HEADER)((PUINT8)Data + ImageData->DosHeader->PeHeaderOffset); ImageData->PeHeader = (PPECOFF_IMAGE_PE_HEADER)((PUCHAR)Data + ImageData->DosHeader->PeHeaderOffset);
/* Validate headers */ /* Validate headers */
Status = PeVerifyImage(ImageData); Status = PeCoff::VerifyImage(ImageData);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Header validation failed, probably broken or invalid PE/COFF image */ /* Header validation failed, probably broken or invalid PE/COFF image */
@@ -472,7 +531,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 */
@@ -482,7 +541,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
} }
/* Store image data and virtual address */ /* Store image data and virtual address */
ImageData->Data = (PUINT8)(UINT_PTR)Address; ImageData->Data = (PUCHAR)(UINT_PTR)Address;
ImageData->PhysicalAddress = (PVOID)(UINT_PTR)Address; ImageData->PhysicalAddress = (PVOID)(UINT_PTR)Address;
if(VirtualAddress) if(VirtualAddress)
{ {
@@ -534,7 +593,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
if(SectionSize > 0 && SectionHeader[Index].PointerToRawData != 0) if(SectionSize > 0 && SectionHeader[Index].PointerToRawData != 0)
{ {
/* Copy section */ /* Copy section */
XtLdrProtocol->Memory.CopyMemory((PUINT8)ImageData->Data + SectionHeader[Index].VirtualAddress, XtLdrProtocol->Memory.CopyMemory((PUCHAR)ImageData->Data + SectionHeader[Index].VirtualAddress,
Data + SectionHeader[Index].PointerToRawData, SectionSize); Data + SectionHeader[Index].PointerToRawData, SectionSize);
} }
@@ -542,7 +601,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
if(SectionSize < SectionHeader[Index].Misc.VirtualSize) if(SectionSize < SectionHeader[Index].Misc.VirtualSize)
{ {
/* Fill remaining space with zeroes */ /* Fill remaining space with zeroes */
XtLdrProtocol->Memory.ZeroMemory((PUINT8)ImageData->Data + SectionHeader[Index].VirtualAddress + SectionSize, XtLdrProtocol->Memory.ZeroMemory((PUCHAR)ImageData->Data + SectionHeader[Index].VirtualAddress + SectionSize,
SectionHeader[Index].Misc.VirtualSize - SectionSize); SectionHeader[Index].Misc.VirtualSize - SectionSize);
} }
} }
@@ -551,7 +610,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
XtLdrProtocol->Memory.FreePages((EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data, Pages); XtLdrProtocol->Memory.FreePages((EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data, Pages);
/* Perform relocation fixups */ /* Perform relocation fixups */
Status = PepRelocateLoadedImage(ImageData); Status = PeCoff::RelocateLoadedImage(ImageData);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to relocate image */ /* Failed to relocate image */
@@ -581,14 +640,16 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
PeRelocateImage(IN PVOID ImagePointer, PeCoff::RelocateImage(IN PVOID ImagePointer,
IN EFI_VIRTUAL_ADDRESS Address) IN EFI_VIRTUAL_ADDRESS Address)
{ {
PPECOFF_IMAGE_CONTEXT Image = ImagePointer; PPECOFF_IMAGE_CONTEXT Image;
ULONGLONG ImageBase, OldVirtualAddress;
UINT64 ImageBase, OldVirtualAddress;
EFI_STATUS Status; EFI_STATUS Status;
/* Get PE/COFF image pointer*/
Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;
/* Store original virtual address */ /* Store original virtual address */
OldVirtualAddress = (UINT_PTR)Image->VirtualAddress; OldVirtualAddress = (UINT_PTR)Image->VirtualAddress;
@@ -606,7 +667,7 @@ PeRelocateImage(IN PVOID ImagePointer,
/* Overwrite virtual address and relocate image once again */ /* Overwrite virtual address and relocate image once again */
Image->VirtualAddress = (PVOID)(Address - OldVirtualAddress + ImageBase); Image->VirtualAddress = (PVOID)(Address - OldVirtualAddress + ImageBase);
Status = PepRelocateLoadedImage(Image); Status = PeCoff::RelocateLoadedImage(Image);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Relocation failed */ /* Relocation failed */
@@ -620,98 +681,6 @@ PeRelocateImage(IN PVOID ImagePointer,
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
/**
* Unloads a PE/COFF image file and frees allocated memory.
*
* @param ImagePointer
* Supplies a pointer to the PE/COFF context structure representing the loaded image.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
PeUnloadImage(IN PVOID ImagePointer)
{
PPECOFF_IMAGE_CONTEXT Image;
EFI_STATUS Status;
/* Get PE/COFF image pointer*/
Image = ImagePointer;
/* Validate input data */
if(!Image || !Image->Data)
{
/* Invalid parameter passed */
return STATUS_EFI_INVALID_PARAMETER;
}
/* Free memory allocated for the image */
Status = XtLdrProtocol->Memory.FreePages(Image->ImagePages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)Image->Data);
Status |= XtLdrProtocol->Memory.FreePool(Image);
/* Return status */
return Status;
}
/**
* Validates a PE/COFF image headers.
*
* @param ImagePointer
* Supplies a pointer to the PE/COFF context structure representing the loaded image.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
PeVerifyImage(IN PVOID ImagePointer)
{
PPECOFF_IMAGE_CONTEXT Image = ImagePointer;
/* Validate input data */
if(!Image || !Image->PeHeader)
{
/* Invalid parameter passed */
return STATUS_EFI_INVALID_PARAMETER;
}
/* Validate file size */
if(Image->FileSize < sizeof(PECOFF_IMAGE_DOS_HEADER))
{
/* PE/COFF image shorter than DOS header, return error*/
return STATUS_EFI_END_OF_FILE;
}
/* Validate DOS header */
if(Image->DosHeader->Magic != PECOFF_IMAGE_DOS_SIGNATURE)
{
/* Invalid DOS signature, return error */
return STATUS_EFI_INCOMPATIBLE_VERSION;
}
/* Validate PE header */
if(Image->PeHeader->Signature != PECOFF_IMAGE_NT_SIGNATURE &&
Image->PeHeader->Signature != PECOFF_IMAGE_XT_SIGNATURE)
{
/* Invalid PE signature, return error */
return STATUS_EFI_INCOMPATIBLE_VERSION;
}
/* Validate optional header */
if(Image->PeHeader->OptionalHeader32.Magic != PECOFF_IMAGE_PE_OPTIONAL_HDR32_MAGIC &&
Image->PeHeader->OptionalHeader64.Magic != PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC)
{
/* Invalid optional header signature, return error */
return STATUS_EFI_INCOMPATIBLE_VERSION;
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
/** /**
* Relocates a loaded PE/COFF image. * Relocates a loaded PE/COFF image.
* *
@@ -724,15 +693,15 @@ PeVerifyImage(IN PVOID ImagePointer)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
PepRelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image) PeCoff::RelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image)
{ {
PPECOFF_IMAGE_BASE_RELOCATION RelocationDir, RelocationEnd; PPECOFF_IMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
PPECOFF_IMAGE_DATA_DIRECTORY DataDirectory; PPECOFF_IMAGE_DATA_DIRECTORY DataDirectory;
USHORT Offset, Type, Count; USHORT Offset, Type, Count;
PUSHORT TypeOffset; PUSHORT TypeOffset;
UINT64 ImageBase; ULONGLONG ImageBase;
PUINT32 Address; PUINT Address;
PUINT64 LongPtr; PULONGLONG LongPtr;
PUINT ShortPtr; PUINT ShortPtr;
/* Make sure image is not stripped */ /* Make sure image is not stripped */
@@ -793,7 +762,7 @@ PepRelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image)
Type = *TypeOffset >> 12; Type = *TypeOffset >> 12;
/* Check if end of the loaded address reached */ /* Check if end of the loaded address reached */
if((PVOID)(PUSHORT)(Address + Offset) >= Image->Data + Image->ImageSize) if((PVOID)(PUSHORT)(Address + Offset) >= (PUCHAR)Image->Data + Image->ImageSize)
{ {
/* Do not relocate after the end of loaded image */ /* Do not relocate after the end of loaded image */
break; break;
@@ -816,7 +785,7 @@ PepRelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image)
break; break;
case PECOFF_IMAGE_REL_BASED_HIGHLOW: case PECOFF_IMAGE_REL_BASED_HIGHLOW:
/* 32-bit relocation of hight and low half of address */ /* 32-bit relocation of hight and low half of address */
ShortPtr = (PUINT32)((PUCHAR)Address + Offset); ShortPtr = (PUINT)((PUCHAR)Address + Offset);
*ShortPtr = *ShortPtr - ImageBase + (UINT_PTR)Image->VirtualAddress; *ShortPtr = *ShortPtr - ImageBase + (UINT_PTR)Image->VirtualAddress;
break; break;
default: default:
@@ -836,6 +805,101 @@ PepRelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image)
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
/**
* Unloads a PE/COFF image file and frees allocated memory.
*
* @param ImagePointer
* Supplies a pointer to the PE/COFF context structure representing the loaded image.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
PeCoff::UnloadImage(IN PVOID ImagePointer)
{
PPECOFF_IMAGE_CONTEXT Image;
EFI_STATUS Status;
/* Get PE/COFF image pointer*/
Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;
/* Validate input data */
if(!Image || !Image->Data)
{
/* Invalid parameter passed */
return STATUS_EFI_INVALID_PARAMETER;
}
/* Free memory allocated for the image */
Status = XtLdrProtocol->Memory.FreePages(Image->ImagePages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)Image->Data);
Status |= XtLdrProtocol->Memory.FreePool(Image);
/* Return status */
return Status;
}
/**
* Validates a PE/COFF image headers.
*
* @param ImagePointer
* Supplies a pointer to the PE/COFF context structure representing the loaded image.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
PeCoff::VerifyImage(IN PVOID ImagePointer)
{
PPECOFF_IMAGE_CONTEXT Image;
/* Get PE/COFF image pointer*/
Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;
/* Validate input data */
if(!Image || !Image->PeHeader)
{
/* Invalid parameter passed */
return STATUS_EFI_INVALID_PARAMETER;
}
/* Validate file size */
if(Image->FileSize < sizeof(PECOFF_IMAGE_DOS_HEADER))
{
/* PE/COFF image shorter than DOS header, return error*/
return STATUS_EFI_END_OF_FILE;
}
/* Validate DOS header */
if(Image->DosHeader->Magic != PECOFF_IMAGE_DOS_SIGNATURE)
{
/* Invalid DOS signature, return error */
return STATUS_EFI_INCOMPATIBLE_VERSION;
}
/* Validate PE header */
if(Image->PeHeader->Signature != PECOFF_IMAGE_NT_SIGNATURE &&
Image->PeHeader->Signature != PECOFF_IMAGE_XT_SIGNATURE)
{
/* Invalid PE signature, return error */
return STATUS_EFI_INCOMPATIBLE_VERSION;
}
/* Validate optional header */
if(Image->PeHeader->OptionalHeader32.Magic != PECOFF_IMAGE_PE_OPTIONAL_HDR32_MAGIC &&
Image->PeHeader->OptionalHeader64.Magic != PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC)
{
/* Invalid optional header signature, return error */
return STATUS_EFI_INCOMPATIBLE_VERSION;
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
/** /**
* This routine is the entry point of the XT EFI boot loader module. * This routine is the entry point of the XT EFI boot loader module.
* *
@@ -854,30 +918,6 @@ EFI_STATUS
XtLdrModuleMain(IN EFI_HANDLE ImageHandle, XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable) IN PEFI_SYSTEM_TABLE SystemTable)
{ {
EFI_GUID Guid = XT_PECOFF_IMAGE_PROTOCOL_GUID; /* Initialize PECOFF module */
EFI_STATUS Status; return PeCoff::InitializeModule(ImageHandle, SystemTable);
/* Open the XTLDR protocol */
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open loader protocol */
return STATUS_EFI_PROTOCOL_ERROR;
}
/* Set routines available via PE/COFF image protocol */
PeCoffProtocol.GetEntryPoint = PeGetEntryPoint;
PeCoffProtocol.GetFileSize = PeGetFileSize;
PeCoffProtocol.GetImageSize = PeGetImageSize;
PeCoffProtocol.GetMachineType = PeGetMachineType;
PeCoffProtocol.GetSection = PeGetSection;
PeCoffProtocol.GetSubSystem = PeGetSubSystem;
PeCoffProtocol.GetVersion = PeGetVersion;
PeCoffProtocol.LoadImage = PeLoadImage;
PeCoffProtocol.RelocateImage = PeRelocateImage;
PeCoffProtocol.UnloadImage = PeUnloadImage;
PeCoffProtocol.VerifyImage = PeVerifyImage;
/* Register PE/COFF protocol */
return XtLdrProtocol->Protocol.Install(&PeCoffProtocol, &Guid);
} }

View File

@@ -8,8 +8,9 @@ include_directories(
# Specify list of source code files # Specify list of source code files
list(APPEND XTLDR_XTOS_O_SOURCE list(APPEND XTLDR_XTOS_O_SOURCE
${XTLDR_XTOS_O_SOURCE_DIR}/${ARCH}/memory.c ${XTLDR_XTOS_O_SOURCE_DIR}/${ARCH}/memory.cc
${XTLDR_XTOS_O_SOURCE_DIR}/xtos.c) ${XTLDR_XTOS_O_SOURCE_DIR}/data.cc
${XTLDR_XTOS_O_SOURCE_DIR}/xtos.cc)
# Link bootloader executable # Link bootloader executable
add_executable(xtos_o ${XTLDR_XTOS_O_SOURCE}) add_executable(xtos_o ${XTLDR_XTOS_O_SOURCE})

View File

@@ -1,13 +1,13 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/amd64/memory.c * FILE: xtldr/amd64/memory.cc
* 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> * Aiken Harris <harraiken91@gmail.com>
*/ */
#include <xtos.h> #include <xtos.hh>
/** /**
@@ -22,30 +22,30 @@
*/ */
XTCDECL XTCDECL
ULONG ULONG
XtpDeterminePagingLevel(IN CONST PWCHAR Parameters) Xtos::DeterminePagingLevel(IN CONST PWCHAR Parameters)
{ {
CPUID_REGISTERS CpuRegisters; CPUID_REGISTERS CpuRegisters;
/* Prepare CPUID registers to query for STD7 features */ /* Prepare CPUID registers to query for STD7 features */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); XtLdrProtocol->Memory.ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING; CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
/* Query CPUID */ /* Query CPUID */
ArCpuId(&CpuRegisters); XtLdrProtocol->Cpu.CpuId(&CpuRegisters);
/* Verify if the CPU supports the STD7 feature leaf (0x00000007) */ /* Verify if the CPU supports the STD7 feature leaf (0x00000007) */
if(CpuRegisters.Eax >= CPUID_GET_STANDARD7_FEATURES) if(CpuRegisters.Eax >= CPUID_GET_STANDARD7_FEATURES)
{ {
/* Prepare CPUID registers to query for LA57 support */ /* Prepare CPUID registers to query for LA57 support */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); XtLdrProtocol->Memory.ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_STANDARD7_FEATURES; CpuRegisters.Leaf = CPUID_GET_STANDARD7_FEATURES;
/* Query CPUID */ /* Query CPUID */
ArCpuId(&CpuRegisters); XtLdrProtocol->Cpu.CpuId(&CpuRegisters);
/* Check if eXtended Physical Addressing (XPA) is enabled and if LA57 is supported by the CPU */ /* Check if eXtended Physical Addressing (XPA) is enabled and if LA57 is supported by the CPU */
if((CpuRegisters.Ecx & CPUID_FEATURES_ECX_LA57) && if((CpuRegisters.Ecx & CPUID_FEATURES_ECX_LA57) &&
!(XtLdrProtocol->BootUtil.GetBooleanParameter(Parameters, L"NOXPA"))) !(XtLdrProtocol->BootUtils.GetBooleanParameter(Parameters, L"NOXPA")))
{ {
/* Enable LA57 (PML5) */ /* Enable LA57 (PML5) */
return 5; return 5;
@@ -56,6 +56,106 @@ XtpDeterminePagingLevel(IN CONST PWCHAR Parameters)
return 4; return 4;
} }
/**
* Builds the actual memory mapping page table and enables paging. This routine exits EFI boot services as well.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
{
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS TrampolineAddress;
PXT_TRAMPOLINE_ENTRY TrampolineEntry;
ULONG_PTR TrampolineSize;
PVOID TrampolineCode;
/* Build page map */
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, (PageMap->PageMapLevel > 4) ? MM_P5E_LA57_BASE : MM_PXE_BASE);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to build page map */
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
return Status;
}
/* Map memory for hardware layer */
Status = MapHardwareMemoryPool(PageMap);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to map memory for hardware layer */
XtLdrProtocol->Debug.Print(L"Failed to map memory for hardware leyer (Status code: %zX)\n", Status);
return Status;
}
/* Check the configured page map level to set the LA57 state accordingly */
if(PageMap->PageMapLevel == 5)
{
/* Get the trampoline code information */
XtLdrProtocol->BootUtils.GetTrampolineInformation(TrampolineEnableXpa, &TrampolineCode, &TrampolineSize);
if(TrampolineCode == NULLPTR || TrampolineSize == 0)
{
/* Failed to get trampoline information */
XtLdrProtocol->Debug.Print(L"Failed to get trampoline information\n");
return STATUS_EFI_INVALID_PARAMETER;
}
/* Set the address of the trampoline code below 1MB */
TrampolineAddress = MM_TRAMPOLINE_ADDRESS;
/* 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;
XtLdrProtocol->Memory.CopyMemory((PVOID)TrampolineEntry, TrampolineCode, TrampolineSize);
}
/* Exit EFI Boot Services */
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
Status = XtLdrProtocol->Utils.ExitBootServices();
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to exit boot services */
XtLdrProtocol->Debug.Print(L"Failed to exit boot services (Status code: %zX)\n", Status);
return STATUS_EFI_ABORTED;
}
/* 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 */
XtLdrProtocol->Cpu.WriteControlRegister(3, (UINT_PTR)PageMap->PtePointer);
XtLdrProtocol->Cpu.WriteControlRegister(0, XtLdrProtocol->Cpu.ReadControlRegister(0) | CR0_PG);
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
/** /**
* Maps the page table for hardware layer addess space. * Maps the page table for hardware layer addess space.
* *
@@ -68,27 +168,56 @@ XtpDeterminePagingLevel(IN CONST PWCHAR Parameters)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap) Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
{ {
PHARDWARE_PTE PdeBase, PpeBase, PxeBase; PHARDWARE_PTE P5eBase, PdeBase, PpeBase, PxeBase;
EFI_PHYSICAL_ADDRESS Address; EFI_PHYSICAL_ADDRESS Address;
EFI_STATUS Status; EFI_STATUS Status;
/* Check page map level */ if(PageMap->PageMapLevel == 5)
if(PageMap->PageMapLevel > 4)
{ {
/* PML5 (LA57) is not supported yet */ /* Get P5E (PML5) base address */
return STATUS_EFI_UNSUPPORTED; 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 */
XtLdrProtocol->Memory.ZeroMemory((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 */ /* Get PXE (PML4) base address */
PxeBase = ((PHARDWARE_PTE)(PageMap->PtePointer)); PxeBase = (PHARDWARE_PTE)PageMap->PtePointer;
}
/* Check if PXE entry already exists */ /* Check if PXE entry already exists */
if(!PxeBase[(MM_HARDWARE_VA_START >> MM_PXI_SHIFT) & 0x1FF].Valid) if(!PxeBase[(MM_HARDWARE_VA_START >> MM_PXI_SHIFT) & 0x1FF].Valid)
{ {
/* No valid PXE, allocate memory */ /* No valid PXE, allocate memory */
Status = XtLdrProtocol->Memory.AllocatePages(1, &Address); Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure, return error */ /* Memory allocation failure, return error */
@@ -96,7 +225,7 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
} }
/* Zero fill memory used by PXE */ /* Zero fill memory used by PXE */
RtlZeroMemory((PVOID)Address, EFI_PAGE_SIZE); XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
/* Make PXE valid */ /* Make PXE valid */
PxeBase[(MM_HARDWARE_VA_START >> MM_PXI_SHIFT) & 0x1FF].Valid = 1; PxeBase[(MM_HARDWARE_VA_START >> MM_PXI_SHIFT) & 0x1FF].Valid = 1;
@@ -116,7 +245,7 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
if(!PpeBase[(MM_HARDWARE_VA_START >> MM_PPI_SHIFT) & 0x1FF].Valid) if(!PpeBase[(MM_HARDWARE_VA_START >> MM_PPI_SHIFT) & 0x1FF].Valid)
{ {
/* No valid PPE, allocate memory */ /* No valid PPE, allocate memory */
Status = XtLdrProtocol->Memory.AllocatePages(1, &Address); Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure, return error */ /* Memory allocation failure, return error */
@@ -124,7 +253,7 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
} }
/* Zero fill memory used by PPE */ /* Zero fill memory used by PPE */
RtlZeroMemory((PVOID)Address, EFI_PAGE_SIZE); XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
/* Make PPE valid */ /* Make PPE valid */
PpeBase[(MM_HARDWARE_VA_START >> MM_PPI_SHIFT) & 0x1FF].Valid = 1; PpeBase[(MM_HARDWARE_VA_START >> MM_PPI_SHIFT) & 0x1FF].Valid = 1;
@@ -147,7 +276,7 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
if(!PdeBase[((MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF) + Index].Valid) if(!PdeBase[((MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF) + Index].Valid)
{ {
/* No valid PDE, allocate memory */ /* No valid PDE, allocate memory */
Status = XtLdrProtocol->Memory.AllocatePages(1, &Address); Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure, return error */ /* Memory allocation failure, return error */
@@ -155,7 +284,7 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
} }
/* Zero fill memory used by PDE */ /* Zero fill memory used by PDE */
RtlZeroMemory((PVOID)Address, EFI_PAGE_SIZE); XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
/* Make PDE valid */ /* 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].Valid = 1;
@@ -167,69 +296,3 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
/* Return success */ /* Return success */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
/**
* Builds the actual memory mapping page table and enables paging. This routine exits EFI boot services as well.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
{
EFI_STATUS Status;
/* Build page map */
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, 0xFFFFF6FB7DBED000);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to build page map */
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
return Status;
}
/* Map memory for hardware layer */
Status = 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;
}
/* Exit EFI Boot Services */
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
Status = XtLdrProtocol->Util.ExitBootServices();
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to exit boot services */
XtLdrProtocol->Debug.Print(L"Failed to exit boot services (Status code: %zX)\n", Status);
return STATUS_EFI_ABORTED;
}
/* 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");
}
else
{
/* Disable Linear Address 57-bit (LA57) extension */
XtLdrProtocol->Debug.Print(L"Disabling Linear Address 57-bit (LA57)\n");
}
/* Write PML4 to CR3 */
ArWriteControlRegister(3, (UINT_PTR)PageMap->PtePointer);
/* Enable paging */
ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_PG);
/* Return success */
return STATUS_EFI_SUCCESS;
}

View File

@@ -0,0 +1,19 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/xtos/data.cc
* DESCRIPTION: XTOS module global and static data
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.hh>
/* XTOS Boot Protocol */
XTBL_BOOT_PROTOCOL Xtos::BootProtocol;
/* XTOS PE/COFF Image Protocol */
PXTBL_EXECUTABLE_IMAGE_PROTOCOL Xtos::PeCoffProtocol;
/* EFI XT Loader Protocol */
PXTBL_LOADER_PROTOCOL Xtos::XtLdrProtocol;

View File

@@ -1,12 +1,12 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/i686/memory.c * FILE: xtldr/i686/memory.cc
* DESCRIPTION: EFI memory management for i686 target * DESCRIPTION: EFI memory management for i686 target
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/** /**
@@ -21,20 +21,20 @@
*/ */
XTCDECL XTCDECL
ULONG ULONG
XtpDeterminePagingLevel(IN CONST PWCHAR Parameters) Xtos::DeterminePagingLevel(IN CONST PWCHAR Parameters)
{ {
CPUID_REGISTERS CpuRegisters; CPUID_REGISTERS CpuRegisters;
/* Prepare CPUID registers to query for PAE support */ /* Prepare CPUID registers to query for PAE support */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); XtLdrProtocol->Memory.ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES; CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
/* Query CPUID */ /* Query CPUID */
ArCpuId(&CpuRegisters); XtLdrProtocol->Cpu.CpuId(&CpuRegisters);
/* Check if eXtended Physical Addressing (XPA) is enabled and if PAE is supported by the CPU */ /* Check if eXtended Physical Addressing (XPA) is enabled and if PAE is supported by the CPU */
if((CpuRegisters.Edx & CPUID_FEATURES_EDX_PAE) && if((CpuRegisters.Edx & CPUID_FEATURES_EDX_PAE) &&
!(XtLdrProtocol->BootUtil.GetBooleanParameter(Parameters, L"NOXPA"))) !(XtLdrProtocol->BootUtils.GetBooleanParameter(Parameters, L"NOXPA")))
{ {
/* Enable PAE (PML3) */ /* Enable PAE (PML3) */
return 3; return 3;
@@ -44,6 +44,77 @@ XtpDeterminePagingLevel(IN CONST PWCHAR Parameters)
return 2; return 2;
} }
/**
* Builds the actual memory mapping page table and enables paging. This routine exits EFI boot services as well.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
{
EFI_STATUS Status;
/* Build page map */
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, MM_PTE_BASE);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to build page map */
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
return Status;
}
/* Map memory for hardware layer */
Status = MapHardwareMemoryPool(PageMap);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to map memory for hardware layer */
XtLdrProtocol->Debug.Print(L"Failed to map memory for hardware layer (Status code: %zX)\n", Status);
return Status;
}
/* Exit EFI Boot Services */
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
Status = XtLdrProtocol->Utils.ExitBootServices();
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to exit boot services */
XtLdrProtocol->Debug.Print(L"Failed to exit boot services (Status code: %zX)\n", Status);
return STATUS_EFI_ABORTED;
}
/* Disable paging */
XtLdrProtocol->Cpu.WriteControlRegister(0, XtLdrProtocol->Cpu.ReadControlRegister(0) & ~CR0_PG);
/* Check the configured page map level to set the PAE state accordingly */
if(PageMap->PageMapLevel == 3)
{
/* Enable Physical Address Extension (PAE) */
XtLdrProtocol->Debug.Print(L"Enabling Physical Address Extension (PAE)\n");
XtLdrProtocol->Cpu.WriteControlRegister(4, XtLdrProtocol->Cpu.ReadControlRegister(4) | CR4_PAE);
}
else
{
/* Disable Physical Address Extension (PAE) */
XtLdrProtocol->Debug.Print(L"Disabling Physical Address Extension (PAE)\n");
XtLdrProtocol->Cpu.WriteControlRegister(4, XtLdrProtocol->Cpu.ReadControlRegister(4) & ~CR4_PAE);
}
/* Write page mappings to CR3 */
XtLdrProtocol->Cpu.WriteControlRegister(3, (UINT_PTR)PageMap->PtePointer);
/* Enable paging */
XtLdrProtocol->Cpu.WriteControlRegister(0, XtLdrProtocol->Cpu.ReadControlRegister(0) | CR0_PG);
/* Return success */
return STATUS_EFI_SUCCESS;
}
/** /**
* Maps the page table for hardware layer addess space. * Maps the page table for hardware layer addess space.
* *
@@ -56,15 +127,15 @@ XtpDeterminePagingLevel(IN CONST PWCHAR Parameters)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap) Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
{ {
EFI_PHYSICAL_ADDRESS Address; EFI_PHYSICAL_ADDRESS Address;
PHARDWARE_LEGACY_PTE LegacyPdeBase; PHARDWARE_LEGACY_PTE LegacyPdeBase;
PHARDWARE_PTE PdeBase; PHARDWARE_MODERN_PTE PdeBase;
EFI_STATUS Status; EFI_STATUS Status;
/* Allocate memory */ /* Allocate memory */
Status = XtLdrProtocol->Memory.AllocatePages(1, &Address); Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure, return error */ /* Memory allocation failure, return error */
@@ -72,16 +143,16 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
} }
/* Zero fill allocated memory */ /* Zero fill allocated memory */
RtlZeroMemory((PVOID)Address, EFI_PAGE_SIZE); XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
/* Check if PAE is enabled (3-level paging) */ /* Check if PAE is enabled (3-level paging) */
if(PageMap->PageMapLevel == 3) if(PageMap->PageMapLevel == 3)
{ {
/* Get PDE base address (PAE enabled) */ /* Get PDE base address (PAE enabled) */
PdeBase = (PHARDWARE_PTE)(((PHARDWARE_PTE)PageMap->PtePointer)[MM_HARDWARE_VA_START >> MM_PPI_SHIFT].PageFrameNumber << MM_PAGE_SHIFT); PdeBase = (PHARDWARE_MODERN_PTE)(((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[MM_HARDWARE_VA_START >> MM_PPI_SHIFT].PageFrameNumber << MM_PAGE_SHIFT);
/* Make PDE valid */ /* Make PDE valid */
RtlZeroMemory(&PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF], sizeof(HARDWARE_PTE)); XtLdrProtocol->Memory.ZeroMemory(&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].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].Valid = 1;
PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF].Writable = 1; PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF].Writable = 1;
@@ -99,7 +170,7 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
} }
/* Make PDE valid */ /* Make PDE valid */
RtlZeroMemory(&LegacyPdeBase[MM_HARDWARE_VA_START >> MM_PDI_LEGACY_SHIFT], sizeof(HARDWARE_LEGACY_PTE)); XtLdrProtocol->Memory.ZeroMemory(&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].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].PageFrameNumber = Address >> MM_PAGE_SHIFT;
LegacyPdeBase[MM_HARDWARE_VA_START >> MM_PDI_LEGACY_SHIFT].Writable = 1; LegacyPdeBase[MM_HARDWARE_VA_START >> MM_PDI_LEGACY_SHIFT].Writable = 1;
@@ -108,74 +179,3 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
/* Return success */ /* Return success */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
/**
* Builds the actual memory mapping page table and enables paging. This routine exits EFI boot services as well.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
{
EFI_STATUS Status;
/* Build page map */
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, 0xC0000000);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to build page map */
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
return Status;
}
/* Map memory for hardware layer */
Status = 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 */
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
Status = XtLdrProtocol->Util.ExitBootServices();
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to exit boot services */
XtLdrProtocol->Debug.Print(L"Failed to exit boot services (Status code: %zX)\n", Status);
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) */
XtLdrProtocol->Debug.Print(L"Enabling Physical Address Extension (PAE)\n");
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 */
ArWriteControlRegister(3, (UINT_PTR)PageMap->PtePointer);
/* Enable paging */
ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_PG);
/* Return success */
return STATUS_EFI_SUCCESS;
}

View File

@@ -0,0 +1,78 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/xtos/includes/xtos.hh
* DESCRIPTION: XTOS boot protocol support header
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTLDR_MODULES_XTOS_HH
#define __XTLDR_MODULES_XTOS_HH
#include <xtblapi.h>
/* XTOS kernel entry point */
typedef VOID (XTAPI *PXT_ENTRY_POINT)(IN PKERNEL_INITIALIZATION_BLOCK BootParameters);
/* XTOS trampoline entry point */
typedef VOID (*PXT_TRAMPOLINE_ENTRY)(UINT64 PageMap);
/* XTOS module for XTLDR */
class Xtos
{
private:
STATIC XTBL_BOOT_PROTOCOL BootProtocol;
STATIC PXTBL_EXECUTABLE_IMAGE_PROTOCOL PeCoffProtocol;
STATIC PXTBL_LOADER_PROTOCOL XtLdrProtocol;
public:
STATIC XTCDECL EFI_STATUS BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters);
STATIC XTCDECL EFI_STATUS InitializeModule(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable);
private:
STATIC XTCDECL EFI_STATUS AddVirtualMemoryMapping(IN PLIST_ENTRY MemoryMappings,
IN PVOID VirtualAddress,
IN PVOID PhysicalAddress,
IN UINT NumberOfPages,
IN LOADER_MEMORY_TYPE MemoryType);
STATIC XTCDECL LOADER_MEMORY_TYPE ConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType);
STATIC XTCDECL ULONG DeterminePagingLevel(IN CONST PWCHAR Parameters);
STATIC XTCDECL EFI_STATUS EnablePaging(IN PXTBL_PAGE_MAPPING PageMap);
STATIC XTCDECL VOID GetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource,
IN PEFI_PHYSICAL_ADDRESS FrameBufferBase,
IN PULONG_PTR FrameBufferSize,
IN PXTBL_FRAMEBUFFER_MODE_INFORMATION FrameBufferModeInfo);
STATIC XTCDECL EFI_STATUS GetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID *VirtualAddress,
OUT PLIST_ENTRY MemoryDescriptorList);
STATIC XTCDECL EFI_STATUS GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID *VirtualAddress,
OUT PLIST_ENTRY SystemResourcesList);
STATIC XTCDECL EFI_STATUS GetVirtualAddress(IN PLIST_ENTRY MemoryMappings,
IN PVOID PhysicalAddress,
OUT PVOID *VirtualAddress);
STATIC XTCDECL EFI_STATUS InitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap);
STATIC XTCDECL EFI_STATUS InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID *VirtualAddress,
IN PXTBL_BOOT_PARAMETERS Parameters);
STATIC XTCDECL EFI_STATUS InitializeVirtualMemory(IN OUT PLIST_ENTRY MemoryMappings,
IN OUT PVOID *MemoryMapAddress);
STATIC XTCDECL EFI_STATUS LoadModule(IN PEFI_FILE_HANDLE BootDir,
IN PWCHAR FileName,
IN PVOID VirtualAddress,
IN LOADER_MEMORY_TYPE MemoryType,
OUT PPECOFF_IMAGE_CONTEXT *ImageContext);
STATIC XTCDECL EFI_STATUS MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap);
STATIC XTCDECL EFI_STATUS MapVirtualMemory(IN PLIST_ENTRY MemoryMappings,
IN UINT_PTR VirtualAddress,
IN UINT_PTR PhysicalAddress,
IN UINT NumberOfPages,
IN OUT PVOID *PtePointer);
STATIC XTCDECL EFI_STATUS RunBootSequence(IN PEFI_FILE_HANDLE BootDir,
IN PXTBL_BOOT_PARAMETERS Parameters);
};
#endif /* __XTLDR_MODULES_XTOS_HH */

View File

@@ -1,12 +1,12 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/xtos/xtos.c * FILE: xtldr/modules/xtos/xtos.cc
* DESCRIPTION: XTOS boot protocol support * DESCRIPTION: XTOS boot protocol support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* XTOS module information */ /* XTOS module information */
@@ -16,216 +16,6 @@ MODULE_DEPENDENCY(L"acpi framebuf pecoff");
MODULE_LICENSE(L"GPLv3"); MODULE_LICENSE(L"GPLv3");
MODULE_VERSION(L"0.1"); MODULE_VERSION(L"0.1");
/* EFI XT Loader Protocol */
PXTBL_LOADER_PROTOCOL XtLdrProtocol;
/* XTOS PE/COFF Image Protocol */
PXTBL_EXECUTABLE_IMAGE_PROTOCOL XtPeCoffProtocol;
/* XTOS Boot Protocol */
XTBL_BOOT_PROTOCOL XtBootProtocol;
/**
* Returns information about frame buffer in XTOS compatible format.
*
* @param InformationBlock
* A pointer to memory area containing XT structure where all the information will be stored.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
XtGetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource,
IN PEFI_PHYSICAL_ADDRESS FrameBufferBase,
IN PULONG_PTR FrameBufferSize,
IN PXTBL_FRAMEBUFFER_MODE_INFORMATION FrameBufferModeInfo)
{
/* Fill in frame buffer resource */
FrameBufferResource->Header.PhysicalAddress = (PVOID)*FrameBufferBase;
FrameBufferResource->Header.ResourceType = SystemResourceFrameBuffer;
FrameBufferResource->Header.ResourceSize = sizeof(SYSTEM_RESOURCE_FRAMEBUFFER);
FrameBufferResource->BufferSize = *FrameBufferSize;
FrameBufferResource->Width = FrameBufferModeInfo->Width;
FrameBufferResource->Height = FrameBufferModeInfo->Height;
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
EFI_STATUS
XtGetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID *VirtualAddress,
OUT PLIST_ENTRY MemoryDescriptorList)
{
EFI_PHYSICAL_ADDRESS Address;
EFI_STATUS Status;
ULONGLONG Pages;
Pages = (ULONGLONG)EFI_SIZE_TO_PAGES((PageMap->MapSize + 1) * sizeof(LOADER_MEMORY_DESCRIPTOR));
Status = XtLdrProtocol->Memory.AllocatePages(Pages, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
return Status;
}
Status = XtLdrProtocol->Memory.MapVirtualMemory(PageMap, *VirtualAddress, (PVOID)Address, Pages, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS)
{
XtLdrProtocol->Memory.FreePages(Address, Pages);
return Status;
}
PVOID PhysicalBase = (PVOID)Address;
PLIST_ENTRY ListEntry;
ListEntry = PageMap->MemoryMap.Flink;
while(ListEntry != &PageMap->MemoryMap)
{
PXTBL_MEMORY_MAPPING MemoryMapping = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);
PLOADER_MEMORY_DESCRIPTOR MemoryDescriptor = (PLOADER_MEMORY_DESCRIPTOR)Address;
MemoryDescriptor->MemoryType = MemoryMapping->MemoryType;
MemoryDescriptor->BasePage = (UINT_PTR)MemoryMapping->PhysicalAddress / EFI_PAGE_SIZE;
MemoryDescriptor->PageCount = MemoryMapping->NumberOfPages;
RtlInsertTailList(MemoryDescriptorList, &MemoryDescriptor->ListEntry);
Address = Address + sizeof(LOADER_MEMORY_DESCRIPTOR);
ListEntry = ListEntry->Flink;
}
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(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;
}
/** /**
* Starts the operating system according to the provided parameters using XTOS boot protocol. * Starts the operating system according to the provided parameters using XTOS boot protocol.
@@ -239,7 +29,7 @@ XtGetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
XtBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters) Xtos::BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
{ {
EFI_GUID PeCoffProtocolGuid = XT_PECOFF_IMAGE_PROTOCOL_GUID; EFI_GUID PeCoffProtocolGuid = XT_PECOFF_IMAGE_PROTOCOL_GUID;
EFI_HANDLE DiskHandle, ProtocolHandle; EFI_HANDLE DiskHandle, ProtocolHandle;
@@ -251,7 +41,7 @@ XtBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
XtLdrProtocol->Debug.Print(L"XTOS boot protocol activated\n"); XtLdrProtocol->Debug.Print(L"XTOS boot protocol activated\n");
/* Open the XT PE/COFF protocol */ /* Open the XT PE/COFF protocol */
Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID *)&XtPeCoffProtocol, &PeCoffProtocolGuid); Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID *)&PeCoffProtocol, &PeCoffProtocolGuid);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to open loader protocol */ /* Failed to open loader protocol */
@@ -260,7 +50,7 @@ XtBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
} }
/* Check device path */ /* Check device path */
if(Parameters->DevicePath == NULL) if(Parameters->DevicePath == NULLPTR)
{ {
/* No device path set */ /* No device path set */
XtLdrProtocol->Debug.Print(L"ERROR: No device path provided, unable to boot system\n"); XtLdrProtocol->Debug.Print(L"ERROR: No device path provided, unable to boot system\n");
@@ -268,7 +58,7 @@ XtBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
} }
/* Check if system path is set */ /* Check if system path is set */
if(Parameters->SystemPath != NULL) if(Parameters->SystemPath != NULLPTR)
{ {
/* Make sure system path begins with backslash, the only separator supported by EFI */ /* Make sure system path begins with backslash, the only separator supported by EFI */
if(Parameters->SystemPath[0] == '/') if(Parameters->SystemPath[0] == '/')
@@ -296,22 +86,22 @@ XtBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
{ {
/* Fallback to '/ExectOS' by default */ /* Fallback to '/ExectOS' by default */
XtLdrProtocol->Debug.Print(L"WARNING: No system path set, falling back to defaults\n"); XtLdrProtocol->Debug.Print(L"WARNING: No system path set, falling back to defaults\n");
Parameters->SystemPath = L"\\ExectOS"; Parameters->SystemPath = (PWCHAR)L"\\ExectOS";
} }
/* Check if kernel file is set */ /* Check if kernel file is set */
if(Parameters->KernelFile == NULL) if(Parameters->KernelFile == NULLPTR)
{ {
/* No kernel filename set, fallback to default */ /* No kernel filename set, fallback to default */
XtLdrProtocol->Debug.Print(L"WARNING: No kernel file specified, falling back to defaults\n"); XtLdrProtocol->Debug.Print(L"WARNING: No kernel file specified, falling back to defaults\n");
Parameters->KernelFile = L"xtoskrnl.exe"; Parameters->KernelFile = (PWCHAR)L"xtoskrnl.exe";
} }
/* Check if provided any kernel boot arguments */ /* Check if provided any kernel boot arguments */
if(Parameters->Parameters == NULL) if(Parameters->Parameters == NULLPTR)
{ {
/* No argument supplied */ /* No argument supplied */
Parameters->Parameters = L""; Parameters->Parameters = (PWCHAR)L"";
} }
/* Print a debug message */ /* Print a debug message */
@@ -332,7 +122,7 @@ XtBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
} }
/* System path has to point to the boot directory */ /* System path has to point to the boot directory */
RtlConcatenateWideString(Parameters->SystemPath, L"\\Boot", 0); XtLdrProtocol->WideString.Concatenate(Parameters->SystemPath, (PWCHAR)L"\\Boot", 0);
/* Open XTOS system boot directory */ /* Open XTOS system boot directory */
Status = FsHandle->Open(FsHandle, &BootDir, Parameters->SystemPath, EFI_FILE_MODE_READ, 0); Status = FsHandle->Open(FsHandle, &BootDir, Parameters->SystemPath, EFI_FILE_MODE_READ, 0);
@@ -345,140 +135,220 @@ XtBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
XtLdrProtocol->Debug.Print(L"ERROR: System boot directory not found\n"); XtLdrProtocol->Debug.Print(L"ERROR: System boot directory not found\n");
/* Close volume */ /* Close volume */
XtLdrProtocol->Disk.CloseVolume(DiskHandle); XtLdrProtocol->Disk.CloseVolume(&DiskHandle);
return Status; return Status;
} }
else if(Status != STATUS_EFI_SUCCESS) else if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to open directory */ /* Failed to open directory */
XtLdrProtocol->Debug.Print(L"ERROR: Unable to open system boot directory\n"); XtLdrProtocol->Debug.Print(L"ERROR: Unable to open system boot directory\n");
XtLdrProtocol->Disk.CloseVolume(DiskHandle); XtLdrProtocol->Disk.CloseVolume(&DiskHandle);
return Status; return Status;
} }
/* Start boot sequence */ /* Start boot sequence */
return XtpBootSequence(BootDir, Parameters); return RunBootSequence(BootDir, Parameters);
} }
/** /**
* This routine initiates an XTOS boot sequence. * Returns information about frame buffer in XTOS compatible format.
* *
* @param BootDir * @param InformationBlock
* An EFI handle to the XTOS boot directory. * A pointer to memory area containing XT structure where all the information will be stored.
* *
* @param Parameters * @return This routine does not return any value.
* Input parameters with detailed system configuration like boot device or kernel path.
*
* @return This routine returns a status code.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
XTCDECL XTCDECL
EFI_STATUS VOID
XtpBootSequence(IN PEFI_FILE_HANDLE BootDir, Xtos::GetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource,
IN PXTBL_BOOT_PARAMETERS Parameters) IN PEFI_PHYSICAL_ADDRESS FrameBufferBase,
IN PULONG_PTR FrameBufferSize,
IN PXTBL_FRAMEBUFFER_MODE_INFORMATION FrameBufferModeInfo)
{ {
EFI_GUID LoadedImageGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; /* Fill in frame buffer resource */
EFI_GUID FrameBufGuid = XT_FRAMEBUFFER_PROTOCOL_GUID; FrameBufferResource->Header.PhysicalAddress = (PVOID)*FrameBufferBase;
PKERNEL_INITIALIZATION_BLOCK KernelParameters; FrameBufferResource->Header.ResourceType = SystemResourceFrameBuffer;
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol; FrameBufferResource->Header.ResourceSize = sizeof(SYSTEM_RESOURCE_FRAMEBUFFER);
PPECOFF_IMAGE_CONTEXT ImageContext = NULL; FrameBufferResource->BufferSize = *FrameBufferSize;
PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol; FrameBufferResource->Width = FrameBufferModeInfo->Width;
PVOID VirtualAddress, VirtualMemoryArea; FrameBufferResource->Height = FrameBufferModeInfo->Height;
PXT_ENTRY_POINT KernelEntryPoint; FrameBufferResource->Depth = FrameBufferModeInfo->Depth;
EFI_HANDLE ProtocolHandle; FrameBufferResource->BitsPerPixel = FrameBufferModeInfo->BitsPerPixel;
EFI_STATUS Status; FrameBufferResource->PixelsPerScanLine = FrameBufferModeInfo->PixelsPerScanLine;
XTBL_PAGE_MAPPING PageMap; 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;
}
/* Initialize XTOS startup sequence */ XTCDECL
XtLdrProtocol->Debug.Print(L"Initializing XTOS startup sequence\n"); EFI_STATUS
Xtos::GetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID *VirtualAddress,
OUT PLIST_ENTRY MemoryDescriptorList)
{
EFI_PHYSICAL_ADDRESS Address;
EFI_STATUS Status;
ULONGLONG Pages;
Pages = (ULONGLONG)EFI_SIZE_TO_PAGES((PageMap->MapSize + 1) * sizeof(LOADER_MEMORY_DESCRIPTOR));
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, Pages, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
return Status;
}
Status = XtLdrProtocol->Memory.MapVirtualMemory(PageMap, *VirtualAddress, (PVOID)Address, Pages, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS)
{
XtLdrProtocol->Memory.FreePages(Address, Pages);
return Status;
}
PVOID PhysicalBase = (PVOID)Address;
PLIST_ENTRY ListEntry;
ListEntry = PageMap->MemoryMap.Flink;
while(ListEntry != &PageMap->MemoryMap)
{
PXTBL_MEMORY_MAPPING MemoryMapping = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);
PLOADER_MEMORY_DESCRIPTOR MemoryDescriptor = (PLOADER_MEMORY_DESCRIPTOR)Address;
MemoryDescriptor->MemoryType = MemoryMapping->MemoryType;
MemoryDescriptor->BasePage = (UINT_PTR)MemoryMapping->PhysicalAddress / EFI_PAGE_SIZE;
MemoryDescriptor->PageCount = MemoryMapping->NumberOfPages;
XtLdrProtocol->LinkedList.InsertTail(MemoryDescriptorList, &MemoryDescriptor->ListEntry);
Address = Address + sizeof(LOADER_MEMORY_DESCRIPTOR);
ListEntry = ListEntry->Flink;
}
XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, MemoryDescriptorList, PhysicalBase, *VirtualAddress);
return STATUS_EFI_SUCCESS;
}
XTCDECL
EFI_STATUS
Xtos::GetSystemResourcesList(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 = (PUINT8)*VirtualAddress + (Pages * EFI_PAGE_SIZE);
AcpiResource = (PSYSTEM_RESOURCE_ACPI)Address;
XtLdrProtocol->Memory.ZeroMemory(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;
XtLdrProtocol->LinkedList.InsertTail(SystemResourcesList, &AcpiResource->Header.ListEntry);
/* Close FrameBuffer protocol */
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
Address = Address + sizeof(SYSTEM_RESOURCE_ACPI);
FrameBufferResource = (PSYSTEM_RESOURCE_FRAMEBUFFER)Address;
XtLdrProtocol->Memory.ZeroMemory(FrameBufferResource, sizeof(SYSTEM_RESOURCE_FRAMEBUFFER));
/* Load FrameBuffer protocol */ /* Load FrameBuffer protocol */
Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&FrameBufProtocol, &FrameBufGuid); Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&FrameBufProtocol, &FrameBufGuid);
if(Status == STATUS_EFI_SUCCESS) if(Status == STATUS_EFI_SUCCESS)
{ {
/* Make sure FrameBuffer is initialized */ /* Get FrameBuffer information */
FrameBufProtocol->Initialize(); Status = FrameBufProtocol->GetDisplayInformation(&FbAddress, &FbSize, &FbModeInfo);
FrameBufProtocol->SetScreenResolution(0, 0); if(Status == STATUS_EFI_SUCCESS)
{
/* Store information about FrameBuffer device */
GetDisplayInformation(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 */ /* Close FrameBuffer protocol */
XtLdrProtocol->Protocol.Close(ProtocolHandle, &FrameBufGuid); XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
/* Set base virtual memory area for the kernel mappings */ *VirtualAddress = (PUINT8)*VirtualAddress + (FrameBufferPages * EFI_PAGE_SIZE);
VirtualMemoryArea = (PVOID)KSEG0_BASE;
VirtualAddress = (PVOID)(KSEG0_BASE + KSEG0_KERNEL_BASE);
/* Initialize virtual memory mappings */ XtLdrProtocol->LinkedList.InsertTail(SystemResourcesList, &FrameBufferResource->Header.ListEntry);
XtLdrProtocol->Memory.InitializePageMap(&PageMap, XtpDeterminePagingLevel(Parameters->Parameters), Size4K);
Status = XtLdrProtocol->Memory.MapEfiMemory(&PageMap, &VirtualMemoryArea, NULL); XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, SystemResourcesList, PhysicalBase, VirtualBase);
if(Status != STATUS_EFI_SUCCESS)
{
return Status;
}
/* Load the kernel */
Status = XtpLoadModule(BootDir, Parameters->KernelFile, VirtualAddress, LoaderSystemCode, &ImageContext);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to load the kernel */
return Status;
}
/* Add kernel image memory mapping */
Status = XtLdrProtocol->Memory.MapVirtualMemory(&PageMap, ImageContext->VirtualAddress,
ImageContext->PhysicalAddress, ImageContext->ImagePages, 0);
if(Status != STATUS_EFI_SUCCESS)
{
return Status;
}
/* Set next valid virtual address right after the kernel */
VirtualAddress += ImageContext->ImagePages * EFI_PAGE_SIZE;
/* Find and map APIC base address */
Status = XtpInitializeApicBase(&PageMap);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to setup kernel initialization block */
XtLdrProtocol->Debug.Print(L"Failed to initialize APIC (Status Code: 0x%zX)\n", Status);
return Status;
}
/* Store virtual address of kernel initialization block for future kernel call */
KernelParameters = (PKERNEL_INITIALIZATION_BLOCK)VirtualAddress;
/* Setup and map kernel initialization block */
Status = XtpInitializeLoaderBlock(&PageMap, &VirtualAddress, Parameters);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to setup kernel initialization block */
XtLdrProtocol->Debug.Print(L"Failed to setup kernel initialization block (Status Code: 0x%zX)\n", Status);
return Status;
}
/* Get kernel entry point */
XtPeCoffProtocol->GetEntryPoint(ImageContext, (PVOID)&KernelEntryPoint);
/* Close boot directory handle */
BootDir->Close(BootDir);
/* Enable paging */
XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&ImageProtocol, &LoadedImageGuid);
Status = XtEnablePaging(&PageMap);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to enable paging */
XtLdrProtocol->Debug.Print(L"Failed to enable paging (Status Code: 0x%zX)\n", Status);
return Status;
}
/* Call XTOS kernel */
XtLdrProtocol->Debug.Print(L"Booting the XTOS kernel\n");
KernelEntryPoint(KernelParameters);
/* Return success */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
@@ -494,7 +364,7 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
XtpInitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap) Xtos::InitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap)
{ {
EFI_GUID AcpiGuid = XT_ACPI_PROTOCOL_GUID; EFI_GUID AcpiGuid = XT_ACPI_PROTOCOL_GUID;
PXTBL_ACPI_PROTOCOL AcpiProtocol; PXTBL_ACPI_PROTOCOL AcpiProtocol;
@@ -538,21 +408,24 @@ XtpInitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap, Xtos::InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID *VirtualAddress, IN PVOID *VirtualAddress,
IN PXTBL_BOOT_PARAMETERS Parameters) IN PXTBL_BOOT_PARAMETERS Parameters)
{ {
PKERNEL_INITIALIZATION_BLOCK LoaderBlock; PKERNEL_INITIALIZATION_BLOCK LoaderBlock;
EFI_PHYSICAL_ADDRESS Address; EFI_PHYSICAL_ADDRESS Address;
// PVOID RuntimeServices;
EFI_STATUS Status; EFI_STATUS Status;
UINT BlockPages; UINT BlockPages;
UINT ParametersSize;
/* Calculate size of parameters */
ParametersSize = (XtLdrProtocol->WideString.Length(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 */
@@ -561,7 +434,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)); XtLdrProtocol->Memory.ZeroMemory(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);
@@ -569,48 +442,63 @@ XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
LoaderBlock->ProtocolVersion = BOOT_PROTOCOL_VERSION; LoaderBlock->ProtocolVersion = BOOT_PROTOCOL_VERSION;
/* Set LoaderInformation block properties */ /* Set LoaderInformation block properties */
LoaderBlock->LoaderInformation.DbgPrint = XtLdrProtocol->Debug.Print; LoaderBlock->LoaderInformation.DbgPrint = (PVOID)XtLdrProtocol->Debug.Print;
/* Store page map level */
LoaderBlock->LoaderInformation.PageMapLevel = PageMap->PageMapLevel;
/* Attempt to find virtual address of the EFI Runtime Services */
// Status = XtLdrProtocol->GetVirtualAddress(MemoryMappings, &EfiSystemTable->RuntimeServices->Hdr, &RuntimeServices);
// if(Status == STATUS_EFI_SUCCESS)
// {
/* Set FirmwareInformation block properties */ /* Set FirmwareInformation block properties */
LoaderBlock->FirmwareInformation.FirmwareType = SystemFirmwareEfi; LoaderBlock->FirmwareInformation.FirmwareType = SystemFirmwareEfi;
LoaderBlock->FirmwareInformation.EfiFirmware.EfiVersion = 0; //EfiSystemTable->Hdr.Revision; // LoaderBlock->FirmwareInformation.EfiFirmware.EfiVersion = EfiSystemTable->Hdr.Revision;
LoaderBlock->FirmwareInformation.EfiFirmware.EfiRuntimeServices = NULL; LoaderBlock->FirmwareInformation.EfiFirmware.EfiRuntimeServices = NULLPTR;
// }
// else
// {
// /* Set invalid firmware type to indicate that kernel cannot rely on FirmwareInformation block */
// LoaderBlock->FirmwareInformation.FirmwareType = SystemFirmwareInvalid;
// }
/* 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)); XtLdrProtocol->Memory.CopyMemory((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,
BlockPages, LoaderSystemBlock); BlockPages, LoaderSystemBlock);
/* Calculate next valid virtual address */ /* Calculate next valid virtual address */
*VirtualAddress += (UINT_PTR)(BlockPages * EFI_PAGE_SIZE); *VirtualAddress = (PUINT8)*VirtualAddress + (BlockPages * EFI_PAGE_SIZE);
RtlInitializeListHead(&LoaderBlock->SystemResourcesListHead); XtLdrProtocol->LinkedList.InitializeHead(&LoaderBlock->SystemResourcesListHead);
XtGetSystemResourcesList(PageMap, VirtualAddress, &LoaderBlock->SystemResourcesListHead); GetSystemResourcesList(PageMap, VirtualAddress, &LoaderBlock->SystemResourcesListHead);
/* Initialize memory descriptor list */ /* Initialize memory descriptor list */
RtlInitializeListHead(&LoaderBlock->MemoryDescriptorListHead); XtLdrProtocol->LinkedList.InitializeHead(&LoaderBlock->MemoryDescriptorListHead);
XtGetMemoryDescriptorList(PageMap, VirtualAddress, &LoaderBlock->MemoryDescriptorListHead); GetMemoryDescriptorList(PageMap, VirtualAddress, &LoaderBlock->MemoryDescriptorListHead);
/* Return success */ /* Return success */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
XTCDECL
EFI_STATUS
Xtos::InitializeModule(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable)
{
EFI_GUID Guid = XT_XTOS_BOOT_PROTOCOL_GUID;
EFI_STATUS Status;
/* Open the XTLDR protocol */
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open loader protocol */
return STATUS_EFI_PROTOCOL_ERROR;
}
/* Set routines available via XTOS boot protocol */
BootProtocol.BootSystem = Xtos::BootSystem;
/* Register XTOS boot protocol */
XtLdrProtocol->Boot.RegisterProtocol(L"XTOS", &Guid);
/* Install XTOS protocol */
return XtLdrProtocol->Protocol.Install(&BootProtocol, &Guid);
}
/** /**
* Loads XTOS PE/COFF module. * Loads XTOS PE/COFF module.
* *
@@ -635,7 +523,7 @@ XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
XtpLoadModule(IN PEFI_FILE_HANDLE SystemDir, Xtos::LoadModule(IN PEFI_FILE_HANDLE SystemDir,
IN PWCHAR FileName, IN PWCHAR FileName,
IN PVOID VirtualAddress, IN PVOID VirtualAddress,
IN LOADER_MEMORY_TYPE MemoryType, IN LOADER_MEMORY_TYPE MemoryType,
@@ -658,7 +546,7 @@ XtpLoadModule(IN PEFI_FILE_HANDLE SystemDir,
} }
/* Load the PE/COFF image file */ /* Load the PE/COFF image file */
Status = XtPeCoffProtocol->LoadImage(ModuleHandle, MemoryType, VirtualAddress, (PVOID)ImageContext); Status = PeCoffProtocol->LoadImage(ModuleHandle, MemoryType, VirtualAddress, (PVOID*)ImageContext);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Unable to load the file */ /* Unable to load the file */
@@ -670,7 +558,7 @@ XtpLoadModule(IN PEFI_FILE_HANDLE SystemDir,
ModuleHandle->Close(ModuleHandle); ModuleHandle->Close(ModuleHandle);
/* Check PE/COFF image machine type compatibility */ /* Check PE/COFF image machine type compatibility */
XtPeCoffProtocol->GetMachineType(*ImageContext, &MachineType); PeCoffProtocol->GetMachineType(*ImageContext, &MachineType);
if(MachineType != _ARCH_IMAGE_MACHINE_TYPE) if(MachineType != _ARCH_IMAGE_MACHINE_TYPE)
{ {
/* Machine type mismatch */ /* Machine type mismatch */
@@ -679,7 +567,7 @@ XtpLoadModule(IN PEFI_FILE_HANDLE SystemDir,
} }
/* Check PE/COFF image subsystem */ /* Check PE/COFF image subsystem */
XtPeCoffProtocol->GetSubSystem(*ImageContext, &SubSystem); PeCoffProtocol->GetSubSystem(*ImageContext, &SubSystem);
if(SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_KERNEL && if(SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_KERNEL &&
SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_APPLICATION && SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_APPLICATION &&
SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_DRIVER) SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_DRIVER)
@@ -695,6 +583,129 @@ XtpLoadModule(IN PEFI_FILE_HANDLE SystemDir,
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
/**
* This routine initiates an XTOS boot sequence.
*
* @param BootDir
* An EFI handle to the XTOS boot directory.
*
* @param Parameters
* Input parameters with detailed system configuration like boot device or kernel path.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
Xtos::RunBootSequence(IN PEFI_FILE_HANDLE BootDir,
IN PXTBL_BOOT_PARAMETERS Parameters)
{
EFI_GUID LoadedImageGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
EFI_GUID FrameBufGuid = XT_FRAMEBUFFER_PROTOCOL_GUID;
PKERNEL_INITIALIZATION_BLOCK KernelParameters;
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
PPECOFF_IMAGE_CONTEXT ImageContext = NULLPTR;
PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol;
PVOID VirtualAddress, VirtualMemoryArea;
PXT_ENTRY_POINT KernelEntryPoint;
EFI_HANDLE ProtocolHandle;
EFI_STATUS Status;
XTBL_PAGE_MAPPING PageMap;
/* Initialize XTOS startup sequence */
XtLdrProtocol->Debug.Print(L"Initializing XTOS startup sequence\n");
/* Load FrameBuffer protocol */
Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&FrameBufProtocol, &FrameBufGuid);
if(Status == STATUS_EFI_SUCCESS)
{
/* Make sure FrameBuffer is initialized */
FrameBufProtocol->Initialize();
FrameBufProtocol->SetScreenResolution(0, 0);
}
/* Close FrameBuffer protocol */
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
/* Set base virtual memory area for the kernel mappings */
VirtualMemoryArea = (PVOID)KSEG0_BASE;
VirtualAddress = (PVOID)(KSEG0_BASE + KSEG0_KERNEL_BASE);
/* Initialize virtual memory mappings */
XtLdrProtocol->Memory.InitializePageMap(&PageMap, DeterminePagingLevel(Parameters->Parameters), Size4K);
Status = XtLdrProtocol->Memory.MapEfiMemory(&PageMap, &VirtualMemoryArea, NULLPTR);
if(Status != STATUS_EFI_SUCCESS)
{
return Status;
}
/* Load the kernel */
Status = LoadModule(BootDir, Parameters->KernelFile, VirtualAddress, LoaderSystemCode, &ImageContext);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to load the kernel */
return Status;
}
/* Add kernel image memory mapping */
Status = XtLdrProtocol->Memory.MapVirtualMemory(&PageMap, ImageContext->VirtualAddress,
ImageContext->PhysicalAddress, ImageContext->ImagePages,
LoaderSystemCode);
if(Status != STATUS_EFI_SUCCESS)
{
return Status;
}
/* Set next valid virtual address right after the kernel */
VirtualAddress = (PUINT8)VirtualAddress + (ImageContext->ImagePages * EFI_PAGE_SIZE);
/* Find and map APIC base address */
Status = InitializeApicBase(&PageMap);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to setup kernel initialization block */
XtLdrProtocol->Debug.Print(L"Failed to initialize APIC (Status Code: 0x%zX)\n", Status);
return Status;
}
/* Store virtual address of kernel initialization block for future kernel call */
KernelParameters = (PKERNEL_INITIALIZATION_BLOCK)VirtualAddress;
/* Setup and map kernel initialization block */
Status = InitializeLoaderBlock(&PageMap, &VirtualAddress, Parameters);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to setup kernel initialization block */
XtLdrProtocol->Debug.Print(L"Failed to setup kernel initialization block (Status Code: 0x%zX)\n", Status);
return Status;
}
/* Get kernel entry point */
PeCoffProtocol->GetEntryPoint(ImageContext, (PVOID*)&KernelEntryPoint);
/* Close boot directory handle */
BootDir->Close(BootDir);
/* Enable paging */
XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&ImageProtocol, &LoadedImageGuid);
Status = EnablePaging(&PageMap);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to enable paging */
XtLdrProtocol->Debug.Print(L"Failed to enable paging (Status Code: 0x%zX)\n", Status);
return Status;
}
/* Call XTOS kernel */
XtLdrProtocol->Debug.Print(L"Booting the XTOS kernel\n");
KernelEntryPoint(KernelParameters);
/* Return success */
return STATUS_EFI_SUCCESS;
}
/** /**
* This routine is the entry point of the XT EFI boot loader module. * This routine is the entry point of the XT EFI boot loader module.
* *
@@ -713,23 +724,6 @@ EFI_STATUS
XtLdrModuleMain(IN EFI_HANDLE ImageHandle, XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable) IN PEFI_SYSTEM_TABLE SystemTable)
{ {
EFI_GUID Guid = XT_XTOS_BOOT_PROTOCOL_GUID; /* Initialize XTOS module */
EFI_STATUS Status; return Xtos::InitializeModule(ImageHandle, SystemTable);
/* Open the XTLDR protocol */
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open loader protocol */
return STATUS_EFI_PROTOCOL_ERROR;
}
/* Set routines available via XTOS boot protocol */
XtBootProtocol.BootSystem = XtBootSystem;
/* Register XTOS boot protocol */
XtLdrProtocol->Boot.RegisterProtocol(L"XTOS", &Guid);
/* Install XTOS protocol */
return XtLdrProtocol->Protocol.Install(&XtBootProtocol, &Guid);
} }

1112
boot/xtldr/protocol.cc Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,12 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/shell.c * FILE: xtldr/shell.cc
* DESCRIPTION: XT Boot Loader shell * DESCRIPTION: XT Boot Loader shell
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtldr.h> #include <xtldr.hh>
/** /**
@@ -18,13 +18,13 @@
*/ */
XTCDECL XTCDECL
VOID VOID
BlStartLoaderShell() Shell::StartLoaderShell()
{ {
/* Initialize console */ /* Initialize console */
BlInitializeConsole(); Console::InitializeConsole();
/* Print prompt */ /* Print prompt */
BlpPrintShellPrompt(); PrintPrompt();
for(;;); for(;;);
} }
@@ -37,14 +37,14 @@ BlStartLoaderShell()
*/ */
XTCDECL XTCDECL
VOID VOID
BlpPrintShellPrompt() Shell::PrintPrompt()
{ {
/* Set prompt color */ /* Set prompt color */
BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_YELLOW); Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_YELLOW);
/* Print prompt */ /* Print prompt */
BlConsolePrint(L"XTLDR> "); Console::Print(L"XTLDR> ");
/* Reset standard shell colors */ /* Reset standard shell colors */
BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +1,13 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/volume.c * FILE: xtldr/volume.cc
* 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> * Aiken Harris <harraiken91@gmail.com>
*/ */
#include <xtldr.h> #include <xtldr.hh>
/** /**
@@ -22,15 +22,16 @@
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlCloseVolume(IN PEFI_HANDLE VolumeHandle) Volume::CloseVolume(IN PEFI_HANDLE VolumeHandle)
{ {
EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
/* Make sure a handle specified */ /* Make sure a handle specified */
if(VolumeHandle != NULL) if(VolumeHandle != NULLPTR)
{ {
/* Close a handle */ /* Close a handle */
return EfiSystemTable->BootServices->CloseProtocol(VolumeHandle, &LIPGuid, EfiImageHandle, NULL); return XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(VolumeHandle, &LIPGuid,
XtLoader::GetEfiImageHandle(), NULLPTR);
} }
/* Return success */ /* Return success */
@@ -46,10 +47,14 @@ BlCloseVolume(IN PEFI_HANDLE VolumeHandle)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlEnumerateBlockDevices() Volume::EnumerateBlockDevices()
{ {
PEFI_DEVICE_PATH_PROTOCOL LastNode = NULL; EFI_GUID LoadedImageProtocolGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
PEFI_BLOCK_DEVICE_DATA ParentNode = NULL; EFI_GUID BlockIoGuid = EFI_BLOCK_IO_PROTOCOL_GUID;
EFI_HANDLE BootDeviceHandle = NULLPTR, DeviceHandle = NULLPTR;
EFI_LOADED_IMAGE_PROTOCOL* LoadedImage;
PEFI_DEVICE_PATH_PROTOCOL DevicePath = NULLPTR, LastNode = NULLPTR;
PEFI_BLOCK_DEVICE_DATA ParentNode = NULLPTR;
PEFI_BLOCK_DEVICE_DATA BlockDeviceData; PEFI_BLOCK_DEVICE_DATA BlockDeviceData;
PEFI_BLOCK_DEVICE BlockDevice; PEFI_BLOCK_DEVICE BlockDevice;
LIST_ENTRY BlockDevices; LIST_ENTRY BlockDevices;
@@ -63,15 +68,28 @@ BlEnumerateBlockDevices()
USHORT DriveType; USHORT DriveType;
ULONG CDCount = 0, FDCount = 0, HDCount = 0, RDCount = 0; ULONG CDCount = 0, FDCount = 0, HDCount = 0, RDCount = 0;
/* Initialize list entries */ /* Get the device handle of the image that is running */
RtlInitializeListHead(&BlockDevices); Status = XtLoader::GetEfiSystemTable()->BootServices->HandleProtocol(XtLoader::GetEfiImageHandle(), &LoadedImageProtocolGuid,
RtlInitializeListHead(&EfiBlockDevices); (VOID**)&LoadedImage);
/* Discover EFI block devices and store them in linked list */
Status = BlpDiscoverEfiBlockDevices(&BlockDevices);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
BlDebugPrint(L"ERROR: Failed to discover EFI block devices (Status Code: 0x%zX)\n", Status); /* Failed to get boot device handle */
Debug::Print(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 */
RTL::LinkedList::InitializeListHead(&BlockDevices);
RTL::LinkedList::InitializeListHead(&EfiBlockDevices);
/* Discover EFI block devices and store them in linked list */
Status = DiscoverEfiBlockDevices(&BlockDevices);
if(Status != STATUS_EFI_SUCCESS)
{
Debug::Print(L"ERROR: Failed to discover EFI block devices (Status Code: 0x%zX)\n", Status);
return Status; return Status;
} }
@@ -81,13 +99,14 @@ BlEnumerateBlockDevices()
{ {
/* Get data for the next discovered device. */ /* 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 = NULLPTR;
/* Find last node */ /* Find last node */
Status = BlpFindLastBlockDeviceNode(BlockDeviceData->DevicePath, &LastNode); Status = FindLastBlockDeviceNode(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 */ /* 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"); Debug::Print(L"WARNING: Block device last node not found\n");
ListEntry = ListEntry->Flink; ListEntry = ListEntry->Flink;
continue; continue;
} }
@@ -96,10 +115,10 @@ BlEnumerateBlockDevices()
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 */ /* Locate the parent for this block device to ensure it is not an orphaned entry */
if(!BlpFindParentBlockDevice(&BlockDevices, BlockDeviceData, &ParentNode)) if(!FindParentBlockDevice(&BlockDevices, BlockDeviceData, &ParentNode))
{ {
/* Orphaned device found. Log a warning and skip it as it cannot be properly classified */ /* 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"); Debug::Print(L"WARNING: No parent device found, skipping orphaned media device path\n");
ListEntry = ListEntry->Flink; ListEntry = ListEntry->Flink;
continue; continue;
} }
@@ -108,7 +127,7 @@ BlEnumerateBlockDevices()
if(!BlockDeviceData->BlockIo->Media) if(!BlockDeviceData->BlockIo->Media)
{ {
/* The device is unusable without media info, log a warning and skip it */ /* The device is unusable without media info, log a warning and skip it */
BlDebugPrint(L"WARNING: Block device is missing media information\n"); Debug::Print(L"WARNING: Block device is missing media information\n");
ListEntry = ListEntry->Flink; ListEntry = ListEntry->Flink;
continue; continue;
} }
@@ -127,7 +146,7 @@ BlEnumerateBlockDevices()
PartitionNumber = 0; PartitionNumber = 0;
/* Print debug message */ /* Print debug message */
BlDebugPrint(L"Found Floppy Disk (DiskNumber: %lu, MediaPresent: %u, RO: %u)\n", Debug::Print(L"Found Floppy Disk (DiskNumber: %lu, MediaPresent: %u, RO: %u)\n",
DriveNumber, Media->MediaPresent, Media->ReadOnly); DriveNumber, Media->MediaPresent, Media->ReadOnly);
} }
} }
@@ -142,7 +161,7 @@ BlEnumerateBlockDevices()
PartitionNumber = 0; PartitionNumber = 0;
/* Print debug message */ /* Print debug message */
BlDebugPrint(L"Found CD-ROM drive (DriveNumber: %lu, MediaPresent: %u, RemovableMedia: %u, RO: %u)\n", Debug::Print(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->Type == EFI_MEDIA_DEVICE_PATH && LastNode->SubType == EFI_MEDIA_HARDDRIVE_DP) else if(LastNode->Type == EFI_MEDIA_DEVICE_PATH && LastNode->SubType == EFI_MEDIA_HARDDRIVE_DP)
@@ -154,11 +173,30 @@ BlEnumerateBlockDevices()
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 != NULLPTR)
{
/* Allocate memory for device path */
DevicePath = DuplicateDevicePath(BlockDeviceData->DevicePath);
if(DevicePath != NULLPTR)
{
/* Check if this is the boot device */
Status = XtLoader::GetEfiSystemTable()->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, " Debug::Print(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->Type == EFI_MEDIA_DEVICE_PATH && LastNode->SubType == EFI_MEDIA_RAMDISK_DP) else if(LastNode->Type == EFI_MEDIA_DEVICE_PATH && LastNode->SubType == EFI_MEDIA_RAMDISK_DP)
{ {
@@ -168,7 +206,7 @@ BlEnumerateBlockDevices()
PartitionNumber = 0; PartitionNumber = 0;
/* Print debug message */ /* Print debug message */
BlDebugPrint(L"Found RAM Disk (DiskNumber: %lu, MediaPresent: %u)\n", Debug::Print(L"Found RAM Disk (DiskNumber: %lu, MediaPresent: %u)\n",
DriveNumber, Media->MediaPresent); DriveNumber, Media->MediaPresent);
} }
@@ -176,22 +214,22 @@ BlEnumerateBlockDevices()
if(DriveType != XTBL_BOOT_DEVICE_UNKNOWN) if(DriveType != XTBL_BOOT_DEVICE_UNKNOWN)
{ {
/* Allocate memory for block device */ /* Allocate memory for block device */
Status = BlAllocateMemoryPool(sizeof(EFI_BLOCK_DEVICE), (PVOID *)&BlockDevice); Status = Memory::AllocatePool(sizeof(EFI_BLOCK_DEVICE), (PVOID *)&BlockDevice);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
BlDebugPrint(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%zX)\n", Status); Debug::Print(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%zX)\n", Status);
return STATUS_EFI_OUT_OF_RESOURCES; return STATUS_EFI_OUT_OF_RESOURCES;
} }
/* Initialize block device */ /* Initialize block device */
BlockDevice->DevicePath = BlpDuplicateDevicePath(BlockDeviceData->DevicePath); BlockDevice->DevicePath = DuplicateDevicePath(BlockDeviceData->DevicePath);
BlockDevice->DriveType = DriveType; BlockDevice->DriveType = DriveType;
BlockDevice->DriveNumber = DriveNumber; BlockDevice->DriveNumber = DriveNumber;
BlockDevice->PartitionNumber = PartitionNumber; BlockDevice->PartitionNumber = PartitionNumber;
BlockDevice->PartitionGuid = PartitionGuid; BlockDevice->PartitionGuid = PartitionGuid;
/* Add block device to global list */ /* Add block device to global list */
RtlInsertTailList(&EfiBlockDevices, &BlockDevice->ListEntry); RTL::LinkedList::InsertTailList(&EfiBlockDevices, &BlockDevice->ListEntry);
} }
/* Get next entry from linked list */ /* Get next entry from linked list */
@@ -220,13 +258,13 @@ BlEnumerateBlockDevices()
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, Volume::FindDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,
IN CONST PWCHAR FileSystemPath, IN CONST PWCHAR FileSystemPath,
OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath) OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath)
{ {
EFI_STATUS Status; EFI_STATUS Status;
SIZE_T FsPathLength, DevicePathLength = 0; SIZE_T FsPathLength, DevicePathLength = 0;
PEFI_FILEPATH_DEVICE_PATH FilePath = NULL; PEFI_FILEPATH_DEVICE_PATH FilePath = NULLPTR;
PEFI_DEVICE_PATH_PROTOCOL EndDevicePath; PEFI_DEVICE_PATH_PROTOCOL EndDevicePath;
PEFI_DEVICE_PATH_PROTOCOL DevicePathHandle; PEFI_DEVICE_PATH_PROTOCOL DevicePathHandle;
@@ -255,10 +293,10 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,
} }
/* Check real path length */ /* Check real path length */
FsPathLength = RtlWideStringLength(FileSystemPath, 0) * sizeof(WCHAR); FsPathLength = RTL::WideString::WideStringLength(FileSystemPath, 0) * sizeof(WCHAR);
/* Allocate memory pool for device path */ /* Allocate memory pool for device path */
Status = BlAllocateMemoryPool(FsPathLength + DevicePathLength + sizeof(EFI_DEVICE_PATH_PROTOCOL), Status = Memory::AllocatePool(FsPathLength + DevicePathLength + sizeof(EFI_DEVICE_PATH_PROTOCOL),
(PVOID *)DevicePath); (PVOID *)DevicePath);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
@@ -267,7 +305,7 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,
} }
/* Set file path */ /* Set file path */
RtlCopyMemory(*DevicePath, FsHandle, DevicePathLength); RTL::Memory::CopyMemory(*DevicePath, FsHandle, DevicePathLength);
FilePath = (PEFI_FILEPATH_DEVICE_PATH)((PUCHAR)*DevicePath + DevicePathLength); FilePath = (PEFI_FILEPATH_DEVICE_PATH)((PUCHAR)*DevicePath + DevicePathLength);
FilePath->Header.Type = EFI_MEDIA_DEVICE_PATH; FilePath->Header.Type = EFI_MEDIA_DEVICE_PATH;
FilePath->Header.SubType = EFI_MEDIA_FILEPATH_DP; FilePath->Header.SubType = EFI_MEDIA_FILEPATH_DP;
@@ -275,7 +313,7 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,
FilePath->Header.Length[1] = FilePath->Header.Length[0] >> 8; FilePath->Header.Length[1] = FilePath->Header.Length[0] >> 8;
/* Set device path end node */ /* Set device path end node */
RtlCopyMemory(FilePath->PathName, FileSystemPath, FsPathLength + sizeof(WCHAR)); RTL::Memory::CopyMemory(FilePath->PathName, FileSystemPath, FsPathLength + sizeof(WCHAR));
EndDevicePath = (PEFI_DEVICE_PATH_PROTOCOL)&FilePath->PathName[(FsPathLength / sizeof(WCHAR)) + 1]; EndDevicePath = (PEFI_DEVICE_PATH_PROTOCOL)&FilePath->PathName[(FsPathLength / sizeof(WCHAR)) + 1];
EndDevicePath->Type = EFI_END_DEVICE_PATH; EndDevicePath->Type = EFI_END_DEVICE_PATH;
EndDevicePath->SubType = EFI_END_ENTIRE_DP; EndDevicePath->SubType = EFI_END_ENTIRE_DP;
@@ -301,26 +339,26 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlGetEfiPath(IN PWCHAR SystemPath, Volume::GetEfiPath(IN PWCHAR SystemPath,
OUT PWCHAR *EfiPath) OUT PWCHAR *EfiPath)
{ {
SIZE_T Index, PathLength; SIZE_T Index, PathLength;
EFI_STATUS Status; EFI_STATUS Status;
/* Get system path length */ /* Get system path length */
PathLength = RtlWideStringLength(SystemPath, 0); PathLength = RTL::WideString::WideStringLength(SystemPath, 0);
/* Allocate memory for storing EFI path */ /* Allocate memory for storing EFI path */
Status = BlAllocateMemoryPool(sizeof(WCHAR) * (PathLength + 1), (PVOID *)EfiPath); Status = Memory::AllocatePool(sizeof(WCHAR) * (PathLength + 1), (PVOID *)EfiPath);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to allocate memory, print error message and return status code */ /* Failed to allocate memory, print error message and return status code */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status);
return STATUS_EFI_OUT_OF_RESOURCES; return STATUS_EFI_OUT_OF_RESOURCES;
} }
/* Make a copy of SystemPath string */ /* Make a copy of SystemPath string */
RtlCopyMemory(*EfiPath, SystemPath, sizeof(WCHAR) * (PathLength + 1)); RTL::Memory::CopyMemory(*EfiPath, SystemPath, sizeof(WCHAR) * (PathLength + 1));
/* Replace directory separator if needed to comply with EFI standard */ /* Replace directory separator if needed to comply with EFI standard */
for(Index = 0; Index < PathLength; Index++) for(Index = 0; Index < PathLength; Index++)
@@ -354,7 +392,7 @@ BlGetEfiPath(IN PWCHAR SystemPath,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlGetVolumeDevicePath(IN PWCHAR SystemPath, Volume::GetDevicePath(IN PWCHAR SystemPath,
OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath,
OUT PWCHAR *ArcName, OUT PWCHAR *ArcName,
OUT PWCHAR *Path) OUT PWCHAR *Path)
@@ -369,7 +407,7 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath,
EFI_STATUS Status; EFI_STATUS Status;
/* Make sure this is not set */ /* Make sure this is not set */
*DevicePath = NULL; *DevicePath = NULLPTR;
/* Find volume path and its length */ /* Find volume path and its length */
Volume = SystemPath; Volume = SystemPath;
@@ -393,13 +431,13 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath,
if(PathLength == GUID_STRING_LENGTH) if(PathLength == GUID_STRING_LENGTH)
{ {
/* This is EFI GUID */ /* This is EFI GUID */
BlDebugPrint(L"WARNING: EFI/GPT GUID in system path is not supported\n"); Debug::Print(L"WARNING: EFI/GPT GUID in system path is not supported\n");
return STATUS_EFI_UNSUPPORTED; return STATUS_EFI_UNSUPPORTED;
} }
else if(PathLength == PARTUUID_STRING_LENGTH) else if(PathLength == PARTUUID_STRING_LENGTH)
{ {
/* This is MBR UUID */ /* This is MBR UUID */
BlDebugPrint(L"WARNING: MBR partition UUID in system path is not supported\n"); Debug::Print(L"WARNING: MBR partition UUID in system path is not supported\n");
return STATUS_EFI_UNSUPPORTED; return STATUS_EFI_UNSUPPORTED;
} }
else else
@@ -411,14 +449,14 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath,
else else
{ {
/* Defaults to ARC path, dissect it */ /* Defaults to ARC path, dissect it */
Status = BlpDissectVolumeArcPath(SystemPath, ArcName, Path, &DriveType, &DriveNumber, &PartNumber); Status = DissectArcPath(SystemPath, ArcName, Path, &DriveType, &DriveNumber, &PartNumber);
} }
/* Check if volume path parsed successfully */ /* Check if volume path parsed successfully */
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to parse system path */ /* Failed to parse system path */
BlDebugPrint(L"ERROR: Failed to parse system path: '%s' (Status Code: 0x%zX)\n", SystemPath, Status); Debug::Print(L"ERROR: Failed to parse system path: '%s' (Status Code: 0x%zX)\n", SystemPath, Status);
return Status; return Status;
} }
@@ -428,21 +466,35 @@ 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 == NULLPTR)
{ {
/* Failed to find volume */ /* Volume not found */
BlDebugPrint(L"ERROR: Volume (DriveType: %u, DriveNumber: %lu, PartNumber: %lu) not found\n", Debug::Print(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;
} }
@@ -469,7 +521,7 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, Volume::OpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
OUT PEFI_HANDLE DiskHandle, OUT PEFI_HANDLE DiskHandle,
OUT PEFI_FILE_HANDLE *FsHandle) OUT PEFI_FILE_HANDLE *FsHandle)
{ {
@@ -480,10 +532,10 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
EFI_STATUS Status; EFI_STATUS Status;
/* Check if device path has been passed or not */ /* Check if device path has been passed or not */
if(DevicePath != NULL) if(DevicePath != NULLPTR)
{ {
/* Locate the device path */ /* Locate the device path */
Status = EfiSystemTable->BootServices->LocateDevicePath(&SFSGuid, &DevicePath, DiskHandle); Status = XtLoader::GetEfiSystemTable()->BootServices->LocateDevicePath(&SFSGuid, &DevicePath, DiskHandle);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to locate device path */ /* Failed to locate device path */
@@ -493,8 +545,12 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
else else
{ {
/* Open the image protocol if no device path specified */ /* Open the image protocol if no device path specified */
Status = EfiSystemTable->BootServices->OpenProtocol(EfiImageHandle, &LIPGuid, (PVOID *)&ImageProtocol, Status = XtLoader::GetEfiSystemTable()->BootServices->OpenProtocol(XtLoader::GetEfiImageHandle(),
EfiImageHandle, NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); &LIPGuid,
(PVOID *)&ImageProtocol,
XtLoader::GetEfiImageHandle(),
NULLPTR,
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to open image protocol */ /* Failed to open image protocol */
@@ -506,14 +562,16 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
} }
/* Open the filesystem protocol */ /* Open the filesystem protocol */
Status = EfiSystemTable->BootServices->OpenProtocol(*DiskHandle, &SFSGuid, (PVOID *)&FileSystemProtocol, Status = XtLoader::GetEfiSystemTable()->BootServices->OpenProtocol(*DiskHandle, &SFSGuid,
EfiImageHandle, NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); (PVOID *)&FileSystemProtocol,
XtLoader::GetEfiImageHandle(), NULLPTR,
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
/* Check if filesystem protocol opened successfully */ /* Check if filesystem protocol opened successfully */
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to open the filesystem protocol, close volume */ /* Failed to open the filesystem protocol, close volume */
BlCloseVolume(*DiskHandle); CloseVolume(DiskHandle);
return Status; return Status;
} }
@@ -522,7 +580,7 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to open the filesystem, close volume */ /* Failed to open the filesystem, close volume */
BlCloseVolume(*DiskHandle); CloseVolume(DiskHandle);
return Status; return Status;
} }
@@ -551,8 +609,8 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlReadFile(IN PEFI_FILE_HANDLE DirHandle, Volume::ReadFile(IN PEFI_FILE_HANDLE DirHandle,
IN CONST PWCHAR FileName, IN PCWSTR FileName,
OUT PVOID *FileData, OUT PVOID *FileData,
OUT PSIZE_T FileSize) OUT PSIZE_T FileSize)
{ {
@@ -564,7 +622,7 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
UINT_PTR ReadSize; UINT_PTR ReadSize;
SIZE_T Pages; SIZE_T Pages;
Status = DirHandle->Open(DirHandle, &FileHandle, FileName, EFI_FILE_MODE_READ, Status = DirHandle->Open(DirHandle, &FileHandle, (PWCHAR)FileName, EFI_FILE_MODE_READ,
EFI_FILE_READ_ONLY | EFI_FILE_HIDDEN | EFI_FILE_SYSTEM); EFI_FILE_READ_ONLY | EFI_FILE_HIDDEN | EFI_FILE_SYSTEM);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
@@ -576,7 +634,7 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
ReadSize = sizeof(EFI_FILE_INFO) + 32; ReadSize = sizeof(EFI_FILE_INFO) + 32;
/* Allocate necessary amount of memory */ /* Allocate necessary amount of memory */
Status = BlAllocateMemoryPool(ReadSize, (PVOID *)&FileInfo); Status = Memory::AllocatePool(ReadSize, (PVOID *)&FileInfo);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -589,8 +647,8 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
if(Status == STATUS_EFI_BUFFER_TOO_SMALL) if(Status == STATUS_EFI_BUFFER_TOO_SMALL)
{ {
/* Buffer is too small, but EFI tells the required size, so reallocate */ /* Buffer is too small, but EFI tells the required size, so reallocate */
BlFreeMemoryPool(&FileInfo); Memory::FreePool(&FileInfo);
Status = BlAllocateMemoryPool(ReadSize, (PVOID *)&FileInfo); Status = Memory::AllocatePool(ReadSize, (PVOID *)&FileInfo);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -607,7 +665,7 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
{ {
/* Unable to get file information */ /* Unable to get file information */
FileHandle->Close(FileHandle); FileHandle->Close(FileHandle);
BlFreeMemoryPool(&FileInfo); Memory::FreePool(&FileInfo);
return Status; return Status;
} }
@@ -616,19 +674,19 @@ 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 = Memory::AllocatePages(AllocateAnyPages, Pages, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Pages allocation failure */ /* Pages allocation failure */
FileHandle->Close(FileHandle); FileHandle->Close(FileHandle);
BlFreeMemoryPool(&FileInfo); Memory::FreePool(&FileInfo);
return Status; return Status;
} }
/* Calculate number of bytes to read and zero memory */ /* Calculate number of bytes to read and zero memory */
ReadSize = Pages * EFI_PAGE_SIZE; ReadSize = Pages * EFI_PAGE_SIZE;
*FileData = (PCHAR)(UINT_PTR)Address; *FileData = (PCHAR)(UINT_PTR)Address;
RtlZeroMemory(*FileData, ReadSize); RTL::Memory::ZeroMemory(*FileData, ReadSize);
/* Read data from the file */ /* Read data from the file */
Status = FileHandle->Read(FileHandle, &ReadSize, *FileData); Status = FileHandle->Read(FileHandle, &ReadSize, *FileData);
@@ -636,14 +694,14 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
{ {
/* Failed to read data */ /* Failed to read data */
FileHandle->Close(FileHandle); FileHandle->Close(FileHandle);
BlFreeMemoryPool(&FileInfo); Memory::FreePool(&FileInfo);
BlFreeMemoryPages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)*FileData); Memory::FreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)*FileData);
return Status; return Status;
} }
/* Close handle and free memory */ /* Close handle and free memory */
FileHandle->Close(FileHandle); FileHandle->Close(FileHandle);
BlFreeMemoryPool(FileInfo); Memory::FreePool(FileInfo);
/* Return success */ /* Return success */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
@@ -661,23 +719,23 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) Volume::DiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
{ {
EFI_GUID DevicePathGuid = EFI_DEVICE_PATH_PROTOCOL_GUID; EFI_GUID DevicePathGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
EFI_GUID IoGuid = EFI_BLOCK_IO_PROTOCOL_GUID; EFI_GUID IoGuid = EFI_BLOCK_IO_PROTOCOL_GUID;
PEFI_DEVICE_PATH_PROTOCOL DevicePath; PEFI_DEVICE_PATH_PROTOCOL DevicePath;
PEFI_BLOCK_DEVICE_DATA BlockDevice; PEFI_BLOCK_DEVICE_DATA BlockDevice;
UINT_PTR HandlesCount, Index; UINT_PTR HandlesCount, Index;
PEFI_HANDLE Handles = NULL; PEFI_HANDLE Handles = NULLPTR;
PEFI_BLOCK_IO_PROTOCOL Io; PEFI_BLOCK_IO_PROTOCOL Io;
EFI_STATUS Status; EFI_STATUS Status;
/* Locate handles which support the disk I/O interface */ /* Locate handles which support the disk I/O interface */
Status = BlLocateProtocolHandles(&Handles, &HandlesCount, &IoGuid); Status = Protocol::LocateProtocolHandles(&Handles, &HandlesCount, &IoGuid);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to locate handles */ /* Failed to locate handles */
BlDebugPrint(L"ERROR: Failed to locate block devices handles (Status Code: 0x%zX)\n", Status); Debug::Print(L"ERROR: Failed to locate block devices handles (Status Code: 0x%zX)\n", Status);
return Status; return Status;
} }
@@ -685,15 +743,15 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
for(Index = 0; Index < HandlesCount; Index++) for(Index = 0; Index < HandlesCount; Index++)
{ {
/* Print debug message */ /* Print debug message */
BlDebugPrint(L"Opening %lu block device from %lu discovered\n", Index + 1, HandlesCount); Debug::Print(L"Opening %lu block device from %lu discovered\n", Index + 1, HandlesCount);
/* Open I/O protocol for given handle */ /* Open I/O protocol for given handle */
Io = NULL; Io = NULLPTR;
Status = BlOpenProtocolHandle(Handles[Index], (PVOID *)&Io, &IoGuid); Status = Protocol::OpenProtocolHandle(Handles[Index], (PVOID *)&Io, &IoGuid);
if(Status != STATUS_EFI_SUCCESS || Io == NULL) if(Status != STATUS_EFI_SUCCESS || Io == NULLPTR)
{ {
/* Failed to open I/O protocol, skip it */ /* Failed to open I/O protocol, skip it */
BlDebugPrint(L"WARNING: Failed to open EFI Block I/O protocol (Status Code: 0x%zX)\n", Status); Debug::Print(L"WARNING: Failed to open EFI Block I/O protocol (Status Code: 0x%zX)\n", Status);
continue; continue;
} }
@@ -701,40 +759,44 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
if(Io->Media && Io->Media->BlockSize == 1 && Io->Media->MediaId == 0x69505845U) if(Io->Media && Io->Media->BlockSize == 1 && Io->Media->MediaId == 0x69505845U)
{ {
/* Skip stub as it is non-functional */ /* Skip stub as it is non-functional */
BlDebugPrint(L"WARNING: Skipping iPXE stub block I/O protocol"); Debug::Print(L"WARNING: Skipping iPXE stub block I/O protocol");
continue; continue;
} }
/* Check if DevicePath protocol is supported by this handle */ /* Check if DevicePath protocol is supported by this handle */
DevicePath = NULL; DevicePath = NULLPTR;
Status = EfiSystemTable->BootServices->HandleProtocol(Handles[Index], &DevicePathGuid, (PVOID *)&DevicePath); Status = XtLoader::GetEfiSystemTable()->BootServices->HandleProtocol(Handles[Index], &DevicePathGuid,
if(Status != STATUS_EFI_SUCCESS || DevicePath == NULL) (PVOID *)&DevicePath);
if(Status != STATUS_EFI_SUCCESS || DevicePath == NULLPTR)
{ {
/* Device failed to handle DP protocol */ /* Device failed to handle DP protocol */
BlDebugPrint(L"WARNING: Unable to open DevicePath protocol (Status Code: 0x%zX)\n", Status); Debug::Print(L"WARNING: Unable to open DevicePath protocol (Status Code: 0x%zX)\n", Status);
EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &IoGuid, EfiImageHandle, NULL); XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(Handles[Index], &IoGuid,
XtLoader::GetEfiImageHandle(), NULLPTR);
continue; continue;
} }
/* Allocate memory for block device */ /* Allocate memory for block device */
Status = BlAllocateMemoryPool(sizeof(*BlockDevice), (PVOID *)&BlockDevice); Status = Memory::AllocatePool(sizeof(*BlockDevice), (PVOID *)&BlockDevice);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
BlDebugPrint(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%zX)\n", Status); Debug::Print(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%zX)\n", Status);
EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &DevicePathGuid, EfiImageHandle, NULL); XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(Handles[Index], &DevicePathGuid,
EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &IoGuid, EfiImageHandle, NULL); XtLoader::GetEfiImageHandle(), NULLPTR);
XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(Handles[Index], &IoGuid,
XtLoader::GetEfiImageHandle(), NULLPTR);
return Status; return Status;
} }
/* Store new block device into a linked list */ /* Store new block device into a linked list */
BlockDevice->BlockIo = Io; BlockDevice->BlockIo = Io;
BlockDevice->DevicePath = DevicePath; BlockDevice->DevicePath = DevicePath;
RtlInsertTailList(BlockDevices, &BlockDevice->ListEntry); RTL::LinkedList::InsertTailList(BlockDevices, &BlockDevice->ListEntry);
} }
/* Free handles buffer */ /* Free handles buffer */
BlFreeMemoryPool(Handles); Memory::FreePool(Handles);
/* Return success */ /* Return success */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
@@ -764,7 +826,7 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlpDissectVolumeArcPath(IN PWCHAR SystemPath, Volume::DissectArcPath(IN PWCHAR SystemPath,
OUT PWCHAR *ArcName, OUT PWCHAR *ArcName,
OUT PWCHAR *Path, OUT PWCHAR *Path,
OUT PUSHORT DriveType, OUT PUSHORT DriveType,
@@ -780,20 +842,26 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath,
*PartNumber = 0; *PartNumber = 0;
/* Look for the ARC path */ /* Look for the ARC path */
if(RtlCompareWideStringInsensitive(SystemPath, L"ramdisk(0)", 0) == 0) if(RTL::WideString::CompareWideStringInsensitive(SystemPath, L"ramdisk(0)", 0) == 0)
{ {
/* This is RAM disk */ /* This is RAM disk */
ArcLength = 10; ArcLength = 10;
*DriveType = XTBL_BOOT_DEVICE_RAMDISK; *DriveType = XTBL_BOOT_DEVICE_RAMDISK;
} }
else if(RtlCompareWideStringInsensitive(SystemPath, L"multi(0)disk(0)", 0) == 0) else if(RTL::WideString::CompareWideStringInsensitive(SystemPath, L"multi(0)esp(0)", 0) == 0)
{
/* This is ESP */
ArcLength = 14;
*DriveType = XTBL_BOOT_DEVICE_ESP;
}
else if(RTL::WideString::CompareWideStringInsensitive(SystemPath, L"multi(0)disk(0)", 0) == 0)
{ {
/* This is a multi-disk port */ /* This is a multi-disk port */
ArcLength = 15; ArcLength = 15;
ArcPath = SystemPath + ArcLength; ArcPath = SystemPath + ArcLength;
/* Check for disk type */ /* Check for disk type */
if(RtlCompareWideStringInsensitive(ArcPath, L"cdrom(", 0) == 0) if(RTL::WideString::CompareWideStringInsensitive(ArcPath, L"cdrom(", 0) == 0)
{ {
/* This is an optical drive */ /* This is an optical drive */
ArcLength += 6; ArcLength += 6;
@@ -814,7 +882,7 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath,
*DriveType = XTBL_BOOT_DEVICE_CDROM; *DriveType = XTBL_BOOT_DEVICE_CDROM;
ArcLength++; ArcLength++;
} }
else if(RtlCompareWideStringInsensitive(ArcPath, L"fdisk(", 0) == 0) else if(RTL::WideString::CompareWideStringInsensitive(ArcPath, L"fdisk(", 0) == 0)
{ {
/* This is a floppy drive */ /* This is a floppy drive */
ArcLength += 6; ArcLength += 6;
@@ -835,7 +903,7 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath,
*DriveType = XTBL_BOOT_DEVICE_FLOPPY; *DriveType = XTBL_BOOT_DEVICE_FLOPPY;
ArcLength++; ArcLength++;
} }
else if(RtlCompareWideStringInsensitive(ArcPath, L"rdisk(", 0) == 0) else if(RTL::WideString::CompareWideStringInsensitive(ArcPath, L"rdisk(", 0) == 0)
{ {
/* This is a hard disk */ /* This is a hard disk */
ArcLength += 6; ArcLength += 6;
@@ -858,7 +926,7 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath,
ArcPath = SystemPath + ArcLength; ArcPath = SystemPath + ArcLength;
/* Look for a partition */ /* Look for a partition */
if(RtlCompareWideStringInsensitive(ArcPath, L"partition(", 0) == 0) if(RTL::WideString::CompareWideStringInsensitive(ArcPath, L"partition(", 0) == 0)
{ {
/* Partition information found */ /* Partition information found */
ArcLength += 10; ArcLength += 10;
@@ -898,8 +966,8 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath,
/* Store ARC name if possible */ /* Store ARC name if possible */
if(ArcName) if(ArcName)
{ {
BlAllocateMemoryPool(ArcLength * sizeof(WCHAR), (PVOID *)&LocalArcName); Memory::AllocatePool(ArcLength * sizeof(WCHAR), (PVOID *)&LocalArcName);
RtlCopyMemory(LocalArcName, SystemPath, ArcLength * sizeof(WCHAR)); RTL::Memory::CopyMemory(LocalArcName, SystemPath, ArcLength * sizeof(WCHAR));
LocalArcName[ArcLength] = '\0'; LocalArcName[ArcLength] = '\0';
*ArcName = LocalArcName; *ArcName = LocalArcName;
} }
@@ -920,18 +988,18 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath,
*/ */
XTCDECL XTCDECL
PEFI_DEVICE_PATH_PROTOCOL PEFI_DEVICE_PATH_PROTOCOL
BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath) Volume::DuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath)
{ {
PEFI_DEVICE_PATH_PROTOCOL DevicePathNode; PEFI_DEVICE_PATH_PROTOCOL DevicePathNode;
PEFI_DEVICE_PATH_PROTOCOL DevicePathClone; PEFI_DEVICE_PATH_PROTOCOL DevicePathClone;
EFI_STATUS Status; EFI_STATUS Status;
UINT Length = 0; UINT Length = 0;
/* Check if the input device path is NULL */ /* Check if the input device path is NULL pointer */
if(!DevicePath) if(!DevicePath)
{ {
/* Nothing to duplicate */ /* Nothing to duplicate */
return NULL; return NULLPTR;
} }
/* Start iterating from the beginning of the device path */ /* Start iterating from the beginning of the device path */
@@ -952,20 +1020,20 @@ BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath)
if(Length == 0) if(Length == 0)
{ {
/* Nothing to duplicate */ /* Nothing to duplicate */
return NULL; return NULLPTR;
} }
/* Allocate memory for the new device path */ /* Allocate memory for the new device path */
Status = BlAllocateMemoryPool(Length, (PVOID *)&DevicePathClone); Status = Memory::AllocatePool(Length, (PVOID *)&DevicePathClone);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to allocate memory */ /* Failed to allocate memory */
BlDebugPrint(L"ERROR: Failed to allocate memory pool for device path duplicate (Status Code: 0x%zX)\n", Status); Debug::Print(L"ERROR: Failed to allocate memory pool for device path duplicate (Status Code: 0x%zX)\n", Status);
return NULL; return NULLPTR;
} }
/* Copy the device path */ /* Copy the device path */
RtlCopyMemory(DevicePathClone, DevicePath, Length); RTL::Memory::CopyMemory(DevicePathClone, DevicePath, Length);
/* Return the cloned object */ /* Return the cloned object */
return DevicePathClone; return DevicePathClone;
@@ -986,7 +1054,7 @@ BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, Volume::FindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode) OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode)
{ {
PEFI_DEVICE_PATH_PROTOCOL EndNode, NextNode; PEFI_DEVICE_PATH_PROTOCOL EndNode, NextNode;
@@ -995,7 +1063,7 @@ BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
if(DevicePath->Type == EFI_END_DEVICE_PATH) if(DevicePath->Type == EFI_END_DEVICE_PATH)
{ {
/* End reached, nothing to do */ /* End reached, nothing to do */
LastNode = NULL; LastNode = NULLPTR;
return STATUS_EFI_INVALID_PARAMETER; return STATUS_EFI_INVALID_PARAMETER;
} }
@@ -1032,7 +1100,7 @@ BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
*/ */
XTCDECL XTCDECL
BOOLEAN BOOLEAN
BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices, Volume::FindParentBlockDevice(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)
{ {
@@ -1047,6 +1115,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;
@@ -1065,10 +1141,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) ||
(RTL::Memory::CompareMemory(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;
} }

328
boot/xtldr/xtldr.cc Normal file
View File

@@ -0,0 +1,328 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/xtldr.cc
* DESCRIPTION: XTOS UEFI Boot Loader
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtldr.hh>
/**
* Disables access to EFI Boot Services.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
XtLoader::DisableBootServices()
{
LoaderStatus.BootServices = FALSE;
}
/**
* Queries the availability of EFI Boot Services.
*
* @return This routine returns TRUE if EFI Boot Services are available, FALSE otherwise.
*
* @since XT 1.0
*/
XTCDECL
BOOLEAN
XtLoader::GetBootServicesStatus()
{
return LoaderStatus.BootServices;
}
/**
* Retrieves the EFI image handle.
*
* @return This routine returns a handle to the EFI-loaded image.
*
* @since XT 1.0
*/
XTCDECL
EFI_HANDLE
XtLoader::GetEfiImageHandle()
{
return XtLoader::EfiImageHandle;
}
/**
* Retrieves the EFI system table pointer.
*
* @return This routine returns a pointer to the EFI system table.
*
* @since XT 1.0
*/
XTCDECL
PEFI_SYSTEM_TABLE
XtLoader::GetEfiSystemTable()
{
return XtLoader::EfiSystemTable;
}
/**
* Provides base address and size of the XTLDR image.
*
* @param LoaderBase
* Supplies a pointer to a variable that receives the base address of the XTLDR image.
*
* @param LoaderSize
* Supplies a pointer to a variable that receives the size of the XTLDR image.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
XtLoader::GetLoaderImageInformation(PVOID *LoaderBase,
PULONGLONG LoaderSize)
{
*LoaderBase = XtLoader::LoaderStatus.LoaderBase;
*LoaderSize = XtLoader::LoaderStatus.LoaderSize;
}
/**
* Retrieves the Secure Boot status.
*
* @return This routine returns SecureBoot status.
*
* @since XT 1.0
*/
XTCDECL
INT_PTR
XtLoader::GetSecureBootStatus()
{
return LoaderStatus.SecureBoot;
}
/**
* Initializes EFI Boot Loader (XTLDR).
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
XtLoader::InitializeBootLoader(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable)
{
EFI_GUID LipGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
PEFI_LOADED_IMAGE_PROTOCOL LoadedImage;
EFI_HANDLE Handle;
EFI_STATUS Status;
/* Set the system table and image handle */
EfiImageHandle = ImageHandle;
EfiSystemTable = SystemTable;
/* Set current XTLDR's EFI BootServices status */
LoaderStatus.BootServices = TRUE;
/* Initialize console */
Console::InitializeConsole();
/* Print XTLDR version */
Console::Print(L"XTLDR boot loader v%s\n", XTOS_VERSION);
/* Initialize XTLDR protocol */
Protocol::InitializeProtocol();
/* Initialize XTLDR configuration */
Configuration::InitializeConfiguration();
/* Store SecureBoot status */
LoaderStatus.SecureBoot = EfiUtils::GetSecureBootStatus();
/* Attempt to open EFI LoadedImage protocol */
Status = Protocol::OpenProtocol(&Handle, (PVOID *)&LoadedImage, &LipGuid);
if(Status == STATUS_EFI_SUCCESS)
{
/* Store boot loader image base and size */
LoaderStatus.LoaderBase = LoadedImage->ImageBase;
LoaderStatus.LoaderSize = LoadedImage->ImageSize;
/* Check if debug is enabled */
if(DEBUG)
{
/* Protocol opened successfully, print useful debug information */
Console::Print(L"\n---------- BOOTLOADER DEBUG ----------\n"
L"Pointer Size : %d\n"
L"Image Base Address : %P\n"
L"Image Base Size : 0x%lX\n"
L"Image Revision : 0x%lX\n"
L"Secure Boot Status : %zd\n"
L"--------------------------------------\n",
sizeof(PVOID),
LoadedImage->ImageBase,
LoadedImage->ImageSize,
LoadedImage->Revision,
LoaderStatus.SecureBoot);
EfiUtils::SleepExecution(3000);
}
/* Close EFI LoadedImage protocol */
Protocol::CloseProtocol(&Handle, &LipGuid);
}
}
/**
* Registers a boot menu callback routine, that will be used to display alternative boot menu.
*
* @param BootMenuRoutine
* Supplies a pointer to the boot menu callback routine.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
XtLoader::RegisterBootMenu(IN PVOID BootMenuRoutine)
{
/* Set boot menu routine */
BootMenu = (PBL_XT_BOOT_MENU)BootMenuRoutine;
}
/**
* Invokes either a custom boot menu handler, if one has been registered, or displays the default boot menu.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
XtLoader::ShowBootMenu()
{
/* Check if custom boot menu registered */
if(BootMenu != NULLPTR)
{
/* Display alternative boot menu */
BootMenu();
}
else
{
/* Display default boot menu */
TextUi::DisplayBootMenu();
}
}
/**
* This routine is the entry point of the XT EFI boot loader.
*
* @param ImageHandle
* Firmware-allocated handle that identifies the image.
*
* @param SystemTable
* Provides the EFI system table.
*
* @return This routine returns status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlStartXtLoader(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable)
{
PWCHAR Modules;
EFI_STATUS Status;
/* Initialize XTLDR and */
XtLoader::InitializeBootLoader(ImageHandle, SystemTable);
/* Parse configuration options passed from UEFI shell */
Status = Configuration::ParseCommandLine();
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to parse command line options */
TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to parse command line parameters.");
}
/* Attempt to early initialize debug console */
if(DEBUG)
{
Status = Debug::InitializeDebugConsole();
if(Status != STATUS_EFI_SUCCESS)
{
/* Initialization failed, notify user on stdout */
TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to initialize debug console.");
}
}
/* Load XTLDR configuration file */
Status = Configuration::LoadConfiguration();
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to load/parse config file */
TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to load and parse configuration file ");
}
/* Reinitialize debug console if it was not initialized earlier */
if(DEBUG)
{
Status = Debug::InitializeDebugConsole();
if(Status != STATUS_EFI_SUCCESS)
{
/* Initialization failed, notify user on stdout */
TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to initialize debug console.");
}
}
/* Disable watchdog timer */
Status = XtLoader::GetEfiSystemTable()->BootServices->SetWatchdogTimer(0, 0x10000, 0, NULLPTR);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to disable the timer, print message */
Debug::Print(L"WARNING: Failed to disable watchdog timer (Status Code: 0x%zX)\n", Status);
}
/* Install loader protocol */
Status = Protocol::InstallXtLoaderProtocol();
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to register loader protocol */
Debug::Print(L"ERROR: Failed to register XTLDR loader protocol (Status Code: 0x%zX)\n", Status);
return Status;
}
/* Load all necessary modules */
Configuration::GetValue(L"MODULES", &Modules);
Status = Protocol::LoadModules(Modules);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to load modules */
Debug::Print(L"ERROR: Failed to load XTLDR modules (Status Code: 0x%zX)\n", Status);
TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to load some XTLDR modules.");
}
/* Discover and enumerate EFI block devices */
Status = Volume::EnumerateBlockDevices();
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to enumerate block devices */
Debug::Print(L"ERROR: Failed to discover and enumerate block devices (Status Code: 0x%zX)\n", Status);
return Status;
}
/* Main boot loader loop */
while(TRUE)
{
/* Show boot menu */
XtLoader::ShowBootMenu();
/* Fallback to shell, if boot menu returned */
Shell::StartLoaderShell();
}
/* This point should be never reached, if this happen return error code */
return STATUS_EFI_LOAD_ERROR;
}

View File

@@ -4,48 +4,41 @@
# DESCRIPTION: Project configuration script for preparing the build environment # DESCRIPTION: Project configuration script for preparing the build environment
# DEVELOPERS: Aiken Harris <harraiken91@gmail.com> # DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
# Check XTchain # Check XTchain
if (-not $env:XTCVER) { if (-not $env:XTCVER) {
Write-Host "XTChain not detected or corrupted!" Write-Error "XTChain not detected or corrupted!"
exit 1 exit 1
} }
# Set target architecture # Set target architecture defaulting to amd64
if ($env:TARGET) { $ARCH = if ($env:TARGET) { $env:TARGET } else { "amd64" }
$ARCH = $env:TARGET
} else {
$ARCH = "amd64"
}
# Set target build type # Set target build type defaulting to Debug
if (-not $env:BUILD_TYPE) { $env:BUILD_TYPE = if ($env:BUILD_TYPE -in @("Debug", "Release")) { $env:BUILD_TYPE } else { "Debug" }
$env:BUILD_TYPE = "DEBUG"
}
# Set variables # Set variables
$EXECTOS_SOURCE_DIR = (Get-Location).Path $EXECTOS_SOURCE_DIR = $PSScriptRoot
$EXECTOS_BINARY_DIR = "build-$($ARCH)-$($env:BUILD_TYPE.ToLower())" $EXECTOS_BINARY_DIR = Join-Path $EXECTOS_SOURCE_DIR "build-$ARCH-$($env:BUILD_TYPE.ToLower())"
# Create directories if needed # Create build directory
if ($EXECTOS_SOURCE_DIR -eq (Get-Location).Path) { if (-not (Test-Path $EXECTOS_BINARY_DIR)) {
Write-Host "Creating directories in $EXECTOS_BINARY_DIR" Write-Host "Creating build directory: $EXECTOS_BINARY_DIR"
New-Item -ItemType Directory -Path $EXECTOS_BINARY_DIR -Force | Out-Null New-Item -ItemType Directory -Path $EXECTOS_BINARY_DIR -Force | Out-Null
Set-Location -Path $EXECTOS_BINARY_DIR
} }
Set-Location $EXECTOS_BINARY_DIR
# Delete old cache # Delete old cache
Remove-Item -Path "CMakeCache.txt" -ErrorAction SilentlyContinue Remove-Item "CMakeCache.txt", "host-tools/CMakeCache.txt" -ErrorAction SilentlyContinue
Remove-Item -Path "host-tools/CMakeCache.txt" -ErrorAction SilentlyContinue
# Configure project using CMake # Configure project using CMake
& cmake -G Ninja -DARCH:STRING=$($ARCH) -DBUILD_TYPE:STRING=$($env:BUILD_TYPE) $EXECTOS_SOURCE_DIR & cmake -G Ninja "-DARCH:STRING=$ARCH" "-DBUILD_TYPE:STRING=$($env:BUILD_TYPE)" $EXECTOS_SOURCE_DIR
# Check if configuration succeeded # Check if configuration succeeded
if ($LASTEXITCODE -ne 0) { if ($LASTEXITCODE -ne 0) {
Write-Host "Configure script failed." Write-Error "Configure script failed."
exit 1 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."
} }
$ARCH | Out-File -Encoding ASCII -NoNewline "build.arch"
Write-Host "Configure completed. Run 'xbuild' to build ExectOS."

View File

@@ -7,8 +7,8 @@ include_directories(
# Specify list of source code files # Specify list of source code files
list(APPEND NTOSDRV_SOURCE list(APPEND NTOSDRV_SOURCE
${NTOSDRV_SOURCE_DIR}/ntosdrv.c ${NTOSDRV_SOURCE_DIR}/ntosdrv.cc
${NTOSDRV_SOURCE_DIR}/rtl.c) ${NTOSDRV_SOURCE_DIR}/rtl.cc)
# Set module definition SPEC file # Set module definition SPEC file
set_specfile(ntosdrv.spec ntosdrv.sys) set_specfile(ntosdrv.spec ntosdrv.sys)

View File

@@ -1,7 +1,7 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: drivers/ntosdrv/ntosdrv.c * FILE: drivers/ntosdrv/ntosdrv.cc
* DESCRIPTION: NTOS compatibility driver * DESCRIPTION: NTOS compatibility driver
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
@@ -16,6 +16,7 @@
* *
* @since XT 1.0 * @since XT 1.0
*/ */
XTCLINK
XTAPI XTAPI
XTSTATUS XTSTATUS
XtDriverEntry(VOID) XtDriverEntry(VOID)

View File

@@ -1,7 +1,7 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: drivers/ntosdrv/rtl.c * FILE: drivers/ntosdrv/rtl.cc
* DESCRIPTION: NTOS compatibility driver runtime library * DESCRIPTION: NTOS compatibility driver runtime library
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
@@ -25,6 +25,7 @@
* *
* @since NT 3.5 * @since NT 3.5
*/ */
XTCLINK
XTAPI XTAPI
VOID VOID
RtlFillMemory(OUT PVOID Destination, RtlFillMemory(OUT PVOID Destination,

1
sdk/CMakeLists.txt Normal file
View File

@@ -0,0 +1 @@
set_sdk_target("xtdk/" "include")

View File

@@ -8,41 +8,79 @@ endif()
# This target creates a disk image # This target creates a disk image
add_custom_target(diskimg add_custom_target(diskimg
DEPENDS install DEPENDS install
COMMAND sh -c "dd if=/dev/zero of=${EXECTOS_BINARY_DIR}/output/disk.img bs=512 count=${PROJECT_DISK_IMAGE_BLOCKS} 2>/dev/null 1>/dev/null" COMMAND diskimg -c ${EXECTOS_BINARY_DIR}/output/binaries -f 32 -o ${EXECTOS_BINARY_DIR}/output/disk.img -s ${PROJECT_DISK_IMAGE_SIZE}
COMMAND parted ${EXECTOS_BINARY_DIR}/output/disk.img -s -a minimal mklabel gpt -m ${EXECTOS_BINARY_DIR}/boot/bootsect/mbrboot.bin -v ${EXECTOS_BINARY_DIR}/boot/bootsect/espboot.bin
COMMAND parted ${EXECTOS_BINARY_DIR}/output/disk.img -s -a minimal mkpart EFI FAT32 2048s ${PROJECT_PART_IMAGE_BLOCKS}s
COMMAND parted ${EXECTOS_BINARY_DIR}/output/disk.img -s -a minimal toggle 1 boot
COMMAND sh -c "dd if=/dev/zero of=${EXECTOS_BINARY_DIR}/output/part.img bs=512 count=${PROJECT_PART_IMAGE_BLOCKS} 2>/dev/null 1>/dev/null"
COMMAND mformat -i ${EXECTOS_BINARY_DIR}/output/part.img -h32 -t32 -n64 -L32
COMMAND sh -c "mcopy -s -i ${EXECTOS_BINARY_DIR}/output/part.img ${EXECTOS_BINARY_DIR}/output/binaries/* ::"
COMMAND sh -c "dd if=${EXECTOS_BINARY_DIR}/output/part.img of=${EXECTOS_BINARY_DIR}/output/disk.img bs=512 count=${PROJECT_PART_IMAGE_BLOCKS} seek=2048 conv=notrunc 2>/dev/null 1>/dev/null"
COMMAND rm ${EXECTOS_BINARY_DIR}/output/part.img
VERBATIM) VERBATIM)
# This target starts up a BOCHS+OVMF virtual machine find_program(BOCHS_EMULATOR bochs)
add_custom_target(bochsvm if(BOCHS_EMULATOR)
# This target starts up a BOCHS+BIOS virtual machine
add_custom_target(bochsvm
DEPENDS diskimg DEPENDS diskimg
COMMAND bochs -f ../sdk/firmware/bochsrc_${ARCH}.cfg -q -unlock COMMAND bochs -f ../sdk/firmware/bochsrc_${ARCH}.cfg -q -unlock
VERBATIM USES_TERMINAL) VERBATIM USES_TERMINAL)
endif()
# This target starts up a QEMU+OVMF virtual machine using KVM accelerator find_program(QEMU_EMULATOR ${QEMU_COMMAND})
add_custom_target(testkvm if(QEMU_EMULATOR)
if(CMAKE_HOST_LINUX)
# This target starts up a QEMU+OVMF virtual machine using KVM accelerator
add_custom_target(testefikvm
DEPENDS install 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}-EFI-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 -bios ${EXECTOS_SOURCE_DIR}/sdk/firmware/ovmf_${ARCH}.fd
-drive file=${EXECTOS_SOURCE_DIR}/sdk/firmware/ovmf_vars_${ARCH}.fd,if=pflash,format=raw,unit=1
-hda fat:rw:${EXECTOS_BINARY_DIR}/output/binaries -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)
elseif(CMAKE_HOST_WIN32)
# This target starts up a QEMU+OVMF virtual machine using TCG accelerator # This target starts up a QEMU+OVMF virtual machine using WHPX accelerator
add_custom_target(testtcg add_custom_target(testefiwhpx
DEPENDS install DEPENDS install
COMMAND ${QEMU_COMMAND} -name "ExectOS-${ARCH}-TCG" -machine type=q35,accel=tcg -cpu max,-hypervisor COMMAND ${QEMU_COMMAND} -name "ExectOS-${ARCH}-EFI-WHPX" -machine type=q35,kernel_irqchip=off,accel=whpx,mem-merge=off,vmport=off
-smp 2,sockets=1,cores=1,threads=2 -m 4G -overcommit mem-lock=off -rtc clock=host,base=localtime,driftfix=none -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 -bios ${EXECTOS_SOURCE_DIR}/sdk/firmware/ovmf_${ARCH}.fd
-drive file=${EXECTOS_SOURCE_DIR}/sdk/firmware/ovmf_vars_${ARCH}.fd,if=pflash,format=raw,unit=1
-hda fat:rw:${EXECTOS_BINARY_DIR}/output/binaries -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)
endif()
# This target starts up a QEMU+OVMF virtual machine using TCG accelerator
add_custom_target(testefitcg
DEPENDS install
COMMAND ${QEMU_COMMAND} -name "ExectOS-${ARCH}-EFI-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
-bios ${EXECTOS_SOURCE_DIR}/sdk/firmware/ovmf_${ARCH}.fd
-hda fat:rw:${EXECTOS_BINARY_DIR}/output/binaries
-boot menu=on -d int -no-reboot -no-shutdown -serial stdio
VERBATIM USES_TERMINAL)
if(CMAKE_HOST_LINUX)
# This target starts up a QEMU+SEABIOS virtual machine using KVM accelerator
add_custom_target(testkvm
DEPENDS diskimg
COMMAND ${QEMU_COMMAND} -name "ExectOS-${ARCH}-BIOS-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
-hda ${EXECTOS_BINARY_DIR}/output/disk.img
-boot menu=on -d int -no-reboot -no-shutdown -serial stdio
VERBATIM USES_TERMINAL)
elseif(CMAKE_HOST_WIN32)
# This target starts up a QEMU+SEABIOS virtual machine using WHPX accelerator
add_custom_target(testwhpx
DEPENDS diskimg
COMMAND ${QEMU_COMMAND} -name "ExectOS-${ARCH}-BIOS-WHPX" -machine type=q35,kernel_irqchip=off,accel=whpx,mem-merge=off,vmport=off
-m 4G -overcommit mem-lock=off -rtc clock=host,base=localtime,driftfix=none
-hda ${EXECTOS_BINARY_DIR}/output/disk.img
-boot menu=on -d int -no-reboot -no-shutdown -serial stdio
VERBATIM USES_TERMINAL)
endif()
# This target starts up a QEMU+SEABIOS virtual machine using TCG accelerator
add_custom_target(testtcg
DEPENDS diskimg
COMMAND ${QEMU_COMMAND} -name "ExectOS-${ARCH}-BIOS-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
-hda ${EXECTOS_BINARY_DIR}/output/disk.img
-boot menu=on -d int -no-reboot -no-shutdown -serial stdio
VERBATIM USES_TERMINAL)
endif()

View File

@@ -59,18 +59,42 @@ function(add_module_linker_flags MODULE FLAGS)
set_module_property(${MODULE} LINK_FLAGS ${FLAGS}) set_module_property(${MODULE} LINK_FLAGS ${FLAGS})
endfunction() endfunction()
# This function sets a property for specified module # This function compiles an assembly bootsector file into a flat binary
function(set_module_property MODULE PROPERTY FLAGS) function(compile_bootsector NAME SOURCE BASEADDR ENTRYPOINT)
if(NOT ${ARGC} EQUAL 3) set(BINARY_NAME "${NAME}.bin")
message(FATAL_ERROR "Invalid number of arguments passwd to add_module_property() function") set(OBJECT_NAME "${NAME}.obj")
endif()
get_target_property(VAL ${MODULE} ${PROPERTY}) add_custom_command(
if(VAL) OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${BINARY_NAME}
set(VAL "${VAL} ${FLAGS}") COMMAND ${CMAKE_ASM_COMPILER}
else() /nologo
set(VAL "${FLAGS}") --target=i386-none-elf
endif() -I${CMAKE_CURRENT_SOURCE_DIR}
set_property(TARGET ${MODULE} PROPERTY ${PROPERTY} ${VAL}) /Fo${CMAKE_CURRENT_BINARY_DIR}/${OBJECT_NAME}
-c -- ${SOURCE}
COMMAND ${CMAKE_ASM_LINKER}
-m elf_i386
--image-base=0
--oformat binary
-Ttext=${BASEADDR}
--entry=_start${ENTRYPOINT}
-o ${CMAKE_CURRENT_BINARY_DIR}/${BINARY_NAME}
${CMAKE_CURRENT_BINARY_DIR}/${OBJECT_NAME}
DEPENDS ${SOURCE}
)
add_custom_target(${NAME} ALL
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${BINARY_NAME}
)
endfunction()
# This function sets the the qemu disk image size (in MiB)
function(set_disk_image_size SIZE)
MATH(EXPR DISK_BLOCKS ${SIZE}*1024*1024/512)
MATH(EXPR PART_BLOCKS ${DISK_BLOCKS}-2048)
set(PROJECT_DISK_IMAGE_SIZE ${SIZE} CACHE INTERNAL "PROJECT_DISK_IMAGE_SIZE")
set(PROJECT_DISK_IMAGE_BLOCKS ${DISK_BLOCKS} CACHE INTERNAL "PROJECT_DISK_IMAGE_BLOCKS")
set(PROJECT_PART_IMAGE_BLOCKS ${PART_BLOCKS} CACHE INTERNAL "PROJECT_PART_IMAGE_BLOCKS")
endfunction() endfunction()
# This function installs specified directory recursively under destination directory # This function installs specified directory recursively under destination directory
@@ -85,9 +109,28 @@ endfunction()
# This function installs specified target results under destination directory # This function installs specified target results under destination directory
function(set_install_target TARGET DESTINATION) function(set_install_target TARGET DESTINATION)
set_target_properties(${TARGET} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${EXECTOS_BINARY_DIR}/output/sdk/lib")
install(TARGETS ${TARGET} DESTINATION ${EXECTOS_BINARY_DIR}/output/binaries/${DESTINATION}) install(TARGETS ${TARGET} DESTINATION ${EXECTOS_BINARY_DIR}/output/binaries/${DESTINATION})
endfunction() endfunction()
# This function sets a property for specified module
function(set_module_property MODULE PROPERTY FLAGS)
if(NOT ${ARGC} EQUAL 3)
message(FATAL_ERROR "Invalid number of arguments passwd to add_module_property() function")
endif()
get_target_property(VAL ${MODULE} ${PROPERTY})
if(VAL)
set(VAL "${VAL} ${FLAGS}")
else()
set(VAL "${FLAGS}")
endif()
set_property(TARGET ${MODULE} PROPERTY ${PROPERTY} ${VAL})
endfunction()
function(set_sdk_target FILENAME DESTINATION)
install(DIRECTORY ${FILENAME} DESTINATION ${EXECTOS_BINARY_DIR}/output/sdk/${DESTINATION})
endfunction()
# This function is responsible for compiling module SPEC file # This function is responsible for compiling module SPEC file
function(set_specfile SPECFILE EXPORTNAME) function(set_specfile SPECFILE EXPORTNAME)
if(NOT ${ARGC} EQUAL 2) if(NOT ${ARGC} EQUAL 2)
@@ -97,11 +140,3 @@ function(set_specfile SPECFILE EXPORTNAME)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}.def ${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}.c add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}.def ${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}.c
COMMAND ${CMAKE_SPEC_COMPILER} -a=${ARCH} -n=${EXPORTNAME} -d=${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}.def -s=${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}.c ${CMAKE_CURRENT_SOURCE_DIR}/${SPECFILE}) COMMAND ${CMAKE_SPEC_COMPILER} -a=${ARCH} -n=${EXPORTNAME} -d=${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}.def -s=${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}.c ${CMAKE_CURRENT_SOURCE_DIR}/${SPECFILE})
endfunction() endfunction()
# This function sets the the qemu disk image size (in MiB)
function(set_disk_image_size SIZE)
MATH(EXPR DISK_BLOCKS ${SIZE}*1024*1024/512)
MATH(EXPR PART_BLOCKS ${DISK_BLOCKS}-2048)
set(PROJECT_DISK_IMAGE_BLOCKS ${DISK_BLOCKS} CACHE INTERNAL "PROJECT_DISK_IMAGE_BLOCKS")
set(PROJECT_PART_IMAGE_BLOCKS ${PART_BLOCKS} CACHE INTERNAL "PROJECT_PART_IMAGE_BLOCKS")
endfunction()

View File

@@ -3,8 +3,10 @@ set(CMAKE_SYSTEM_NAME Windows)
# Set toolchain compilers # Set toolchain compilers
set(CMAKE_ASM_COMPILER clang-cl) set(CMAKE_ASM_COMPILER clang-cl)
set(CMAKE_ASM_LINKER ld.lld)
set(CMAKE_C_COMPILER clang-cl) set(CMAKE_C_COMPILER clang-cl)
set(CMAKE_CXX_COMPILER clang-cl) set(CMAKE_CXX_COMPILER clang-cl)
set(CMAKE_LINKER lld-link)
set(CMAKE_MC_COMPILER wmc) set(CMAKE_MC_COMPILER wmc)
set(CMAKE_RC_COMPILER wrc) set(CMAKE_RC_COMPILER wrc)
set(CMAKE_SPEC_COMPILER xtcspecc) set(CMAKE_SPEC_COMPILER xtcspecc)
@@ -20,8 +22,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

@@ -12,7 +12,7 @@ endif()
# Set build optimisation # Set build optimisation
if(BUILD_TYPE STREQUAL "DEBUG") if(BUILD_TYPE STREQUAL "DEBUG")
add_compiler_ccxxflags("/GS- /Zi /Ob0 /Od") add_compiler_ccxxflags("/GS- /Zi /Ob0 /Od")
add_linker_flags("/DEBUG /INCREMENTAL /OPT:NOREF /OPT:NOICF /PDBSOURCEPATH:build") add_linker_flags("/DEBUG /INCREMENTAL:NO /OPT:REF /OPT:NOICF /PDBSOURCEPATH:build")
else() else()
add_compiler_ccxxflags("/GS- /Ob2 /Ot /Ox /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")
@@ -50,8 +50,9 @@ add_compiler_ccxxflags("-Wno-gnu-folding-constant")
# Disable compiler builtins # Disable compiler builtins
add_compiler_ccxxflags("-fno-builtin") add_compiler_ccxxflags("-fno-builtin")
# Set debugging symbols output directory # Set symbols and libraries output directory
set(CMAKE_PDB_OUTPUT_DIRECTORY "${EXECTOS_BINARY_DIR}/output/symbols") set(CMAKE_PDB_OUTPUT_DIRECTORY "${EXECTOS_BINARY_DIR}/output/symbols")
set(LIBRARY_OUTPUT_PATH "${EXECTOS_BINARY_DIR}/output/sdk/lib")
# Set linker flags # Set linker flags
add_linker_flags("${HOTPATCH_LINKER_FLAG} /LARGEADDRESSAWARE /IGNORE:4039 /IGNORE:4104 /MANIFEST:NO /NODEFAULTLIB /SAFESEH:NO") add_linker_flags("${HOTPATCH_LINKER_FLAG} /LARGEADDRESSAWARE /IGNORE:4039 /IGNORE:4104 /MANIFEST:NO /NODEFAULTLIB /SAFESEH:NO")

View File

@@ -3,9 +3,9 @@ plugin_ctrl: usb_xhci=false, serial=true, e1000=false, extfpuirq=true, parallel=
config_interface: textconfig config_interface: textconfig
display_library: x display_library: x
memory: host=64, guest=64 memory: host=64, guest=64
romimage: file="../sdk/firmware/ovmf_pure_amd64.fd", address=0x00000000, options=none romimage: file="../sdk/firmware/rombios.bin", address=0x00000000, options=none
vgaromimage: file="../sdk/firmware/vgabios.bin" vgaromimage: file="../sdk/firmware/vgabios.bin"
boot: floppy boot: disk
floppy_bootsig_check: disabled=0 floppy_bootsig_check: disabled=0
floppya: type=1_44 floppya: type=1_44
# no floppyb # no floppyb
@@ -27,11 +27,7 @@ optramimage3: file=none
optramimage4: file=none optramimage4: file=none
pci: enabled=1, chipset=i440fx, slot1=cirrus, slot2=none, slot3=none, slot4=none, slot5=none pci: enabled=1, chipset=i440fx, slot1=cirrus, slot2=none, slot3=none, slot4=none, slot5=none
vga: extension=cirrus, update_freq=5, realtime=1, ddc=builtin vga: extension=cirrus, update_freq=5, realtime=1, ddc=builtin
cpu: count=1:1:1, ips=400000000, quantum=16, model=bx_generic, reset_on_triple_fault=0, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0 cpu: count=1:1:1, ips=400000000, quantum=16, model=corei7_sandy_bridge_2600k, reset_on_triple_fault=0, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0
cpuid: level=6, stepping=3, model=3, family=6, vendor_string="GenuineIntel", brand_string=" Intel(R) Pentium(R) 4 CPU "
cpuid: mmx=true, apic=xapic, simd=sse4_2, sse4a=false, misaligned_sse=false, sep=true
cpuid: movbe=false, adx=false, aes=false, sha=false, xsave=false, xsaveopt=false, x86_64=true
cpuid: 1g_pages=false, pcid=false, fsgsbase=false, smep=false, smap=false, mwait=true
print_timestamps: enabled=0 print_timestamps: enabled=0
port_e9_hack: enabled=0 port_e9_hack: enabled=0
private_colormap: enabled=0 private_colormap: enabled=0

View File

@@ -3,9 +3,9 @@ plugin_ctrl: usb_xhci=false, serial=true, e1000=false, extfpuirq=true, parallel=
config_interface: textconfig config_interface: textconfig
display_library: x display_library: x
memory: host=64, guest=64 memory: host=64, guest=64
romimage: file="../sdk/firmware/ovmf_pure_i686.fd", address=0x00000000, options=none romimage: file="../sdk/firmware/rombios.bin", address=0x00000000, options=none
vgaromimage: file="../sdk/firmware/vgabios.bin" vgaromimage: file="../sdk/firmware/vgabios.bin"
boot: floppy boot: disk
floppy_bootsig_check: disabled=0 floppy_bootsig_check: disabled=0
floppya: type=1_44 floppya: type=1_44
# no floppyb # no floppyb
@@ -27,11 +27,7 @@ optramimage3: file=none
optramimage4: file=none optramimage4: file=none
pci: enabled=1, chipset=i440fx, slot1=cirrus, slot2=none, slot3=none, slot4=none, slot5=none pci: enabled=1, chipset=i440fx, slot1=cirrus, slot2=none, slot3=none, slot4=none, slot5=none
vga: extension=cirrus, update_freq=5, realtime=1, ddc=builtin vga: extension=cirrus, update_freq=5, realtime=1, ddc=builtin
cpu: count=1:1:1, ips=400000000, quantum=16, model=bx_generic, reset_on_triple_fault=0, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0 cpu: count=1:1:1, ips=400000000, quantum=16, model=corei7_sandy_bridge_2600k, reset_on_triple_fault=0, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0
cpuid: level=6, stepping=3, model=3, family=6, vendor_string="GenuineIntel", brand_string=" Intel(R) Pentium(R) 4 CPU "
cpuid: mmx=true, apic=xapic, simd=sse4_2, sse4a=false, misaligned_sse=false, sep=true
cpuid: movbe=false, adx=false, aes=false, sha=false, xsave=false, xsaveopt=false, x86_64=true
cpuid: 1g_pages=false, pcid=false, fsgsbase=false, smep=false, smap=false, mwait=true
print_timestamps: enabled=0 print_timestamps: enabled=0
port_e9_hack: enabled=0 port_e9_hack: enabled=0
private_colormap: enabled=0 private_colormap: enabled=0

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
sdk/firmware/rombios.bin Normal file

Binary file not shown.

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

@@ -1,44 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: sdk/xtdk/amd64/arfuncs.h
* DESCRIPTION: AMD64 architecture library routines
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTDK_AMD64_ARFUNCS_H
#define __XTDK_AMD64_ARFUNCS_H
#include <xtdefs.h>
#include <xtstruct.h>
#include <xttypes.h>
#include <amd64/xtstruct.h>
/* Routines used by XTLDR */
XTCDECL
VOID
ArClearInterruptFlag(VOID);
XTCDECL
BOOLEAN
ArCpuId(IN OUT PCPUID_REGISTERS Registers);
XTCDECL
VOID
ArHalt(VOID);
XTCDECL
ULONG_PTR
ArReadControlRegister(IN USHORT ControlRegister);
XTCDECL
ULONGLONG
ArReadModelSpecificRegister(IN ULONG Register);
XTCDECL
VOID
ArWriteControlRegister(IN USHORT ControlRegister,
IN UINT_PTR Value);
#endif /* __XTDK_AMD64_ARFUNCS_H */

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,6 +101,10 @@
#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_NF_MASK 0x00000000 /* None */ #define X86_EFLAGS_NF_MASK 0x00000000 /* None */
@@ -405,4 +419,11 @@ typedef struct _CPUID_SIGNATURE
ULONG Unused2:4; ULONG Unused2:4;
} CPU_SIGNATURE, *PCPU_SIGNATURE; } CPU_SIGNATURE, *PCPU_SIGNATURE;
/* Trampoline types */
typedef enum _TRAMPOLINE_TYPE
{
TrampolineApStartup,
TrampolineEnableXpa
} TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;
#endif /* __XTDK_AMD64_ARTYPES_H */ #endif /* __XTDK_AMD64_ARTYPES_H */

View File

@@ -15,32 +15,38 @@
#include <amd64/xtstruct.h> #include <amd64/xtstruct.h>
/* HAL library routines forward references */ /* Hardware layer routines forward references */
XTCLINK
XTCDECL XTCDECL
UCHAR UCHAR
HlIoPortInByte(IN USHORT Port); HlReadPort8(IN USHORT Port);
XTCDECL
ULONG
HlIoPortInLong(IN USHORT Port);
XTCLINK
XTCDECL XTCDECL
USHORT USHORT
HlIoPortInShort(IN USHORT Port); HlReadPort16(IN USHORT Port);
XTCLINK
XTCDECL
ULONG
HlReadPort32(IN USHORT Port);
XTCLINK
XTCDECL XTCDECL
VOID VOID
HlIoPortOutByte(IN USHORT Port, HlWritePort8(IN USHORT Port,
IN UCHAR Data); IN UCHAR Data);
XTCLINK
XTCDECL XTCDECL
VOID VOID
HlIoPortOutLong(IN USHORT Port, HlWritePort16(IN USHORT Port,
IN ULONG Value);
XTCDECL
VOID
HlIoPortOutShort(IN USHORT Port,
IN USHORT Value); IN USHORT Value);
XTCLINK
XTCDECL
VOID
HlWritePort32(IN USHORT Port,
IN ULONG Value);
#endif /* __XTDK_AMD64_HLFUNCS_H */ #endif /* __XTDK_AMD64_HLFUNCS_H */

View File

@@ -42,16 +42,6 @@
#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 0x00000000
#define APIC_DM_LOWPRIO 0x00000100
#define APIC_DM_SMI 0x00000200
#define APIC_DM_REMOTE 0x00000300
#define APIC_DM_NMI 0x00000400
#define APIC_DM_INIT 0x00000500
#define APIC_DM_STARTUP 0x00000600
#define APIC_DM_EXTINT 0x00000700
/* 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
@@ -79,6 +69,35 @@
/* 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 */ /* APIC Register Address Map */
typedef enum _APIC_REGISTER typedef enum _APIC_REGISTER
{ {
@@ -116,35 +135,6 @@ typedef enum _APIC_REGISTER
APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */ APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */
} APIC_REGISTER, *PAPIC_REGISTER; } APIC_REGISTER, *PAPIC_REGISTER;
/* APIC mode list */
typedef enum _APIC_MODE
{
APIC_MODE_COMPAT,
APIC_MODE_X2APIC
} APIC_MODE, *PAPIC_MODE;
/* 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 message type enumeration list */
typedef enum _APIC_MT
{
APIC_MT_Fixed,
APIC_MT_LowestPriority,
APIC_MT_SMI,
APIC_MT_RemoteRead,
APIC_MT_NMI,
APIC_MT_INIT,
APIC_MT_Startup,
APIC_MT_ExtInt,
} APIC_MT, *PAPIC_MT;
/* I8259 PIC interrupt mode enumeration list */ /* I8259 PIC interrupt mode enumeration list */
typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE
{ {
@@ -217,7 +207,7 @@ typedef union _APIC_COMMAND_REGISTER
struct struct
{ {
ULONGLONG Vector:8; ULONGLONG Vector:8;
ULONGLONG MessageType:3; ULONGLONG DeliveryMode:3;
ULONGLONG DestinationMode:1; ULONGLONG DestinationMode:1;
ULONGLONG DeliveryStatus:1; ULONGLONG DeliveryStatus:1;
ULONGLONG ReservedMBZ:1; ULONGLONG ReservedMBZ:1;
@@ -237,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;

View File

@@ -118,8 +118,8 @@
#define KERNEL_STACK_GUARD_PAGES 1 #define KERNEL_STACK_GUARD_PAGES 1
/* Processor structures size */ /* Processor structures size */
#define KPROCESSOR_STRUCTURES_SIZE ((2 * KERNEL_STACK_SIZE) + sizeof(ArInitialGdt) + sizeof(ArInitialTss) + \ #define KPROCESSOR_STRUCTURES_SIZE ((2 * KERNEL_STACK_SIZE) + (GDT_ENTRIES * sizeof(KGDTENTRY)) + sizeof(KTSS) + \
sizeof(ArInitialProcessorBlock) + MM_PAGE_SIZE) sizeof(KPROCESSOR_BLOCK) + MM_PAGE_SIZE)
/* Kernel frames */ /* Kernel frames */
#define KEXCEPTION_FRAME_SIZE sizeof(KEXCEPTION_FRAME) #define KEXCEPTION_FRAME_SIZE sizeof(KEXCEPTION_FRAME)

View File

@@ -18,11 +18,18 @@
#define MM_PAGE_SHIFT 12L #define MM_PAGE_SHIFT 12L
#define MM_PAGE_SIZE 4096 #define MM_PAGE_SIZE 4096
/* Page directory and page base addresses */ /* Page directory and page base addresses for 4-level paging */
#define MM_PTE_BASE 0xFFFFF68000000000UI64 #define MM_PTE_BASE 0xFFFFF68000000000ULL
#define MM_PDE_BASE 0xFFFFF6FB40000000UI64 #define MM_PDE_BASE 0xFFFFF6FB40000000ULL
#define MM_PPE_BASE 0xFFFFF6FB7DA00000UI64 #define MM_PPE_BASE 0xFFFFF6FB7DA00000ULL
#define MM_PXE_BASE 0xFFFFF6FB7DBED000UI64 #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 */ /* PTE shift values */
#define MM_PTE_SHIFT 3 #define MM_PTE_SHIFT 3
@@ -30,7 +37,7 @@
#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_LA57_SHIFT 48 #define MM_P5I_SHIFT 48
/* Number of PTEs per page */ /* Number of PTEs per page */
#define MM_PTE_PER_PAGE 512 #define MM_PTE_PER_PAGE 512
@@ -54,7 +61,10 @@
#define MM_HARDWARE_VA_START 0xFFFFFFFFFFC00000ULL #define MM_HARDWARE_VA_START 0xFFFFFFFFFFC00000ULL
/* Maximum physical address used by HAL allocations */ /* Maximum physical address used by HAL allocations */
#define MM_MAXIMUM_PHYSICAL_ADDRESS 0x00000000FFFFFFFF #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
@@ -85,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,9 +13,9 @@
/* 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_DSH APIC_DSH, *PAPIC_DSH;
typedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE; typedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE;
typedef enum _APIC_MT APIC_MT, *PAPIC_MT;
typedef enum _APIC_REGISTER APIC_REGISTER, *PAPIC_REGISTER; 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_EXTENDED CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED; typedef enum _CPUID_FEATURES_EXTENDED CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
@@ -30,6 +30,7 @@ typedef enum _PIC_I8259_ICW1_OPERATING_MODE PIC_I8259_ICW1_OPERATING_MODE, *PPIC
typedef enum _PIC_I8259_ICW4_BUFFERED_MODE PIC_I8259_ICW4_BUFFERED_MODE, *PPIC_I8259_ICW4_BUFFERED_MODE; typedef enum _PIC_I8259_ICW4_BUFFERED_MODE PIC_I8259_ICW4_BUFFERED_MODE, *PPIC_I8259_ICW4_BUFFERED_MODE;
typedef enum _PIC_I8259_ICW4_EOI_MODE PIC_I8259_ICW4_EOI_MODE, *PPIC_I8259_ICW4_EOI_MODE; typedef enum _PIC_I8259_ICW4_EOI_MODE PIC_I8259_ICW4_EOI_MODE, *PPIC_I8259_ICW4_EOI_MODE;
typedef enum _PIC_I8259_ICW4_SYSTEM_MODE PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE; typedef enum _PIC_I8259_ICW4_SYSTEM_MODE PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;
typedef enum _TRAMPOLINE_TYPE TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;
/* Architecture-specific structures forward references */ /* Architecture-specific structures forward references */
typedef struct _CONTEXT CONTEXT, *PCONTEXT; typedef struct _CONTEXT CONTEXT, *PCONTEXT;
@@ -51,6 +52,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;
@@ -66,6 +68,7 @@ typedef union _APIC_BASE_REGISTER APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER;
typedef union _APIC_COMMAND_REGISTER APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGISTER; typedef union _APIC_COMMAND_REGISTER APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGISTER;
typedef union _APIC_LVT_REGISTER APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER; typedef union _APIC_LVT_REGISTER APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER;
typedef union _APIC_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER; typedef union _APIC_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
typedef union _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;

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

@@ -4,6 +4,7 @@
* FILE: sdk/xtdk/bltypes.h * FILE: sdk/xtdk/bltypes.h
* DESCRIPTION: XT Boot Loader structures definitions * DESCRIPTION: XT Boot Loader structures definitions
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/ */
#ifndef __XTDK_BLTYPES_H #ifndef __XTDK_BLTYPES_H
@@ -18,10 +19,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,100 +42,130 @@
#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 EFI_MEMORY_TYPE EfiMemoryType); typedef LOADER_MEMORY_TYPE (XTCDECL *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 (XTCDECL *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 (XTCDECL *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 (XTCDECL *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 BOOLEAN (XTCDECL *PBL_BOOTUTILS_GET_BOOLEAN_PARAMETER)(IN PCWSTR Parameters, IN PCWSTR Needle);
typedef EFI_STATUS (*PBL_BUILD_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR SelfMapAddress); typedef VOID (XTAPI *PBL_BOOTUTILS_GET_TRAMPOLINE_INFORMATION)(IN TRAMPOLINE_TYPE TrampolineType, OUT PVOID *TrampolineCode, OUT PULONG_PTR TrampolineSize);
typedef EFI_STATUS (*PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle); typedef EFI_STATUS (XTCDECL *PBL_BUILD_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR SelfMapAddress);
typedef VOID (*PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo); typedef EFI_STATUS (XTCDECL *PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle);
typedef EFI_STATUS (*PBL_CLOSE_XT_PROTOCOL)(IN PEFI_HANDLE Handle, IN PEFI_GUID ProtocolGuid); typedef VOID (XTCDECL *PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo);
typedef BOOLEAN (*PBL_CONFIG_GET_BOOLEAN_VALUE)(IN CONST PWCHAR ConfigName); typedef BOOLEAN (XTCDECL *PBL_CPU_CPUID)(IN OUT PCPUID_REGISTERS Registers);
typedef PWCHAR (*PBL_CONFIG_GET_VALUE)(IN CONST PWCHAR ConfigName); typedef ULONG_PTR (XTCDECL *PBL_CPU_READ_CONTROL_REGISTER)(IN USHORT ControlRegister);
typedef VOID (*PBL_CONSOLE_CLEAR_SCREEN)(); typedef ULONGLONG (XTCDECL *PBL_CPU_READ_MODEL_SPECIFIC_REGISTER)(IN ULONG Register);
typedef VOID (*PBL_CONSOLE_DISABLE_CURSOR)(); typedef VOID (XTCDECL *PBL_CPU_WRITE_CONTROL_REGISTER)(IN USHORT ControlRegister, IN UINT_PTR Value);
typedef VOID (*PBL_CONSOLE_ENABLE_CURSOR)(); typedef EFI_STATUS (XTCDECL *PBL_CLOSE_XT_PROTOCOL)(IN PEFI_HANDLE Handle, IN PEFI_GUID ProtocolGuid);
typedef VOID (*PBL_CONSOLE_PRINT)(IN PUSHORT Format, IN ...); typedef BOOLEAN (XTCDECL *PBL_CONFIG_GET_BOOLEAN_VALUE)(IN PCWSTR ConfigName);
typedef VOID (*PBL_CONSOLE_QUERY_MODE)(OUT PUINT_PTR ResX, OUT PUINT_PTR ResY); typedef EFI_STATUS (XTCDECL *PBL_CONFIG_GET_BOOT_OPTION_VALUE)(IN PLIST_ENTRY Options, IN PCWSTR OptionName, OUT PWCHAR *OptionValue);
typedef VOID (*PBL_CONSOLE_READ_KEY_STROKE)(OUT PEFI_INPUT_KEY Key); typedef VOID (XTCDECL *PBL_CONFIG_GET_EDITABLE_OPTIONS)(OUT PCWSTR **OptionsArray, OUT PULONG OptionsCount);
typedef VOID (*PBL_CONSOLE_RESET_INPUT_BUFFER)(); typedef EFI_STATUS (XTCDECL *PBL_CONFIG_GET_VALUE)(IN PCWSTR ConfigName, OUT PWCHAR *ConfigValue);
typedef VOID (*PBL_CONSOLE_SET_ATTRIBUTES)(IN ULONGLONG Attributes); typedef EFI_STATUS (XTCDECL *PBL_CONFIG_SET_BOOT_OPTION_VALUE)(IN PLIST_ENTRY Options, IN PCWSTR OptionName, IN PCWSTR OptionValue);
typedef VOID (*PBL_CONSOLE_SET_CURSOR_POSITION)(IN ULONGLONG PosX, IN ULONGLONG PosY); typedef VOID (XTCDECL *PBL_CONSOLE_CLEAR_SCREEN)();
typedef VOID (*PBL_CONSOLE_WRITE)(IN PUSHORT String); typedef VOID (XTCDECL *PBL_CONSOLE_DISABLE_CURSOR)();
typedef VOID (XTCDECL *PBL_CONSOLE_ENABLE_CURSOR)();
typedef VOID (XTCDECL *PBL_CONSOLE_PRINT)(IN PCWSTR Format, IN ...);
typedef VOID (XTCDECL *PBL_CONSOLE_QUERY_MODE)(OUT PUINT_PTR ResX, OUT PUINT_PTR ResY);
typedef VOID (XTCDECL *PBL_CONSOLE_READ_KEY_STROKE)(OUT PEFI_INPUT_KEY Key);
typedef VOID (XTCDECL *PBL_CONSOLE_RESET_INPUT_BUFFER)();
typedef VOID (XTCDECL *PBL_CONSOLE_SET_ATTRIBUTES)(IN ULONGLONG Attributes);
typedef VOID (XTCDECL *PBL_CONSOLE_SET_CURSOR_POSITION)(IN ULONGLONG PosX, IN ULONGLONG PosY);
typedef VOID (XTCDECL *PBL_CONSOLE_WRITE)(IN PCWSTR String);
typedef SIZE_T (XTAPI *PBL_COMPARE_MEMORY)(IN PCVOID LeftBuffer, IN PCVOID RightBuffer, IN SIZE_T Length);
typedef SIZE_T (XTAPI *PBL_WIDESTRING_COMPARE)(IN PCWSTR String1, IN PCWSTR String2, IN SIZE_T Length);
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 (XTCDECL *PBL_DEBUG_PRINT)(IN PCWSTR Format, IN ...);
typedef EFI_STATUS (*PBL_ENTER_FIRMWARE_SETUP)(); typedef EFI_STATUS (XTCDECL *PBL_ENTER_FIRMWARE_SETUP)();
typedef EFI_STATUS (*PBL_EXIT_BOOT_SERVICES)(); typedef EFI_STATUS (XTCDECL *PBL_EXIT_BOOT_SERVICES)();
typedef EFI_STATUS (*PBL_FIND_BOOT_PROTOCOL)(IN PWCHAR SystemType, OUT PEFI_GUID BootProtocolGuid); typedef EFI_STATUS (XTCDECL *PBL_FIND_BOOT_PROTOCOL)(IN PCWSTR SystemType, OUT PEFI_GUID BootProtocolGuid);
typedef EFI_STATUS (*PBL_FREE_PAGES)(IN ULONGLONG Size, IN EFI_PHYSICAL_ADDRESS Memory); typedef EFI_STATUS (XTCDECL *PBL_FREE_PAGES)(IN ULONGLONG Size, IN EFI_PHYSICAL_ADDRESS Memory);
typedef EFI_STATUS (*PBL_FREE_POOL)(IN PVOID Memory); typedef EFI_STATUS (XTCDECL *PBL_FREE_POOL)(IN PVOID Memory);
typedef EFI_STATUS (*PBL_GET_CONFIGURATION_TABLE)(IN PEFI_GUID TableGuid, OUT PVOID *Table); typedef EFI_STATUS (XTCDECL *PBL_GET_CONFIGURATION_TABLE)(IN PEFI_GUID TableGuid, OUT PVOID *Table);
typedef EFI_STATUS (*PBL_GET_EFI_VARIABLE)(IN PEFI_GUID Vendor, IN PWCHAR VariableName, OUT PVOID *VariableValue); typedef EFI_STATUS (XTCDECL *PBL_GET_EFI_VARIABLE)(IN PEFI_GUID Vendor, IN PCWSTR VariableName, OUT PVOID *VariableValue);
typedef VOID (*PBL_GET_MAPPINGS_COUNT)(IN PXTBL_PAGE_MAPPING PageMap, OUT PULONG NumberOfMappings); typedef VOID (XTCDECL *PBL_GET_MAPPINGS_COUNT)(IN PXTBL_PAGE_MAPPING PageMap, OUT PULONG NumberOfMappings);
typedef EFI_STATUS (*PBL_GET_MEMORY_MAP)(OUT PEFI_MEMORY_MAP MemoryMap); typedef EFI_STATUS (XTCDECL *PBL_GET_MEMORY_MAP)(OUT PEFI_MEMORY_MAP MemoryMap);
typedef PLIST_ENTRY (*PBL_GET_MODULES_LIST)(); typedef PLIST_ENTRY (XTCDECL *PBL_GET_MODULES_LIST)();
typedef ULONGLONG (*PBL_GET_RANDOM_VALUE)(IN OUT PULONGLONG RNGBuffer); typedef ULONGLONG (XTCDECL *PBL_GET_RANDOM_VALUE)(IN OUT PULONGLONG RNGBuffer);
typedef INT_PTR (*PBL_GET_SECURE_BOOT_STATUS)(); typedef INT_PTR (XTCDECL *PBL_GET_SECURE_BOOT_STATUS)();
typedef PVOID (*PBL_GET_VIRTUAL_ADDRESS)(IN PXTBL_PAGE_MAPPING PageMap, IN PVOID PhysicalAddress); typedef PVOID (XTCDECL *PBL_GET_VIRTUAL_ADDRESS)(IN PXTBL_PAGE_MAPPING PageMap, IN PVOID PhysicalAddress);
typedef EFI_STATUS (*PBL_INITIALIZE_ENTROPY)(PULONGLONG RNGBuffer); typedef EFI_STATUS (XTCDECL *PBL_INITIALIZE_ENTROPY)(PULONGLONG RNGBuffer);
typedef VOID (*PBL_INITIALIZE_PAGE_MAP)(OUT PXTBL_PAGE_MAPPING PageMap, IN SHORT PageMapLevel, IN PAGE_SIZE PageSize); typedef VOID (XTCDECL *PBL_INITIALIZE_PAGE_MAP)(OUT PXTBL_PAGE_MAPPING PageMap, IN SHORT PageMapLevel, IN PAGE_SIZE PageSize);
typedef EFI_STATUS (*PBL_INSTALL_XT_PROTOCOL)(IN PVOID Interface, IN PEFI_GUID Guid); typedef EFI_STATUS (XTCDECL *PBL_INSTALL_XT_PROTOCOL)(IN PVOID Interface, IN PEFI_GUID Guid);
typedef EFI_STATUS (*PBL_INVOKE_BOOT_PROTOCOL)(IN PWCHAR ShortName, IN PLIST_ENTRY OptionsList); typedef EFI_STATUS (XTCDECL *PBL_INVOKE_BOOT_PROTOCOL)(IN PWCHAR ShortName, IN PLIST_ENTRY OptionsList);
typedef EFI_STATUS (*PBL_LOCATE_PROTOCOL_HANDLES)(OUT PEFI_HANDLE *Handles, OUT PUINT_PTR Count, IN PEFI_GUID ProtocolGuid); typedef EFI_STATUS (XTCDECL *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 (XTCDECL *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 VOID (XTCDECL *PBL_LLIST_INITIALIZE_HEAD)(IN PLIST_ENTRY ListHead);
typedef EFI_STATUS (*PBL_MAP_PAGE)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR VirtualAddress, IN ULONG_PTR PhysicalAddress, IN ULONG NumberOfPages); typedef VOID (XTCDECL *PBL_LLIST_INSERT_HEAD)(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry);
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 VOID (XTCDECL *PBL_LLIST_INSERT_TAIL)(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry);
typedef EFI_STATUS (*PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle); typedef VOID (XTCDECL *PBL_LLIST_REMOVE_ENTRY)(IN PLIST_ENTRY Entry);
typedef EFI_STATUS (*PBL_OPEN_PROTOCOL)(OUT PEFI_HANDLE Handle, OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid); typedef EFI_STATUS (XTCDECL *PBL_MAP_EFI_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN OUT PVOID *MemoryMapAddress, IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine);
typedef EFI_STATUS (*PBL_OPEN_PROTOCOL_HANDLE)(IN EFI_HANDLE Handle, OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid); typedef EFI_STATUS (XTCDECL *PBL_MAP_PAGE)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR VirtualAddress, IN ULONG_PTR PhysicalAddress, IN ULONG NumberOfPages);
typedef PVOID (*PBL_PHYSICAL_ADDRESS_TO_VIRTUAL)(IN PVOID PhysicalAddress, IN PVOID PhysicalBase, IN PVOID VirtualBase); typedef EFI_STATUS (XTCDECL *PBL_MAP_VIRTUAL_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN PVOID VirtualAddress, IN PVOID PhysicalAddress, IN ULONGLONG NumberOfPages, IN LOADER_MEMORY_TYPE MemoryType);
typedef EFI_STATUS (*PBL_PHYSICAL_LIST_TO_VIRTUAL)(IN PXTBL_PAGE_MAPPING PageMap, IN OUT PLIST_ENTRY ListHead, IN PVOID PhysicalBase, IN PVOID VirtualBase); typedef VOID (XTAPI *PBL_MOVE_MEMORY)(IN OUT PVOID Destination, IN PCVOID Source, IN SIZE_T Length);
typedef EFI_STATUS (*PBL_POWER_SYSTEM)(); typedef EFI_STATUS (XTCDECL *PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle);
typedef EFI_STATUS (*PBL_READ_FILE)(IN PEFI_FILE_HANDLE DirHandle, IN CONST PWCHAR FileName, OUT PVOID *FileData, OUT PSIZE_T FileSize); typedef EFI_STATUS (XTCDECL *PBL_OPEN_PROTOCOL)(OUT PEFI_HANDLE Handle, OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid);
typedef EFI_STATUS (*PBL_REGISTER_BOOT_PROTOCOL)(IN PWCHAR SystemType, IN PEFI_GUID BootProtocolGuid); typedef EFI_STATUS (XTCDECL *PBL_OPEN_PROTOCOL_HANDLE)(IN EFI_HANDLE Handle, OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid);
typedef VOID (*PBL_REGISTER_XT_BOOT_MENU)(PVOID BootMenuRoutine); typedef PVOID (XTCDECL *PBL_PHYSICAL_ADDRESS_TO_VIRTUAL)(IN PVOID PhysicalAddress, IN PVOID PhysicalBase, IN PVOID VirtualBase);
typedef EFI_STATUS (*PBL_SET_EFI_VARIABLE)(IN PEFI_GUID Vendor, IN PWCHAR VariableName, IN PVOID VariableValue, IN UINT_PTR Size); typedef UCHAR (XTCDECL *PBL_IOPORT_READ_8)(IN USHORT Port);
typedef USHORT (XTCDECL *PBL_IOPORT_READ_16)(IN USHORT Port);
typedef ULONG (XTCDECL *PBL_IOPORT_READ_32)(IN USHORT Port);
typedef VOID (XTCDECL *PBL_IOPORT_WRITE_8)(IN USHORT Port, IN UCHAR Value);
typedef VOID (XTCDECL *PBL_IOPORT_WRITE_16)(IN USHORT Port, IN USHORT Value);
typedef VOID (XTCDECL *PBL_IOPORT_WRITE_32)(IN USHORT Port, IN ULONG Value);
typedef EFI_STATUS (XTCDECL *PBL_PHYSICAL_LIST_TO_VIRTUAL)(IN PXTBL_PAGE_MAPPING PageMap, IN OUT PLIST_ENTRY ListHead, IN PVOID PhysicalBase, IN PVOID VirtualBase);
typedef EFI_STATUS (XTCDECL *PBL_POWER_SYSTEM)();
typedef EFI_STATUS (XTCDECL *PBL_READ_FILE)(IN PEFI_FILE_HANDLE DirHandle, IN PCWSTR FileName, OUT PVOID *FileData, OUT PSIZE_T FileSize);
typedef EFI_STATUS (XTCDECL *PBL_REGISTER_BOOT_PROTOCOL)(IN PCWSTR SystemType, IN PEFI_GUID BootProtocolGuid);
typedef VOID (XTCDECL *PBL_REGISTER_XT_BOOT_MENU)(PVOID BootMenuRoutine);
typedef EFI_STATUS (XTCDECL *PBL_SET_EFI_VARIABLE)(IN PEFI_GUID Vendor, IN PCWSTR VariableName, IN PVOID VariableValue, IN UINT_PTR Size);
typedef SIZE_T (XTAPI *PBL_STRING_COMPARE)(IN PCSTR String1, IN PCSTR String2, IN SIZE_T Length);
typedef SIZE_T (XTAPI *PBL_STRING_LENGTH)(IN PCSTR String, IN SIZE_T MaxLength);
typedef SIZE_T (XTAPI *PBL_STRING_TO_WIDESTRING)(OUT PWCHAR Destination, IN PCSTR *Source, IN SIZE_T Length);
typedef PCHAR (XTAPI *PBL_STRING_TRIM)(IN PCHAR String);
typedef VOID (XTAPI *PBL_SET_MEMORY)(OUT PVOID Destination, IN UCHAR Byte, IN SIZE_T Length); typedef VOID (XTAPI *PBL_SET_MEMORY)(OUT PVOID Destination, IN UCHAR Byte, IN SIZE_T Length);
typedef VOID (*PBL_SLEEP_EXECUTION)(IN ULONG_PTR Milliseconds); typedef VOID (XTCDECL *PBL_SLEEP_EXECUTION)(IN ULONG_PTR Milliseconds);
typedef EFI_STATUS (*PBL_START_EFI_IMAGE)(IN EFI_HANDLE ImageHandle); typedef EFI_STATUS (XTCDECL *PBL_START_EFI_IMAGE)(IN EFI_HANDLE ImageHandle);
typedef VOID (*PBL_TUI_DISPLAY_ERROR_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message); typedef VOID (XTCDECL *PBL_TUI_DISPLAY_ERROR_DIALOG)(IN PCWSTR Caption, IN PCWSTR Message);
typedef VOID (*PBL_TUI_DISPLAY_INFO_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message); typedef VOID (XTCDECL *PBL_TUI_DISPLAY_INFO_DIALOG)(IN PCWSTR Caption, IN PCWSTR Message);
typedef VOID (*PBL_TUI_DISPLAY_INPUT_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message, IN PWCHAR *InputFieldText); typedef VOID (XTCDECL *PBL_TUI_DISPLAY_INPUT_DIALOG)(IN PCWSTR Caption, IN PCWSTR Message, IN OUT PWCHAR *InputFieldText);
typedef XTBL_DIALOG_HANDLE (*PBL_TUI_DISPLAY_PROGRESS_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message, IN UCHAR Percentage); typedef XTBL_DIALOG_HANDLE (XTCDECL *PBL_TUI_DISPLAY_PROGRESS_DIALOG)(IN PCWSTR Caption, IN PCWSTR Message, IN UCHAR Percentage);
typedef VOID (*PBL_TUI_UPDATE_PROGRESS_BAR)(IN PXTBL_DIALOG_HANDLE Handle, IN PWCHAR Message, IN UCHAR Percentage); typedef VOID (XTCDECL *PBL_TUI_UPDATE_PROGRESS_BAR)(IN PXTBL_DIALOG_HANDLE Handle, IN PCWSTR Message, IN UCHAR Percentage);
typedef EFI_STATUS (*PBL_WAIT_FOR_EFI_EVENT)(IN UINT_PTR NumberOfEvents, IN PEFI_EVENT Event, OUT PUINT_PTR Index); typedef SIZE_T (XTAPI *PBL_WIDESTRING_COMPARE_INSENSITIVE)(IN PCWSTR String1, IN PCWSTR String2, IN SIZE_T Length);
typedef VOID (*PBL_XT_BOOT_MENU)(); typedef PWCHAR (XTAPI *PBL_WIDESTRING_CONCATENATE)(OUT PWCHAR Destination, IN PWCHAR Source, IN SIZE_T Count);
typedef XTSTATUS (XTAPI *PBL_WIDESTRING_FORMAT)(IN PRTL_PRINT_CONTEXT Context, IN PCWSTR Format, IN VA_LIST ArgumentList);
typedef SIZE_T (XTAPI *PBL_WIDESTRING_LENGTH)(IN PCWSTR String, IN SIZE_T MaxLength);
typedef PWCHAR (XTAPI *PBL_WIDESTRING_TOKENIZE)(IN PWCHAR String, IN PCWSTR Delimiter, IN OUT PWCHAR *SavePtr);
typedef EFI_STATUS (XTCDECL *PBL_WAIT_FOR_EFI_EVENT)(IN UINT_PTR NumberOfEvents, IN PEFI_EVENT Event, OUT PUINT_PTR Index);
typedef VOID (XTCDECL *PBL_XT_BOOT_MENU)();
typedef VOID (XTAPI *PBL_ZERO_MEMORY)(OUT PVOID Destination, IN SIZE_T Length); typedef VOID (XTAPI *PBL_ZERO_MEMORY)(OUT PVOID Destination, IN SIZE_T Length);
/* Module protocols routine pointers */ /* Module protocols routine pointers */
typedef EFI_STATUS (*PBL_ACPI_GET_ACPI_DESCRIPTION_POINTER)(OUT PVOID *AcpiTable); typedef EFI_STATUS (XTCDECL *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 (XTCDECL *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 (XTCDECL *PBL_ACPI_GET_APIC_BASE)(OUT PVOID *ApicBase);
typedef EFI_STATUS (*PBL_ACPI_GET_RSDP_TABLE)(OUT PVOID *AcpiTable); typedef EFI_STATUS (XTCDECL *PBL_ACPI_GET_RSDP_TABLE)(OUT PVOID *AcpiTable);
typedef EFI_STATUS (*PBL_ACPI_GET_SMBIOS_TABLE)(OUT PVOID *SmBiosTable); typedef EFI_STATUS (XTCDECL *PBL_ACPI_GET_SMBIOS_TABLE)(OUT PVOID *SmBiosTable);
typedef EFI_STATUS (*PBL_ACPI_GET_SMBIOS3_TABLE)(OUT PVOID *SmBiosTable); typedef EFI_STATUS (XTCDECL *PBL_ACPI_GET_SMBIOS3_TABLE)(OUT PVOID *SmBiosTable);
typedef EFI_STATUS (*PBL_ACPI_GET_XSDP_TABLE)(OUT PVOID *AcpiTable); typedef EFI_STATUS (XTCDECL *PBL_ACPI_GET_XSDP_TABLE)(OUT PVOID *AcpiTable);
typedef EFI_STATUS (*PBL_BOOTPROTO_BOOT_SYSTEM)(IN PXTBL_BOOT_PARAMETERS Parameters); typedef EFI_STATUS (XTCDECL *PBL_BOOTPROTO_BOOT_SYSTEM)(IN PXTBL_BOOT_PARAMETERS Parameters);
typedef EFI_STATUS (*PBL_EXECIMAGE_GET_ENTRY_POINT)(IN PVOID ImagePointer, OUT PVOID *EntryPoint); typedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_GET_ENTRY_POINT)(IN PVOID ImagePointer, OUT PVOID *EntryPoint);
typedef EFI_STATUS (*PBL_EXECIMAGE_GET_FILE_SIZE)(IN PVOID ImagePointer, OUT PULONGLONG FileSize); typedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_GET_FILE_SIZE)(IN PVOID ImagePointer, OUT PULONGLONG FileSize);
typedef EFI_STATUS (*PBL_EXECIMAGE_GET_IMAGE_SIZE)(IN PVOID ImagePointer, OUT PUINT ImageSize); typedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_GET_IMAGE_SIZE)(IN PVOID ImagePointer, OUT PUINT ImageSize);
typedef EFI_STATUS (*PBL_EXECIMAGE_GET_MACHINE_TYPE)(IN PVOID ImagePointer, OUT PUSHORT MachineType); typedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_GET_MACHINE_TYPE)(IN PVOID ImagePointer, OUT PUSHORT MachineType);
typedef EFI_STATUS (*PBL_EXECIMAGE_GET_SECTION)(IN PVOID ImagePointer, IN PCHAR SectionName, OUT PULONG *RawData); typedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_GET_SECTION)(IN PVOID ImagePointer, IN PCHAR SectionName, OUT PULONG *RawData);
typedef EFI_STATUS (*PBL_EXECIMAGE_GET_SUBSYSTEM)(IN PVOID ImagePointer, OUT PUSHORT SubSystem); typedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_GET_SUBSYSTEM)(IN PVOID ImagePointer, OUT PUSHORT SubSystem);
typedef EFI_STATUS (*PBL_EXECIMAGE_GET_VERSION)(IN PVOID ImagePointer, OUT PUSHORT Version); typedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_GET_VERSION)(IN PVOID ImagePointer, OUT PUSHORT Version);
typedef EFI_STATUS (*PBL_EXECIMAGE_LOAD_IMAGE)(IN PEFI_FILE_HANDLE FileHandle, IN LOADER_MEMORY_TYPE MemoryType, IN PVOID VirtualAddress, OUT PVOID *ImagePointer); typedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_LOAD_IMAGE)(IN PEFI_FILE_HANDLE FileHandle, IN LOADER_MEMORY_TYPE MemoryType, IN PVOID VirtualAddress, OUT PVOID *ImagePointer);
typedef EFI_STATUS (*PBL_EXECIMAGE_RELOCATE_IMAGE)(IN PVOID ImagePointer, IN EFI_VIRTUAL_ADDRESS Address); typedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_RELOCATE_IMAGE)(IN PVOID ImagePointer, IN EFI_VIRTUAL_ADDRESS Address);
typedef EFI_STATUS (*PBL_EXECIMAGE_UNLOAD_IMAGE)(IN PVOID ImagePointer); typedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_UNLOAD_IMAGE)(IN PVOID ImagePointer);
typedef EFI_STATUS (*PBL_EXECIMAGE_VERIFY_IMAGE)(IN PVOID ImagePointer); typedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_VERIFY_IMAGE)(IN PVOID ImagePointer);
typedef EFI_STATUS (*PBL_FRAMEBUFFER_GET_DISPLAY_DRIVER)(OUT PEFI_GRAPHICS_PROTOCOL Protocol); typedef EFI_STATUS (XTCDECL *PBL_FRAMEBUFFER_GET_DISPLAY_DRIVER)(OUT PEFI_GRAPHICS_PROTOCOL Protocol);
typedef EFI_STATUS (*PBL_FRAMEBUFFER_GET_DISPLAY_INFORMATION)(OUT PEFI_PHYSICAL_ADDRESS FrameBufferBase, OUT PULONG_PTR FrameBufferSize, OUT PXTBL_FRAMEBUFFER_MODE_INFORMATION ModeInfo); typedef EFI_STATUS (XTCDECL *PBL_FRAMEBUFFER_GET_DISPLAY_INFORMATION)(OUT PEFI_PHYSICAL_ADDRESS FrameBufferBase, OUT PULONG_PTR FrameBufferSize, OUT PXTBL_FRAMEBUFFER_MODE_INFORMATION ModeInfo);
typedef EFI_STATUS (*PBL_FRAMEBUFFER_GET_PREFERRED_SCREEN_RESOLUTION)(OUT PUINT PreferredWidth, OUT PUINT PreferredHeight); typedef EFI_STATUS (XTCDECL *PBL_FRAMEBUFFER_GET_PREFERRED_SCREEN_RESOLUTION)(OUT PUINT PreferredWidth, OUT PUINT PreferredHeight);
typedef EFI_STATUS (*PBL_FRAMEBUFFER_INITIALIZE)(); typedef EFI_STATUS (XTCDECL *PBL_FRAMEBUFFER_INITIALIZE)();
typedef EFI_STATUS (*PBL_FRAMEBUFFER_SET_SCREEN_RESOLUTION)(IN UINT Width, IN UINT Height); typedef EFI_STATUS (XTCDECL *PBL_FRAMEBUFFER_SET_SCREEN_RESOLUTION)(IN UINT Width, IN UINT Height);
/* Boot parameters structure */ /* Boot parameters structure */
typedef struct _XTBL_BOOT_PARAMETERS typedef struct _XTBL_BOOT_PARAMETERS
@@ -153,6 +185,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;
@@ -248,13 +281,10 @@ typedef struct _XTBL_PAGE_MAPPING
/* XTLDR Status data */ /* XTLDR Status data */
typedef struct _XTBL_STATUS typedef struct _XTBL_STATUS
{ {
PBL_XT_BOOT_MENU BootMenu;
BOOLEAN BootServices;
ULONG DebugPort;
PVOID LoaderBase; PVOID LoaderBase;
ULONGLONG LoaderSize; ULONGLONG LoaderSize;
BOOLEAN BootServices;
INT_PTR SecureBoot; INT_PTR SecureBoot;
CPPORT SerialPort;
} XTBL_STATUS, *PXTBL_STATUS; } XTBL_STATUS, *PXTBL_STATUS;
/* XT framebuffer video mode information structure definition */ /* XT framebuffer video mode information structure definition */
@@ -356,12 +386,16 @@ typedef struct _XTBL_LOADER_PROTOCOL
} Boot; } Boot;
struct struct
{ {
PBL_BOOTUTIL_GET_BOOLEAN_PARAMETER GetBooleanParameter; PBL_BOOTUTILS_GET_BOOLEAN_PARAMETER GetBooleanParameter;
} BootUtil; PBL_BOOTUTILS_GET_TRAMPOLINE_INFORMATION GetTrampolineInformation;
} BootUtils;
struct 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
{ {
@@ -378,6 +412,13 @@ typedef struct _XTBL_LOADER_PROTOCOL
PBL_CONSOLE_WRITE Write; PBL_CONSOLE_WRITE Write;
} Console; } Console;
struct struct
{
PBL_CPU_CPUID CpuId;
PBL_CPU_READ_CONTROL_REGISTER ReadControlRegister;
PBL_CPU_READ_MODEL_SPECIFIC_REGISTER ReadModelSpecificRegister;
PBL_CPU_WRITE_CONTROL_REGISTER WriteControlRegister;
} Cpu;
struct
{ {
PBL_DEBUG_PRINT Print; PBL_DEBUG_PRINT Print;
} Debug; } Debug;
@@ -388,10 +429,27 @@ typedef struct _XTBL_LOADER_PROTOCOL
PBL_READ_FILE ReadFile; PBL_READ_FILE ReadFile;
} Disk; } Disk;
struct struct
{
PBL_IOPORT_READ_8 Read8;
PBL_IOPORT_READ_16 Read16;
PBL_IOPORT_READ_32 Read32;
PBL_IOPORT_WRITE_8 Write8;
PBL_IOPORT_WRITE_16 Write16;
PBL_IOPORT_WRITE_32 Write32;
} IoPort;
struct
{
PBL_LLIST_INITIALIZE_HEAD InitializeHead;
PBL_LLIST_INSERT_HEAD InsertHead;
PBL_LLIST_INSERT_TAIL InsertTail;
PBL_LLIST_REMOVE_ENTRY RemoveEntry;
} LinkedList;
struct
{ {
PBL_ALLOCATE_PAGES AllocatePages; PBL_ALLOCATE_PAGES AllocatePages;
PBL_ALLOCATE_POOL AllocatePool; PBL_ALLOCATE_POOL AllocatePool;
PBL_BUILD_PAGE_MAP BuildPageMap; PBL_BUILD_PAGE_MAP BuildPageMap;
PBL_COMPARE_MEMORY CompareMemory;
PBL_COPY_MEMORY CopyMemory; PBL_COPY_MEMORY CopyMemory;
PBL_FREE_PAGES FreePages; PBL_FREE_PAGES FreePages;
PBL_FREE_POOL FreePool; PBL_FREE_POOL FreePool;
@@ -402,6 +460,7 @@ typedef struct _XTBL_LOADER_PROTOCOL
PBL_MAP_EFI_MEMORY MapEfiMemory; PBL_MAP_EFI_MEMORY MapEfiMemory;
PBL_MAP_PAGE MapPage; PBL_MAP_PAGE MapPage;
PBL_MAP_VIRTUAL_MEMORY MapVirtualMemory; PBL_MAP_VIRTUAL_MEMORY MapVirtualMemory;
PBL_MOVE_MEMORY MoveMemory;
PBL_PHYSICAL_ADDRESS_TO_VIRTUAL PhysicalAddressToVirtual; PBL_PHYSICAL_ADDRESS_TO_VIRTUAL PhysicalAddressToVirtual;
PBL_PHYSICAL_LIST_TO_VIRTUAL PhysicalListToVirtual; PBL_PHYSICAL_LIST_TO_VIRTUAL PhysicalListToVirtual;
PBL_SET_MEMORY SetMemory; PBL_SET_MEMORY SetMemory;
@@ -417,6 +476,13 @@ typedef struct _XTBL_LOADER_PROTOCOL
PBL_OPEN_PROTOCOL_HANDLE OpenHandle; PBL_OPEN_PROTOCOL_HANDLE OpenHandle;
} Protocol; } Protocol;
struct struct
{
PBL_STRING_COMPARE Compare;
PBL_STRING_LENGTH Length;
PBL_STRING_TO_WIDESTRING ToWideString;
PBL_STRING_TRIM Trim;
} String;
struct
{ {
PBL_TUI_DISPLAY_ERROR_DIALOG DisplayErrorDialog; PBL_TUI_DISPLAY_ERROR_DIALOG DisplayErrorDialog;
PBL_TUI_DISPLAY_INFO_DIALOG DisplayInfoDialog; PBL_TUI_DISPLAY_INFO_DIALOG DisplayInfoDialog;
@@ -440,7 +506,16 @@ typedef struct _XTBL_LOADER_PROTOCOL
PBL_SLEEP_EXECUTION SleepExecution; PBL_SLEEP_EXECUTION SleepExecution;
PBL_START_EFI_IMAGE StartEfiImage; PBL_START_EFI_IMAGE StartEfiImage;
PBL_WAIT_FOR_EFI_EVENT WaitForEfiEvent; PBL_WAIT_FOR_EFI_EVENT WaitForEfiEvent;
} Util; } Utils;
struct
{
PBL_WIDESTRING_COMPARE Compare;
PBL_WIDESTRING_COMPARE_INSENSITIVE CompareInsensitive;
PBL_WIDESTRING_CONCATENATE Concatenate;
PBL_WIDESTRING_FORMAT Format;
PBL_WIDESTRING_LENGTH Length;
PBL_WIDESTRING_TOKENIZE Tokenize;
} WideString;
} XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL; } XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL;
#endif /* __XTDK_BLTYPES_H */ #endif /* __XTDK_BLTYPES_H */

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

@@ -14,16 +14,38 @@
#include <xttypes.h> #include <xttypes.h>
/* Routines used by XTLDR */ /* Hardware layer routines forward references */
XTCDECL XTCLINK
XTSTATUS XTAPI
HlComPortPutByte(IN PCPPORT Port, UCHAR
IN UCHAR Byte); HlReadRegister8(IN PVOID Register);
XTCDECL XTCLINK
XTSTATUS XTAPI
HlInitializeComPort(IN OUT PCPPORT Port, USHORT
IN PUCHAR PortAddress, HlReadRegister16(IN PVOID Register);
IN ULONG BaudRate);
XTCLINK
XTAPI
ULONG
HlReadRegister32(IN PVOID Register);
XTCLINK
XTAPI
VOID
HlWriteRegister8(IN PVOID Register,
IN UCHAR Value);
XTCLINK
XTAPI
VOID
HlWriteRegister16(IN PVOID Register,
IN USHORT Value);
XTCLINK
XTAPI
VOID
HlWriteRegister32(IN PVOID Register,
IN ULONG Value);
#endif /* __XTDK_HLFUNCS_H */ #endif /* __XTDK_HLFUNCS_H */

View File

@@ -366,8 +366,8 @@ typedef struct _CPPORT
UCHAR Ring; 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;
@@ -375,7 +375,7 @@ 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;
struct struct
@@ -389,7 +389,22 @@ typedef struct _HAL_FRAMEBUFFER_DATA
USHORT ReservedShift; USHORT ReservedShift;
USHORT ReservedSize; USHORT ReservedSize;
} Pixels; } Pixels;
} HAL_FRAMEBUFFER_DATA, *PHAL_FRAMEBUFFER_DATA; } 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 */ /* Processor identity structure */
typedef struct _PROCESSOR_IDENTITY typedef struct _PROCESSOR_IDENTITY

View File

@@ -1,44 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: sdk/xtdk/i686/arfuncs.h
* DESCRIPTION: I686 architecture library routines
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTDK_I686_ARFUNCS_H
#define __XTDK_I686_ARFUNCS_H
#include <xtdefs.h>
#include <xtstruct.h>
#include <xttypes.h>
#include <i686/xtstruct.h>
/* Routines used by XTLDR */
XTCDECL
VOID
ArClearInterruptFlag(VOID);
XTCDECL
BOOLEAN
ArCpuId(IN OUT PCPUID_REGISTERS Registers);
XTCDECL
VOID
ArHalt(VOID);
XTCDECL
ULONG_PTR
ArReadControlRegister(IN USHORT ControlRegister);
XTCDECL
ULONGLONG
ArReadModelSpecificRegister(IN ULONG Register);
XTCDECL
VOID
ArWriteControlRegister(IN USHORT ControlRegister,
IN UINT_PTR Value);
#endif /* __XTDK_I686_ARFUNCS_H */

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
@@ -375,4 +384,10 @@ typedef struct _CPUID_SIGNATURE
ULONG Unused2:4; ULONG Unused2:4;
} CPU_SIGNATURE, *PCPU_SIGNATURE; } CPU_SIGNATURE, *PCPU_SIGNATURE;
/* Trampoline types */
typedef enum _TRAMPOLINE_TYPE
{
TrampolineApStartup
} TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;
#endif /* __XTDK_I686_ARTYPES_H */ #endif /* __XTDK_I686_ARTYPES_H */

View File

@@ -15,32 +15,38 @@
#include <i686/xtstruct.h> #include <i686/xtstruct.h>
/* HAL library routines forward references */ /* Hardware layer routines forward references */
XTCLINK
XTCDECL XTCDECL
UCHAR UCHAR
HlIoPortInByte(IN USHORT Port); HlReadPort8(IN USHORT Port);
XTCDECL
ULONG
HlIoPortInLong(IN USHORT Port);
XTCLINK
XTCDECL XTCDECL
USHORT USHORT
HlIoPortInShort(IN USHORT Port); HlReadPort16(IN USHORT Port);
XTCLINK
XTCDECL
ULONG
HlReadPort32(IN USHORT Port);
XTCLINK
XTCDECL XTCDECL
VOID VOID
HlIoPortOutByte(IN USHORT Port, HlWritePort8(IN USHORT Port,
IN UCHAR Data); IN UCHAR Data);
XTCLINK
XTCDECL XTCDECL
VOID VOID
HlIoPortOutLong(IN USHORT Port, HlWritePort16(IN USHORT Port,
IN ULONG Value);
XTCDECL
VOID
HlIoPortOutShort(IN USHORT Port,
IN USHORT Value); IN USHORT Value);
XTCLINK
XTCDECL
VOID
HlWritePort32(IN USHORT Port,
IN ULONG Value);
#endif /* __XTDK_I686_HLFUNCS_H */ #endif /* __XTDK_I686_HLFUNCS_H */

View File

@@ -47,16 +47,6 @@
#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 0x00000000
#define APIC_DM_LOWPRIO 0x00000100
#define APIC_DM_SMI 0x00000200
#define APIC_DM_REMOTE 0x00000300
#define APIC_DM_NMI 0x00000400
#define APIC_DM_INIT 0x00000500
#define APIC_DM_STARTUP 0x00000600
#define APIC_DM_EXTINT 0x00000700
/* 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
@@ -86,6 +76,35 @@
/* 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 */ /* APIC Register Address Map */
typedef enum _APIC_REGISTER typedef enum _APIC_REGISTER
{ {
@@ -123,35 +142,6 @@ typedef enum _APIC_REGISTER
APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */ APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */
} APIC_REGISTER, *PAPIC_REGISTER; } APIC_REGISTER, *PAPIC_REGISTER;
/* APIC mode list */
typedef enum _APIC_MODE
{
APIC_MODE_COMPAT,
APIC_MODE_X2APIC
} APIC_MODE, *PAPIC_MODE;
/* 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 message type enumeration list */
typedef enum _APIC_MT
{
APIC_MT_Fixed,
APIC_MT_LowestPriority,
APIC_MT_SMI,
APIC_MT_RemoteRead,
APIC_MT_NMI,
APIC_MT_INIT,
APIC_MT_Startup,
APIC_MT_ExtInt,
} APIC_MT, *PAPIC_MT;
/* I8259 PIC interrupt mode enumeration list */ /* I8259 PIC interrupt mode enumeration list */
typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE
{ {
@@ -224,7 +214,7 @@ typedef union _APIC_COMMAND_REGISTER
struct struct
{ {
ULONGLONG Vector:8; ULONGLONG Vector:8;
ULONGLONG MessageType:3; ULONGLONG DeliveryMode:3;
ULONGLONG DestinationMode:1; ULONGLONG DestinationMode:1;
ULONGLONG DeliveryStatus:1; ULONGLONG DeliveryStatus:1;
ULONGLONG ReservedMBZ:1; ULONGLONG ReservedMBZ:1;
@@ -244,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;

View File

@@ -144,8 +144,8 @@
#define KERNEL_STACK_GUARD_PAGES 1 #define KERNEL_STACK_GUARD_PAGES 1
/* Processor structures size */ /* Processor structures size */
#define KPROCESSOR_STRUCTURES_SIZE ((2 * KERNEL_STACK_SIZE) + sizeof(ArInitialGdt) + sizeof(ArInitialTss) + \ #define KPROCESSOR_STRUCTURES_SIZE ((2 * KERNEL_STACK_SIZE) + (GDT_ENTRIES * sizeof(KGDTENTRY)) + sizeof(KTSS) + \
sizeof(ArInitialProcessorBlock) + MM_PAGE_SIZE) sizeof(KPROCESSOR_BLOCK) + MM_PAGE_SIZE)
/* Kernel frames */ /* Kernel frames */
#define KTRAP_FRAME_ALIGN 0x08 #define KTRAP_FRAME_ALIGN 0x08

View File

@@ -28,7 +28,11 @@
#define MM_PDI_SHIFT 21 #define MM_PDI_SHIFT 21
#define MM_PPI_SHIFT 30 #define MM_PPI_SHIFT 30
/* Page directory and page base legacy address */
#define MM_PDE_LEGACY_BASE 0xC0300000
/* PTE legacy shift values */ /* PTE legacy shift values */
#define MM_PTE_LEGACY_SHIFT 2
#define MM_PDI_LEGACY_SHIFT 22 #define MM_PDI_LEGACY_SHIFT 22
/* Minimum number of physical pages needed by the system */ /* Minimum number of physical pages needed by the system */
@@ -49,6 +53,8 @@
/* Maximum physical address used by HAL allocations */ /* Maximum physical address used by HAL allocations */
#define MM_MAXIMUM_PHYSICAL_ADDRESS 0xFFFFFFFF #define MM_MAXIMUM_PHYSICAL_ADDRESS 0xFFFFFFFF
/* Trampoline code address */
#define MM_TRAMPOLINE_ADDRESS 0x80000
/* Page size enumeration list */ /* Page size enumeration list */
typedef enum _PAGE_SIZE typedef enum _PAGE_SIZE
@@ -58,8 +64,26 @@ 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 typedef struct _HARDWARE_LEGACY_PTE
{
ULONG Valid:1;
ULONG Writable:1;
ULONG Owner:1;
ULONG WriteThrough:1;
ULONG CacheDisable:1;
ULONG Accessed:1;
ULONG Dirty:1;
ULONG LargePage:1;
ULONG Global:1;
ULONG CopyOnWrite:1;
ULONG Prototype:1;
ULONG Reserved0:1;
ULONG PageFrameNumber:20;
} HARDWARE_LEGACY_PTE, *PHARDWARE_LEGACY_PTE;
/* Page Table entry structure definition (PML3) */
typedef struct _HARDWARE_MODERN_PTE
{ {
ULONGLONG Valid:1; ULONGLONG Valid:1;
ULONGLONG Writable:1; ULONGLONG Writable:1;
@@ -77,10 +101,117 @@ typedef struct _HARDWARE_PTE
ULONGLONG Reserved1:14; ULONGLONG Reserved1:14;
ULONGLONG SoftwareWsIndex:11; ULONGLONG SoftwareWsIndex:11;
ULONGLONG NoExecute:1; 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; } HARDWARE_PTE, *PHARDWARE_PTE;
/* Page Table Entry on PAE enabled system */ /* Page map information structure definition */
typedef struct _MMPTE_HARDWARE 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 Writable:1;
ULONG Owner:1;
ULONG WriteThrough:1;
ULONG CacheDisable:1;
ULONG Accessed:1;
ULONG Dirty:1;
ULONG LargePage:1;
ULONG Global:1;
ULONG CopyOnWrite:1;
ULONG Prototype:1;
ULONG Write:1;
ULONG PageFrameNumber:20;
} MMPML2_PTE_HARDWARE, *PMMPML2_PTE_HARDWARE;
/* Legacy Page Table Entry list structure definition (PML2) */
typedef struct _MMPML2_PTE_LIST
{
ULONG Valid:1;
ULONG OneEntry:1;
ULONG Reserved0:8;
ULONG Prototype:1;
ULONG Reserved1:1;
ULONG NextEntry:20;
} MMPML2_PTE_LIST, *PMMPML2_PTE_LIST;
/* Legacy Page Table Entry subsection structure definition (PML2) */
typedef struct _MMPML2_PTE_PROTOTYPE
{
ULONG Valid:1;
ULONG ProtoAddressLow:7;
ULONG ReadOnly:1;
ULONG WhichPool:1;
ULONG Prototype:1;
ULONG ProtoAddressHigh:21;
} MMPML2_PTE_PROTOTYPE, *PMMPML2_PTE_PROTOTYPE;
/* Legacy Page Table Entry software structure definition (PML2) */
typedef struct _MMPML2_PTE_SOFTWARE
{
ULONG Valid:1;
ULONG PageFileLow:4;
ULONG Protection:5;
ULONG Prototype:1;
ULONG Transition:1;
ULONG PageFileHigh:20;
} MMPML2_PTE_SOFTWARE, *PMMPML2_PTE_SOFTWARE;
/* Legacy Page Table Entry subsection structure definition (PML2) */
typedef struct _MMPML2_PTE_SUBSECTION
{
ULONG Valid:1;
ULONG SubsectionAddressLow:4;
ULONG Protection:5;
ULONG Prototype:1;
ULONG SubsectionAddressHigh:20;
ULONG WhichPool:1;
} MMPML2_PTE_SUBSECTION, *PMMPML2_PTE_SUBSECTION;
/* Legacy Page Table Entry transition structure definition (PML2) */
typedef struct _MMPML2_PTE_TRANSITION
{
ULONG Valid:1;
ULONG Write:1;
ULONG Owner:1;
ULONG WriteThrough:1;
ULONG CacheDisable:1;
ULONG Protection:5;
ULONG Prototype:1;
ULONG Transition:1;
ULONG PageFrameNumber:20;
} MMPML2_PTE_TRANSITION, *PMMPML2_PTE_TRANSITION;
/* Legacy Page Table Entry union definition (PML2) */
typedef union _MMPML2_PTE
{
ULONG Long;
HARDWARE_PTE Flush;
MMPML2_PTE_HARDWARE Hard;
MMPML2_PTE_PROTOTYPE Proto;
MMPML2_PTE_SOFTWARE Soft;
MMPML2_PTE_TRANSITION Trans;
MMPML2_PTE_SUBSECTION Subsect;
MMPML2_PTE_LIST List;
} MMPML2_PTE, *PMMPML2_PTE;
/* Page Table Entry hardware structure definition (PML3) */
typedef struct _MMPML3_PTE_HARDWARE
{ {
ULONGLONG Valid:1; ULONGLONG Valid:1;
ULONGLONG Writable:1; ULONGLONG Writable:1;
@@ -95,59 +226,59 @@ typedef struct _MMPTE_HARDWARE
ULONGLONG Prototype:1; ULONGLONG Prototype:1;
ULONGLONG Write:1; ULONGLONG Write:1;
ULONGLONG PageFrameNumber:26; ULONGLONG PageFrameNumber:26;
ULONGLONG Reserved1:25; ULONGLONG Reserved0:25;
ULONGLONG NoExecute:1; ULONGLONG NoExecute:1;
} MMPTE_HARDWARE, *PMMPTE_HARDWARE; } MMPML3_PTE_HARDWARE, *PMMPML3_PTE_HARDWARE;
/* Page Table Entry list structure definition (with PAE support) */ /* Page Table Entry list structure definition (PML3) */
typedef struct _MMPTE_LIST typedef struct _MMPML3_PTE_LIST
{ {
ULONGLONG Valid:1; ULONGLONG Valid:1;
ULONGLONG OneEntry:1; ULONGLONG OneEntry:1;
ULONGLONG Reserved1:8; ULONGLONG Reserved0:8;
ULONGLONG Prototype:1; ULONGLONG Prototype:1;
ULONGLONG Reserved2:21; ULONGLONG Reserved1:21;
ULONGLONG NextEntry:32; ULONGLONG NextEntry:32;
} MMPTE_LIST, *PMMPTE_LIST; } MMPML3_PTE_LIST, *PMMPML3_PTE_LIST;
/* Page Table Entry subsection structure definition (with PAE support) */ /* Page Table Entry subsection structure definition (PML3) */
typedef struct _MMPTE_PROTOTYPE typedef struct _MMPML3_PTE_PROTOTYPE
{ {
ULONGLONG Valid:1; ULONGLONG Valid:1;
ULONGLONG Reserved1:7; ULONGLONG Reserved0:7;
ULONGLONG ReadOnly:1; ULONGLONG ReadOnly:1;
ULONGLONG Reserved2:1; ULONGLONG Reserved1:1;
ULONGLONG Prototype:1; ULONGLONG Prototype:1;
ULONGLONG Protection:5; ULONGLONG Protection:5;
ULONGLONG Reserved3:16; ULONGLONG Reserved2:16;
ULONGLONG ProtoAddress:32; ULONGLONG ProtoAddress:32;
} MMPTE_PROTOTYPE, *PMMPTE_PROTOTYPE; } MMPML3_PTE_PROTOTYPE, *PMMPML3_PTE_PROTOTYPE;
/* Page Table Entry software structure definition (with PAE support) */ /* Page Table Entry software structure definition (PML3) */
typedef struct _MMPTE_SOFTWARE typedef struct _MMPML3_PTE_SOFTWARE
{ {
ULONGLONG Valid:1; ULONGLONG Valid:1;
ULONGLONG PageFileLow:4; ULONGLONG PageFileLow:4;
ULONGLONG Protection:5; ULONGLONG Protection:5;
ULONGLONG Prototype:1; ULONGLONG Prototype:1;
ULONGLONG Transition:1; ULONGLONG Transition:1;
ULONGLONG Reserved1:20; ULONGLONG Reserved0:20;
ULONGLONG PageFileHigh:32; ULONGLONG PageFileHigh:32;
} MMPTE_SOFTWARE, *PMMPTE_SOFTWARE; } MMPML3_PTE_SOFTWARE, *PMMPML3_PTE_SOFTWARE;
/* Page Table Entry subsection structure definition (with PAE support) */ /* Page Table Entry subsection structure definition (PML3) */
typedef struct _MMPTE_SUBSECTION typedef struct _MMPML3_PTE_SUBSECTION
{ {
ULONGLONG Valid:1; ULONGLONG Valid:1;
ULONGLONG Reserved1:4; ULONGLONG Reserved0:4;
ULONGLONG Protection:5; ULONGLONG Protection:5;
ULONGLONG Prototype:1; ULONGLONG Prototype:1;
ULONGLONG Reserved2:21; ULONGLONG Reserved1:21;
ULONGLONG SubsectionAddress:32; ULONGLONG SubsectionAddress:32;
} MMPTE_SUBSECTION, *PMMPTE_SUBSECTION; } MMPML3_PTE_SUBSECTION, *PMMPML3_PTE_SUBSECTION;
/* Page Table Entry transition structure definition (with PAE support) */ /* Page Table Entry transition structure definition (PML3) */
typedef struct _MMPTE_TRANSITION typedef struct _MMPML3_PTE_TRANSITION
{ {
ULONGLONG Valid:1; ULONGLONG Valid:1;
ULONGLONG Write:1; ULONGLONG Write:1;
@@ -159,38 +290,28 @@ typedef struct _MMPTE_TRANSITION
ULONGLONG Transition:1; ULONGLONG Transition:1;
ULONGLONG PageFrameNumber:26; ULONGLONG PageFrameNumber:26;
ULONGLONG Unused:26; ULONGLONG Unused:26;
} MMPTE_TRANSITION, *PMMPTE_TRANSITION; } MMPML3_PTE_TRANSITION, *PMMPML3_PTE_TRANSITION;
/* Page Table Entry structure definition (with PAE support) */ /* Page Table Entry union definition (PML3) */
typedef union _MMPTE typedef union _MMPML3_PTE
{ {
ULONGLONG Long; ULONGLONG Long;
HARDWARE_PTE Flush; HARDWARE_PTE Flush;
MMPTE_HARDWARE Hardware; MMPML3_PTE_HARDWARE Hardware;
MMPTE_PROTOTYPE Prototype; MMPML3_PTE_PROTOTYPE Prototype;
MMPTE_SOFTWARE Software; MMPML3_PTE_SOFTWARE Software;
MMPTE_TRANSITION Transition; MMPML3_PTE_TRANSITION Transition;
MMPTE_SUBSECTION Subsection; MMPML3_PTE_SUBSECTION Subsection;
MMPTE_LIST List; MMPML3_PTE_LIST List;
} MMPTE, *PMMPTE; } MMPML3_PTE, *PMMPML3_PTE;
/* Legacy Page Table entry structure definition (without PAE support) */ /* Generic Page Table Entry union to abstract PML2 and PML3 formats */
typedef struct _HARDWARE_LEGACY_PTE typedef union _MMPTE
{ {
ULONG Valid:1; ULONGLONG Long;
ULONG Writable:1; MMPML2_PTE Pml2;
ULONG Owner:1; MMPML3_PTE Pml3;
ULONG WriteThrough:1; } MMPTE, *PMMPTE;
ULONG CacheDisable:1;
ULONG Accessed:1;
ULONG Dirty:1;
ULONG LargePage:1;
ULONG Global:1;
ULONG CopyOnWrite:1;
ULONG Prototype:1;
ULONG Reserved0:1;
ULONG PageFrameNumber:20;
} HARDWARE_LEGACY_PTE, *PHARDWARE_LEGACY_PTE;
/* Page Frame Number structure definition */ /* Page Frame Number structure definition */
typedef struct _MMPFN typedef struct _MMPFN

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