diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 58701da..93b056c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,7 +28,7 @@ jobs: OSCW_ARTIFACTS_USERKEY: ${{ secrets.OSCW_ARTIFACTS_USERKEY }} 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 }}-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 . 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 diff --git a/CMakeLists.txt b/CMakeLists.txt index f6ce6f6..92e0253 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,9 +55,6 @@ add_definitions(-D__XTOS__) add_definitions(-DXTOS_SOURCE_DIR="${EXECTOS_SOURCE_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 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]") @@ -68,5 +65,6 @@ set_disk_image_size(32) # Build all subprojects add_subdirectory(bootdata) add_subdirectory(drivers) +add_subdirectory(sdk) add_subdirectory(xtldr) add_subdirectory(xtoskrnl) diff --git a/drivers/ntosdrv/CMakeLists.txt b/drivers/ntosdrv/CMakeLists.txt index 6552909..7abfae2 100644 --- a/drivers/ntosdrv/CMakeLists.txt +++ b/drivers/ntosdrv/CMakeLists.txt @@ -7,8 +7,8 @@ include_directories( # Specify list of source code files list(APPEND NTOSDRV_SOURCE - ${NTOSDRV_SOURCE_DIR}/ntosdrv.c - ${NTOSDRV_SOURCE_DIR}/rtl.c) + ${NTOSDRV_SOURCE_DIR}/ntosdrv.cc + ${NTOSDRV_SOURCE_DIR}/rtl.cc) # Set module definition SPEC file set_specfile(ntosdrv.spec ntosdrv.sys) diff --git a/drivers/ntosdrv/ntosdrv.c b/drivers/ntosdrv/ntosdrv.cc similarity index 89% rename from drivers/ntosdrv/ntosdrv.c rename to drivers/ntosdrv/ntosdrv.cc index 5ed73d3..f646410 100644 --- a/drivers/ntosdrv/ntosdrv.c +++ b/drivers/ntosdrv/ntosdrv.cc @@ -1,7 +1,7 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: drivers/ntosdrv/ntosdrv.c + * FILE: drivers/ntosdrv/ntosdrv.cc * DESCRIPTION: NTOS compatibility driver * DEVELOPERS: Rafal Kupiec */ @@ -16,6 +16,7 @@ * * @since XT 1.0 */ +XTCLINK XTAPI XTSTATUS XtDriverEntry(VOID) diff --git a/drivers/ntosdrv/rtl.c b/drivers/ntosdrv/rtl.cc similarity index 94% rename from drivers/ntosdrv/rtl.c rename to drivers/ntosdrv/rtl.cc index ab33304..43ef7a9 100644 --- a/drivers/ntosdrv/rtl.c +++ b/drivers/ntosdrv/rtl.cc @@ -1,7 +1,7 @@ /** * PROJECT: ExectOS * 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 * DEVELOPERS: Rafal Kupiec */ @@ -25,6 +25,7 @@ * * @since NT 3.5 */ +XTCLINK XTAPI VOID RtlFillMemory(OUT PVOID Destination, diff --git a/sdk/CMakeLists.txt b/sdk/CMakeLists.txt new file mode 100644 index 0000000..780305a --- /dev/null +++ b/sdk/CMakeLists.txt @@ -0,0 +1 @@ +set_sdk_target("xtdk/" "include") diff --git a/sdk/cmake/functions.cmake b/sdk/cmake/functions.cmake index 8555522..fe17eea 100644 --- a/sdk/cmake/functions.cmake +++ b/sdk/cmake/functions.cmake @@ -85,9 +85,14 @@ endfunction() # This function installs specified target results under destination directory 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}) 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 function(set_specfile SPECFILE EXPORTNAME) if(NOT ${ARGC} EQUAL 2) diff --git a/sdk/cmake/toolchain.cmake b/sdk/cmake/toolchain.cmake index 2d72ec6..051e5c6 100644 --- a/sdk/cmake/toolchain.cmake +++ b/sdk/cmake/toolchain.cmake @@ -20,8 +20,9 @@ set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_C_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_CXX_STANDARD_LIBRARIES "" CACHE INTERNAL "") # Clean linker flags set(CMAKE_STATIC_LINKER_FLAGS "") diff --git a/sdk/cmake/xtchain.cmake b/sdk/cmake/xtchain.cmake index 9e48f5a..127861a 100644 --- a/sdk/cmake/xtchain.cmake +++ b/sdk/cmake/xtchain.cmake @@ -12,7 +12,7 @@ endif() # Set build optimisation if(BUILD_TYPE STREQUAL "DEBUG") 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() add_compiler_ccxxflags("/GS- /Ob2 /Ot /Ox /Oy") add_linker_flags("/INCREMENTAL:NO /OPT:REF /OPT:ICF") @@ -50,8 +50,9 @@ add_compiler_ccxxflags("-Wno-gnu-folding-constant") # Disable compiler builtins 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(LIBRARY_OUTPUT_PATH "${EXECTOS_BINARY_DIR}/output/sdk/lib") # Set linker flags add_linker_flags("${HOTPATCH_LINKER_FLAG} /LARGEADDRESSAWARE /IGNORE:4039 /IGNORE:4104 /MANIFEST:NO /NODEFAULTLIB /SAFESEH:NO") diff --git a/sdk/xtbk/README.md b/sdk/xtbk/README.md deleted file mode 100644 index b5882a1..0000000 --- a/sdk/xtbk/README.md +++ /dev/null @@ -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. diff --git a/sdk/xtdk/amd64/arfuncs.h b/sdk/xtdk/amd64/arfuncs.h deleted file mode 100644 index 72a9d2c..0000000 --- a/sdk/xtdk/amd64/arfuncs.h +++ /dev/null @@ -1,48 +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 - */ - -#ifndef __XTDK_AMD64_ARFUNCS_H -#define __XTDK_AMD64_ARFUNCS_H - -#include -#include -#include -#include - - -/* Routines used by XTLDR */ -XTCDECL -VOID -ArClearInterruptFlag(VOID); - -XTCDECL -BOOLEAN -ArCpuId(IN OUT PCPUID_REGISTERS Registers); - -XTCDECL -VOID -ArEnableExtendedPhysicalAddressing(IN ULONG_PTR PageMap); - -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 */ diff --git a/sdk/xtdk/amd64/artypes.h b/sdk/xtdk/amd64/artypes.h index b9fdedd..61461a9 100644 --- a/sdk/xtdk/amd64/artypes.h +++ b/sdk/xtdk/amd64/artypes.h @@ -419,4 +419,11 @@ typedef struct _CPUID_SIGNATURE ULONG Unused2:4; } CPU_SIGNATURE, *PCPU_SIGNATURE; +/* Trampoline types */ +typedef enum _TRAMPOLINE_TYPE +{ + TrampolineApStartup, + TrampolineEnableXpa +} TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE; + #endif /* __XTDK_AMD64_ARTYPES_H */ diff --git a/sdk/xtdk/amd64/hlfuncs.h b/sdk/xtdk/amd64/hlfuncs.h index d5d6bff..84954ad 100644 --- a/sdk/xtdk/amd64/hlfuncs.h +++ b/sdk/xtdk/amd64/hlfuncs.h @@ -15,32 +15,38 @@ #include -/* HAL library routines forward references */ +/* Hardware layer routines forward references */ +XTCLINK XTCDECL UCHAR -HlIoPortInByte(IN USHORT Port); - -XTCDECL -ULONG -HlIoPortInLong(IN USHORT Port); +HlReadPort8(IN USHORT Port); +XTCLINK XTCDECL USHORT -HlIoPortInShort(IN USHORT Port); +HlReadPort16(IN USHORT Port); +XTCLINK +XTCDECL +ULONG +HlReadPort32(IN USHORT Port); + +XTCLINK XTCDECL VOID -HlIoPortOutByte(IN USHORT Port, - IN UCHAR Data); +HlWritePort8(IN USHORT Port, + IN UCHAR Data); +XTCLINK XTCDECL VOID -HlIoPortOutLong(IN USHORT Port, - IN ULONG Value); +HlWritePort16(IN USHORT Port, + IN USHORT Value); +XTCLINK XTCDECL VOID -HlIoPortOutShort(IN USHORT Port, - IN USHORT Value); +HlWritePort32(IN USHORT Port, + IN ULONG Value); #endif /* __XTDK_AMD64_HLFUNCS_H */ diff --git a/sdk/xtdk/amd64/ketypes.h b/sdk/xtdk/amd64/ketypes.h index 0dce5be..2d6943f 100644 --- a/sdk/xtdk/amd64/ketypes.h +++ b/sdk/xtdk/amd64/ketypes.h @@ -118,8 +118,8 @@ #define KERNEL_STACK_GUARD_PAGES 1 /* Processor structures size */ -#define KPROCESSOR_STRUCTURES_SIZE ((2 * KERNEL_STACK_SIZE) + sizeof(ArInitialGdt) + sizeof(ArInitialTss) + \ - sizeof(ArInitialProcessorBlock) + MM_PAGE_SIZE) +#define KPROCESSOR_STRUCTURES_SIZE ((2 * KERNEL_STACK_SIZE) + (GDT_ENTRIES * sizeof(KGDTENTRY)) + sizeof(KTSS) + \ + sizeof(KPROCESSOR_BLOCK) + MM_PAGE_SIZE) /* Kernel frames */ #define KEXCEPTION_FRAME_SIZE sizeof(KEXCEPTION_FRAME) diff --git a/sdk/xtdk/amd64/xtstruct.h b/sdk/xtdk/amd64/xtstruct.h index 82b950e..64aa6d4 100644 --- a/sdk/xtdk/amd64/xtstruct.h +++ b/sdk/xtdk/amd64/xtstruct.h @@ -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_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 _TRAMPOLINE_TYPE TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE; /* Architecture-specific structures forward references */ typedef struct _CONTEXT CONTEXT, *PCONTEXT; diff --git a/sdk/xtdk/blfuncs.h b/sdk/xtdk/blfuncs.h index 77e0bf1..6dc2bad 100644 --- a/sdk/xtdk/blfuncs.h +++ b/sdk/xtdk/blfuncs.h @@ -14,6 +14,7 @@ /* XT BootLoader routines forward references */ +XTCLINK XTCDECL EFI_STATUS BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable, diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index f045781..3ea3355 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -4,6 +4,7 @@ * FILE: sdk/xtdk/bltypes.h * DESCRIPTION: XT Boot Loader structures definitions * DEVELOPERS: Rafal Kupiec + * Aiken Harris */ #ifndef __XTDK_BLTYPES_H @@ -41,103 +42,130 @@ #define XTBL_TUI_MAX_DIALOG_WIDTH 100 /* 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 */ -typedef EFI_STATUS (*PBL_ALLOCATE_PAGES)(IN EFI_ALLOCATE_TYPE AllocationType, IN ULONGLONG Size, OUT PEFI_PHYSICAL_ADDRESS Memory); -typedef EFI_STATUS (*PBL_ALLOCATE_POOL)(IN UINT_PTR Size, OUT PVOID *Memory); -typedef EFI_STATUS (*PBL_BOOTMENU_INITIALIZE_OS_LIST)(IN ULONG MaxNameLength, OUT PXTBL_BOOTMENU_ITEM *MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId); -typedef BOOLEAN (*PBL_BOOTUTIL_GET_BOOLEAN_PARAMETER)(IN CONST PWCHAR Parameters, IN CONST PWCHAR Needle); -typedef EFI_STATUS (*PBL_BUILD_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR SelfMapAddress); -typedef EFI_STATUS (*PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle); -typedef VOID (*PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo); -typedef EFI_STATUS (*PBL_CLOSE_XT_PROTOCOL)(IN PEFI_HANDLE Handle, IN PEFI_GUID ProtocolGuid); -typedef BOOLEAN (*PBL_CONFIG_GET_BOOLEAN_VALUE)(IN CONST PWCHAR ConfigName); -typedef EFI_STATUS (*PBL_CONFIG_GET_BOOT_OPTION_VALUE)(IN PLIST_ENTRY Options, IN CONST PWCHAR OptionName, OUT PWCHAR *OptionValue); -typedef VOID (*PBL_CONFIG_GET_EDITABLE_OPTIONS)(OUT CONST PWCHAR **OptionsArray, OUT PULONG OptionsCount); -typedef EFI_STATUS (*PBL_CONFIG_GET_VALUE)(IN CONST PWCHAR ConfigName, OUT PWCHAR *ConfigValue); -typedef EFI_STATUS (*PBL_CONFIG_SET_BOOT_OPTION_VALUE)(IN PLIST_ENTRY Options, IN CONST PWCHAR OptionName, IN CONST PWCHAR OptionValue); -typedef VOID (*PBL_CONSOLE_CLEAR_SCREEN)(); -typedef VOID (*PBL_CONSOLE_DISABLE_CURSOR)(); -typedef VOID (*PBL_CONSOLE_ENABLE_CURSOR)(); -typedef VOID (*PBL_CONSOLE_PRINT)(IN PCWSTR Format, IN ...); -typedef VOID (*PBL_CONSOLE_QUERY_MODE)(OUT PUINT_PTR ResX, OUT PUINT_PTR ResY); -typedef VOID (*PBL_CONSOLE_READ_KEY_STROKE)(OUT PEFI_INPUT_KEY Key); -typedef VOID (*PBL_CONSOLE_RESET_INPUT_BUFFER)(); -typedef VOID (*PBL_CONSOLE_SET_ATTRIBUTES)(IN ULONGLONG Attributes); -typedef VOID (*PBL_CONSOLE_SET_CURSOR_POSITION)(IN ULONGLONG PosX, IN ULONGLONG PosY); -typedef VOID (*PBL_CONSOLE_WRITE)(IN PCWSTR String); +typedef EFI_STATUS (XTCDECL *PBL_ALLOCATE_PAGES)(IN EFI_ALLOCATE_TYPE AllocationType, IN ULONGLONG Size, OUT PEFI_PHYSICAL_ADDRESS Memory); +typedef EFI_STATUS (XTCDECL *PBL_ALLOCATE_POOL)(IN UINT_PTR Size, OUT PVOID *Memory); +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 (XTCDECL *PBL_BOOTUTILS_GET_BOOLEAN_PARAMETER)(IN PCWSTR Parameters, IN PCWSTR Needle); +typedef VOID (XTAPI *PBL_BOOTUTILS_GET_TRAMPOLINE_INFORMATION)(IN TRAMPOLINE_TYPE TrampolineType, OUT PVOID *TrampolineCode, OUT PULONG_PTR TrampolineSize); +typedef EFI_STATUS (XTCDECL *PBL_BUILD_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR SelfMapAddress); +typedef EFI_STATUS (XTCDECL *PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle); +typedef VOID (XTCDECL *PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo); +typedef BOOLEAN (XTCDECL *PBL_CPU_CPUID)(IN OUT PCPUID_REGISTERS Registers); +typedef ULONG_PTR (XTCDECL *PBL_CPU_READ_CONTROL_REGISTER)(IN USHORT ControlRegister); +typedef ULONGLONG (XTCDECL *PBL_CPU_READ_MODEL_SPECIFIC_REGISTER)(IN ULONG Register); +typedef VOID (XTCDECL *PBL_CPU_WRITE_CONTROL_REGISTER)(IN USHORT ControlRegister, IN UINT_PTR Value); +typedef EFI_STATUS (XTCDECL *PBL_CLOSE_XT_PROTOCOL)(IN PEFI_HANDLE Handle, IN PEFI_GUID ProtocolGuid); +typedef BOOLEAN (XTCDECL *PBL_CONFIG_GET_BOOLEAN_VALUE)(IN PCWSTR ConfigName); +typedef EFI_STATUS (XTCDECL *PBL_CONFIG_GET_BOOT_OPTION_VALUE)(IN PLIST_ENTRY Options, IN PCWSTR OptionName, OUT PWCHAR *OptionValue); +typedef VOID (XTCDECL *PBL_CONFIG_GET_EDITABLE_OPTIONS)(OUT PCWSTR **OptionsArray, OUT PULONG OptionsCount); +typedef EFI_STATUS (XTCDECL *PBL_CONFIG_GET_VALUE)(IN PCWSTR ConfigName, OUT PWCHAR *ConfigValue); +typedef EFI_STATUS (XTCDECL *PBL_CONFIG_SET_BOOT_OPTION_VALUE)(IN PLIST_ENTRY Options, IN PCWSTR OptionName, IN PCWSTR OptionValue); +typedef VOID (XTCDECL *PBL_CONSOLE_CLEAR_SCREEN)(); +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 (*PBL_DEBUG_PRINT)(IN PCWSTR Format, IN ...); -typedef EFI_STATUS (*PBL_ENTER_FIRMWARE_SETUP)(); -typedef EFI_STATUS (*PBL_EXIT_BOOT_SERVICES)(); -typedef EFI_STATUS (*PBL_FIND_BOOT_PROTOCOL)(IN PWCHAR SystemType, OUT PEFI_GUID BootProtocolGuid); -typedef EFI_STATUS (*PBL_FREE_PAGES)(IN ULONGLONG Size, IN EFI_PHYSICAL_ADDRESS Memory); -typedef EFI_STATUS (*PBL_FREE_POOL)(IN PVOID Memory); -typedef EFI_STATUS (*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 VOID (*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 PLIST_ENTRY (*PBL_GET_MODULES_LIST)(); -typedef ULONGLONG (*PBL_GET_RANDOM_VALUE)(IN OUT PULONGLONG RNGBuffer); -typedef INT_PTR (*PBL_GET_SECURE_BOOT_STATUS)(); -typedef PVOID (*PBL_GET_VIRTUAL_ADDRESS)(IN PXTBL_PAGE_MAPPING PageMap, IN PVOID PhysicalAddress); -typedef EFI_STATUS (*PBL_INITIALIZE_ENTROPY)(PULONGLONG RNGBuffer); -typedef VOID (*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 (*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 (*PBL_LOAD_EFI_IMAGE)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, IN PVOID ImageData, IN SIZE_T ImageSize, OUT PEFI_HANDLE ImageHandle); -typedef EFI_STATUS (*PBL_MAP_EFI_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN OUT PVOID *MemoryMapAddress, IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine); -typedef EFI_STATUS (*PBL_MAP_PAGE)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR VirtualAddress, IN ULONG_PTR PhysicalAddress, IN ULONG NumberOfPages); -typedef EFI_STATUS (*PBL_MAP_VIRTUAL_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN PVOID VirtualAddress, IN PVOID PhysicalAddress, IN ULONGLONG NumberOfPages, IN LOADER_MEMORY_TYPE MemoryType); -typedef EFI_STATUS (*PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle); -typedef EFI_STATUS (*PBL_OPEN_PROTOCOL)(OUT PEFI_HANDLE Handle, OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid); -typedef EFI_STATUS (*PBL_OPEN_PROTOCOL_HANDLE)(IN EFI_HANDLE Handle, OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid); -typedef PVOID (*PBL_PHYSICAL_ADDRESS_TO_VIRTUAL)(IN PVOID PhysicalAddress, IN PVOID PhysicalBase, IN PVOID VirtualBase); -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 EFI_STATUS (*PBL_POWER_SYSTEM)(); -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 (*PBL_REGISTER_BOOT_PROTOCOL)(IN PWCHAR SystemType, IN PEFI_GUID BootProtocolGuid); -typedef VOID (*PBL_REGISTER_XT_BOOT_MENU)(PVOID BootMenuRoutine); -typedef EFI_STATUS (*PBL_SET_EFI_VARIABLE)(IN PEFI_GUID Vendor, IN PWCHAR VariableName, IN PVOID VariableValue, IN UINT_PTR Size); +typedef VOID (XTCDECL *PBL_DEBUG_PRINT)(IN PCWSTR Format, IN ...); +typedef EFI_STATUS (XTCDECL *PBL_ENTER_FIRMWARE_SETUP)(); +typedef EFI_STATUS (XTCDECL *PBL_EXIT_BOOT_SERVICES)(); +typedef EFI_STATUS (XTCDECL *PBL_FIND_BOOT_PROTOCOL)(IN PCWSTR SystemType, OUT PEFI_GUID BootProtocolGuid); +typedef EFI_STATUS (XTCDECL *PBL_FREE_PAGES)(IN ULONGLONG Size, IN EFI_PHYSICAL_ADDRESS Memory); +typedef EFI_STATUS (XTCDECL *PBL_FREE_POOL)(IN PVOID Memory); +typedef EFI_STATUS (XTCDECL *PBL_GET_CONFIGURATION_TABLE)(IN PEFI_GUID TableGuid, OUT PVOID *Table); +typedef EFI_STATUS (XTCDECL *PBL_GET_EFI_VARIABLE)(IN PEFI_GUID Vendor, IN PCWSTR VariableName, OUT PVOID *VariableValue); +typedef VOID (XTCDECL *PBL_GET_MAPPINGS_COUNT)(IN PXTBL_PAGE_MAPPING PageMap, OUT PULONG NumberOfMappings); +typedef EFI_STATUS (XTCDECL *PBL_GET_MEMORY_MAP)(OUT PEFI_MEMORY_MAP MemoryMap); +typedef PLIST_ENTRY (XTCDECL *PBL_GET_MODULES_LIST)(); +typedef ULONGLONG (XTCDECL *PBL_GET_RANDOM_VALUE)(IN OUT PULONGLONG RNGBuffer); +typedef INT_PTR (XTCDECL *PBL_GET_SECURE_BOOT_STATUS)(); +typedef PVOID (XTCDECL *PBL_GET_VIRTUAL_ADDRESS)(IN PXTBL_PAGE_MAPPING PageMap, IN PVOID PhysicalAddress); +typedef EFI_STATUS (XTCDECL *PBL_INITIALIZE_ENTROPY)(PULONGLONG RNGBuffer); +typedef VOID (XTCDECL *PBL_INITIALIZE_PAGE_MAP)(OUT PXTBL_PAGE_MAPPING PageMap, IN SHORT PageMapLevel, IN PAGE_SIZE PageSize); +typedef EFI_STATUS (XTCDECL *PBL_INSTALL_XT_PROTOCOL)(IN PVOID Interface, IN PEFI_GUID Guid); +typedef EFI_STATUS (XTCDECL *PBL_INVOKE_BOOT_PROTOCOL)(IN PWCHAR ShortName, IN PLIST_ENTRY OptionsList); +typedef EFI_STATUS (XTCDECL *PBL_LOCATE_PROTOCOL_HANDLES)(OUT PEFI_HANDLE *Handles, OUT PUINT_PTR Count, IN PEFI_GUID ProtocolGuid); +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 VOID (XTCDECL *PBL_LLIST_INITIALIZE_HEAD)(IN PLIST_ENTRY ListHead); +typedef VOID (XTCDECL *PBL_LLIST_INSERT_HEAD)(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry); +typedef VOID (XTCDECL *PBL_LLIST_INSERT_TAIL)(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry); +typedef VOID (XTCDECL *PBL_LLIST_REMOVE_ENTRY)(IN PLIST_ENTRY Entry); +typedef EFI_STATUS (XTCDECL *PBL_MAP_EFI_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN OUT PVOID *MemoryMapAddress, IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine); +typedef EFI_STATUS (XTCDECL *PBL_MAP_PAGE)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR VirtualAddress, IN ULONG_PTR PhysicalAddress, IN ULONG NumberOfPages); +typedef EFI_STATUS (XTCDECL *PBL_MAP_VIRTUAL_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN PVOID VirtualAddress, IN PVOID PhysicalAddress, IN ULONGLONG NumberOfPages, IN LOADER_MEMORY_TYPE MemoryType); +typedef VOID (XTAPI *PBL_MOVE_MEMORY)(IN OUT PVOID Destination, IN PCVOID Source, IN SIZE_T Length); +typedef EFI_STATUS (XTCDECL *PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle); +typedef EFI_STATUS (XTCDECL *PBL_OPEN_PROTOCOL)(OUT PEFI_HANDLE Handle, OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid); +typedef EFI_STATUS (XTCDECL *PBL_OPEN_PROTOCOL_HANDLE)(IN EFI_HANDLE Handle, OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid); +typedef PVOID (XTCDECL *PBL_PHYSICAL_ADDRESS_TO_VIRTUAL)(IN PVOID PhysicalAddress, IN PVOID PhysicalBase, IN PVOID VirtualBase); +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 (*PBL_SLEEP_EXECUTION)(IN ULONG_PTR Milliseconds); -typedef EFI_STATUS (*PBL_START_EFI_IMAGE)(IN EFI_HANDLE ImageHandle); -typedef VOID (*PBL_TUI_DISPLAY_ERROR_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message); -typedef VOID (*PBL_TUI_DISPLAY_INFO_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message); -typedef VOID (*PBL_TUI_DISPLAY_INPUT_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message, IN PWCHAR *InputFieldText); -typedef XTBL_DIALOG_HANDLE (*PBL_TUI_DISPLAY_PROGRESS_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message, IN UCHAR Percentage); -typedef VOID (*PBL_TUI_UPDATE_PROGRESS_BAR)(IN PXTBL_DIALOG_HANDLE Handle, IN PWCHAR 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 VOID (*PBL_XT_BOOT_MENU)(); +typedef VOID (XTCDECL *PBL_SLEEP_EXECUTION)(IN ULONG_PTR Milliseconds); +typedef EFI_STATUS (XTCDECL *PBL_START_EFI_IMAGE)(IN EFI_HANDLE ImageHandle); +typedef VOID (XTCDECL *PBL_TUI_DISPLAY_ERROR_DIALOG)(IN PCWSTR Caption, IN PCWSTR Message); +typedef VOID (XTCDECL *PBL_TUI_DISPLAY_INFO_DIALOG)(IN PCWSTR Caption, IN PCWSTR Message); +typedef VOID (XTCDECL *PBL_TUI_DISPLAY_INPUT_DIALOG)(IN PCWSTR Caption, IN PCWSTR Message, IN OUT PWCHAR *InputFieldText); +typedef XTBL_DIALOG_HANDLE (XTCDECL *PBL_TUI_DISPLAY_PROGRESS_DIALOG)(IN PCWSTR Caption, IN PCWSTR Message, IN UCHAR Percentage); +typedef VOID (XTCDECL *PBL_TUI_UPDATE_PROGRESS_BAR)(IN PXTBL_DIALOG_HANDLE Handle, IN PCWSTR Message, IN UCHAR Percentage); +typedef SIZE_T (XTAPI *PBL_WIDESTRING_COMPARE_INSENSITIVE)(IN PCWSTR String1, IN PCWSTR String2, IN SIZE_T Length); +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); /* Module protocols routine pointers */ -typedef EFI_STATUS (*PBL_ACPI_GET_ACPI_DESCRIPTION_POINTER)(OUT PVOID *AcpiTable); -typedef EFI_STATUS (*PBL_ACPI_GET_ACPI_TABLE)(IN CONST UINT Signature, IN PVOID PreviousTable, OUT PVOID *AcpiTable); -typedef EFI_STATUS (*PBL_ACPI_GET_APIC_BASE)(OUT PVOID *ApicBase); -typedef EFI_STATUS (*PBL_ACPI_GET_RSDP_TABLE)(OUT PVOID *AcpiTable); -typedef EFI_STATUS (*PBL_ACPI_GET_SMBIOS_TABLE)(OUT PVOID *SmBiosTable); -typedef EFI_STATUS (*PBL_ACPI_GET_SMBIOS3_TABLE)(OUT PVOID *SmBiosTable); -typedef EFI_STATUS (*PBL_ACPI_GET_XSDP_TABLE)(OUT PVOID *AcpiTable); -typedef EFI_STATUS (*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 (*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 (*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 (*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 (*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 (*PBL_EXECIMAGE_UNLOAD_IMAGE)(IN PVOID ImagePointer); -typedef EFI_STATUS (*PBL_EXECIMAGE_VERIFY_IMAGE)(IN PVOID ImagePointer); -typedef EFI_STATUS (*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 (*PBL_FRAMEBUFFER_GET_PREFERRED_SCREEN_RESOLUTION)(OUT PUINT PreferredWidth, OUT PUINT PreferredHeight); -typedef EFI_STATUS (*PBL_FRAMEBUFFER_INITIALIZE)(); -typedef EFI_STATUS (*PBL_FRAMEBUFFER_SET_SCREEN_RESOLUTION)(IN UINT Width, IN UINT Height); +typedef EFI_STATUS (XTCDECL *PBL_ACPI_GET_ACPI_DESCRIPTION_POINTER)(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 (XTCDECL *PBL_ACPI_GET_APIC_BASE)(OUT PVOID *ApicBase); +typedef EFI_STATUS (XTCDECL *PBL_ACPI_GET_RSDP_TABLE)(OUT PVOID *AcpiTable); +typedef EFI_STATUS (XTCDECL *PBL_ACPI_GET_SMBIOS_TABLE)(OUT PVOID *SmBiosTable); +typedef EFI_STATUS (XTCDECL *PBL_ACPI_GET_SMBIOS3_TABLE)(OUT PVOID *SmBiosTable); +typedef EFI_STATUS (XTCDECL *PBL_ACPI_GET_XSDP_TABLE)(OUT PVOID *AcpiTable); +typedef EFI_STATUS (XTCDECL *PBL_BOOTPROTO_BOOT_SYSTEM)(IN PXTBL_BOOT_PARAMETERS Parameters); +typedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_GET_ENTRY_POINT)(IN PVOID ImagePointer, OUT PVOID *EntryPoint); +typedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_GET_FILE_SIZE)(IN PVOID ImagePointer, OUT PULONGLONG FileSize); +typedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_GET_IMAGE_SIZE)(IN PVOID ImagePointer, OUT PUINT ImageSize); +typedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_GET_MACHINE_TYPE)(IN PVOID ImagePointer, OUT PUSHORT MachineType); +typedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_GET_SECTION)(IN PVOID ImagePointer, IN PCHAR SectionName, OUT PULONG *RawData); +typedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_GET_SUBSYSTEM)(IN PVOID ImagePointer, OUT PUSHORT SubSystem); +typedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_GET_VERSION)(IN PVOID ImagePointer, OUT PUSHORT Version); +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 (XTCDECL *PBL_EXECIMAGE_RELOCATE_IMAGE)(IN PVOID ImagePointer, IN EFI_VIRTUAL_ADDRESS Address); +typedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_UNLOAD_IMAGE)(IN PVOID ImagePointer); +typedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_VERIFY_IMAGE)(IN PVOID ImagePointer); +typedef EFI_STATUS (XTCDECL *PBL_FRAMEBUFFER_GET_DISPLAY_DRIVER)(OUT PEFI_GRAPHICS_PROTOCOL Protocol); +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 (XTCDECL *PBL_FRAMEBUFFER_GET_PREFERRED_SCREEN_RESOLUTION)(OUT PUINT PreferredWidth, OUT PUINT PreferredHeight); +typedef EFI_STATUS (XTCDECL *PBL_FRAMEBUFFER_INITIALIZE)(); +typedef EFI_STATUS (XTCDECL *PBL_FRAMEBUFFER_SET_SCREEN_RESOLUTION)(IN UINT Width, IN UINT Height); /* Boot parameters structure */ typedef struct _XTBL_BOOT_PARAMETERS @@ -253,13 +281,10 @@ typedef struct _XTBL_PAGE_MAPPING /* XTLDR Status data */ typedef struct _XTBL_STATUS { - PBL_XT_BOOT_MENU BootMenu; - BOOLEAN BootServices; - ULONG DebugPort; PVOID LoaderBase; ULONGLONG LoaderSize; + BOOLEAN BootServices; INT_PTR SecureBoot; - CPPORT SerialPort; } XTBL_STATUS, *PXTBL_STATUS; /* XT framebuffer video mode information structure definition */ @@ -361,8 +386,9 @@ typedef struct _XTBL_LOADER_PROTOCOL } Boot; struct { - PBL_BOOTUTIL_GET_BOOLEAN_PARAMETER GetBooleanParameter; - } BootUtil; + PBL_BOOTUTILS_GET_BOOLEAN_PARAMETER GetBooleanParameter; + PBL_BOOTUTILS_GET_TRAMPOLINE_INFORMATION GetTrampolineInformation; + } BootUtils; struct { PBL_CONFIG_GET_BOOLEAN_VALUE GetBooleanValue; @@ -386,6 +412,13 @@ typedef struct _XTBL_LOADER_PROTOCOL PBL_CONSOLE_WRITE Write; } Console; 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; } Debug; @@ -396,10 +429,27 @@ typedef struct _XTBL_LOADER_PROTOCOL PBL_READ_FILE ReadFile; } Disk; 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_POOL AllocatePool; PBL_BUILD_PAGE_MAP BuildPageMap; + PBL_COMPARE_MEMORY CompareMemory; PBL_COPY_MEMORY CopyMemory; PBL_FREE_PAGES FreePages; PBL_FREE_POOL FreePool; @@ -410,6 +460,7 @@ typedef struct _XTBL_LOADER_PROTOCOL PBL_MAP_EFI_MEMORY MapEfiMemory; PBL_MAP_PAGE MapPage; PBL_MAP_VIRTUAL_MEMORY MapVirtualMemory; + PBL_MOVE_MEMORY MoveMemory; PBL_PHYSICAL_ADDRESS_TO_VIRTUAL PhysicalAddressToVirtual; PBL_PHYSICAL_LIST_TO_VIRTUAL PhysicalListToVirtual; PBL_SET_MEMORY SetMemory; @@ -425,6 +476,13 @@ typedef struct _XTBL_LOADER_PROTOCOL PBL_OPEN_PROTOCOL_HANDLE OpenHandle; } Protocol; 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_INFO_DIALOG DisplayInfoDialog; @@ -448,7 +506,16 @@ typedef struct _XTBL_LOADER_PROTOCOL PBL_SLEEP_EXECUTION SleepExecution; PBL_START_EFI_IMAGE StartEfiImage; 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; #endif /* __XTDK_BLTYPES_H */ diff --git a/sdk/xtdk/exfuncs.h b/sdk/xtdk/exfuncs.h index 8928661..6c42959 100644 --- a/sdk/xtdk/exfuncs.h +++ b/sdk/xtdk/exfuncs.h @@ -14,26 +14,32 @@ /* Kernel Executive routines forward references */ +XTCLINK XTFASTCALL BOOLEAN ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor); +XTCLINK XTFASTCALL VOID ExCompleteRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor); +XTCLINK XTFASTCALL VOID ExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor); +XTCLINK XTFASTCALL VOID ExReInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor); +XTCLINK XTFASTCALL VOID ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor); +XTCLINK XTFASTCALL VOID ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor); diff --git a/sdk/xtdk/hlfuncs.h b/sdk/xtdk/hlfuncs.h index 43de6a4..87e9abe 100644 --- a/sdk/xtdk/hlfuncs.h +++ b/sdk/xtdk/hlfuncs.h @@ -14,16 +14,38 @@ #include -/* Routines used by XTLDR */ -XTCDECL -XTSTATUS -HlComPortPutByte(IN PCPPORT Port, - IN UCHAR Byte); +/* Hardware layer routines forward references */ +XTCLINK +XTAPI +UCHAR +HlReadRegister8(IN PVOID Register); -XTCDECL -XTSTATUS -HlInitializeComPort(IN OUT PCPPORT Port, - IN PUCHAR PortAddress, - IN ULONG BaudRate); +XTCLINK +XTAPI +USHORT +HlReadRegister16(IN PVOID Register); + +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 */ diff --git a/sdk/xtdk/i686/arfuncs.h b/sdk/xtdk/i686/arfuncs.h deleted file mode 100644 index 8c48bb5..0000000 --- a/sdk/xtdk/i686/arfuncs.h +++ /dev/null @@ -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 - */ - -#ifndef __XTDK_I686_ARFUNCS_H -#define __XTDK_I686_ARFUNCS_H - -#include -#include -#include -#include - - -/* 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 */ diff --git a/sdk/xtdk/i686/artypes.h b/sdk/xtdk/i686/artypes.h index 0c4da8b..f3b5b73 100644 --- a/sdk/xtdk/i686/artypes.h +++ b/sdk/xtdk/i686/artypes.h @@ -384,4 +384,10 @@ typedef struct _CPUID_SIGNATURE ULONG Unused2:4; } CPU_SIGNATURE, *PCPU_SIGNATURE; +/* Trampoline types */ +typedef enum _TRAMPOLINE_TYPE +{ + TrampolineApStartup +} TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE; + #endif /* __XTDK_I686_ARTYPES_H */ diff --git a/sdk/xtdk/i686/hlfuncs.h b/sdk/xtdk/i686/hlfuncs.h index dfc35ac..34d2216 100644 --- a/sdk/xtdk/i686/hlfuncs.h +++ b/sdk/xtdk/i686/hlfuncs.h @@ -15,32 +15,38 @@ #include -/* HAL library routines forward references */ +/* Hardware layer routines forward references */ +XTCLINK XTCDECL UCHAR -HlIoPortInByte(IN USHORT Port); - -XTCDECL -ULONG -HlIoPortInLong(IN USHORT Port); +HlReadPort8(IN USHORT Port); +XTCLINK XTCDECL USHORT -HlIoPortInShort(IN USHORT Port); +HlReadPort16(IN USHORT Port); +XTCLINK +XTCDECL +ULONG +HlReadPort32(IN USHORT Port); + +XTCLINK XTCDECL VOID -HlIoPortOutByte(IN USHORT Port, - IN UCHAR Data); +HlWritePort8(IN USHORT Port, + IN UCHAR Data); +XTCLINK XTCDECL VOID -HlIoPortOutLong(IN USHORT Port, - IN ULONG Value); +HlWritePort16(IN USHORT Port, + IN USHORT Value); +XTCLINK XTCDECL VOID -HlIoPortOutShort(IN USHORT Port, - IN USHORT Value); +HlWritePort32(IN USHORT Port, + IN ULONG Value); #endif /* __XTDK_I686_HLFUNCS_H */ diff --git a/sdk/xtdk/i686/ketypes.h b/sdk/xtdk/i686/ketypes.h index be1feba..fc5df51 100644 --- a/sdk/xtdk/i686/ketypes.h +++ b/sdk/xtdk/i686/ketypes.h @@ -144,8 +144,8 @@ #define KERNEL_STACK_GUARD_PAGES 1 /* Processor structures size */ -#define KPROCESSOR_STRUCTURES_SIZE ((2 * KERNEL_STACK_SIZE) + sizeof(ArInitialGdt) + sizeof(ArInitialTss) + \ - sizeof(ArInitialProcessorBlock) + MM_PAGE_SIZE) +#define KPROCESSOR_STRUCTURES_SIZE ((2 * KERNEL_STACK_SIZE) + (GDT_ENTRIES * sizeof(KGDTENTRY)) + sizeof(KTSS) + \ + sizeof(KPROCESSOR_BLOCK) + MM_PAGE_SIZE) /* Kernel frames */ #define KTRAP_FRAME_ALIGN 0x08 diff --git a/sdk/xtdk/i686/xtstruct.h b/sdk/xtdk/i686/xtstruct.h index a3162c8..2f034d9 100644 --- a/sdk/xtdk/i686/xtstruct.h +++ b/sdk/xtdk/i686/xtstruct.h @@ -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_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 _TRAMPOLINE_TYPE TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE; /* Architecture-specific structures forward references */ typedef struct _CONTEXT CONTEXT, *PCONTEXT; diff --git a/sdk/xtdk/kdfuncs.h b/sdk/xtdk/kdfuncs.h new file mode 100644 index 0000000..3274c14 --- /dev/null +++ b/sdk/xtdk/kdfuncs.h @@ -0,0 +1,23 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: sdk/xtdk/kdfuncs.h + * DESCRIPTION: XTOS kernel debugger routine definitions + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTDK_KDFUNCS_H +#define __XTDK_KDFUNCS_H + +#include +#include + + +/* Kernel debugger routines forward references */ +XTCLINK +XTCDECL +VOID +DbgPrint(PCWSTR Format, + ...); + +#endif /* __XTDK_KDFUNCS_H */ diff --git a/sdk/xtdk/kefuncs.h b/sdk/xtdk/kefuncs.h index 3dbb8ea..a531b72 100644 --- a/sdk/xtdk/kefuncs.h +++ b/sdk/xtdk/kefuncs.h @@ -16,36 +16,44 @@ /* Kernel services routines forward references */ +XTCLINK XTFASTCALL VOID KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel); +XTCLINK XTFASTCALL VOID KeAcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock); +XTCLINK XTAPI XTSTATUS KeAcquireSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader); +XTCLINK XTAPI BOOLEAN KeCancelTimer(IN PKTIMER Timer); +XTCLINK XTFASTCALL KRUNLEVEL KeGetCurrentRunLevel(VOID); +XTCLINK XTAPI XTSTATUS KeGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader); +XTCLINK XTAPI BOOLEAN KeGetTimerState(IN PKTIMER Timer); +XTCLINK XTAPI VOID KeInitializeApc(IN PKAPC Apc, @@ -57,45 +65,54 @@ KeInitializeApc(IN PKAPC Apc, IN KPROCESSOR_MODE ApcMode, IN PVOID Context); +XTCLINK XTAPI VOID KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DpcRoutine, IN PVOID DpcContext); +XTCLINK XTAPI VOID KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, IN LONG Count, IN LONG Limit); +XTCLINK XTAPI VOID KeInitializeSpinLock(IN PKSPIN_LOCK SpinLock); +XTCLINK XTAPI VOID KeInitializeThreadedDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DpcRoutine, IN PVOID DpcContext); +XTCLINK XTAPI VOID KeInitializeTimer(OUT PKTIMER Timer, IN KTIMER_TYPE Type); +XTCLINK XTFASTCALL VOID KeLowerRunLevel(IN KRUNLEVEL RunLevel); +XTCLINK XTFASTCALL KRUNLEVEL KeRaiseRunLevel(IN KRUNLEVEL RunLevel); +XTCLINK XTAPI LONG KeReadSemaphoreState(IN PKSEMAPHORE Semaphore); +XTCLINK XTAPI LONG KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, @@ -103,23 +120,28 @@ KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN LONG Adjustment, IN BOOLEAN Wait); +XTCLINK XTFASTCALL VOID KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel); +XTCLINK XTFASTCALL VOID KeReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock); +XTCLINK XTAPI VOID KeReleaseSystemResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader); +XTCLINK XTAPI VOID KeSetTargetProcessorDpc(IN PKDPC Dpc, IN CCHAR Number); +XTCLINK XTAPI VOID KeSetTimer(IN PKTIMER Timer, @@ -127,10 +149,12 @@ KeSetTimer(IN PKTIMER Timer, IN LONG Period, IN PKDPC Dpc); +XTCLINK XTAPI VOID KeSignalCallDpcDone(IN PVOID SystemArgument); +XTCLINK XTAPI BOOLEAN KeSignalCallDpcSynchronize(IN PVOID SystemArgument); diff --git a/sdk/xtdk/rtlfuncs.h b/sdk/xtdk/rtlfuncs.h index 3773663..2dee67c 100644 --- a/sdk/xtdk/rtlfuncs.h +++ b/sdk/xtdk/rtlfuncs.h @@ -15,326 +15,356 @@ #include -/* Routines used by XTLDR */ -XTCDECL -VOID -RtlInitializeListHead(IN PLIST_ENTRY ListHead); - -XTCDECL -VOID -RtlInsertHeadList(IN OUT PLIST_ENTRY ListHead, - IN PLIST_ENTRY Entry); - -XTCDECL -VOID -RtlInsertTailList(IN OUT PLIST_ENTRY ListHead, - IN PLIST_ENTRY Entry); - -XTAPI -UCHAR -RtlReadRegisterByte(IN VOLATILE PVOID Register); - -XTAPI -ULONG -RtlReadRegisterLong(IN VOLATILE PVOID Register); - -XTAPI -USHORT -RtlReadRegisterShort(IN VOLATILE PVOID Register); - - -XTCDECL -VOID -RtlRemoveEntryList(IN PLIST_ENTRY Entry); - - /* Runtime Library routines forward references */ +XTCLINK XTAPI VOID RtlClearAllBits(IN PRTL_BITMAP BitMap); +XTCLINK XTAPI VOID RtlClearBit(IN PRTL_BITMAP BitMap, IN ULONG_PTR Bit); +XTCLINK XTAPI VOID RtlClearBits(IN PRTL_BITMAP BitMap, IN ULONG_PTR StartingIndex, IN ULONG_PTR Length); +XTCLINK XTAPI ULONG RtlClearSetBits(IN PRTL_BITMAP BitMap, IN ULONG_PTR Length, IN ULONG_PTR Index); +XTCLINK XTAPI BOOLEAN RtlCompareGuids(IN PGUID Guid1, IN PGUID Guid2); +XTCLINK XTAPI SIZE_T RtlCompareMemory(IN PCVOID LeftBuffer, IN PCVOID RightBuffer, IN SIZE_T Length); +XTCLINK XTAPI SIZE_T RtlCompareString(IN PCSTR String1, IN PCSTR String2, IN SIZE_T Length); +XTCLINK XTAPI SIZE_T RtlCompareStringInsensitive(IN PCSTR String1, IN PCSTR String2, IN SIZE_T Length); +XTCLINK XTAPI SIZE_T RtlCompareWideString(IN PCWSTR String1, IN PCWSTR String2, IN SIZE_T Length); +XTCLINK XTAPI SIZE_T RtlCompareWideStringInsensitive(IN PCWSTR String1, IN PCWSTR String2, IN SIZE_T Length); +XTCLINK XTAPI PCHAR RtlConcatenateString(OUT PCHAR Destination, IN PCHAR Source, IN SIZE_T Count); +XTCLINK XTAPI PWCHAR RtlConcatenateWideString(OUT PWCHAR Destination, IN PWCHAR Source, IN SIZE_T Count); +XTCLINK XTAPI LARGE_INTEGER RtlConvertToLargeInteger32(IN LONG Value); +XTCLINK XTAPI LARGE_INTEGER RtlConvertToLargeIntegerUnsigned32(IN ULONG Value); +XTCLINK XTAPI VOID RtlCopyMemory(OUT PVOID Destination, IN PCVOID Source, IN SIZE_T Length); +XTCLINK XTAPI VOID RtlCopyString(IN PCHAR Destination, IN PCSTR Source, IN ULONG Length); +XTCLINK XTAPI VOID RtlCopyWideString(IN PWCHAR Destination, IN PCWSTR Source, IN ULONG Length); +XTCLINK XTAPI LARGE_INTEGER RtlDivideLargeInteger(IN LARGE_INTEGER Dividend, IN ULONG Divisor, OUT PULONG Remainder); +XTCLINK XTAPI ULONG_PTR RtlFindClearBits(IN PRTL_BITMAP BitMap, IN ULONG_PTR Length, IN ULONG_PTR Index); +XTCLINK XTAPI ULONG_PTR RtlFindSetBits(IN PRTL_BITMAP BitMap, IN ULONG_PTR Length, IN ULONG_PTR Index); +XTCLINK XTAPI PCSTR RtlFindString(IN PCSTR Source, IN PCSTR Search); +XTCLINK XTAPI PCSTR RtlFindStringInsensitive(IN PCSTR Source, IN PCSTR Search); +XTCLINK XTAPI PCWSTR RtlFindWideString(IN PCWSTR Source, IN PCWSTR Search); +XTCLINK XTAPI PCWSTR RtlFindWideStringInsensitive(IN PCWSTR Source, IN PCWSTR Search); -XTAPI -XTSTATUS -RtlFormatWideString(IN PRTL_PRINT_CONTEXT Context, - IN PCWSTR Format, - IN VA_LIST ArgumentList); - +XTCLINK XTAPI VOID RtlInitializeBitMap(IN PRTL_BITMAP BitMap, IN PULONG_PTR Buffer, IN ULONG Size); +XTCLINK +XTCDECL +VOID +RtlInitializeListHead(IN PLIST_ENTRY ListHead); + +XTCLINK +XTCDECL +VOID +RtlInsertHeadList(IN OUT PLIST_ENTRY ListHead, + IN PLIST_ENTRY Entry); + +XTCLINK +XTCDECL +VOID +RtlInsertTailList(IN OUT PLIST_ENTRY ListHead, + IN PLIST_ENTRY Entry); + +XTCLINK +XTCDECL +BOOLEAN +RtlListEmpty(IN PLIST_ENTRY ListHead); + +XTCLINK +XTCDECL +BOOLEAN +RtlListLoop(IN PLIST_ENTRY ListHead); + +XTCLINK XTAPI VOID RtlMoveMemory(OUT PVOID Destination, IN PCVOID Source, IN SIZE_T Length); +XTCLINK XTAPI LARGE_INTEGER RtlMultiplyLargeInteger(IN LARGE_INTEGER Multiplicand, IN LONG Multiplier); +XTCLINK +XTCDECL +VOID +RtlRemoveEntryList(IN PLIST_ENTRY Entry); + +XTCLINK XTAPI VOID RtlReverseString(IN OUT PCHAR String, IN ULONG Length); +XTCLINK XTAPI VOID RtlReverseWideString(IN OUT PWCHAR String, IN ULONG Length); +XTCLINK XTAPI BOOLEAN RtlSameMemory(IN PCVOID LeftBuffer, IN PCVOID RightBuffer, IN SIZE_T Length); +XTCLINK XTAPI VOID RtlSetAllBits(IN PRTL_BITMAP BitMap); +XTCLINK XTAPI VOID RtlSetBit(IN PRTL_BITMAP BitMap, IN ULONG_PTR Bit); +XTCLINK XTAPI VOID RtlSetBits(IN PRTL_BITMAP BitMap, IN ULONG_PTR StartingIndex, IN ULONG_PTR Length); +XTCLINK XTAPI ULONG RtlSetClearBits(IN PRTL_BITMAP BitMap, IN ULONG_PTR Length, IN ULONG_PTR Index); +XTCLINK XTAPI VOID RtlSetMemory(OUT PVOID Destination, IN UCHAR Byte, IN SIZE_T Length); +XTCLINK XTAPI SIZE_T RtlStringLength(IN PCSTR String, IN SIZE_T MaxLength); +XTCLINK XTAPI SIZE_T RtlStringToWideString(OUT PWCHAR Destination, IN PCSTR *Source, IN SIZE_T Length); +XTCLINK XTAPI BOOLEAN RtlTestBit(IN PRTL_BITMAP BitMap, IN ULONG_PTR Bit); +XTCLINK XTAPI PCHAR RtlTokenizeString(IN PCHAR String, IN PCSTR Delimiter, IN OUT PCHAR *SavePtr); +XTCLINK XTAPI PWCHAR RtlTokenizeWideString(IN PWCHAR String, IN PCWSTR Delimiter, IN OUT PWCHAR *SavePtr); +XTCLINK XTAPI CHAR RtlToLowerCharacter(IN CHAR Character); +XTCLINK XTAPI WCHAR RtlToLowerWideCharacter(IN WCHAR Character); +XTCLINK XTAPI CHAR RtlToUpperCharacter(IN CHAR Character); +XTCLINK XTAPI WCHAR RtlToUpperWideCharacter(IN WCHAR Character); +XTCLINK XTAPI PCHAR RtlTrimLeftString(IN PCHAR String); +XTCLINK XTAPI PWCHAR RtlTrimLeftWideString(IN PWCHAR String); +XTCLINK XTAPI PCHAR RtlTrimRightString(IN PCHAR String); +XTCLINK XTAPI PWCHAR RtlTrimRightWideString(IN PWCHAR String); +XTCLINK XTAPI PCHAR RtlTrimString(IN PCHAR String); +XTCLINK XTAPI PWCHAR RtlTrimWideString(IN PWCHAR String); +XTCLINK XTAPI SIZE_T RtlWideStringLength(IN PCWSTR String, IN SIZE_T MaxLength); -XTAPI -VOID -RtlWriteRegisterByte(IN VOLATILE PVOID Register, - IN UCHAR Value); - -XTAPI -VOID -RtlWriteRegisterLong(IN VOLATILE PVOID Register, - IN ULONG Value); - -XTAPI -VOID -RtlWriteRegisterShort(IN VOLATILE PVOID Register, - IN USHORT Value); - +XTCLINK XTAPI VOID RtlZeroMemory(OUT PVOID Destination, diff --git a/sdk/xtdk/rtltypes.h b/sdk/xtdk/rtltypes.h index 5c9dce6..505f1e6 100644 --- a/sdk/xtdk/rtltypes.h +++ b/sdk/xtdk/rtltypes.h @@ -56,17 +56,17 @@ typedef XTSTATUS (*PWRITE_WIDE_CHARACTER)(IN WCHAR Character); /* Variable types enumeration list */ typedef enum _RTL_VARIABLE_TYPE { - Unknown, - AnsiString, - Boolean, - Char, - Float, - Guid, - Integer, - String, - UnicodeString, - WideChar, - WideString + TypeUnknown, + TypeAnsiString, + TypeBoolean, + TypeChar, + TypeFloat, + TypeGuid, + TypeInteger, + TypeString, + TypeUnicodeString, + TypeWideChar, + TypeWideString } RTL_VARIABLE_TYPE, *PRTL_VARIABLE_TYPE; /* Bit Map structure definition */ diff --git a/sdk/xtdk/xtblapi.h b/sdk/xtdk/xtblapi.h index 5d00676..574c03a 100644 --- a/sdk/xtdk/xtblapi.h +++ b/sdk/xtdk/xtblapi.h @@ -7,6 +7,7 @@ */ /* Base XT headers */ +#include #include #include #include @@ -37,14 +38,6 @@ #include ARCH_HEADER(ketypes.h) #include ARCH_HEADER(mmtypes.h) -/* XT Kernel runtime routines */ -#include -#include - -/* Architecture specific XT kernel routines */ -#include ARCH_HEADER(arfuncs.h) -#include ARCH_HEADER(hlfuncs.h) - /* Boot Manager specific structures */ #include #include diff --git a/sdk/xtdk/xtcompat.h b/sdk/xtdk/xtcompat.h new file mode 100644 index 0000000..27544d5 --- /dev/null +++ b/sdk/xtdk/xtcompat.h @@ -0,0 +1,41 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: sdk/xtdk/xtcompat.h + * DESCRIPTION: C/C++ compatibility macros + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTDK_XTCOMPAT_H +#define __XTDK_XTCOMPAT_H + + +#ifdef __cplusplus + /* C++ definitions */ + #define XTCLINK extern "C" + #define NULLPTR nullptr + + /* C++ boolean type */ + typedef bool BOOLEAN, *PBOOLEAN; + #define TRUE true + #define FALSE false + + /* C++ widechar type */ + typedef wchar_t wchar; +#else + /* C definitions */ + #define XTCLINK + #define NULLPTR ((void *)0) + + /* C boolean type */ + typedef enum _BOOLEAN + { + FALSE = 0, + TRUE = 1 + } BOOLEAN, *PBOOLEAN; + + /* C widechar type */ + typedef unsigned short wchar; +#endif + +#endif /* __XTDK_XTCOMPAT_H */ diff --git a/sdk/xtdk/xtdebug.h b/sdk/xtdk/xtdebug.h index be4681a..862b658 100644 --- a/sdk/xtdk/xtdebug.h +++ b/sdk/xtdk/xtdebug.h @@ -13,14 +13,14 @@ /* Debugging macros */ #define CHECKPOINT DebugPrint(L"Checkpoint reached at %s:%d\n", __RELFILE__, __LINE__); #define DEPRECATED DebugPrint(L"Called deprecated routine '%s()' at %s:%d\n", \ - __FUNCTION__, __RELFILE__, __LINE__); + __FUNCTION__, __RELFILE__, __LINE__); #define UNIMPLEMENTED DebugPrint(L"Called unimplemented routine '%s()' at %s:%d\n", \ - __FUNCTION__, __RELFILE__, __LINE__); + __FUNCTION__, __RELFILE__, __LINE__); /* XTOS platform debugging macros */ #ifdef DBG #define DEBUG 1 - #define DebugPrint(Format, ...) if(KdPrint) KdPrint(Format, __VA_ARGS__); + #define DebugPrint(Format, ...) DbgPrint(Format, __VA_ARGS__); #else #define DEBUG 0 #define DebugPrint(Format, ...) ((VOID)NULL) diff --git a/sdk/xtdk/xtdefs.h b/sdk/xtdk/xtdefs.h index 1f1a57a..7faae86 100644 --- a/sdk/xtdk/xtdefs.h +++ b/sdk/xtdk/xtdefs.h @@ -29,10 +29,6 @@ #define UNION union #define VOLATILE volatile -/* NULL values */ -#define NULL ((PVOID) 0) -#define NULL64 ((VOID * PVOID) 0) - /* Type limits */ #define MINCHAR 0x80 #define MAXCHAR 0x7F diff --git a/sdk/xtdk/xtkmapi.h b/sdk/xtdk/xtkmapi.h index d03d602..e6cd9a1 100644 --- a/sdk/xtdk/xtkmapi.h +++ b/sdk/xtdk/xtkmapi.h @@ -7,6 +7,7 @@ */ /* Base XT headers */ +#include #include #include #include @@ -47,9 +48,9 @@ /* XT routines */ #include #include +#include #include #include /* Architecture specific XT routines */ -#include ARCH_HEADER(arfuncs.h) #include ARCH_HEADER(hlfuncs.h) diff --git a/sdk/xtdk/xtstruct.h b/sdk/xtdk/xtstruct.h index d004635..62fa2f8 100644 --- a/sdk/xtdk/xtstruct.h +++ b/sdk/xtdk/xtstruct.h @@ -14,7 +14,6 @@ /* Enumeration lists forward references */ typedef enum _ADJUST_REASON ADJUST_REASON, *PADJUST_REASON; -typedef enum _BOOLEAN BOOLEAN, *PBOOLEAN; typedef enum _EXCEPTION_DISPOSITION EXCEPTION_DISPOSITION, *PEXCEPTION_DISPOSITION; typedef enum _EFI_ALLOCATE_TYPE EFI_ALLOCATE_TYPE, *PEFI_ALLOCATE_TYPE; typedef enum _EFI_FRAMEWORK_CPU_DESIGNATION EFI_FRAMEWORK_CPU_DESIGNATION, *PEFI_FRAMEWORK_CPU_DESIGNATION; @@ -52,6 +51,7 @@ typedef enum _LOADER_MEMORY_TYPE LOADER_MEMORY_TYPE, *PLOADER_MEMORY_TYPE; typedef enum _MODE MODE, *PMODE; typedef enum _RTL_VARIABLE_TYPE RTL_VARIABLE_TYPE, *PRTL_VARIABLE_TYPE; typedef enum _SYSTEM_FIRMWARE_TYPE SYSTEM_FIRMWARE_TYPE, *PSYSTEM_FIRMWARE_TYPE; +typedef enum _SYSTEM_RESOURCE_TYPE SYSTEM_RESOURCE_TYPE, *PSYSTEM_RESOURCE_TYPE; typedef enum _WAIT_TYPE WAIT_TYPE, *PWAIT_TYPE; /* Structures forward references */ diff --git a/sdk/xtdk/xttypes.h b/sdk/xtdk/xttypes.h index 7bf5071..5d994b7 100644 --- a/sdk/xtdk/xttypes.h +++ b/sdk/xtdk/xttypes.h @@ -10,6 +10,7 @@ #define __XTDK_XTTYPES_H #include +#include /* Standard C types */ @@ -128,7 +129,7 @@ typedef CHAR SZ, *PSZ; typedef const CHAR CSZ, *PCSZ; /* UNICODE character types */ -typedef USHORT WCHAR, *PWCHAR; +typedef wchar WCHAR, *PWCHAR; typedef WCHAR *PWCH, *LPWCH; typedef const WCHAR *PCWCH, *LPCWCH; typedef WCHAR *PWSTR, *LPWSTR, *NWPSTR; @@ -149,13 +150,6 @@ typedef LPCWSTR PCTSTR, LPCTSTR; typedef LPUWSTR PUTSTR, LPUTSTR; typedef LPCUWSTR PCUTSTR, LPCUTSTR; -/* Boolean type */ -typedef enum _BOOLEAN -{ - FALSE = 0, - TRUE = 1 -} BOOLEAN, *PBOOLEAN; - /* 128-bit floats structure */ typedef struct _FLOAT128 { diff --git a/sdk/xtdk/xtuefi.h b/sdk/xtdk/xtuefi.h index 9aa21d2..1f873d3 100644 --- a/sdk/xtdk/xtuefi.h +++ b/sdk/xtdk/xtuefi.h @@ -356,6 +356,7 @@ #define EFI_RNG_PROTOCOL_GUID {0x3152BCA5, 0xEADE, 0x433D, {0x86, 0x2E, 0xC0, 0x1C, 0xDC, 0x29, 0x1F, 0x44}} #define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID {0x964E5B22, 0x6459, 0x11D2, {0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}} #define EFI_SIMPLE_NETWORK_PROTOCOL_GUID {0xA19832B9, 0xAC25, 0x11D3, {0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}} +#define EFI_SIMPLE_POINTER_PROTOCOL_GUID {0x31878C87, 0x0B75, 0x11D5, {0x9A, 0x4F, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}} #define EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID {0x387477C1, 0x69C7, 0x11D2, {0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}} #define EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID {0xDD9E7534, 0x7762, 0x4698, {0x8C, 0x14, 0xF5, 0x85, 0x17, 0xA6, 0x25, 0xAA}} #define EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID {0x387477C2, 0x69C7, 0x11D2, {0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}} @@ -634,9 +635,9 @@ typedef EFI_STATUS (*PEFI_FREE_POOL)(IN PVOID Buffer); typedef VOID (*PEFI_EVENT_NOTIFY)(IN EFI_EVENT Event, IN PVOID Context); typedef EFI_STATUS (*PEFI_CREATE_EVENT)(IN UINT32 Type, IN EFI_TPL NotifyTpl, IN PEFI_EVENT_NOTIFY NotifyFunction, IN PVOID NotifyContext, OUT PEFI_EVENT Event); typedef EFI_STATUS (*PEFI_GET_MEMORY_MAP)(IN OUT PUINT_PTR MemoryMapSize, IN OUT PEFI_MEMORY_DESCRIPTOR MemoryMap, OUT PUINT_PTR MapKey, OUT PUINT_PTR DescriptorSize, OUT PUINT32 DescriptorVersion); -typedef EFI_STATUS (*PEFI_GET_VARIABLE)(IN PUINT16 VariableName, IN PEFI_GUID VendorGuid, OUT PUINT32 Attributes, IN OUT PUINT_PTR DataSize, OUT PVOID Data); +typedef EFI_STATUS (*PEFI_GET_VARIABLE)(IN PWCHAR VariableName, IN PEFI_GUID VendorGuid, OUT PUINT32 Attributes, IN OUT PUINT_PTR DataSize, OUT PVOID Data); typedef EFI_STATUS (*PEFI_GET_NEXT_HIGH_MONO_COUNT)(OUT PUINT32 HighCount); -typedef EFI_STATUS (*PEFI_GET_NEXT_VARIABLE_NAME)(IN OUT PUINT_PTR VariableNameSize, IN OUT PUINT16 VariableName, IN OUT PEFI_GUID VendorGuid); +typedef EFI_STATUS (*PEFI_GET_NEXT_VARIABLE_NAME)(IN OUT PUINT_PTR VariableNameSize, IN OUT PWCHAR VariableName, IN OUT PEFI_GUID VendorGuid); typedef EFI_STATUS (*PEFI_GET_TIME)(OUT PEFI_TIME Time, OUT PEFI_TIME_CAPABILITIES Capabilities); typedef EFI_STATUS (*PEFI_SET_TIME)(IN PEFI_TIME Time); typedef EFI_STATUS (*PEFI_SET_TIMER)(IN EFI_EVENT Event, IN EFI_TIMER_DELAY Type, IN UINT64 TriggerTime); @@ -648,13 +649,13 @@ typedef EFI_STATUS (*PEFI_WAIT_FOR_EVENT)(IN UINT_PTR NumberOfEvents, IN PEFI_EV typedef EFI_STATUS (*PEFI_QUERY_CAPSULE_CAPABILITIES)(IN PEFI_CAPSULE_HEADER *CapsuleHeaderArray, IN UINT_PTR CapsuleCount, OUT PUINT64 MaximumCapsuleSize, OUT PEFI_RESET_TYPE ResetType); typedef EFI_STATUS (*PEFI_QUERY_VARIABLE_INFO)(IN UINT32 Attributes, OUT PUINT64 MaximumVariableStorageSize, OUT PUINT64 RemainingVariableStorageSize, OUT PUINT64 MaximumVariableSize); typedef EFI_STATUS (*PEFI_RAISE_TPL)(IN EFI_TPL NewTpl); -typedef EFI_STATUS (*PEFI_RESET_SYSTEM)(IN EFI_RESET_TYPE ResetType, IN EFI_STATUS ResetStatus, IN UINT_PTR DataSize, IN PUINT16 ResetData); +typedef EFI_STATUS (*PEFI_RESET_SYSTEM)(IN EFI_RESET_TYPE ResetType, IN EFI_STATUS ResetStatus, IN UINT_PTR DataSize, IN PWCHAR ResetData); typedef EFI_STATUS (*PEFI_RESTORE_TPL)(IN EFI_TPL OldTpl); typedef EFI_STATUS (*PEFI_UPDATE_CAPSULE)(IN PEFI_CAPSULE_HEADER *CapsuleHeaderArray, IN UINT_PTR CapsuleCount, IN EFI_PHYSICAL_ADDRESS ScatterGatherList); -typedef EFI_STATUS (*PEFI_SET_VARIABLE)(IN PUINT16 VariableName, IN PEFI_GUID VendorGuid, IN UINT32 Attributes, IN UINT_PTR DataSize, IN PVOID Data); +typedef EFI_STATUS (*PEFI_SET_VARIABLE)(IN PWCHAR VariableName, IN PEFI_GUID VendorGuid, IN UINT32 Attributes, IN UINT_PTR DataSize, IN PVOID Data); typedef EFI_STATUS (*PEFI_SET_VIRTUAL_ADDRESS_MAP)(IN UINT_PTR MemoryMapSize, IN UINT_PTR DescriptorSize, IN UINT32 DescriptorVersion, IN PEFI_MEMORY_DESCRIPTOR VirtualMap); -typedef EFI_STATUS (*PEFI_GET_WAKEUP_TIME)(OUT UCHAR Enabled, OUT UCHAR Pending, OUT PEFI_TIME Time); -typedef EFI_STATUS (*PEFI_SET_WAKEUP_TIME)(IN UCHAR Enable, IN PEFI_TIME Time); +typedef EFI_STATUS (*PEFI_GET_WAKEUP_TIME)(OUT BOOLEAN Enabled, OUT BOOLEAN Pending, OUT PEFI_TIME Time); +typedef EFI_STATUS (*PEFI_SET_WAKEUP_TIME)(IN BOOLEAN Enable, IN PEFI_TIME Time); typedef EFI_STATUS (*PEFI_INSTALL_PROTOCOL_INTERFACE)(IN OUT PEFI_HANDLE Handle, IN PEFI_GUID Protocol, IN EFI_INTERFACE_TYPE InterfaceType, IN PVOID Interface); typedef EFI_STATUS (*PEFI_REINSTALL_PROTOCOL_INTERFACE)(IN EFI_HANDLE Handle, IN PEFI_GUID Protocol, IN PVOID OldInterface, IN PVOID NewInterface); typedef EFI_STATUS (*PEFI_UNINSTALL_PROTOCOL_INTERFACE)(IN EFI_HANDLE Handle, IN PEFI_GUID Protocol, IN PVOID Interface); @@ -665,15 +666,15 @@ typedef EFI_STATUS (*PEFI_LOCATE_DEVICE_PATH)(IN PEFI_GUID Protocol, IN OUT PEFI typedef EFI_STATUS (*PEFI_LOCATE_HANDLE_BUFFER)(IN EFI_LOCATE_SEARCH_TYPE SearchType, IN PEFI_GUID Protocol, IN PVOID SearchKey, IN OUT PUINT_PTR NoHandles, OUT PEFI_HANDLE *Buffer); typedef EFI_STATUS (*PEFI_LOCATE_PROTOCOL)(IN PEFI_GUID Protocol, IN PVOID Registration, OUT PVOID *Interface); typedef EFI_STATUS (*PEFI_INSTALL_CONFIGURATION_TABLE)(IN PEFI_GUID Guid, IN PVOID Table); -typedef EFI_STATUS (*PEFI_IMAGE_LOAD)(IN UCHAR BootPolicy, IN EFI_HANDLE ParentImageHandle, IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, IN PVOID SourceBuffer, IN UINT_PTR SourceSize, OUT PEFI_HANDLE ImageHandle); +typedef EFI_STATUS (*PEFI_IMAGE_LOAD)(IN BOOLEAN BootPolicy, IN EFI_HANDLE ParentImageHandle, IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, IN PVOID SourceBuffer, IN UINT_PTR SourceSize, OUT PEFI_HANDLE ImageHandle); typedef EFI_STATUS (*PEFI_IMAGE_UNLOAD)(IN EFI_HANDLE ImageHandle); -typedef EFI_STATUS (*PEFI_IMAGE_START)(IN EFI_HANDLE ImageHandle, OUT PUINT_PTR ExitDataSize, OUT PUINT16 *ExitData); -typedef EFI_STATUS (*PEFI_EXIT)(IN EFI_HANDLE ImageHandle, IN EFI_STATUS ExitStatus, IN UINT_PTR ExitDataSize, IN PUINT16 ExitData); +typedef EFI_STATUS (*PEFI_IMAGE_START)(IN EFI_HANDLE ImageHandle, OUT PUINT_PTR ExitDataSize, OUT PWCHAR *ExitData); +typedef EFI_STATUS (*PEFI_EXIT)(IN EFI_HANDLE ImageHandle, IN EFI_STATUS ExitStatus, IN UINT_PTR ExitDataSize, IN PWCHAR ExitData); typedef EFI_STATUS (*PEFI_EXIT_BOOT_SERVICES)(IN EFI_HANDLE ImageHandle, IN UINT_PTR MapKey); typedef EFI_STATUS (*PEFI_GET_NEXT_MONOTONIC_COUNT)(OUT PUINT64 Count); typedef EFI_STATUS (*PEFI_STALL)(IN UINT_PTR Microseconds); -typedef EFI_STATUS (*PEFI_SET_WATCHDOG_TIMER)(IN UINT_PTR Timeout, IN UINT64 WatchdogCode, IN UINT_PTR DataSize, IN PUINT16 WatchdogData); -typedef EFI_STATUS (*PEFI_CONNECT_CONTROLLER)(IN EFI_HANDLE ControllerHandle, IN PEFI_HANDLE DriverImageHandle, IN PEFI_DEVICE_PATH_PROTOCOL RemainingDevicePath, IN UCHAR Recursive); +typedef EFI_STATUS (*PEFI_SET_WATCHDOG_TIMER)(IN UINT_PTR Timeout, IN UINT64 WatchdogCode, IN UINT_PTR DataSize, IN PWCHAR WatchdogData); +typedef EFI_STATUS (*PEFI_CONNECT_CONTROLLER)(IN EFI_HANDLE ControllerHandle, IN PEFI_HANDLE DriverImageHandle, IN PEFI_DEVICE_PATH_PROTOCOL RemainingDevicePath, IN BOOLEAN Recursive); typedef EFI_STATUS (*PEFI_DISCONNECT_CONTROLLER)(IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE DriverImageHandle, IN EFI_HANDLE ChildHandle); typedef EFI_STATUS (*PEFI_OPEN_PROTOCOL)(IN EFI_HANDLE Handle, IN PEFI_GUID Protocol, OUT PVOID *Interface, IN EFI_HANDLE AgentHandle, IN EFI_HANDLE ControllerHandle, IN UINT32 Attributes); typedef EFI_STATUS (*PEFI_CLOSE_PROTOCOL)(IN EFI_HANDLE Handle, IN PEFI_GUID Protocol, IN EFI_HANDLE AgentHandle, IN EFI_HANDLE ControllerHandle); @@ -684,18 +685,18 @@ typedef EFI_STATUS (*PEFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES)(IN OUT PEFI_HA typedef EFI_STATUS (*PEFI_CALCULATE_CRC32)(IN PVOID Data, IN UINT_PTR DataSize, OUT PUINT32 Crc32); typedef EFI_STATUS (*PEFI_COPY_MEM)(IN OUT PVOID Destination, IN PVOID Source, IN UINT_PTR Length); typedef EFI_STATUS (*PEFI_SET_MEM)(IN OUT PVOID Buffer, IN UINT_PTR Size, IN UINT8 Value); -typedef EFI_STATUS (*PEFI_INPUT_RESET)(IN PEFI_SIMPLE_TEXT_INPUT_PROTOCOL This, IN UCHAR ExtendedVerification); +typedef EFI_STATUS (*PEFI_INPUT_RESET)(IN PEFI_SIMPLE_TEXT_INPUT_PROTOCOL This, IN BOOLEAN ExtendedVerification); typedef EFI_STATUS (*PEFI_INPUT_READ_KEY)(IN PEFI_SIMPLE_TEXT_INPUT_PROTOCOL This, OUT PEFI_INPUT_KEY Key); -typedef EFI_STATUS (*PEFI_TEXT_RESET)(IN PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL This, IN UCHAR ExtendedVerification); -typedef EFI_STATUS (*PEFI_TEXT_OUTPUT_STRING)(IN PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL This, IN PUINT16 String); -typedef EFI_STATUS (*PEFI_TEXT_TEST_STRING)(IN PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL This, IN PUINT16 String); +typedef EFI_STATUS (*PEFI_TEXT_RESET)(IN PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL This, IN BOOLEAN ExtendedVerification); +typedef EFI_STATUS (*PEFI_TEXT_OUTPUT_STRING)(IN PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL This, IN PWCHAR String); +typedef EFI_STATUS (*PEFI_TEXT_TEST_STRING)(IN PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL This, IN PWCHAR String); typedef EFI_STATUS (*PEFI_TEXT_QUERY_MODE)(IN PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL This, IN UINT_PTR ModeNumber, OUT PUINT_PTR Columns, OUT PUINT_PTR Rows); typedef EFI_STATUS (*PEFI_TEXT_SET_MODE)(IN PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL This, IN UINT_PTR ModeNumber); typedef EFI_STATUS (*PEFI_TEXT_SET_ATTRIBUTE)(IN PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL This, IN UINT_PTR Attribute); typedef EFI_STATUS (*PEFI_TEXT_CLEAR_SCREEN)(IN PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL This); typedef EFI_STATUS (*PEFI_TEXT_SET_CURSOR_POSITION)(IN PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL This, IN UINT_PTR Column, IN UINT_PTR Row); -typedef EFI_STATUS (*PEFI_TEXT_ENABLE_CURSOR)(IN PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL This, IN UCHAR Enable); -typedef EFI_STATUS (*PEFI_INPUT_RESET_EX)(IN PEFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL This, IN UCHAR ExtendedVerification); +typedef EFI_STATUS (*PEFI_TEXT_ENABLE_CURSOR)(IN PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL This, IN BOOLEAN Enable); +typedef EFI_STATUS (*PEFI_INPUT_RESET_EX)(IN PEFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL This, IN BOOLEAN ExtendedVerification); typedef EFI_STATUS (*PEFI_INPUT_READ_KEY_EX)(IN PEFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL This, OUT PEFI_KEY_DATA KeyData); typedef EFI_STATUS (*PEFI_SET_STATE)(IN PEFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL This, IN PUINT8 KeyToggleState); typedef EFI_STATUS (*PEFI_KEY_NOTIFY_FUNCTION)(IN PEFI_KEY_DATA KeyData); @@ -737,11 +738,11 @@ typedef EFI_STATUS (*EFI_PCI_IO_PROTOCOL_GET_BAR_ATTRIBUTES)(IN PEFI_PCI_IO_PROT typedef EFI_STATUS (*EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GET_ATTRIBUTES)(IN PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL This, OUT PUINT64 Supports, OUT PUINT64 Attributes); typedef EFI_STATUS (*EFI_PCI_IO_PROTOCOL_SET_BAR_ATTRIBUTES)(IN PEFI_PCI_IO_PROTOCOL This, IN UINT64 Attributes, IN UINT8 BarIndex, IN OUT PUINT64 Offset, IN OUT PUINT64 Length); typedef EFI_STATUS (*EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_SET_ATTRIBUTES)(IN PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL This, IN UINT64 Attributes, IN OUT PUINT64 ResourceBase, IN OUT PUINT64 ResourceLength); -typedef EFI_STATUS (*PEFI_BLOCK_RESET)(IN PEFI_BLOCK_IO_PROTOCOL This, IN UCHAR ExtendedVerification); +typedef EFI_STATUS (*PEFI_BLOCK_RESET)(IN PEFI_BLOCK_IO_PROTOCOL This, IN BOOLEAN ExtendedVerification); typedef EFI_STATUS (*PEFI_BLOCK_READ)(IN PEFI_BLOCK_IO_PROTOCOL This, IN UINT32 MediaId, IN EFI_LBA LBA, IN UINT_PTR BufferSize, OUT PVOID Buffer); typedef EFI_STATUS (*PEFI_BLOCK_WRITE)(IN PEFI_BLOCK_IO_PROTOCOL This, IN UINT32 MediaId, IN EFI_LBA LBA, IN UINT_PTR BufferSize, IN PVOID Buffer); typedef EFI_STATUS (*PEFI_BLOCK_FLUSH)(IN PEFI_BLOCK_IO_PROTOCOL This); -typedef EFI_STATUS (*PEFI_BLOCK_RESET_EX)(IN PEFI_BLOCK_IO2_PROTOCOL This, IN UCHAR ExtendedVerification); +typedef EFI_STATUS (*PEFI_BLOCK_RESET_EX)(IN PEFI_BLOCK_IO2_PROTOCOL This, IN BOOLEAN ExtendedVerification); typedef EFI_STATUS (*PEFI_BLOCK_READ_EX)(IN PEFI_BLOCK_IO2_PROTOCOL This, IN UINT32 MediaId, IN EFI_LBA LBA, IN OUT PEFI_BLOCK_IO2_TOKEN Token, IN UINT_PTR BufferSize, OUT PVOID Buffer); typedef EFI_STATUS (*PEFI_BLOCK_WRITE_EX)(IN PEFI_BLOCK_IO2_PROTOCOL This, IN UINT32 MediaId, IN EFI_LBA LBA, IN OUT PEFI_BLOCK_IO2_TOKEN Token, IN UINT_PTR BufferSize, IN PVOID Buffer); typedef EFI_STATUS (*PEFI_BLOCK_FLUSH_EX)(IN PEFI_BLOCK_IO2_PROTOCOL This, IN OUT PEFI_BLOCK_IO2_TOKEN Token); @@ -752,7 +753,7 @@ typedef EFI_STATUS (*PEFI_DISK_READ_EX)(IN PEFI_DISK_IO2_PROTOCOL This, IN UINT3 typedef EFI_STATUS (*PEFI_DISK_WRITE_EX)(IN PEFI_DISK_IO2_PROTOCOL This, IN UINT32 MediaId, IN UINT64 Offset, IN OUT PEFI_DISK_IO2_TOKEN Token, IN UINT_PTR BufferSize, IN PVOID Buffer); typedef EFI_STATUS (*PEFI_DISK_FLUSH_EX)(IN PEFI_DISK_IO2_PROTOCOL This, IN OUT PEFI_DISK_IO2_TOKEN Token); typedef EFI_STATUS (*PEFI_VOLUME_OPEN)(IN PEFI_SIMPLE_FILE_SYSTEM_PROTOCOL This, OUT PEFI_FILE_HANDLE *Root); -typedef EFI_STATUS (*PEFI_FILE_OPEN)(IN PEFI_FILE_HANDLE File, OUT PEFI_FILE_HANDLE *NewHandle, IN PUINT16 FileName, IN UINT64 OpenMode, IN UINT64 Attributes); +typedef EFI_STATUS (*PEFI_FILE_OPEN)(IN PEFI_FILE_HANDLE File, OUT PEFI_FILE_HANDLE *NewHandle, IN PWCHAR FileName, IN UINT64 OpenMode, IN UINT64 Attributes); typedef EFI_STATUS (*PEFI_FILE_CLOSE)(IN PEFI_FILE_HANDLE File); typedef EFI_STATUS (*PEFI_FILE_DELETE)(IN PEFI_FILE_HANDLE File); typedef EFI_STATUS (*PEFI_FILE_READ)(IN PEFI_FILE_HANDLE File, IN OUT PUINT_PTR BufferSize, OUT PVOID Buffer); @@ -762,7 +763,7 @@ typedef EFI_STATUS (*PEFI_FILE_GET_POSITION)(IN PEFI_FILE_HANDLE File, OUT PUINT typedef EFI_STATUS (*PEFI_FILE_GET_INFO)(IN PEFI_FILE_HANDLE File, IN PEFI_GUID InformationType, IN OUT PUINT_PTR BufferSize, OUT PVOID Buffer); typedef EFI_STATUS (*PEFI_FILE_SET_INFO)(IN PEFI_FILE_HANDLE File, IN PEFI_GUID InformationType, IN UINT_PTR BufferSize, IN PVOID Buffer); typedef EFI_STATUS (*PEFI_FILE_FLUSH)(IN PEFI_FILE_HANDLE File); -typedef EFI_STATUS (*PEFI_FILE_OPEN_EX)(IN PEFI_FILE_HANDLE File, OUT PEFI_FILE_HANDLE *NewHandle, IN PUINT16 FileName, IN UINT64 OpenMode, IN UINT64 Attributes, IN OUT PEFI_FILE_IO_TOKEN Token); +typedef EFI_STATUS (*PEFI_FILE_OPEN_EX)(IN PEFI_FILE_HANDLE File, OUT PEFI_FILE_HANDLE *NewHandle, IN PWCHAR FileName, IN UINT64 OpenMode, IN UINT64 Attributes, IN OUT PEFI_FILE_IO_TOKEN Token); typedef EFI_STATUS (*PEFI_FILE_READ_EX)(IN PEFI_FILE_HANDLE File, IN OUT PEFI_FILE_IO_TOKEN Token); typedef EFI_STATUS (*PEFI_FILE_WRITE_EX)(IN PEFI_FILE_HANDLE File, IN OUT PEFI_FILE_IO_TOKEN Token); typedef EFI_STATUS (*PEFI_FILE_FLUSH_EX)(IN PEFI_FILE_HANDLE File, IN OUT PEFI_FILE_IO_TOKEN Token); @@ -806,10 +807,10 @@ typedef EFI_STATUS (*PEFI_SERVICE_BINDING_DESTROY_CHILD)(IN PEFI_SERVICE_BINDING typedef EFI_STATUS (*PEFI_DRIVER_BINDING_PROTOCOL_SUPPORTED)(IN PEFI_DRIVER_BINDING_PROTOCOL This, IN EFI_HANDLE ControllerHandle, IN PEFI_DEVICE_PATH_PROTOCOL RemainingDevicePath); typedef EFI_STATUS (*PEFI_DRIVER_BINDING_PROTOCOL_START)(IN PEFI_DRIVER_BINDING_PROTOCOL This, IN EFI_HANDLE ControllerHandle, IN PEFI_DEVICE_PATH_PROTOCOL RemainingDevicePath); typedef EFI_STATUS (*PEFI_DRIVER_BINDING_PROTOCOL_STOP)(IN PEFI_DRIVER_BINDING_PROTOCOL This, IN EFI_HANDLE ControllerHandle, IN UINT_PTR NumberOfChildren, IN PEFI_HANDLE ChildHandleBuffer); -typedef EFI_STATUS (*PEFI_COMPONENT_NAME_GET_DRIVER_NAME)(IN PEFI_COMPONENT_NAME_PROTOCOL This, IN PUINT8 Language, OUT PUINT16 *DriverName); -typedef EFI_STATUS (*PEFI_COMPONENT_NAME_GET_CONTROLLER_NAME)(IN PEFI_COMPONENT_NAME_PROTOCOL This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle, IN PUINT8 Language, OUT PUINT16 *ControllerName); -typedef EFI_STATUS (*PEFI_COMPONENT_NAME2_GET_DRIVER_NAME)(IN PEFI_COMPONENT_NAME2_PROTOCOL This, IN PUINT8 Language, OUT PUINT16 *DriverName); -typedef EFI_STATUS (*PEFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)(IN PEFI_COMPONENT_NAME2_PROTOCOL This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle, IN PUINT8 Language, OUT PUINT16 *ControllerName); +typedef EFI_STATUS (*PEFI_COMPONENT_NAME_GET_DRIVER_NAME)(IN PEFI_COMPONENT_NAME_PROTOCOL This, IN PUINT8 Language, OUT PWCHAR *DriverName); +typedef EFI_STATUS (*PEFI_COMPONENT_NAME_GET_CONTROLLER_NAME)(IN PEFI_COMPONENT_NAME_PROTOCOL This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle, IN PUINT8 Language, OUT PWCHAR *ControllerName); +typedef EFI_STATUS (*PEFI_COMPONENT_NAME2_GET_DRIVER_NAME)(IN PEFI_COMPONENT_NAME2_PROTOCOL This, IN PUINT8 Language, OUT PWCHAR *DriverName); +typedef EFI_STATUS (*PEFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)(IN PEFI_COMPONENT_NAME2_PROTOCOL This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle, IN PUINT8 Language, OUT PWCHAR *ControllerName); typedef EFI_STATUS (*PEFI_RNG_GET_INFO)(IN PEFI_RNG_PROTOCOL This, IN OUT PUINT_PTR RNGAlgorithmListSize, OUT PEFI_GUID RNGAlgorithmList); typedef EFI_STATUS (*PEFI_RNG_GET_RNG)(IN PEFI_RNG_PROTOCOL This, IN PEFI_GUID RNGAlgorithm, IN UINT_PTR RNGValueLength, OUT PUINT8 RNGValue); typedef EFI_STATUS (*PEFI_PLATFORM_DRIVER_OVERRIDE_GET_DRIVER)(IN PEFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL This, IN EFI_HANDLE ControllerHandle, IN OUT PEFI_HANDLE DriverImageHandle); @@ -845,7 +846,7 @@ typedef EFI_STATUS (*PEFI_PXE_BASE_CODE_START)(IN PEFI_PXE_BASE_CODE_PROTOCOL Th typedef EFI_STATUS (*PEFI_PXE_BASE_CODE_STOP)(IN PEFI_PXE_BASE_CODE_PROTOCOL This); typedef EFI_STATUS (*PEFI_PXE_BASE_CODE_DHCP)(IN PEFI_PXE_BASE_CODE_PROTOCOL This, IN UCHAR SortOffers); typedef EFI_STATUS (*PEFI_PXE_BASE_CODE_DISCOVER)(IN PEFI_PXE_BASE_CODE_PROTOCOL This, IN UINT16 Type, IN PUINT16 Layer, IN UCHAR UseBis, IN OUT PEFI_PXE_BASE_CODE_DISCOVER_INFO Info); -typedef EFI_STATUS (*PEFI_PXE_BASE_CODE_MTFTP)(IN PEFI_PXE_BASE_CODE_PROTOCOL This, IN EFI_PXE_BASE_CODE_TFTP_OPCODE Operation, IN OUT PVOID *BufferPtr, IN UCHAR Overwrite, IN OUT PUINT64 BufferSize, IN PUINT_PTR BlockSize, IN PEFI_IP_ADDRESS ServerIp, IN PUINT8 Filename, IN PEFI_PXE_BASE_CODE_MTFTP_INFO Info, IN UCHAR DontUseBuffer); +typedef EFI_STATUS (*PEFI_PXE_BASE_CODE_MTFTP)(IN PEFI_PXE_BASE_CODE_PROTOCOL This, IN EFI_PXE_BASE_CODE_TFTP_OPCODE Operation, IN OUT PVOID *BufferPtr, IN UCHAR Overwrite, IN OUT PUINT64 BufferSize, IN PUINT_PTR BlockSize, IN PEFI_IP_ADDRESS ServerIp, IN PWCHAR Filename, IN PEFI_PXE_BASE_CODE_MTFTP_INFO Info, IN UCHAR DontUseBuffer); typedef EFI_STATUS (*PEFI_PXE_BASE_CODE_UDP_WRITE)(IN PEFI_PXE_BASE_CODE_PROTOCOL This, IN UINT16 OpFlags, IN PEFI_IP_ADDRESS DestIp, IN PUINT16 DestPort, IN PEFI_IP_ADDRESS GatewayIp, IN PEFI_IP_ADDRESS SrcIp, IN OUT PUINT16 SrcPort, IN PUINT_PTR HeaderSize, IN PVOID HeaderPtr, IN PUINT_PTR BufferSize, IN PVOID BufferPtr); typedef EFI_STATUS (*PEFI_PXE_BASE_CODE_UDP_READ)(IN PEFI_PXE_BASE_CODE_PROTOCOL This, IN UINT16 OpFlags, IN OUT PEFI_IP_ADDRESS DestIp, IN OUT PUINT16 DestPort, IN OUT PEFI_IP_ADDRESS SrcIp, IN OUT PUINT16 SrcPort, IN PUINT_PTR HeaderSize, IN PVOID HeaderPtr, IN OUT PUINT_PTR BufferSize, IN PVOID BufferPtr); typedef EFI_STATUS (*PEFI_PXE_BASE_CODE_SET_IP_FILTER)(IN PEFI_PXE_BASE_CODE_PROTOCOL This, IN PEFI_PXE_BASE_CODE_IP_FILTER NewFilter); @@ -952,7 +953,7 @@ typedef struct _EFI_TIME_CAPABILITIES { UINT32 Resolution; UINT32 Accuracy; - UCHAR SetsToZero; + BOOLEAN SetsToZero; } EFI_TIME_CAPABILITIES, *PEFI_TIME_CAPABILITIES; /* EFI Open Protocol Information Entry */ @@ -1072,14 +1073,14 @@ typedef struct _EFI_SIMPLE_TEXT_OUTPUT_MODE INT32 Attribute; INT32 CursorColumn; INT32 CursorRow; - UCHAR CursorVisible; + BOOLEAN CursorVisible; } EFI_SIMPLE_TEXT_OUTPUT_MODE, *PEFI_SIMPLE_TEXT_OUTPUT_MODE; /* The keystroke information for the key that was pressed */ typedef struct _EFI_INPUT_KEY { UINT16 ScanCode; - UINT16 UnicodeChar; + WCHAR UnicodeChar; } EFI_INPUT_KEY, *PEFI_INPUT_KEY; /* EFI Key State information */ @@ -1111,7 +1112,7 @@ typedef struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL typedef struct _EFI_SYSTEM_TABLE { EFI_TABLE_HEADER Hdr; - PUINT16 FirmwareVendor; + PWCHAR FirmwareVendor; UINT32 FirmwareRevision; EFI_HANDLE ConsoleInHandle; PEFI_SIMPLE_TEXT_INPUT_PROTOCOL ConIn; @@ -1458,7 +1459,7 @@ typedef struct _EFI_CDROM_DEVICE_PATH typedef struct _EFI_FILEPATH_DEVICE_PATH { EFI_DEVICE_PATH_PROTOCOL Header; - UINT16 PathName[1]; + WCHAR PathName[1]; } EFI_FILEPATH_DEVICE_PATH, *PEFI_FILEPATH_DEVICE_PATH; /* Media Protocol device path node */ @@ -1687,11 +1688,11 @@ typedef struct _EFI_BLOCK_DEVICE_DATA typedef struct _EFI_BLOCK_IO_MEDIA { UINT32 MediaId; - UCHAR RemovableMedia; - UCHAR MediaPresent; - UCHAR LogicalPartition; - UCHAR ReadOnly; - UCHAR WriteCaching; + BOOLEAN RemovableMedia; + BOOLEAN MediaPresent; + BOOLEAN LogicalPartition; + BOOLEAN ReadOnly; + BOOLEAN WriteCaching; UINT32 BlockSize; UINT32 IoAlign; EFI_LBA LastBlock; @@ -1799,7 +1800,7 @@ typedef struct _EFI_FILE_INFO EFI_TIME LastAccessTime; EFI_TIME ModificationTime; UINT64 Attribute; - UINT16 FileName[1]; + WCHAR FileName[1]; } EFI_FILE_INFO, *PEFI_FILE_INFO; /* EFI File System Info structure */ @@ -2321,7 +2322,7 @@ typedef struct _EFI_GPT_PARTITION_ENTRY EFI_LBA StartingLBA; EFI_LBA EndingLBA; UINT64 Attributes; - UINT16 PartitionName[36]; + WCHAR PartitionName[36]; } EFI_GPT_PARTITION_ENTRY, *PEFI_GPT_PARTITION_ENTRY; /* EFI file header */ diff --git a/xtldr/CMakeLists.txt b/xtldr/CMakeLists.txt index f3a18a6..4e161be 100644 --- a/xtldr/CMakeLists.txt +++ b/xtldr/CMakeLists.txt @@ -11,24 +11,23 @@ include_directories( # Specify list of library source code files list(APPEND LIBXTLDR_SOURCE - ${XTLDR_SOURCE_DIR}/library/modproto.c) + ${XTLDR_SOURCE_DIR}/library/modproto.cc) # Specify list of source code files list(APPEND XTLDR_SOURCE - ${XTLDR_SOURCE_DIR}/arch/${ARCH}/memory.c - ${XTLDR_SOURCE_DIR}/bootutil.c - ${XTLDR_SOURCE_DIR}/config.c - ${XTLDR_SOURCE_DIR}/console.c - ${XTLDR_SOURCE_DIR}/debug.c - ${XTLDR_SOURCE_DIR}/efiutils.c - ${XTLDR_SOURCE_DIR}/globals.c - ${XTLDR_SOURCE_DIR}/hardware.c - ${XTLDR_SOURCE_DIR}/memory.c - ${XTLDR_SOURCE_DIR}/protocol.c - ${XTLDR_SOURCE_DIR}/shell.c - ${XTLDR_SOURCE_DIR}/textui.c - ${XTLDR_SOURCE_DIR}/volume.c - ${XTLDR_SOURCE_DIR}/xtldr.c) + ${XTLDR_SOURCE_DIR}/arch/${ARCH}/memory.cc + ${XTLDR_SOURCE_DIR}/bootutil.cc + ${XTLDR_SOURCE_DIR}/config.cc + ${XTLDR_SOURCE_DIR}/console.cc + ${XTLDR_SOURCE_DIR}/data.cc + ${XTLDR_SOURCE_DIR}/debug.cc + ${XTLDR_SOURCE_DIR}/efiutils.cc + ${XTLDR_SOURCE_DIR}/memory.cc + ${XTLDR_SOURCE_DIR}/protocol.cc + ${XTLDR_SOURCE_DIR}/shell.cc + ${XTLDR_SOURCE_DIR}/textui.cc + ${XTLDR_SOURCE_DIR}/volume.cc + ${XTLDR_SOURCE_DIR}/xtldr.cc) # Link static XTLDR library add_library(libxtldr ${LIBXTLDR_SOURCE}) diff --git a/xtldr/arch/amd64/memory.c b/xtldr/arch/amd64/memory.cc similarity index 77% rename from xtldr/arch/amd64/memory.c rename to xtldr/arch/amd64/memory.cc index c94e735..ed12532 100644 --- a/xtldr/arch/amd64/memory.c +++ b/xtldr/arch/amd64/memory.cc @@ -1,13 +1,13 @@ /** * PROJECT: ExectOS * 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 * DEVELOPERS: Rafal Kupiec * Aiken Harris */ -#include +#include /** @@ -25,17 +25,19 @@ */ XTCDECL EFI_STATUS -BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, - IN ULONG_PTR SelfMapAddress) +Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, + IN ULONG_PTR SelfMapAddress) { PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry; PXTBL_MEMORY_MAPPING Mapping; PXTBL_MODULE_INFO ModuleInfo; EFI_PHYSICAL_ADDRESS Address; + PVOID LoaderBase; + ULONGLONG LoaderSize; EFI_STATUS Status; /* Allocate pages for the Page Map */ - Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address); + Status = AllocatePages(AllocateAnyPages, 1, &Address); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ @@ -44,10 +46,10 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, /* Assign and zero-fill memory used by page mappings */ 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 */ - Status = BlpSelfMapPml(PageMap, SelfMapAddress); + Status = Memory::SelfMapPml(PageMap, SelfMapAddress); if(Status != STATUS_EFI_SUCCESS) { /* PML mapping failed */ @@ -55,8 +57,8 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, } /* Map the trampoline code area */ - Status = BlMapVirtualMemory(PageMap, (PVOID)MM_TRAMPOLINE_ADDRESS,(PVOID)MM_TRAMPOLINE_ADDRESS, - 1, LoaderFirmwareTemporary); + Status = MapVirtualMemory(PageMap, (PVOID)MM_TRAMPOLINE_ADDRESS,(PVOID)MM_TRAMPOLINE_ADDRESS, + 1, LoaderFirmwareTemporary); if(Status != STATUS_EFI_SUCCESS) { /* Mapping trampoline code failed */ @@ -64,7 +66,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, } /* Get list of XTLDR modules */ - ModulesList = BlGetModulesList(); + ModulesList = Protocol::GetModulesList(); ModulesListEntry = ModulesList->Flink; while(ModulesListEntry != ModulesList) { @@ -72,8 +74,8 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink); /* Map module code */ - Status = BlMapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase, - EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary); + Status = MapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase, + EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary); /* Check if mapping succeeded */ if(Status != STATUS_EFI_SUCCESS) @@ -86,12 +88,15 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, ModulesListEntry = ModulesListEntry->Flink; } + /* Get boot loader image information */ + XtLoader::GetLoaderImageInformation(&LoaderBase, &LoaderSize); + /* Make sure boot loader image base and size are set */ - if(BlpStatus.LoaderBase && BlpStatus.LoaderSize) + if(LoaderBase && LoaderSize) { /* Map boot loader code as well */ - Status = BlMapVirtualMemory(PageMap, BlpStatus.LoaderBase, BlpStatus.LoaderBase, - EFI_SIZE_TO_PAGES(BlpStatus.LoaderSize), LoaderFirmwareTemporary); + Status = MapVirtualMemory(PageMap, LoaderBase, LoaderBase, + EFI_SIZE_TO_PAGES(LoaderSize), LoaderFirmwareTemporary); if(Status != STATUS_EFI_SUCCESS) { /* Mapping boot loader code failed */ @@ -105,7 +110,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, } /* 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; while(ListEntry != &PageMap->MemoryMap) { @@ -116,12 +121,12 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, if(Mapping->VirtualAddress) { /* 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); /* Map memory */ - Status = BlMapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress, - (UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages); + Status = MapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress, + (UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages); if(Status != STATUS_EFI_SUCCESS) { /* Memory mapping failed */ @@ -137,114 +142,6 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, 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_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 = 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. * @@ -266,10 +163,10 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap, */ XTCDECL EFI_STATUS -BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, - IN PVOID PageTable, - IN SIZE_T Entry, - OUT PVOID *NextPageTable) +Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, + IN PVOID PageTable, + IN SIZE_T Entry, + OUT PVOID *NextPageTable) { EFI_PHYSICAL_ADDRESS Address; ULONGLONG PmlPointer = 0; @@ -288,7 +185,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, else { /* Allocate pages for new PML entry */ - Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address); + Status = AllocatePages(AllocateAnyPages, 1, &Address); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ @@ -296,7 +193,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, } /* 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) { /* Memory mapping failure */ @@ -304,7 +201,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, } /* 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 */ PmlTable[Entry].PageFrameNumber = Address / EFI_PAGE_SIZE; @@ -320,6 +217,114 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, 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. * @@ -335,8 +340,8 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, */ XTCDECL EFI_STATUS -BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap, - IN ULONG_PTR SelfMapAddress) +Memory::SelfMapPml(IN PXTBL_PAGE_MAPPING PageMap, + IN ULONG_PTR SelfMapAddress) { PHARDWARE_PTE PmlBase; ULONGLONG PmlIndex; @@ -357,7 +362,7 @@ BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap, } /* 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].Valid = 1; PmlBase[PmlIndex].Writable = 1; diff --git a/xtldr/arch/i686/memory.c b/xtldr/arch/i686/memory.cc similarity index 79% rename from xtldr/arch/i686/memory.c rename to xtldr/arch/i686/memory.cc index f6aede9..a194d2d 100644 --- a/xtldr/arch/i686/memory.c +++ b/xtldr/arch/i686/memory.cc @@ -1,13 +1,13 @@ /** * PROJECT: ExectOS * 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 * DEVELOPERS: Rafal Kupiec * Aiken Harris */ -#include +#include /** @@ -22,13 +22,15 @@ */ XTCDECL EFI_STATUS -BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, - IN ULONG_PTR SelfMapAddress) +Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, + IN ULONG_PTR SelfMapAddress) { PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry; EFI_PHYSICAL_ADDRESS Address, DirectoryAddress; PXTBL_MODULE_INFO ModuleInfo; PXTBL_MEMORY_MAPPING Mapping; + PVOID LoaderBase; + ULONGLONG LoaderSize; EFI_STATUS Status; ULONG Index; @@ -36,7 +38,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, if(PageMap->PageMapLevel == 3) { /* Allocate a page for the 3-level page map structure (PAE enabled) */ - Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address); + Status = AllocatePages(AllocateAnyPages, 1, &Address); if(Status != STATUS_EFI_SUCCESS) { /* 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 */ 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) */ - Status = BlAllocateMemoryPages(AllocateAnyPages, 4, &DirectoryAddress); + Status = AllocatePages(AllocateAnyPages, 4, &DirectoryAddress); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failed, cannot proceed with page map creation */ @@ -56,12 +58,12 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, } /* 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 */ for(Index = 0; Index < 4; Index++) { - RtlZeroMemory(&((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[Index], sizeof(HARDWARE_MODERN_PTE)); + RTL::Memory::ZeroMemory(&((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[Index], sizeof(HARDWARE_MODERN_PTE)); ((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[Index].PageFrameNumber = DirectoryAddress / EFI_PAGE_SIZE; ((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[Index].Valid = 1; DirectoryAddress += EFI_PAGE_SIZE; @@ -70,7 +72,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, else { /* Allocate a page for the 2-level page map structure (PAE disabled) */ - Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address); + Status = AllocatePages(AllocateAnyPages, 1, &Address); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failed, cannot proceed with page map creation */ @@ -79,11 +81,11 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, /* Assign the allocated page to the page map and zero it out */ 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 */ - Status = BlpSelfMapPml(PageMap, SelfMapAddress); + Status = SelfMapPml(PageMap, SelfMapAddress); if(Status != STATUS_EFI_SUCCESS) { /* PML mapping failed */ @@ -91,8 +93,8 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, } /* Map the trampoline code area */ - Status = BlMapVirtualMemory(PageMap, (PVOID)MM_TRAMPOLINE_ADDRESS,(PVOID)MM_TRAMPOLINE_ADDRESS, - 1, LoaderFirmwareTemporary); + Status = MapVirtualMemory(PageMap, (PVOID)MM_TRAMPOLINE_ADDRESS,(PVOID)MM_TRAMPOLINE_ADDRESS, + 1, LoaderFirmwareTemporary); if(Status != STATUS_EFI_SUCCESS) { /* Mapping trampoline code failed */ @@ -100,7 +102,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, } /* Get list of XTLDR modules */ - ModulesList = BlGetModulesList(); + ModulesList = Protocol::GetModulesList(); ModulesListEntry = ModulesList->Flink; while(ModulesListEntry != ModulesList) { @@ -108,8 +110,8 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink); /* Map module code */ - Status = BlMapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase, - EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary); + Status = MapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase, + EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary); /* Check if mapping succeeded */ if(Status != STATUS_EFI_SUCCESS) @@ -122,12 +124,15 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, ModulesListEntry = ModulesListEntry->Flink; } + /* Get boot loader image information */ + XtLoader::GetLoaderImageInformation(&LoaderBase, &LoaderSize); + /* Make sure boot loader image base and size are set */ - if(BlpStatus.LoaderBase && BlpStatus.LoaderSize) + if(LoaderBase && LoaderSize) { /* Map boot loader code as well */ - Status = BlMapVirtualMemory(PageMap, BlpStatus.LoaderBase, BlpStatus.LoaderBase, - EFI_SIZE_TO_PAGES(BlpStatus.LoaderSize), LoaderFirmwareTemporary); + Status = MapVirtualMemory(PageMap, LoaderBase, LoaderBase, + EFI_SIZE_TO_PAGES(LoaderSize), LoaderFirmwareTemporary); if(Status != STATUS_EFI_SUCCESS) { /* Mapping boot loader code failed */ @@ -141,7 +146,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, } /* 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; while(ListEntry != &PageMap->MemoryMap) { @@ -152,12 +157,12 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, if(Mapping->VirtualAddress) { /* 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); /* Map memory */ - Status = BlMapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress, - (UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages); + Status = MapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress, + (UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages); if(Status != STATUS_EFI_SUCCESS) { /* Memory mapping failed */ @@ -173,116 +178,6 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, 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_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 = 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_MODERN_PTE)Pml1; - RtlZeroMemory(&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 = 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. * @@ -304,10 +199,10 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap, */ XTCDECL EFI_STATUS -BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, - IN PVOID PageTable, - IN SIZE_T Entry, - OUT PVOID *NextPageTable) +Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, + IN PVOID PageTable, + IN SIZE_T Entry, + OUT PVOID *NextPageTable) { EFI_PHYSICAL_ADDRESS Address; ULONGLONG PmlPointer = 0; @@ -349,7 +244,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, else { /* Allocate pages for new PML entry */ - Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address); + Status = AllocatePages(AllocateAnyPages, 1, &Address); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ @@ -357,7 +252,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, } /* 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) { /* Memory mapping failure */ @@ -365,7 +260,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, } /* 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 */ if(PageMap->PageMapLevel >= 3) @@ -396,6 +291,116 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, 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. * @@ -411,8 +416,8 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, */ XTCDECL EFI_STATUS -BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap, - IN ULONG_PTR SelfMapAddress) +Memory::SelfMapPml(IN PXTBL_PAGE_MAPPING PageMap, + IN ULONG_PTR SelfMapAddress) { PHARDWARE_LEGACY_PTE LegacyPml; PHARDWARE_MODERN_PTE Pml; @@ -431,7 +436,7 @@ BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap, /* Add self-mapping for PML3 (PAE enabled) */ for(Index = 0; Index < 4; Index++) { - RtlZeroMemory(&Pml[PmlIndex + Index], sizeof(HARDWARE_MODERN_PTE)); + RTL::Memory::ZeroMemory(&Pml[PmlIndex + Index], sizeof(HARDWARE_MODERN_PTE)); Pml[PmlIndex + Index].PageFrameNumber = ((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[Index].PageFrameNumber; Pml[PmlIndex + Index].Valid = 1; Pml[PmlIndex + Index].Writable = 1; @@ -445,7 +450,7 @@ BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap, PmlIndex = (SelfMapAddress >> MM_PDI_LEGACY_SHIFT); /* 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].Valid = 1; LegacyPml[PmlIndex].Writable = 1; diff --git a/xtldr/bootutil.c b/xtldr/bootutil.cc similarity index 82% rename from xtldr/bootutil.c rename to xtldr/bootutil.cc index 9ca1aa9..e29ed12 100644 --- a/xtldr/bootutil.c +++ b/xtldr/bootutil.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * 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 * DEVELOPERS: Aiken Harris */ -#include +#include /** @@ -24,21 +24,21 @@ */ XTCDECL BOOLEAN -BlGetBooleanParameter(IN CONST PWCHAR Parameters, - IN CONST PWCHAR Needle) +BootUtils::GetBooleanParameter(IN PCWSTR Parameters, + IN PCWSTR Needle) { - PWCHAR CurrentPosition, TokenEnd, TokenStart; + PCWSTR CurrentPosition, TokenEnd, TokenStart; SIZE_T NeedleLength, TokenLength; /* Validate input data and ensure the option is not an empty string */ - if(Parameters == NULL || Needle == NULL || *Needle == L'\0') + if(Parameters == NULLPTR || Needle == NULLPTR || *Needle == L'\0') { /* One of the parameters was invalid */ return FALSE; } CurrentPosition = Parameters; - NeedleLength = RtlWideStringLength(Needle, 0); + NeedleLength = RTL::WideString::WideStringLength(Needle, 0); /* Iterate through the entire parameters string */ while(*CurrentPosition != L'\0') @@ -71,7 +71,7 @@ BlGetBooleanParameter(IN CONST PWCHAR Parameters, if(TokenLength == NeedleLength) { /* Length matches, compare the strings */ - if(RtlCompareWideStringInsensitive(TokenStart, Needle, NeedleLength) == 0) + if(RTL::WideString::CompareWideStringInsensitive(TokenStart, Needle, NeedleLength) == 0) { /* A match was found */ return TRUE; diff --git a/xtldr/config.c b/xtldr/config.cc similarity index 59% rename from xtldr/config.c rename to xtldr/config.cc index 8f3ae15..b7e9445 100644 --- a/xtldr/config.c +++ b/xtldr/config.cc @@ -1,15 +1,48 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/config.c + * FILE: xtldr/config.cc * DESCRIPTION: XT Boot Loader Configuration * DEVELOPERS: Rafal Kupiec * Aiken Harris */ -#include +#include +/** + * Returns a boolean value of the specified configuration key. + * + * @param ConfigName + * Specifies the configuration key to return its boolean representation. + * + * @return This routine returns a boolean representation of the configuration value. + * + * @since XT 1.0 + */ +XTCDECL +BOOLEAN +Configuration::GetBooleanValue(IN PCWSTR ConfigName) +{ + PWCHAR Value; + + /* Get config value */ + GetValue(ConfigName, &Value); + + /* Check if option is enabled */ + if(RTL::WideString::CompareWideStringInsensitive(Value, L"ENABLED", 0) == 0 || + RTL::WideString::CompareWideStringInsensitive(Value, L"ON", 0) == 0 || + RTL::WideString::CompareWideStringInsensitive(Value, L"TRUE", 0) == 0 || + RTL::WideString::CompareWideStringInsensitive(Value, L"YES", 0) == 0) + { + /* This option is enabled */ + return TRUE; + } + + /* Return FALSE by default */ + return FALSE; +} + /** * @brief Retrieves the value of a specific OS boot option from a list. * @@ -28,9 +61,9 @@ */ XTCDECL EFI_STATUS -BlGetBootOptionValue(IN PLIST_ENTRY Options, - IN CONST PWCHAR OptionName, - OUT PWCHAR *OptionValue) +Configuration::GetBootOptionValue(IN PLIST_ENTRY Options, + IN PCWSTR OptionName, + OUT PWCHAR *OptionValue) { PXTBL_CONFIG_ENTRY ConfigEntry; PLIST_ENTRY ConfigList; @@ -38,10 +71,10 @@ BlGetBootOptionValue(IN PLIST_ENTRY Options, EFI_STATUS Status; /* Assume the option will not be found */ - *OptionValue = NULL; + *OptionValue = NULLPTR; /* Get the length of the option name we are looking for */ - KeyLength = RtlWideStringLength(OptionName, 0); + KeyLength = RTL::WideString::WideStringLength(OptionName, 0); /* Start iterating from the first entry in the options list */ ConfigList = Options->Flink; @@ -51,23 +84,23 @@ BlGetBootOptionValue(IN PLIST_ENTRY Options, ConfigEntry = CONTAIN_RECORD(ConfigList, XTBL_CONFIG_ENTRY, Flink); /* Compare the current entry's name with the requested option name */ - if(RtlCompareWideStringInsensitive(ConfigEntry->Name, OptionName, KeyLength) == 0) + if(RTL::WideString::CompareWideStringInsensitive(ConfigEntry->Name, OptionName, KeyLength) == 0) { /* Found the option, now prepare to copy its value */ - ValueLength = RtlWideStringLength(ConfigEntry->Value, 0); + ValueLength = RTL::WideString::WideStringLength(ConfigEntry->Value, 0); /* Allocate memory for the output value string */ - Status = BlAllocateMemoryPool((ValueLength + 1) * sizeof(WCHAR), (PVOID *)OptionValue); + Status = Memory::AllocatePool((ValueLength + 1) * sizeof(WCHAR), (PVOID *)OptionValue); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure, print debug message and return status code */ - BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); - *OptionValue = NULL; + Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); + *OptionValue = NULLPTR; return Status; } /* Copy the value and NULL-terminate the new string */ - RtlCopyMemory(*OptionValue, ConfigEntry->Value, ValueLength * sizeof(WCHAR)); + RTL::Memory::CopyMemory(*OptionValue, ConfigEntry->Value, ValueLength * sizeof(WCHAR)); (*OptionValue)[ValueLength] = L'\0'; /* Successfully retrieved the option value, return success */ @@ -82,103 +115,6 @@ BlGetBootOptionValue(IN PLIST_ENTRY Options, return STATUS_EFI_NOT_FOUND; } -/** - * Returns a boolean value of the specified configuration key. - * - * @param ConfigName - * Specifies the configuration key to return its boolean representation. - * - * @return This routine returns a boolean representation of the configuration value. - * - * @since XT 1.0 - */ -XTCDECL -BOOLEAN -BlGetConfigBooleanValue(IN CONST PWCHAR ConfigName) -{ - PWCHAR Value; - - /* Get config value */ - BlGetConfigValue(ConfigName, &Value); - - /* Check if option is enabled */ - if(RtlCompareWideStringInsensitive(Value, L"ENABLED", 0) == 0 || - RtlCompareWideStringInsensitive(Value, L"ON", 0) == 0 || - RtlCompareWideStringInsensitive(Value, L"TRUE", 0) == 0 || - RtlCompareWideStringInsensitive(Value, L"YES", 0) == 0) - { - /* This option is enabled */ - return TRUE; - } - - /* Return FALSE by default */ - return FALSE; -} - -/** - * Returns a value of the specified configuration key. - * - * @param ConfigName - * Specifies the configuration key to return its value. - * - * @return This routine returns a pointer to the configuration value, or NULL if key was not found. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlGetConfigValue(IN CONST PWCHAR ConfigName, - OUT PWCHAR *ConfigValue) -{ - PXTBL_CONFIG_ENTRY ConfigEntry; - PLIST_ENTRY ConfigListEntry; - SIZE_T KeyLength, ValueLength; - EFI_STATUS Status; - PWCHAR Value; - - /* Assume the option will not be found */ - *ConfigValue = NULL; - - /* Get config entry name length */ - KeyLength = RtlWideStringLength(ConfigName, 0); - - /* Iterate through config entries */ - ConfigListEntry = BlpConfig.Flink; - while(ConfigListEntry != &BlpConfig) - { - /* Get config entry */ - ConfigEntry = CONTAIN_RECORD(ConfigListEntry, XTBL_CONFIG_ENTRY, Flink); - - /* Check if requested configuration found */ - if(RtlCompareWideStringInsensitive(ConfigEntry->Name, ConfigName, KeyLength) == 0) - { - /* Get value length */ - ValueLength = RtlWideStringLength(ConfigEntry->Value, 0); - - /* Allocate memory for value */ - Status = BlAllocateMemoryPool((ValueLength + 1) * sizeof(WCHAR), (PVOID *)&Value); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure, return NULL */ - BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); - return Status; - } - - /* Copy value and return it */ - RtlCopyMemory(Value, ConfigEntry->Value, ValueLength * sizeof(WCHAR)); - Value[ValueLength] = L'\0'; - *ConfigValue = Value; - return STATUS_EFI_SUCCESS; - } - - /* Move to the next config entry */ - ConfigListEntry = ConfigListEntry->Flink; - } - - /* Config entry not found, return NULL */ - return STATUS_EFI_NOT_FOUND; -} - /** * Retrieves the list of user-editable boot options. * @@ -194,16 +130,16 @@ BlGetConfigValue(IN CONST PWCHAR ConfigName, */ XTCDECL VOID -BlGetEditableOptions(OUT CONST PWCHAR **OptionsArray, - OUT PULONG OptionsCount) +Configuration::GetEditableOptions(OUT PCWSTR **OptionsArray, + OUT PULONG OptionsCount) { ULONG Count = 0; /* Return a pointer to the global array of editable options */ - *OptionsArray = BlpEditableConfigOptions; + *OptionsArray = EditableConfigOptions; /* Calculate the number of elements in the array */ - while(BlpEditableConfigOptions[Count]) + while(EditableConfigOptions[Count]) { Count++; } @@ -213,181 +149,58 @@ BlGetEditableOptions(OUT CONST PWCHAR **OptionsArray, } /** - * Sets the value of a specific OS boot option in a list, or adds it if it doesn't exist. - * - * @param Options - * A pointer to the head of a list of XTBL_CONFIG_ENTRY structures. - * - * @param OptionName - * A pointer to a wide string that contains the name of the boot option to set. - * - * @param OptionValue - * A pointer to a wide string that contains the new value for the boot option. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlSetBootOptionValue(IN PLIST_ENTRY Options, - IN CONST PWCHAR OptionName, - IN CONST PWCHAR OptionValue) -{ - PXTBL_CONFIG_ENTRY ConfigEntry; - PLIST_ENTRY ConfigList; - ULONG Length; - EFI_STATUS Status; - - /* Get the length of the option name we are looking for */ - Length = RtlWideStringLength(OptionName, 0); - - /* Start iterating from the first entry in the options list */ - ConfigList = Options->Flink; - while(ConfigList != Options) - { - /* Get the container record for the current config entry */ - ConfigEntry = CONTAIN_RECORD(ConfigList, XTBL_CONFIG_ENTRY, Flink); - - /* Compare the current entry's name with the requested option name */ - if(RtlCompareWideStringInsensitive(ConfigEntry->Name, OptionName, Length) == 0) - { - /* Found the option, get its length */ - Length = RtlWideStringLength(OptionValue, 0); - - /* Reallocate memory for the new value */ - Status = BlFreeMemoryPool(ConfigEntry->Value); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to free memory, return status code */ - return Status; - } - - /* Allocate new memory for the updated value */ - Status = BlAllocateMemoryPool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Value); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure, print debug message and return status code */ - BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status); - return Status; - } - - /* Copy the value and NULL-terminate the new string */ - RtlCopyMemory(ConfigEntry->Value, OptionValue, Length * sizeof(WCHAR)); - ConfigEntry->Value[Length] = L'\0'; - return STATUS_EFI_SUCCESS; - } - - /* Move to the next entry in the list */ - ConfigList = ConfigList->Flink; - } - - /* Option not found, allocate memory for the new one */ - Status = BlAllocateMemoryPool(sizeof(XTBL_CONFIG_ENTRY), (PVOID *)&ConfigEntry); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure, print debug message and return status code */ - BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status); - return Status; - } - - /* Allocate memory for the option name */ - Length = RtlWideStringLength(OptionName, 0); - Status = BlAllocateMemoryPool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Name); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure, print debug message and return status code */ - BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status); - BlFreeMemoryPool(ConfigEntry); - return Status; - } - - /* Copy the option name and NULL-terminate the new string */ - RtlCopyMemory(ConfigEntry->Name, OptionName, Length * sizeof(WCHAR)); - ConfigEntry->Name[Length] = L'\0'; - - /* Allocate memory for the option value */ - Length = RtlWideStringLength(OptionValue, 0); - Status = BlAllocateMemoryPool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Value); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure, print debug message and return status code */ - BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status); - BlFreeMemoryPool(ConfigEntry->Name); - BlFreeMemoryPool(ConfigEntry); - return Status; - } - - /* Copy the value and NULL-terminate the new string */ - RtlCopyMemory(ConfigEntry->Value, OptionValue, Length * sizeof(WCHAR)); - ConfigEntry->Value[Length] = L'\0'; - - /* Insert the new config entry at the end of the options list */ - RtlInsertTailList(Options, &ConfigEntry->Flink); - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * Updates existing configuration value. + * Returns a value of the specified configuration key. * * @param ConfigName - * Specifies the configuration key to update. + * Specifies the configuration key to return its value. * - * @param ConfigValue - * Specifies the new configuration value. - * - * @return This routine returns a status code. + * @return This routine returns a pointer to the configuration value, or NULLPTR if key was not found. * * @since XT 1.0 */ XTCDECL EFI_STATUS -BlSetConfigValue(IN CONST PWCHAR ConfigName, - IN CONST PWCHAR ConfigValue) +Configuration::GetValue(IN PCWSTR ConfigName, + OUT PWCHAR *ConfigValue) { PXTBL_CONFIG_ENTRY ConfigEntry; PLIST_ENTRY ConfigListEntry; + SIZE_T KeyLength, ValueLength; EFI_STATUS Status; - SIZE_T Length; + PWCHAR Value; + + /* Assume the option will not be found */ + *ConfigValue = NULLPTR; /* Get config entry name length */ - Length = RtlWideStringLength(ConfigName, 0); + KeyLength = RTL::WideString::WideStringLength(ConfigName, 0); /* Iterate through config entries */ - ConfigListEntry = BlpConfig.Flink; - while(ConfigListEntry != &BlpConfig) + ConfigListEntry = Config.Flink; + while(ConfigListEntry != &Config) { /* Get config entry */ ConfigEntry = CONTAIN_RECORD(ConfigListEntry, XTBL_CONFIG_ENTRY, Flink); /* Check if requested configuration found */ - if(RtlCompareWideStringInsensitive(ConfigEntry->Name, ConfigName, Length) == 0) + if(RTL::WideString::CompareWideStringInsensitive(ConfigEntry->Name, ConfigName, KeyLength) == 0) { - /* Check new config value length */ - Length = RtlWideStringLength(ConfigValue, 0); + /* Get value length */ + ValueLength = RTL::WideString::WideStringLength(ConfigEntry->Value, 0); - /* Reallocate memory for new config value */ - Status = BlFreeMemoryPool(ConfigEntry->Value); - if(Status == STATUS_EFI_SUCCESS) - { - /* Successfully freed memory, allocate a new pool */ - Status = BlAllocateMemoryPool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Value); - } - - /* Check memory reallocation status */ + /* Allocate memory for value */ + Status = Memory::AllocatePool((ValueLength + 1) * sizeof(WCHAR), (PVOID *)&Value); if(Status != STATUS_EFI_SUCCESS) { - /* Failed to reallocate memory */ + /* Memory allocation failure, return NULLPTR */ + Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); return Status; } - /* Update config value */ - RtlCopyMemory(ConfigEntry->Value, ConfigValue, Length * sizeof(WCHAR)); - ConfigEntry->Value[Length] = L'\0'; - - /* Return success */ + /* Copy value and return it */ + RTL::Memory::CopyMemory(Value, ConfigEntry->Value, ValueLength * sizeof(WCHAR)); + Value[ValueLength] = L'\0'; + *ConfigValue = Value; return STATUS_EFI_SUCCESS; } @@ -395,10 +208,175 @@ BlSetConfigValue(IN CONST PWCHAR ConfigName, ConfigListEntry = ConfigListEntry->Flink; } - /* Config entry not found */ + /* Config entry not found, return NULLPTR */ return STATUS_EFI_NOT_FOUND; } +/** + * Initializes a list of operating systems for XTLDR boot menu. + * + * @param MenuEntries + * Supplies a pointer to memory area where operating systems list will be stored. + * + * @param EntriesCount + * Supplies a pointer to memory area where number of menu entries will be stored. + * + * @param DefaultId + * Supplies a pointer to memory area where ID of default menu entry will be stored. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +Configuration::InitializeBootMenuList(IN ULONG MaxNameLength, + OUT PXTBL_BOOTMENU_ITEM *MenuEntries, + OUT PULONG EntriesCount, + OUT PULONG DefaultId) +{ + EFI_GUID VendorGuid = XT_BOOT_LOADER_PROTOCOL_GUID; + PWCHAR DefaultMenuEntry, LastBooted, MenuEntryName, VisibleName; + PLIST_ENTRY MenuEntrySectionList, MenuEntryList; + PXTBL_CONFIG_SECTION MenuEntrySection; + PXTBL_CONFIG_ENTRY MenuEntryOption; + ULONG DefaultOS, NameLength,NumberOfEntries; + PXTBL_BOOTMENU_ITEM OsList; + EFI_STATUS Status; + + /* Set default values */ + DefaultOS = 0; + NumberOfEntries = 0; + + /* Get default menu entry from configuration */ + Configuration::GetValue(L"DEFAULT", &DefaultMenuEntry); + + /* Check if configuration allows to use last booted OS */ + if(Configuration::GetBooleanValue(L"KEEPLASTBOOT")) + { + /* Attempt to get last booted Operating System from NVRAM */ + Status = EfiUtils::GetEfiVariable(&VendorGuid, L"XtLdrLastBootOS", (PVOID*)&LastBooted); + if(Status == STATUS_EFI_SUCCESS) + { + /* Set default menu entry to last booted OS */ + DefaultMenuEntry = LastBooted; + } + } + + /* Iterate through menu items to get a total number of entries */ + MenuEntrySectionList = BootMenuList->Flink; + while(MenuEntrySectionList != BootMenuList) + { + /* Increase number of menu entries, and simply get next item */ + NumberOfEntries++; + MenuEntrySectionList = MenuEntrySectionList->Flink; + } + + /* Allocate memory for the OS list depending on the item count */ + Status = Memory::AllocatePool(NumberOfEntries * sizeof(XTBL_BOOTMENU_ITEM), (PVOID*)&OsList); + if(Status != STATUS_EFI_SUCCESS || !OsList) + { + /* Memory allocation failure */ + return STATUS_EFI_OUT_OF_RESOURCES; + } + + /* Reset counter and iterate through all menu items once again */ + NumberOfEntries = 0; + MenuEntrySectionList = BootMenuList->Flink; + while(MenuEntrySectionList != BootMenuList) + { + /* NULLify menu entry name */ + MenuEntryName = NULLPTR; + + /* Get menu section */ + MenuEntrySection = CONTAIN_RECORD(MenuEntrySectionList, XTBL_CONFIG_SECTION, Flink); + + /* Check if this is the default menu entry */ + if((RTL::WideString::WideStringLength(MenuEntrySection->SectionName, 0) == RTL::WideString::WideStringLength(DefaultMenuEntry, 0)) && + (RTL::WideString::CompareWideStringInsensitive(MenuEntrySection->SectionName, DefaultMenuEntry, 0) == 0)) + { + /* Set default OS ID */ + DefaultOS = NumberOfEntries; + } + + /* Iterate through all entry parameters */ + MenuEntryList = MenuEntrySection->Options.Flink; + while(MenuEntryList != &MenuEntrySection->Options) + { + /* Get menu entry parameter */ + MenuEntryOption = CONTAIN_RECORD(MenuEntryList, XTBL_CONFIG_ENTRY, Flink); + + /* Check if this is the menu entry display name */ + if(RTL::WideString::CompareWideStringInsensitive(MenuEntryOption->Name, L"SYSTEMNAME", 0) == 0) + { + /* Set menu entry display name */ + MenuEntryName = MenuEntryOption->Value; + } + + /* Get next parameter for this menu entry */ + MenuEntryList = MenuEntryList->Flink; + } + + /* Add OS to the boot menu list */ + OsList[NumberOfEntries].FullName = MenuEntryName; + OsList[NumberOfEntries].ShortName = MenuEntrySection->SectionName; + OsList[NumberOfEntries].Options = &MenuEntrySection->Options; + + /* Check if the menu entry name fits the maximum length */ + NameLength = RTL::WideString::WideStringLength(MenuEntryName, 0); + if(NameLength > MaxNameLength) + { + /* Menu entry name is too long, allocate memory for shorter name visible in the boot menu */ + Status = Memory::AllocatePool((MaxNameLength + 1) * sizeof(WCHAR), (PVOID*)&VisibleName); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + return STATUS_EFI_OUT_OF_RESOURCES; + } + + /* Copy shorter name and append "..." at the end */ + RTL::Memory::CopyMemory(VisibleName, MenuEntryName, (MaxNameLength - 3) * sizeof(WCHAR)); + RTL::Memory::CopyMemory(VisibleName + MaxNameLength - 3, L"...", 3 * sizeof(WCHAR)); + VisibleName[MaxNameLength] = L'\0'; + + /* Set visible menu entry name */ + OsList[NumberOfEntries].EntryName = VisibleName; + } + else + { + /* Menu entry name fits the maximum length, use it as is */ + OsList[NumberOfEntries].EntryName = MenuEntryName; + } + + /* Get next menu entry */ + MenuEntrySectionList = MenuEntrySectionList->Flink; + NumberOfEntries++; + } + + /* Set return values */ + *DefaultId = DefaultOS; + *EntriesCount = NumberOfEntries; + *MenuEntries = OsList; + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Initializes the XTLDR configuration subsystem. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +Configuration::InitializeConfiguration() +{ + /* Initialize XTLDR configuration linked lists */ + RTL::LinkedList::InitializeListHead(&Config); +} + /** * Loads and parses XTLDR configuration file. * @@ -408,55 +386,55 @@ BlSetConfigValue(IN CONST PWCHAR ConfigName, */ XTCDECL EFI_STATUS -BlpLoadConfiguration() +Configuration::LoadConfiguration() { PLIST_ENTRY SectionListEntry; EFI_STATUS Status; PCHAR ConfigData; /* Initialize configuration pointer */ - RtlInitializeListHead(&BlpConfigSections); + RTL::LinkedList::InitializeListHead(&ConfigSections); /* Read data from configuration file */ - Status = BlpReadConfigFile(XTBL_LOADER_DIRECTORY_PATH, L"XTLDR.INI", &ConfigData); + Status = ReadConfigFile(XTBL_LOADER_DIRECTORY_PATH, L"XTLDR.INI", &ConfigData); if(Status != STATUS_EFI_SUCCESS) { /* Failed to read config file, try with architecture specific directory */ - Status = BlpReadConfigFile(XTBL_ARCH_LOADER_DIRECTORY_PATH, L"XTLDR.INI", &ConfigData); + Status = ReadConfigFile(XTBL_ARCH_LOADER_DIRECTORY_PATH, L"XTLDR.INI", &ConfigData); } /* Check if configuration was read successfully */ if(Status != STATUS_EFI_SUCCESS) { /* Failed to load configuration */ - BlDebugPrint(L"Failed to load FS0:/EFI/BOOT/XTLDR/XTLDR.INI configuration file (Status Code: 0x%zX)\n", Status); + Debug::Print(L"Failed to load FS0:/EFI/BOOT/XTLDR/XTLDR.INI configuration file (Status Code: 0x%zX)\n", Status); return Status; } /* Parse configuration data */ - Status = BlpParseConfigFile(ConfigData, &BlpConfigSections); + Status = ParseConfigFile(ConfigData, &ConfigSections); if(Status != STATUS_EFI_SUCCESS) { /* Failed to parse configuration */ - BlDebugPrint(L"Failed to parse FS0:/EFI/BOOT/XTLDR/XTLDR.INI configuration file (Status Code: 0x%zX)\n", Status); + Debug::Print(L"Failed to parse FS0:/EFI/BOOT/XTLDR/XTLDR.INI configuration file (Status Code: 0x%zX)\n", Status); return Status; } /* Iterate through config sections */ - SectionListEntry = BlpConfigSections.Flink; - while(SectionListEntry != &BlpConfigSections) + SectionListEntry = ConfigSections.Flink; + while(SectionListEntry != &ConfigSections) { /* Get config section */ PXTBL_CONFIG_SECTION Section = CONTAIN_RECORD(SectionListEntry, XTBL_CONFIG_SECTION, Flink); /* Look for global XTLDR configuration section */ - if(RtlCompareWideStringInsensitive(Section->SectionName, L"XTLDR", 5) == 0) + if(RTL::WideString::CompareWideStringInsensitive(Section->SectionName, L"XTLDR", 5) == 0) { /* Update global configuration */ - BlpUpdateConfiguration(&Section->Options); + UpdateConfiguration(&Section->Options); /* Remove XTLDR section from the list */ - RtlRemoveEntryList(SectionListEntry); + RTL::LinkedList::RemoveEntryList(SectionListEntry); break; } @@ -465,7 +443,7 @@ BlpLoadConfiguration() } /* Update boot menu OS list */ - BlpMenuList = &BlpConfigSections; + BootMenuList = &ConfigSections; /* Return success */ return STATUS_EFI_SUCCESS; @@ -480,7 +458,7 @@ BlpLoadConfiguration() */ XTCDECL EFI_STATUS -BlpParseCommandLine(VOID) +Configuration::ParseCommandLine(VOID) { EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; @@ -491,20 +469,21 @@ BlpParseCommandLine(VOID) LIST_ENTRY Config; /* Initialize configuration list */ - RtlInitializeListHead(&Config); + RTL::LinkedList::InitializeListHead(&Config); /* Handle loaded image protocol */ - Status = EfiSystemTable->BootServices->HandleProtocol(EfiImageHandle, &LIPGuid, (PVOID *)&LoadedImage); + Status = XtLoader::GetEfiSystemTable()->BootServices->HandleProtocol(XtLoader::GetEfiImageHandle(), + &LIPGuid, (PVOID *)&LoadedImage); if(Status == STATUS_EFI_SUCCESS) { /* Check if launched from UEFI shell */ if(LoadedImage && LoadedImage->LoadOptions) { /* Tokenize provided options */ - Argument = RtlTokenizeWideString(LoadedImage->LoadOptions, L" ", &LastArg); + Argument = RTL::WideString::TokenizeWideString((PWCHAR)LoadedImage->LoadOptions, L" ", &LastArg); /* Iterate over all arguments passed to boot loader */ - while(Argument != NULL) + while(Argument != NULLPTR) { /* Store key name */ Key = Argument; @@ -535,8 +514,8 @@ BlpParseCommandLine(VOID) Argument++; /* Get length of the key and its value */ - KeyLength = RtlWideStringLength(Key, 0); - ValueLength = RtlWideStringLength(Value, 0); + KeyLength = RTL::WideString::WideStringLength(Key, 0); + ValueLength = RTL::WideString::WideStringLength(Value, 0); /* Check if argument is valid */ if(KeyLength == 0 || ValueLength == 0) @@ -546,15 +525,15 @@ BlpParseCommandLine(VOID) } /* Allocate memory for new option */ - Status = BlAllocateMemoryPool(sizeof(XTBL_CONFIG_ENTRY), (PVOID*)&Option); + Status = Memory::AllocatePool(sizeof(XTBL_CONFIG_ENTRY), (PVOID*)&Option); if(Status == STATUS_EFI_SUCCESS) { /* Allocate more memory for option name */ - Status = BlAllocateMemoryPool(sizeof(WCHAR) * (KeyLength + 1), (PVOID*)&Option->Name); + Status = Memory::AllocatePool(sizeof(WCHAR) * (KeyLength + 1), (PVOID*)&Option->Name); if(Status == STATUS_EFI_SUCCESS) { /* Allocate even more memory for option value */ - Status = BlAllocateMemoryPool(sizeof(WCHAR) * (ValueLength + 1), (PVOID*)&Option->Value); + Status = Memory::AllocatePool(sizeof(WCHAR) * (ValueLength + 1), (PVOID*)&Option->Value); } } if(Status != STATUS_EFI_SUCCESS) @@ -564,20 +543,20 @@ BlpParseCommandLine(VOID) } /* Set entry name and value */ - RtlCopyMemory(Option->Name, Key, (KeyLength * sizeof(WCHAR))); - RtlCopyMemory(Option->Value, Value, (ValueLength * sizeof(WCHAR))); + RTL::Memory::CopyMemory(Option->Name, Key, (KeyLength * sizeof(WCHAR))); + RTL::Memory::CopyMemory(Option->Value, Value, (ValueLength * sizeof(WCHAR))); Option->Name[KeyLength] = L'\0'; Option->Value[ValueLength] = L'\0'; /* Add entry to the list */ - RtlInsertTailList(&Config, &Option->Flink); + RTL::LinkedList::InsertTailList(&Config, &Option->Flink); /* Take next argument */ - Argument = RtlTokenizeWideString(NULL, L" ", &LastArg); + Argument = RTL::WideString::TokenizeWideString(NULLPTR, L" ", &LastArg); } /* Update global configuration */ - BlpUpdateConfiguration(&Config); + UpdateConfiguration(&Config); } } @@ -600,8 +579,8 @@ BlpParseCommandLine(VOID) */ XTCDECL EFI_STATUS -BlpParseConfigFile(IN CONST PCHAR RawConfig, - OUT PLIST_ENTRY Configuration) +Configuration::ParseConfigFile(IN CONST PCHAR RawConfig, + OUT PLIST_ENTRY Configuration) { SIZE_T SectionLength, KeyLength, ValueLength; PCHAR InputData, Key, SectionName, Value; @@ -611,11 +590,11 @@ BlpParseConfigFile(IN CONST PCHAR RawConfig, /* Initialize pointers */ InputData = RawConfig; - Section = NULL; - Option = NULL; - SectionName = NULL; - Key = NULL; - Value = NULL; + Section = NULLPTR; + Option = NULLPTR; + SectionName = NULLPTR; + Key = NULLPTR; + Value = NULLPTR; /* Analyze configuration data until end of file is reached */ while(*InputData != '\0') @@ -661,17 +640,17 @@ BlpParseConfigFile(IN CONST PCHAR RawConfig, InputData++; /* Remove leading and trailing spaces from section name */ - SectionName = RtlTrimString(SectionName); + SectionName = RTL::String::TrimString(SectionName); /* Find length of the section name */ - SectionLength = RtlStringLength(SectionName, 0); + SectionLength = RTL::String::StringLength(SectionName, 0); /* Allocate memory for new section */ - Status = BlAllocateMemoryPool(sizeof(XTBL_CONFIG_SECTION), (PVOID*)&Section); + Status = Memory::AllocatePool(sizeof(XTBL_CONFIG_SECTION), (PVOID*)&Section); if(Status == STATUS_EFI_SUCCESS) { /* Allocate more memory for section name */ - Status = BlAllocateMemoryPool(sizeof(WCHAR) * (SectionLength + 1), (PVOID*)&Section->SectionName); + Status = Memory::AllocatePool(sizeof(WCHAR) * (SectionLength + 1), (PVOID*)&Section->SectionName); } if(Status != STATUS_EFI_SUCCESS) { @@ -680,12 +659,12 @@ BlpParseConfigFile(IN CONST PCHAR RawConfig, } /* Initialize new section and convert its name to wide string */ - RtlInitializeListHead(&Section->Options); - RtlStringToWideString(Section->SectionName, (PCSTR*)&SectionName, SectionLength); + RTL::LinkedList::InitializeListHead(&Section->Options); + RTL::String::StringToWideString(Section->SectionName, (PCSTR*)&SectionName, SectionLength); /* Ensure string is NULL-terminated and add new section to the configuration list */ Section->SectionName[SectionLength] = L'\0'; - RtlInsertTailList(Configuration, &Section->Flink); + RTL::LinkedList::InsertTailList(Configuration, &Section->Flink); } else { @@ -732,23 +711,23 @@ BlpParseConfigFile(IN CONST PCHAR RawConfig, InputData++; /* Remove leading and trailing spaces from key and value */ - Key = RtlTrimString(Key); - Value = RtlTrimString(Value); + Key = RTL::String::TrimString(Key); + Value = RTL::String::TrimString(Value); /* Find length of the key and its value */ - KeyLength = RtlStringLength(Key, 0); - ValueLength = RtlStringLength(Value, 0); + KeyLength = RTL::String::StringLength(Key, 0); + ValueLength = RTL::String::StringLength(Value, 0); /* Allocate memory for new option */ - Status = BlAllocateMemoryPool(sizeof(XTBL_CONFIG_ENTRY), (PVOID*)&Option); + Status = Memory::AllocatePool(sizeof(XTBL_CONFIG_ENTRY), (PVOID*)&Option); if(Status == STATUS_EFI_SUCCESS) { /* Allocate more memory for option name */ - Status = BlAllocateMemoryPool(sizeof(WCHAR) * (KeyLength + 1), (PVOID*)&Option->Name); + Status = Memory::AllocatePool(sizeof(WCHAR) * (KeyLength + 1), (PVOID*)&Option->Name); if(Status == STATUS_EFI_SUCCESS) { /* Allocate even more memory for option value */ - Status = BlAllocateMemoryPool(sizeof(WCHAR) * (ValueLength + 1), (PVOID*)&Option->Value); + Status = Memory::AllocatePool(sizeof(WCHAR) * (ValueLength + 1), (PVOID*)&Option->Value); } } if(Status != STATUS_EFI_SUCCESS) @@ -770,13 +749,13 @@ BlpParseConfigFile(IN CONST PCHAR RawConfig, } /* Convert key and value to wide strings */ - RtlStringToWideString(Option->Name, (PCSTR*)&Key, RtlStringLength(Key, 0) + 1); - RtlStringToWideString(Option->Value, (PCSTR*)&Value, RtlStringLength(Value, 0) + 1); + RTL::String::StringToWideString(Option->Name, (PCSTR*)&Key, RTL::String::StringLength(Key, 0) + 1); + RTL::String::StringToWideString(Option->Value, (PCSTR*)&Value, RTL::String::StringLength(Value, 0) + 1); /* Ensure strings are NULL-terminated and add new option to the list */ Option->Name[KeyLength] = L'\0'; Option->Value[ValueLength] = L'\0'; - RtlInsertTailList(&Section->Options, &Option->Flink); + RTL::LinkedList::InsertTailList(&Section->Options, &Option->Flink); } } @@ -802,9 +781,9 @@ BlpParseConfigFile(IN CONST PCHAR RawConfig, */ XTCDECL EFI_STATUS -BlpReadConfigFile(IN CONST PWCHAR ConfigDirectory, - IN CONST PWCHAR ConfigFile, - OUT PCHAR *ConfigData) +Configuration::ReadConfigFile(IN PCWSTR ConfigDirectory, + IN PCWSTR ConfigFile, + OUT PCHAR *ConfigData) { PEFI_FILE_HANDLE DirHandle, FsHandle; EFI_HANDLE DiskHandle; @@ -812,7 +791,7 @@ BlpReadConfigFile(IN CONST PWCHAR ConfigDirectory, SIZE_T FileSize; /* Open EFI volume */ - Status = BlOpenVolume(NULL, &DiskHandle, &FsHandle); + Status = Volume::OpenVolume(NULLPTR, &DiskHandle, &FsHandle); if(Status != STATUS_EFI_SUCCESS) { /* Failed to open a volume */ @@ -820,28 +799,216 @@ BlpReadConfigFile(IN CONST PWCHAR ConfigDirectory, } /* Open specified directory, containing the configuration file and close the FS immediately */ - Status = FsHandle->Open(FsHandle, &DirHandle, ConfigDirectory, EFI_FILE_MODE_READ, 0); + Status = FsHandle->Open(FsHandle, &DirHandle, (PWCHAR)ConfigDirectory, EFI_FILE_MODE_READ, 0); FsHandle->Close(FsHandle); /* Check if directory opened successfully */ if(Status != STATUS_EFI_SUCCESS) { /* Failed to open directory */ - BlCloseVolume(DiskHandle); + Volume::CloseVolume(&DiskHandle); return Status; } /* Read configuration file and close directory */ - Status = BlReadFile(DirHandle, ConfigFile, (PVOID *)ConfigData, &FileSize); + Status = Volume::ReadFile(DirHandle, ConfigFile, (PVOID *)ConfigData, &FileSize); DirHandle->Close(DirHandle); /* Close EFI volume */ - BlCloseVolume(DiskHandle); + Volume::CloseVolume(&DiskHandle); /* Return read status */ return Status; } + +/** + * Sets the value of a specific OS boot option in a list, or adds it if it doesn't exist. + * + * @param Options + * A pointer to the head of a list of XTBL_CONFIG_ENTRY structures. + * + * @param OptionName + * A pointer to a wide string that contains the name of the boot option to set. + * + * @param OptionValue + * A pointer to a wide string that contains the new value for the boot option. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +Configuration::SetBootOptionValue(IN PLIST_ENTRY Options, + IN PCWSTR OptionName, + IN PCWSTR OptionValue) +{ + PXTBL_CONFIG_ENTRY ConfigEntry; + PLIST_ENTRY ConfigList; + ULONG Length; + EFI_STATUS Status; + + /* Get the length of the option name we are looking for */ + Length = RTL::WideString::WideStringLength(OptionName, 0); + + /* Start iterating from the first entry in the options list */ + ConfigList = Options->Flink; + while(ConfigList != Options) + { + /* Get the container record for the current config entry */ + ConfigEntry = CONTAIN_RECORD(ConfigList, XTBL_CONFIG_ENTRY, Flink); + + /* Compare the current entry's name with the requested option name */ + if(RTL::WideString::CompareWideStringInsensitive(ConfigEntry->Name, OptionName, Length) == 0) + { + /* Found the option, get its length */ + Length = RTL::WideString::WideStringLength(OptionValue, 0); + + /* Reallocate memory for the new value */ + Status = Memory::FreePool(ConfigEntry->Value); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to free memory, return status code */ + return Status; + } + + /* Allocate new memory for the updated value */ + Status = Memory::AllocatePool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Value); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure, print debug message and return status code */ + Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status); + return Status; + } + + /* Copy the value and NULL-terminate the new string */ + RTL::Memory::CopyMemory(ConfigEntry->Value, OptionValue, Length * sizeof(WCHAR)); + ConfigEntry->Value[Length] = L'\0'; + return STATUS_EFI_SUCCESS; + } + + /* Move to the next entry in the list */ + ConfigList = ConfigList->Flink; + } + + /* Option not found, allocate memory for the new one */ + Status = Memory::AllocatePool(sizeof(XTBL_CONFIG_ENTRY), (PVOID *)&ConfigEntry); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure, print debug message and return status code */ + Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status); + return Status; + } + + /* Allocate memory for the option name */ + Length = RTL::WideString::WideStringLength(OptionName, 0); + Status = Memory::AllocatePool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Name); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure, print debug message and return status code */ + Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status); + Memory::FreePool(ConfigEntry); + return Status; + } + + /* Copy the option name and NULL-terminate the new string */ + RTL::Memory::CopyMemory(ConfigEntry->Name, OptionName, Length * sizeof(WCHAR)); + ConfigEntry->Name[Length] = L'\0'; + + /* Allocate memory for the option value */ + Length = RTL::WideString::WideStringLength(OptionValue, 0); + Status = Memory::AllocatePool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Value); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure, print debug message and return status code */ + Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status); + Memory::FreePool(ConfigEntry->Name); + Memory::FreePool(ConfigEntry); + return Status; + } + + /* Copy the value and NULL-terminate the new string */ + RTL::Memory::CopyMemory(ConfigEntry->Value, OptionValue, Length * sizeof(WCHAR)); + ConfigEntry->Value[Length] = L'\0'; + + /* Insert the new config entry at the end of the options list */ + RTL::LinkedList::InsertTailList(Options, &ConfigEntry->Flink); + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Updates existing configuration value. + * + * @param ConfigName + * Specifies the configuration key to update. + * + * @param ConfigValue + * Specifies the new configuration value. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +Configuration::SetValue(IN PCWSTR ConfigName, + IN PCWSTR ConfigValue) +{ + PXTBL_CONFIG_ENTRY ConfigEntry; + PLIST_ENTRY ConfigListEntry; + EFI_STATUS Status; + SIZE_T Length; + + /* Get config entry name length */ + Length = RTL::WideString::WideStringLength(ConfigName, 0); + + /* Iterate through config entries */ + ConfigListEntry = Config.Flink; + while(ConfigListEntry != &Config) + { + /* Get config entry */ + ConfigEntry = CONTAIN_RECORD(ConfigListEntry, XTBL_CONFIG_ENTRY, Flink); + + /* Check if requested configuration found */ + if(RTL::WideString::CompareWideStringInsensitive(ConfigEntry->Name, ConfigName, Length) == 0) + { + /* Check new config value length */ + Length = RTL::WideString::WideStringLength(ConfigValue, 0); + + /* Reallocate memory for new config value */ + Status = Memory::FreePool(ConfigEntry->Value); + if(Status == STATUS_EFI_SUCCESS) + { + /* Successfully freed memory, allocate a new pool */ + Status = Memory::AllocatePool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Value); + } + + /* Check memory reallocation status */ + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to reallocate memory */ + return Status; + } + + /* Update config value */ + RTL::Memory::CopyMemory(ConfigEntry->Value, ConfigValue, Length * sizeof(WCHAR)); + ConfigEntry->Value[Length] = L'\0'; + + /* Return success */ + return STATUS_EFI_SUCCESS; + } + + /* Move to the next config entry */ + ConfigListEntry = ConfigListEntry->Flink; + } + + /* Config entry not found */ + return STATUS_EFI_NOT_FOUND; +} + /** * Adds new XTLDR configuration entries to the global configuration list. Existing entries are not overwritten. * @@ -854,7 +1021,7 @@ BlpReadConfigFile(IN CONST PWCHAR ConfigDirectory, */ XTCDECL VOID -BlpUpdateConfiguration(IN PLIST_ENTRY NewConfig) +Configuration::UpdateConfiguration(IN PLIST_ENTRY NewConfig) { PXTBL_CONFIG_ENTRY ConfigEntry; PWCHAR ConfigValue; @@ -871,12 +1038,12 @@ BlpUpdateConfiguration(IN PLIST_ENTRY NewConfig) NextListEntry = ConfigListEntry->Flink; /* Make sure config entry does not exist yet */ - BlGetConfigValue(ConfigEntry->Name, &ConfigValue); - if(ConfigValue == NULL) + GetValue(ConfigEntry->Name, &ConfigValue); + if(ConfigValue == NULLPTR) { /* Remove new config entry from input list and put it into global config list */ - RtlRemoveEntryList(&ConfigEntry->Flink); - RtlInsertTailList(&BlpConfig, &ConfigEntry->Flink); + RTL::LinkedList::RemoveEntryList(&ConfigEntry->Flink); + RTL::LinkedList::InsertTailList(&Config, &ConfigEntry->Flink); } /* Move to the next new config entry */ diff --git a/xtldr/console.c b/xtldr/console.cc similarity index 63% rename from xtldr/console.c rename to xtldr/console.cc index 618df8e..e003591 100644 --- a/xtldr/console.c +++ b/xtldr/console.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/console.c + * FILE: xtldr/console.cc * DESCRIPTION: EFI console support * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -21,19 +21,19 @@ */ XTCDECL VOID -BlClearConsoleLine(IN ULONGLONG LineNo) +Console::ClearLine(IN ULONGLONG LineNo) { UINT_PTR Index, ResX, ResY; /* Query console mode */ - BlQueryConsoleMode(&ResX, &ResY); + QueryMode(&ResX, &ResY); /* Set cursor position and clear line */ - BlSetCursorPosition(0, LineNo); + SetCursorPosition(0, LineNo); for(Index = 0; Index < ResX; Index++) { /* Clear line */ - BlConsoleWrite(L" "); + Write(L" "); } } @@ -46,10 +46,10 @@ BlClearConsoleLine(IN ULONGLONG LineNo) */ XTCDECL VOID -BlClearConsoleScreen() +Console::ClearScreen() { /* Clear screen */ - EfiSystemTable->ConOut->ClearScreen(EfiSystemTable->ConOut); + XtLoader::GetEfiSystemTable()->ConOut->ClearScreen(XtLoader::GetEfiSystemTable()->ConOut); } /** @@ -61,9 +61,9 @@ BlClearConsoleScreen() */ XTCDECL VOID -BlDisableConsoleCursor() +Console::DisableCursor() { - EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, FALSE); + XtLoader::GetEfiSystemTable()->ConOut->EnableCursor(XtLoader::GetEfiSystemTable()->ConOut, FALSE); } /** @@ -75,9 +75,39 @@ BlDisableConsoleCursor() */ XTCDECL 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 VOID -BlConsolePrint(IN PCWSTR Format, +Console::Print(IN PCWSTR Format, IN ...) { RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext; VA_LIST Arguments; /* Initialise the print contexts */ - ConsolePrintContext.WriteWideCharacter = BlpConsolePutChar; - SerialPrintContext.WriteWideCharacter = BlpDebugPutChar; + ConsolePrintContext.WriteWideCharacter = PutChar; + SerialPrintContext.WriteWideCharacter = Debug::PutChar; /* Initialise the va_list */ VA_START(Arguments, Format); /* 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 */ - 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 */ - if(DEBUG && (BlpStatus.SerialPort.Flags & COMPORT_FLAG_INIT)) + if(DEBUG && Debug::SerialPortReady()) { /* 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 PCWSTR Format, } /** - * Displays the string on the device at the current cursor location. + * Writes a character to the default EFI console. * - * @param String - * The string to be displayed. + * @param Character + * 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 */ XTCDECL -VOID -BlConsoleWrite(IN PCWSTR String) +XTSTATUS +Console::PutChar(IN WCHAR Character) { - EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, (PWSTR)String); -} + WCHAR Buffer[2]; -/** - * This routine initializes the EFI console. - * - * @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) + /* Check if character is a newline ('\n') */ + if(Character == L'\n') { - /* Set console mode to 0, which is standard, 80x25 text mode */ - BlSetConsoleMode(0); + /* Print carriage return ('\r') as well */ + PutChar(L'\r'); } - /* Clear screen and enable cursor */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); - BlClearConsoleScreen(); - BlEnableConsoleCursor(); + /* Write character to the screen console */ + Buffer[0] = Character; + Buffer[1] = 0; + XtLoader::GetEfiSystemTable()->ConOut->OutputString(XtLoader::GetEfiSystemTable()->ConOut, Buffer); + + /* Return success */ + return STATUS_SUCCESS; } /** @@ -188,10 +203,11 @@ BlInitializeConsole() */ XTCDECL VOID -BlQueryConsoleMode(OUT PUINT_PTR ResX, +Console::QueryMode(OUT PUINT_PTR ResX, 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 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 VOID -BlResetConsoleInputBuffer() +Console::ResetInputBuffer() { - EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, FALSE); + XtLoader::GetEfiSystemTable()->ConIn->Reset(XtLoader::GetEfiSystemTable()->ConIn, FALSE); } /** @@ -237,26 +253,9 @@ BlResetConsoleInputBuffer() */ XTCDECL VOID -BlSetConsoleAttributes(IN ULONGLONG Attributes) +Console::SetAttributes(IN ULONGLONG Attributes) { - EfiSystemTable->ConOut->SetAttribute(EfiSystemTable->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); + XtLoader::GetEfiSystemTable()->ConOut->SetAttribute(XtLoader::GetEfiSystemTable()->ConOut, Attributes); } /** @@ -274,40 +273,42 @@ BlSetConsoleMode(IN ULONGLONG Mode) */ XTCDECL VOID -BlSetCursorPosition(IN ULONGLONG PosX, - IN ULONGLONG PosY) +Console::SetCursorPosition(IN ULONGLONG PosX, + 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 - * The integer promotion of the character to be written. + * @param Mode + * Supplies a text mode number to set. * * @return This routine returns a status code. * * @since XT 1.0 */ XTCDECL -XTSTATUS -BlpConsolePutChar(IN WCHAR Character) +EFI_STATUS +Console::SetMode(IN ULONGLONG Mode) { - WCHAR Buffer[2]; - - /* Check if character is a newline ('\n') */ - if(Character == L'\n') - { - /* Print carriage return ('\r') as well */ - BlpConsolePutChar(L'\r'); - } - - /* Write character to the screen console */ - Buffer[0] = Character; - Buffer[1] = 0; - EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, Buffer); - - /* Return success */ - return STATUS_SUCCESS; + return XtLoader::GetEfiSystemTable()->ConOut->SetMode(XtLoader::GetEfiSystemTable()->ConOut, Mode); +} + +/** + * Displays the string on the device at the current cursor location. + * + * @param String + * The string to be displayed. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +Console::Write(IN PCWSTR String) +{ + XtLoader::GetEfiSystemTable()->ConOut->OutputString(XtLoader::GetEfiSystemTable()->ConOut, (PWSTR)String); } diff --git a/xtldr/data.cc b/xtldr/data.cc new file mode 100644 index 0000000..d0a30aa --- /dev/null +++ b/xtldr/data.cc @@ -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 + * Aiken Harris + */ + +#include + + +/* 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}; diff --git a/xtldr/debug.c b/xtldr/debug.c deleted file mode 100644 index f2334d6..0000000 --- a/xtldr/debug.c +++ /dev/null @@ -1,284 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/debug.c - * DESCRIPTION: XT Boot Loader debugging support - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/** - * 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 -BlDebugPrint(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 = BlpConsolePutChar; - SerialPrintContext.WriteWideCharacter = BlpDebugPutChar; - - /* Initialise the va_list */ - VA_START(Arguments, Format); - - /* Check if serial debug port is enabled */ - if((BlpStatus.DebugPort & XTBL_DEBUGPORT_SERIAL) && (BlpStatus.SerialPort.Flags & COMPORT_FLAG_INIT)) - { - /* Format and print the string to the serial console */ - RtlFormatWideString(&SerialPrintContext, (PWCHAR)Format, Arguments); - } - - /* Check if screen debug port is enabled and Boot Services are still available */ - if((BlpStatus.DebugPort & XTBL_DEBUGPORT_SCREEN) && (BlpStatus.BootServices == TRUE)) - { - /* Format and print the string to the screen */ - RtlFormatWideString(&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 -BlpDebugPutChar(IN WCHAR Character) -{ - WCHAR Buffer[2]; - - /* Write character to the serial console */ - Buffer[0] = Character; - Buffer[1] = 0; - return HlComPortPutByte(&BlpStatus.SerialPort, Buffer[0]); -} - -/** - * This routine initializes the XTLDR debug console. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlpInitializeDebugConsole() -{ - 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 */ - BlGetConfigValue(L"DEBUG", &DebugConfiguration); - - /* Make sure any debug options are provided and debug console is not initialized yet */ - if(DebugConfiguration && BlpStatus.DebugPort == 0) - { - /* Find all debug ports */ - DebugPort = RtlTokenizeWideString(DebugConfiguration, L";", &LastPort); - - /* Iterate over all debug ports */ - while(DebugPort != NULL) - { - /* Check what port is set for debugging */ - if(RtlCompareWideStringInsensitive(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 && RtlCompareWideStringInsensitive(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 */ - BlpStatus.DebugPort |= XTBL_DEBUGPORT_SERIAL; - } - else if(RtlCompareWideStringInsensitive(DebugPort, L"SCREEN", 5) == 0) - { - /* Enable debug port */ - BlpStatus.DebugPort |= XTBL_DEBUGPORT_SCREEN; - } - else - { - /* Unsupported debug port specified */ - BlConsolePrint(L"ERROR: Unsupported debug port ('%S') specified\n", DebugPort); - BlSleepExecution(3000); - } - - /* Take next debug port */ - DebugPort = RtlTokenizeWideString(NULL, L";", &LastPort); - } - - /* Check if serial debug port is enabled */ - if(BlpStatus.DebugPort & XTBL_DEBUGPORT_SERIAL) - { - /* Try to initialize COM port */ - Status = BlpInitializeSerialPort(PortNumber, PortAddress, BaudRate); - if(Status != STATUS_EFI_SUCCESS) - { - /* Remove serial debug port, as COM port initialization failed and return */ - BlpStatus.DebugPort &= ~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 -BlpInitializeSerialPort(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 = BlComPortList[PortNumber - 1]; - BlConsolePrint(L"Initializing serial console at port COM%d\n", PortNumber); - } - else - { - /* Custom port address supplied, print debug message */ - BlConsolePrint(L"Initializing serial console at COM port address: 0x%lX\n", PortAddress); - } - - /* Initialize COM port */ - Status = HlInitializeComPort(&BlpStatus.SerialPort, 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 = BlpActivateSerialIOController(); - if(EfiStatus == STATUS_EFI_SUCCESS) - { - /* Try to reinitialize COM port */ - BlConsolePrint(L"Enabled I/O space access for all PCI(E) serial controllers found\n"); - Status = HlInitializeComPort(&BlpStatus.SerialPort, 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; -} diff --git a/xtldr/debug.cc b/xtldr/debug.cc new file mode 100644 index 0000000..34c4946 --- /dev/null +++ b/xtldr/debug.cc @@ -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 + */ + +#include + + +/** + * 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); +} diff --git a/xtldr/efiutils.c b/xtldr/efiutils.cc similarity index 64% rename from xtldr/efiutils.c rename to xtldr/efiutils.cc index 5bda800..ede371b 100644 --- a/xtldr/efiutils.c +++ b/xtldr/efiutils.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * 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 * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -18,29 +18,35 @@ */ XTCDECL EFI_STATUS -BlEnterFirmwareSetup() +EfiUtils::EnterFirmwareSetup() { EFI_GUID Guid = EFI_GLOBAL_VARIABLE_GUID; - PULONGLONG SetupSupport; + PULONGLONG SetupSupport = NULLPTR; ULONGLONG Indications; EFI_STATUS Status; /* 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)) { /* 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; } + Memory::FreePool((PVOID)SetupSupport); + /* Get the value of OsIndications variable */ Indications = 0; - Status = BlGetEfiVariable(&Guid, L"OsIndications", (PVOID)&Indications); + Status = GetEfiVariable(&Guid, L"OsIndications", (PVOID*)&Indications); /* Enable FW setup on next boot */ 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) { /* Failed to update OsIndications variable */ @@ -48,7 +54,7 @@ BlEnterFirmwareSetup() } /* Reboot into firmware setup */ - BlRebootSystem(); + RebootSystem(); /* Must not reach this point, just make the compiler happy */ return STATUS_EFI_SUCCESS; @@ -63,33 +69,33 @@ BlEnterFirmwareSetup() */ XTCDECL EFI_STATUS -BlExitBootServices() +EfiUtils::ExitBootServices() { PEFI_MEMORY_MAP MemoryMap; EFI_STATUS Status; ULONG Counter; /* Boot Services might be partially shutdown, so mark them as unavailable */ - BlpStatus.BootServices = FALSE; + XtLoader::DisableBootServices(); /* 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) { /* 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; } /* Zero fill the buffer and initialize counter */ - RtlZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP)); + RTL::Memory::ZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP)); Counter = 0xFF; /* Attempt to exit boot services */ while(Counter > 0) { /* Get memory map each time as it can change between two calls */ - Status = BlGetMemoryMap(MemoryMap); + Status = Memory::GetMemoryMap(MemoryMap); if(Status != STATUS_EFI_SUCCESS) { /* Failed to get new memory map */ @@ -97,7 +103,8 @@ BlExitBootServices() } /* Exit boot services */ - Status = EfiSystemTable->BootServices->ExitBootServices(EfiImageHandle, MemoryMap->MapKey); + Status = XtLoader::GetEfiSystemTable()->BootServices->ExitBootServices(XtLoader::GetEfiImageHandle(), + MemoryMap->MapKey); if(Status == STATUS_EFI_SUCCESS) { break; @@ -126,25 +133,26 @@ BlExitBootServices() */ XTCDECL EFI_STATUS -BlGetConfigurationTable(IN PEFI_GUID TableGuid, - OUT PVOID *Table) +EfiUtils::GetConfigurationTable(IN PEFI_GUID TableGuid, + OUT PVOID *Table) { SIZE_T Index; /* 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 */ - 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 */ - *Table = EfiSystemTable->ConfigurationTable[Index].VendorTable; + *Table = XtLoader::GetEfiSystemTable()->ConfigurationTable[Index].VendorTable; return STATUS_EFI_SUCCESS; } } /* Table not found */ - *Table = NULL; + *Table = NULLPTR; return STATUS_EFI_NOT_FOUND; } @@ -166,17 +174,17 @@ BlGetConfigurationTable(IN PEFI_GUID TableGuid, */ XTCDECL EFI_STATUS -BlGetEfiVariable(IN PEFI_GUID Vendor, - IN PWCHAR VariableName, - OUT PVOID *VariableValue) +EfiUtils::GetEfiVariable(IN PEFI_GUID Vendor, + IN PCWSTR VariableName, + OUT PVOID *VariableValue) { EFI_STATUS Status; PVOID Buffer; - UINT_PTR Size; + UINT_PTR Size = 0; /* Allocate a buffer for storing a variable's value */ Size = EFI_MAXIMUM_VARIABLE_SIZE * sizeof(PWCHAR); - Status = BlAllocateMemoryPool(Size, (PVOID*)&Buffer); + Status = Memory::AllocatePool(Size, (PVOID*)&Buffer); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ @@ -184,7 +192,8 @@ BlGetEfiVariable(IN PEFI_GUID Vendor, } /* 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) { /* Failed to get variable, probably not found such one */ @@ -210,7 +219,7 @@ BlGetEfiVariable(IN PEFI_GUID Vendor, */ XTCDECL ULONGLONG -BlGetRandomValue(IN OUT PULONGLONG RNGBuffer) +EfiUtils::GetRandomValue(IN OUT PULONGLONG RNGBuffer) { /* Recalculate RNG buffer with XORSHIFT */ *RNGBuffer ^= *RNGBuffer >> 12; @@ -230,21 +239,21 @@ BlGetRandomValue(IN OUT PULONGLONG RNGBuffer) */ XTCDECL INT_PTR -BlGetSecureBootStatus() +EfiUtils::GetSecureBootStatus() { EFI_GUID VarGuid = EFI_GLOBAL_VARIABLE_GUID; INT_PTR SecureBootStatus = 0; - UCHAR VarValue = 0; + INT_PTR VarValue = 0; UINT_PTR Size; - Size = sizeof(VarValue); - if(EfiSystemTable->RuntimeServices->GetVariable(L"SecureBoot", &VarGuid, - NULL, &Size, &VarValue) == STATUS_EFI_SUCCESS) + Size = sizeof(INT_PTR); + if(XtLoader::GetEfiSystemTable()->RuntimeServices->GetVariable((PWCHAR)L"SecureBoot", &VarGuid, + NULLPTR, &Size, &VarValue) == STATUS_EFI_SUCCESS) { - SecureBootStatus = (INT_PTR)VarValue; - - if((EfiSystemTable->RuntimeServices->GetVariable(L"SetupMode", &VarGuid, - NULL, &Size, &VarValue) == STATUS_EFI_SUCCESS) && VarValue != 0) + SecureBootStatus = VarValue; + Size = sizeof(INT_PTR); + if((XtLoader::GetEfiSystemTable()->RuntimeServices->GetVariable((PWCHAR)L"SetupMode", &VarGuid, + NULLPTR, &Size, &VarValue) == STATUS_EFI_SUCCESS) && VarValue != 0) { SecureBootStatus = -1; } @@ -266,7 +275,7 @@ BlGetSecureBootStatus() */ XTCDECL EFI_STATUS -BlInitializeEntropy(PULONGLONG RNGBuffer) +EfiUtils::InitializeEntropy(PULONGLONG RNGBuffer) { EFI_GUID RngGuid = EFI_RNG_PROTOCOL_GUID; PEFI_RNG_PROTOCOL Rng; @@ -274,11 +283,11 @@ BlInitializeEntropy(PULONGLONG RNGBuffer) ULONGLONG Seed; /* Initialize variables */ - Rng = NULL; + Rng = NULLPTR; Seed = 0; /* 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) { /* Failed to locate RNG protocol, return status code */ @@ -286,7 +295,7 @@ BlInitializeEntropy(PULONGLONG RNGBuffer) } /* 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) { /* Failed to get RNG value, return status code */ @@ -319,13 +328,14 @@ BlInitializeEntropy(PULONGLONG RNGBuffer) */ XTCDECL EFI_STATUS -BlLoadEfiImage(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, - IN PVOID ImageData, - IN SIZE_T ImageSize, - OUT PEFI_HANDLE ImageHandle) +EfiUtils::LoadEfiImage(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, + IN PVOID ImageData, + IN SIZE_T ImageSize, + OUT PEFI_HANDLE ImageHandle) { /* 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 EFI_STATUS -BlRebootSystem() +EfiUtils::RebootSystem() { /* Reboot machine */ - return EfiSystemTable->RuntimeServices->ResetSystem(EfiResetCold, STATUS_EFI_SUCCESS, 0, NULL); + return XtLoader::GetEfiSystemTable()->RuntimeServices->ResetSystem(EfiResetCold, STATUS_EFI_SUCCESS, 0, NULLPTR); } /** @@ -364,16 +374,17 @@ BlRebootSystem() */ XTCDECL EFI_STATUS -BlSetEfiVariable(IN PEFI_GUID Vendor, - IN PWCHAR VariableName, - IN PVOID VariableValue, - IN UINT_PTR Size) +EfiUtils::SetEfiVariable(IN PEFI_GUID Vendor, + IN PCWSTR VariableName, + IN PVOID VariableValue, + IN UINT_PTR Size) { ULONG Attributes; /* Set EFI variable */ 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 EFI_STATUS -BlShutdownSystem() +EfiUtils::ShutdownSystem() { /* 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 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 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 EFI_STATUS -BlWaitForEfiEvent(IN UINT_PTR NumberOfEvents, - IN PEFI_EVENT Event, - OUT PUINT_PTR Index) +EfiUtils::WaitForEfiEvent(IN UINT_PTR NumberOfEvents, + IN PEFI_EVENT Event, + OUT PUINT_PTR Index) { - return EfiSystemTable->BootServices->WaitForEvent(NumberOfEvents, Event, Index); + return XtLoader::GetEfiSystemTable()->BootServices->WaitForEvent(NumberOfEvents, Event, Index); } diff --git a/xtldr/globals.c b/xtldr/globals.c deleted file mode 100644 index d88b201..0000000 --- a/xtldr/globals.c +++ /dev/null @@ -1,51 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/globals.c - * DESCRIPTION: XT Boot Loader global variables - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/* XT Boot Loader registered boot protocol list */ -LIST_ENTRY BlpBootProtocols; - -/* XT Boot Loader serial ports list */ -ULONG BlComPortList[COMPORT_COUNT] = COMPORT_ADDRESS; - -/* XT Boot Loader configuration list */ -LIST_ENTRY BlpConfig; - -/* XT Boot Loader loaded configuration */ -LIST_ENTRY BlpConfigSections; - -/* List of user-editable boot options */ -PWCHAR BlpEditableConfigOptions[] = { - L"BootModules", L"SystemType", L"SystemPath", - L"KernelFile", L"InitrdFile", L"HalFile", - L"Parameters", NULL -}; - -/* XT Boot Loader protocol */ -XTBL_LOADER_PROTOCOL BlpLdrProtocol; - -/* XT Boot Loader loaded modules list */ -LIST_ENTRY BlpLoadedModules; - -/* XT Boot Loader menu list */ -PLIST_ENTRY BlpMenuList = NULL; - -/* XT Boot Loader status data */ -XTBL_STATUS BlpStatus = {0}; - -/* List of available block devices */ -LIST_ENTRY EfiBlockDevices; - -/* EFI Image Handle */ -EFI_HANDLE EfiImageHandle; - -/* EFI System Table */ -PEFI_SYSTEM_TABLE EfiSystemTable; - diff --git a/xtldr/hardware.c b/xtldr/hardware.c deleted file mode 100644 index 08b6a03..0000000 --- a/xtldr/hardware.c +++ /dev/null @@ -1,112 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/hardware.c - * DESCRIPTION: EFI hardware support for XT Boot Loader - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/** - * 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 -BlpActivateSerialIOController() -{ - 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 = NULL; - 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 = BlAllocateMemoryPool(PciHandleSize, (PVOID*)&PciHandle); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure */ - return Status; - } - - /* Get all instances of PciRootBridgeIo */ - Status = EfiSystemTable->BootServices->LocateHandle(ByProtocol, &PciGuid, NULL, &PciHandleSize, PciHandle); - if(Status == STATUS_EFI_BUFFER_TOO_SMALL) - { - /* Reallocate more memory as requested by UEFI */ - BlFreeMemoryPool(PciHandle); - Status = BlAllocateMemoryPool(PciHandleSize, (PVOID*)&PciHandle); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory reallocation failure */ - return Status; - } - - /* Second attempt to get instances of PciRootBridgeIo */ - Status = EfiSystemTable->BootServices->LocateHandle(ByProtocol, &PciGuid, NULL, &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 = EfiSystemTable->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, 2, 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, 1, Address, 1, &Command); - } - } - } - } - } - - /* Return SUCCESS */ - return STATUS_EFI_SUCCESS; -} diff --git a/xtldr/includes/globals.h b/xtldr/includes/globals.hh similarity index 86% rename from xtldr/includes/globals.h rename to xtldr/includes/globals.hh index 5798f47..d40360a 100644 --- a/xtldr/includes/globals.h +++ b/xtldr/includes/globals.hh @@ -1,13 +1,13 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/includes/globals.h + * FILE: xtldr/includes/globals.hh * DESCRIPTION: XTLDR global variables * DEVELOPERS: Rafal Kupiec */ -#ifndef __XTLDR_GLOBALS_H -#define __XTLDR_GLOBALS_H +#ifndef __XTLDR_GLOBALS_HH +#define __XTLDR_GLOBALS_HH #include @@ -25,7 +25,7 @@ EXTERN LIST_ENTRY BlpConfig; EXTERN LIST_ENTRY BlpConfigSections; /* List of user-editable boot options */ -EXTERN PWCHAR BlpEditableConfigOptions[]; +EXTERN PCWSTR BlpEditableConfigOptions[]; /* XT Boot Loader protocol */ EXTERN XTBL_LOADER_PROTOCOL BlpLdrProtocol; @@ -48,4 +48,4 @@ EXTERN EFI_HANDLE EfiImageHandle; /* EFI System Table */ EXTERN PEFI_SYSTEM_TABLE EfiSystemTable; -#endif /* __XTLDR_GLOBALS_H */ +#endif /* __XTLDR_GLOBALS_HH */ diff --git a/xtldr/includes/libxtos.hh b/xtldr/includes/libxtos.hh new file mode 100644 index 0000000..741d523 --- /dev/null +++ b/xtldr/includes/libxtos.hh @@ -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 + */ + +#ifndef __XTLDR_LIBXTOS_HH +#define __XTLDR_LIBXTOS_HH + +#include + + +/* 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 */ diff --git a/xtldr/includes/xtldr.h b/xtldr/includes/xtldr.h deleted file mode 100644 index 778dceb..0000000 --- a/xtldr/includes/xtldr.h +++ /dev/null @@ -1,582 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/includes/xtldr.h - * DESCRIPTION: Top level header for XTLDR - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTLDR_XTLDR_H -#define __XTLDR_XTLDR_H - -#include -#include - -#include - - -/* XTLDR routines forward references */ -XTCDECL -EFI_STATUS -BlAllocateMemoryPages(IN EFI_ALLOCATE_TYPE AllocationType, - IN ULONGLONG NumberOfPages, - OUT PEFI_PHYSICAL_ADDRESS Memory); - -XTCDECL -EFI_STATUS -BlAllocateMemoryPool(IN UINT_PTR Size, - OUT PVOID *Memory); - -XTCDECL -EFI_STATUS -BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, - IN ULONG_PTR SelfMapAddress); - -XTCDECL -VOID -BlClearConsoleLine(IN ULONGLONG LineNo); - -XTCDECL -VOID -BlClearConsoleScreen(); - -XTCDECL -EFI_STATUS -BlCloseProtocol(IN PEFI_HANDLE Handle, - IN PEFI_GUID ProtocolGuid); - -XTCDECL -EFI_STATUS -BlCloseVolume(IN PEFI_HANDLE VolumeHandle); - -XTCDECL -VOID -BlConsolePrint(IN PCWSTR Format, - IN ...); - -XTCDECL -VOID -BlConsoleWrite(IN PCWSTR String); - -XTCDECL -VOID -BlDebugPrint(IN PCWSTR Format, - IN ...); - -XTCDECL -VOID -BlDisableConsoleCursor(); - -XTCDECL -VOID -BlDisplayBootMenu(); - -XTCDECL -VOID -BlDisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry); - -XTCDECL -VOID -BlDisplayErrorDialog(IN PWCHAR Caption, - IN PWCHAR Message); - -XTCDECL -VOID -BlDisplayInfoDialog(IN PWCHAR Caption, - IN PWCHAR Message); - -XTCDECL -VOID -BlDisplayInputDialog(IN PWCHAR Caption, - IN PWCHAR Message, - IN OUT PWCHAR *InputFieldText); - -XTCDECL -XTBL_DIALOG_HANDLE -BlDisplayProgressDialog(IN PWCHAR Caption, - IN PWCHAR Message, - IN UCHAR Percentage); - -XTCDECL -VOID -BlEnableConsoleCursor(); - -XTCDECL -EFI_STATUS -BlEnterFirmwareSetup(); - -XTCDECL -EFI_STATUS -BlEnumerateBlockDevices(); - -XTCDECL -EFI_STATUS -BlExitBootServices(); - -XTCDECL -EFI_STATUS -BlFindBootProtocol(IN PWCHAR SystemType, - OUT PEFI_GUID BootProtocolGuid); - -XTCDECL -EFI_STATUS -BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, - IN CONST PWCHAR FileSystemPath, - OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath); - -XTCDECL -EFI_STATUS -BlFreeMemoryPages(IN ULONGLONG NumberOfPages, - IN EFI_PHYSICAL_ADDRESS Memory); - -XTCDECL -EFI_STATUS -BlFreeMemoryPool(IN PVOID Memory); - -XTCDECL -BOOLEAN -BlGetBooleanParameter(IN CONST PWCHAR Parameters, - IN CONST PWCHAR Needle); - -XTCDECL -EFI_STATUS -BlGetBootOptionValue(IN PLIST_ENTRY Options, - IN CONST PWCHAR OptionName, - OUT PWCHAR *OptionValue); - -XTCDECL -BOOLEAN -BlGetConfigBooleanValue(IN CONST PWCHAR ConfigName); - -XTCDECL -EFI_STATUS -BlGetConfigValue(IN CONST PWCHAR ConfigName, - OUT PWCHAR *ConfigValue); - -XTCDECL -EFI_STATUS -BlGetConfigurationTable(IN PEFI_GUID TableGuid, - OUT PVOID *Table); - -XTCDECL -VOID -BlGetEditableOptions(OUT CONST PWCHAR **OptionsArray, - OUT PULONG OptionsCount); - -XTCDECL -EFI_STATUS -BlGetEfiPath(IN PWCHAR SystemPath, - OUT PWCHAR *EfiPath); - -XTCDECL -EFI_STATUS -BlGetEfiVariable(IN PEFI_GUID Vendor, - IN PWCHAR VariableName, - OUT PVOID *VariableValue); - -XTCDECL -VOID -BlGetMappingsCount(IN PXTBL_PAGE_MAPPING PageMap, - OUT PULONG NumberOfMappings); - -XTCDECL -EFI_STATUS -BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap); - -XTCDECL -PLIST_ENTRY -BlGetModulesList(); - -XTCDECL -ULONGLONG -BlGetRandomValue(IN OUT PULONGLONG RNGBuffer); - -XTCDECL -INT_PTR -BlGetSecureBootStatus(); - -XTCDECL -PVOID -BlGetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap, - IN PVOID PhysicalAddress); - -XTCDECL -EFI_STATUS -BlGetVolumeDevicePath(IN PWCHAR SystemPath, - OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath, - OUT PWCHAR *ArcName, - OUT PWCHAR *Path); - -XTCDECL -VOID -BlInitializeBootLoader(); - -XTCDECL -EFI_STATUS -BlInitializeBootMenuList(IN ULONG MaxNameLength, - OUT PXTBL_BOOTMENU_ITEM *MenuEntries, - OUT PULONG EntriesCount, - OUT PULONG DefaultId); - -XTCDECL -VOID -BlInitializeConsole(); - -XTCDECL -EFI_STATUS -BlInitializeEntropy(PULONGLONG RNGBuffer); - -XTCDECL -VOID -BlInitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap, - IN SHORT PageMapLevel, - IN PAGE_SIZE PageSize); - -XTCDECL -EFI_STATUS -BlInstallProtocol(IN PVOID Interface, - IN PEFI_GUID Guid); - -XTCDECL -EFI_STATUS -BlInvokeBootProtocol(IN PWCHAR ShortName, - IN PLIST_ENTRY OptionsList); - -XTCDECL -EFI_STATUS -BlLoadEfiImage(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, - IN PVOID ImageData, - IN SIZE_T ImageSize, - OUT PEFI_HANDLE ImageHandle); - -XTCDECL -EFI_STATUS -BlLoadModule(IN PWCHAR ModuleName); - -XTCDECL -EFI_STATUS -BlLoadModules(IN PWCHAR ModulesList); - -XTCDECL -EFI_STATUS -BlLocateProtocolHandles(OUT PEFI_HANDLE *Handles, - OUT PUINT_PTR Count, - IN PEFI_GUID ProtocolGuid); - -XTCDECL -EFI_STATUS -BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, - IN OUT PVOID *DesiredVirtualAddress, - IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine); - -XTCDECL -EFI_STATUS -BlMapPage(IN PXTBL_PAGE_MAPPING PageMap, - IN ULONG_PTR VirtualAddress, - IN ULONG_PTR PhysicalAddress, - IN ULONG NumberOfPages); - -XTCDECL -EFI_STATUS -BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, - IN PVOID VirtualAddress, - IN PVOID PhysicalAddress, - IN ULONGLONG NumberOfPages, - IN LOADER_MEMORY_TYPE MemoryType); - -XTCDECL -EFI_STATUS -BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, - OUT PEFI_HANDLE DiskHandle, - OUT PEFI_FILE_HANDLE *FsHandle); - -XTCDECL -EFI_STATUS -BlOpenProtocol(OUT PEFI_HANDLE Handle, - OUT PVOID *ProtocolHandler, - IN PEFI_GUID ProtocolGuid); - -XTCDECL -EFI_STATUS -BlOpenProtocolHandle(IN EFI_HANDLE Handle, - OUT PVOID *ProtocolHandler, - IN PEFI_GUID ProtocolGuid); - -XTCDECL -PVOID -BlPhysicalAddressToVirtual(IN PVOID PhysicalAddress, - IN PVOID PhysicalBase, - IN PVOID VirtualBase); - -XTCDECL -EFI_STATUS -BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap, - IN OUT PLIST_ENTRY ListHead, - IN PVOID PhysicalBase, - IN PVOID VirtualBase); - -XTCDECL -VOID -BlQueryConsoleMode(OUT PUINT_PTR ResX, - OUT PUINT_PTR ResY); - -XTCDECL -EFI_STATUS -BlReadFile(IN PEFI_FILE_HANDLE DirHandle, - IN CONST PWCHAR FileName, - OUT PVOID *FileData, - OUT PSIZE_T FileSize); - -XTCDECL -VOID -BlReadKeyStroke(OUT PEFI_INPUT_KEY Key); - -XTCDECL -EFI_STATUS -BlRebootSystem(); - -XTCDECL -VOID -BlRegisterBootMenu(PVOID BootMenuRoutine); - -XTCDECL -EFI_STATUS -BlRegisterBootProtocol(IN PWCHAR SystemType, - IN PEFI_GUID BootProtocolGuid); - -XTCDECL -VOID -BlResetConsoleInputBuffer(); - -XTCDECL -EFI_STATUS -BlSetBootOptionValue(IN PLIST_ENTRY Options, - IN CONST PWCHAR OptionName, - IN CONST PWCHAR OptionValue); - -XTCDECL -EFI_STATUS -BlSetConfigValue(IN CONST PWCHAR ConfigName, - IN CONST PWCHAR ConfigValue); - -XTCDECL -VOID -BlSetConsoleAttributes(IN ULONGLONG Attributes); - -XTCDECL -EFI_STATUS -BlSetConsoleMode(IN ULONGLONG Mode); - -XTCDECL -VOID -BlSetCursorPosition(IN ULONGLONG PosX, - IN ULONGLONG PosY); - -XTCDECL -EFI_STATUS -BlSetEfiVariable(IN PEFI_GUID Vendor, - IN PWCHAR VariableName, - IN PVOID VariableValue, - IN UINT_PTR Size); - -XTCDECL -EFI_STATUS -BlShutdownSystem(); - -XTCDECL -VOID -BlSleepExecution(IN ULONG_PTR Milliseconds); - -XTCDECL -EFI_STATUS -BlStartEfiImage(IN EFI_HANDLE ImageHandle); - -XTCDECL -VOID -BlStartLoaderShell(); - -XTCDECL -EFI_STATUS -BlStartXtLoader(IN EFI_HANDLE ImageHandle, - IN PEFI_SYSTEM_TABLE SystemTable); - -XTCDECL -VOID -BlUpdateProgressBar(IN PXTBL_DIALOG_HANDLE Handle, - IN PWCHAR Message, - IN UCHAR Percentage); - -XTCDECL -EFI_STATUS -BlWaitForEfiEvent(IN UINT_PTR NumberOfEvents, - IN PEFI_EVENT Event, - OUT PUINT_PTR Index); - -XTCDECL -EFI_STATUS -BlpActivateSerialIOController(); - -XTCDECL -XTSTATUS -BlpConsolePutChar(IN WCHAR Character); - -XTCDECL -XTSTATUS -BlpDebugPutChar(IN WCHAR Character); - -XTCDECL -VOID -BlpDetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle, - IN PWCHAR Message); - -XTCDECL -EFI_STATUS -BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices); - -XTCDECL -EFI_STATUS -BlpDissectVolumeArcPath(IN PWCHAR SystemPath, - OUT PWCHAR *ArcName, - OUT PWCHAR *Path, - OUT PUSHORT DriveType, - OUT PULONG DriveNumber, - OUT PULONG PartNumber); - -XTCDECL -VOID -BlpDrawBootMenu(OUT PXTBL_DIALOG_HANDLE Handle); - -XTCDECL -VOID -BlpDrawBootMenuEntry(IN PXTBL_DIALOG_HANDLE Handle, - IN PWCHAR MenuEntry, - IN UINT Position, - IN BOOLEAN Highlighted); - -XTCDECL -VOID -BlpDrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, - IN PWCHAR Caption, - IN PWCHAR Message); - -XTCDECL -VOID -BlpDrawDialogButton(IN PXTBL_DIALOG_HANDLE Handle); - -XTCDECL -VOID -BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, - IN PWCHAR InputFieldText); - -XTCDECL -VOID -BlpDrawDialogMessage(IN PXTBL_DIALOG_HANDLE Handle, - IN PWCHAR Message); - -XTCDECL -VOID -BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle, - IN UCHAR Percentage); - -XTCDECL -VOID -BlpDrawEditMenu(OUT PXTBL_DIALOG_HANDLE Handle); - -XTCDECL -EFI_STATUS -BlpDrawEditMenuEntry(IN PXTBL_DIALOG_HANDLE Handle, - IN PWCHAR OptionName, - IN PWCHAR OptionValue, - IN UINT Position, - IN BOOLEAN Highlighted); - -XTCDECL -PEFI_DEVICE_PATH_PROTOCOL -BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath); - -XTCDECL -EFI_STATUS -BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, - OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode); - -XTCDECL -BOOLEAN -BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices, - IN PEFI_BLOCK_DEVICE_DATA ChildNode, - OUT PEFI_BLOCK_DEVICE_DATA *ParentNode); - -XTCDECL -LONG -BlpGetLoaderMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType); - -XTCDECL -EFI_STATUS -BlpGetModuleInformation(IN PWCHAR SectionData, - IN ULONG SectionSize, - OUT PXTBL_MODULE_INFO ModuleInfo); - -XTCDECL -EFI_STATUS -BlpGetModuleInfoStrings(IN PWCHAR SectionData, - IN ULONG SectionSize, - OUT PWCHAR **ModInfo, - OUT PULONG InfoCount); - -XTCDECL -EFI_STATUS -BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, - IN PVOID PageTable, - IN SIZE_T Entry, - OUT PVOID *NextPageTable); - -XTCDECL -EFI_STATUS -BlpInitializeDebugConsole(); - -XTCDECL -EFI_STATUS -BlpInitializeSerialPort(IN ULONG PortNumber, - IN ULONG PortAddress, - IN ULONG BaudRate); - -XTCDECL -EFI_STATUS -BlpInstallXtLoaderProtocol(); - -XTCDECL -EFI_STATUS -BlpLoadConfiguration(); - -XTCDECL -EFI_STATUS -BlpParseCommandLine(VOID); - -XTCDECL -EFI_STATUS -BlpParseConfigFile(IN CONST PCHAR RawConfig, - OUT PLIST_ENTRY Configuration); - -XTCDECL -VOID -BlpPrintShellPrompt(); - -XTCDECL -EFI_STATUS -BlpReadConfigFile(IN CONST PWCHAR ConfigDirectory, - IN CONST PWCHAR ConfigFile, - OUT PCHAR *ConfigData); - -XTCDECL -EFI_STATUS -BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap, - IN ULONG_PTR SelfMapAddress); - -XTCDECL -ULONGLONG -BlpStringReadPadding(IN PUSHORT *Format); - -XTCDECL -VOID -BlpUpdateConfiguration(IN PLIST_ENTRY NewConfig); - -#endif /* __XTLDR_XTLDR_H */ diff --git a/xtldr/includes/xtldr.hh b/xtldr/includes/xtldr.hh new file mode 100644 index 0000000..6ebe2ee --- /dev/null +++ b/xtldr/includes/xtldr.hh @@ -0,0 +1,352 @@ +/** + * 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 + */ + +#ifndef __XTLDR_XTLDR_HH +#define __XTLDR_XTLDR_HH + +#include +#include + +#include +#include + + +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 */ diff --git a/xtldr/library/modproto.c b/xtldr/library/modproto.cc similarity index 90% rename from xtldr/library/modproto.c rename to xtldr/library/modproto.cc index 3a3b67f..3a0f3f2 100644 --- a/xtldr/library/modproto.c +++ b/xtldr/library/modproto.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * 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 * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -25,6 +25,7 @@ * * @since XT 1.0 */ +XTCLINK XTCDECL EFI_STATUS BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable, @@ -32,13 +33,13 @@ BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable, OUT PXTBL_LOADER_PROTOCOL *ProtocolHandler) { EFI_GUID ProtocolGuid = XT_BOOT_LOADER_PROTOCOL_GUID; - PEFI_HANDLE Handles = NULL; + PEFI_HANDLE Handles = NULLPTR; EFI_STATUS Status; UINT_PTR Count; UINT Index; /* 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) { /* Unable to get handles */ @@ -53,7 +54,7 @@ BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable, { /* Try to open protocol */ Status = SystemTable->BootServices->OpenProtocol(Handles[Index], &ProtocolGuid, - (PVOID*)ProtocolHandler, ImageHandle, NULL, + (PVOID*)ProtocolHandler, ImageHandle, NULLPTR, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); /* Check if successfully opened the loader protocol */ @@ -69,7 +70,7 @@ BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable, SystemTable->BootServices->FreePool(Handles); /* Make sure the loaded protocol has been found */ - if(*ProtocolHandler == NULL) + if(*ProtocolHandler == NULLPTR) { /* Protocol not found */ return STATUS_EFI_NOT_FOUND; diff --git a/xtldr/memory.c b/xtldr/memory.cc similarity index 77% rename from xtldr/memory.c rename to xtldr/memory.cc index 1d6f25b..91ff66d 100644 --- a/xtldr/memory.c +++ b/xtldr/memory.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/memory.c + * FILE: xtldr/memory.cc * DESCRIPTION: XT Boot Loader memory management * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -24,11 +24,12 @@ */ XTCDECL EFI_STATUS -BlAllocateMemoryPages(IN EFI_ALLOCATE_TYPE AllocationType, +Memory::AllocatePages(IN EFI_ALLOCATE_TYPE AllocationType, IN ULONGLONG NumberOfPages, OUT PEFI_PHYSICAL_ADDRESS Memory) { - return EfiSystemTable->BootServices->AllocatePages(AllocationType, EfiLoaderData, NumberOfPages, Memory); + return XtLoader::GetEfiSystemTable()->BootServices->AllocatePages(AllocationType, EfiLoaderData, + NumberOfPages, Memory); } /** @@ -46,11 +47,11 @@ BlAllocateMemoryPages(IN EFI_ALLOCATE_TYPE AllocationType, */ XTCDECL EFI_STATUS -BlAllocateMemoryPool(IN UINT_PTR Size, +Memory::AllocatePool(IN UINT_PTR Size, OUT PVOID *Memory) { /* Allocate pool */ - return EfiSystemTable->BootServices->AllocatePool(EfiLoaderData, Size, Memory); + return XtLoader::GetEfiSystemTable()->BootServices->AllocatePool(EfiLoaderData, Size, Memory); } /** @@ -68,10 +69,10 @@ BlAllocateMemoryPool(IN UINT_PTR Size, */ XTCDECL EFI_STATUS -BlFreeMemoryPages(IN ULONGLONG NumberOfPages, +Memory::FreePages(IN ULONGLONG NumberOfPages, IN EFI_PHYSICAL_ADDRESS Memory) { - return EfiSystemTable->BootServices->FreePages(Memory, NumberOfPages); + return XtLoader::GetEfiSystemTable()->BootServices->FreePages(Memory, NumberOfPages); } /** @@ -86,10 +87,58 @@ BlFreeMemoryPages(IN ULONGLONG NumberOfPages, */ XTCDECL EFI_STATUS -BlFreeMemoryPool(IN PVOID Memory) +Memory::FreePool(IN PVOID Memory) { /* 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; } /** @@ -107,8 +156,8 @@ BlFreeMemoryPool(IN PVOID Memory) */ XTCDECL VOID -BlGetMappingsCount(IN PXTBL_PAGE_MAPPING PageMap, - OUT PULONG NumberOfMappings) +Memory::GetMappingsCount(IN PXTBL_PAGE_MAPPING PageMap, + OUT PULONG NumberOfMappings) { /* Return number of mappings */ *NumberOfMappings = PageMap->MapSize; @@ -126,24 +175,27 @@ BlGetMappingsCount(IN PXTBL_PAGE_MAPPING PageMap, */ XTCDECL EFI_STATUS -BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap) +Memory::GetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap) { EFI_STATUS Status; - if(MemoryMap == NULL) + if(MemoryMap == NULLPTR) { return STATUS_EFI_INVALID_PARAMETER; } - MemoryMap->Map = NULL; + MemoryMap->Map = NULLPTR; MemoryMap->MapSize = 0; /* Get memory map */ do { /* Attempt do get EFI memory map */ - Status = EfiSystemTable->BootServices->GetMemoryMap(&MemoryMap->MapSize, MemoryMap->Map, &MemoryMap->MapKey, - &MemoryMap->DescriptorSize, &MemoryMap->DescriptorVersion); + Status = XtLoader::GetEfiSystemTable()->BootServices->GetMemoryMap(&MemoryMap->MapSize, + MemoryMap->Map, + &MemoryMap->MapKey, + &MemoryMap->DescriptorSize, + &MemoryMap->DescriptorVersion); if(Status == STATUS_EFI_SUCCESS) { /* Go further if succeeded */ @@ -155,19 +207,19 @@ BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap) if(MemoryMap->Map) { /* Free allocated memory */ - BlFreeMemoryPool(MemoryMap->Map); + FreePool(MemoryMap->Map); } return Status; } /* Allocate the desired amount of memory */ MemoryMap->MapSize += 2 * MemoryMap->DescriptorSize; - BlAllocateMemoryPool(MemoryMap->MapSize, (PVOID *)&MemoryMap->Map); + AllocatePool(MemoryMap->MapSize, (PVOID *)&MemoryMap->Map); } while(Status == STATUS_EFI_BUFFER_TOO_SMALL); /* Make sure memory map is set */ - if(MemoryMap->Map == NULL) + if(MemoryMap->Map == NULLPTR) { /* Something went wrong */ return STATUS_EFI_NO_MAPPING; @@ -192,8 +244,8 @@ BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap) */ XTCDECL PVOID -BlGetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap, - IN PVOID PhysicalAddress) +Memory::GetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap, + IN PVOID PhysicalAddress) { PXTBL_MEMORY_MAPPING Mapping; PLIST_ENTRY ListEntry; @@ -209,11 +261,11 @@ BlGetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap, if(Mapping->VirtualAddress) { /* Check if provided physical address is in range of this mapping */ - if((PhysicalAddress >= Mapping->PhysicalAddress) && - (PhysicalAddress < Mapping->PhysicalAddress + (Mapping->NumberOfPages * EFI_PAGE_SIZE))) + if(((UINT_PTR)PhysicalAddress >= (UINT_PTR)Mapping->PhysicalAddress) && + ((UINT_PTR)PhysicalAddress < ((UINT_PTR)Mapping->PhysicalAddress + (Mapping->NumberOfPages * EFI_PAGE_SIZE)))) { /* 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); } } @@ -243,12 +295,12 @@ BlGetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap, */ XTCDECL VOID -BlInitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap, - IN SHORT PageMapLevel, - IN PAGE_SIZE PageSize) +Memory::InitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap, + IN SHORT PageMapLevel, + IN PAGE_SIZE PageSize) { /* Initialize memory mappings */ - RtlInitializeListHead(&PageMap->MemoryMap); + RTL::LinkedList::InitializeListHead(&PageMap->MemoryMap); PageMap->MapSize = 0; /* Set page map size/level and memory map address */ @@ -274,9 +326,9 @@ BlInitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap, */ XTCDECL EFI_STATUS -BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, - IN OUT PVOID *MemoryMapAddress, - IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine) +Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, + IN OUT PVOID *MemoryMapAddress, + IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine) { PEFI_MEMORY_DESCRIPTOR Descriptor; LOADER_MEMORY_TYPE MemoryType; @@ -287,21 +339,21 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, SIZE_T Index; /* Set virtual address as specified in argument */ - VirtualAddress = *MemoryMapAddress; + VirtualAddress = (PUCHAR)*MemoryMapAddress; /* Check if custom memory type routine is specified */ - if(GetMemoryTypeRoutine == NULL) + if(GetMemoryTypeRoutine == NULLPTR) { /* Use default memory type routine */ - GetMemoryTypeRoutine = BlpGetLoaderMemoryType; + GetMemoryTypeRoutine = GetLoaderMemoryType; } /* Allocate and zero-fill buffer for EFI memory map */ - BlAllocateMemoryPool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap); - RtlZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP)); + AllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap); + RTL::Memory::ZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP)); /* Get EFI memory map */ - Status = BlGetMemoryMap(MemoryMap); + Status = GetMemoryMap(MemoryMap); if(Status != STATUS_EFI_SUCCESS) { /* Failed to get EFI memory map */ @@ -346,20 +398,20 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, } /* 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 */ if(MemoryType == LoaderFirmwareTemporary) { /* Map EFI firmware code */ - Status = BlMapVirtualMemory(PageMap, (PVOID)Descriptor->PhysicalStart, - (PVOID)Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType); + Status = MapVirtualMemory(PageMap, (PVOID)Descriptor->PhysicalStart, + (PVOID)Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType); } else if(MemoryType != LoaderFree) { /* Add any non-free memory mapping */ - Status = BlMapVirtualMemory(PageMap, VirtualAddress, (PVOID)Descriptor->PhysicalStart, - Descriptor->NumberOfPages, MemoryType); + Status = MapVirtualMemory(PageMap, VirtualAddress, (PVOID)Descriptor->PhysicalStart, + Descriptor->NumberOfPages, MemoryType); /* Calculate next valid virtual address */ VirtualAddress += Descriptor->NumberOfPages * EFI_PAGE_SIZE; @@ -367,8 +419,8 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, else { /* Map all other memory as loader free */ - Status = BlMapVirtualMemory(PageMap, NULL, (PVOID)Descriptor->PhysicalStart, - Descriptor->NumberOfPages, LoaderFree); + Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)Descriptor->PhysicalStart, + Descriptor->NumberOfPages, LoaderFree); } /* Make sure memory mapping succeeded */ @@ -384,7 +436,7 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, } /* 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) { /* Mapping failed */ @@ -392,7 +444,7 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, } /* 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) { /* Mapping failed */ @@ -428,11 +480,11 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, */ XTCDECL EFI_STATUS -BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, - IN PVOID VirtualAddress, - IN PVOID PhysicalAddress, - IN ULONGLONG NumberOfPages, - IN LOADER_MEMORY_TYPE MemoryType) +Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, + IN PVOID VirtualAddress, + IN PVOID PhysicalAddress, + IN ULONGLONG NumberOfPages, + IN LOADER_MEMORY_TYPE MemoryType) { PXTBL_MEMORY_MAPPING Mapping1, Mapping2, Mapping3; PVOID PhysicalAddressEnd, PhysicalAddress2End; @@ -441,7 +493,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, EFI_STATUS Status; /* 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) { /* Memory allocation failure */ @@ -491,7 +543,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, if(NumberOfMappedPages > 0) { /* 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) { /* Memory allocation failure */ @@ -500,10 +552,10 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, /* Set mapping fields and insert it on the top */ Mapping3->PhysicalAddress = (PUCHAR)PhysicalAddressEnd + 1; - Mapping3->VirtualAddress = NULL; + Mapping3->VirtualAddress = NULLPTR; Mapping3->NumberOfPages = NumberOfMappedPages; 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 */ @@ -527,7 +579,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, if(NumberOfMappedPages > 0) { /* 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) { /* Memory allocation failure */ @@ -536,10 +588,10 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, /* Set mapping fields and insert it on the top */ Mapping3->PhysicalAddress = Mapping1->PhysicalAddress; - Mapping3->VirtualAddress = NULL; + Mapping3->VirtualAddress = NULLPTR; Mapping3->NumberOfPages = NumberOfMappedPages; 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 */ @@ -563,8 +615,8 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, MappingListEntry = ListEntry->Flink; /* Remove mapping from the list and free up it's memory */ - RtlRemoveEntryList(&Mapping2->ListEntry); - Status = BlFreeMemoryPool(Mapping2); + RTL::LinkedList::RemoveEntryList(&Mapping2->ListEntry); + Status = FreePool(Mapping2); ListEntry = MappingListEntry; /* Go to the next mapping */ @@ -575,7 +627,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, if(Mapping2->PhysicalAddress > Mapping1->PhysicalAddress) { /* Insert new mapping in front */ - RtlInsertHeadList(Mapping2->ListEntry.Blink, &Mapping1->ListEntry); + RTL::LinkedList::InsertHeadList(Mapping2->ListEntry.Blink, &Mapping1->ListEntry); return STATUS_EFI_SUCCESS; } @@ -584,7 +636,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, } /* 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++; /* Return success */ @@ -609,9 +661,9 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, */ XTCDECL PVOID -BlPhysicalAddressToVirtual(IN PVOID PhysicalAddress, - IN PVOID PhysicalBase, - IN PVOID VirtualBase) +Memory::PhysicalAddressToVirtual(IN PVOID PhysicalAddress, + IN PVOID PhysicalBase, + IN PVOID VirtualBase) { /* Convert physical address to virtual address */ return (PUCHAR)VirtualBase + ((PUCHAR)PhysicalAddress - (PUCHAR)PhysicalBase); @@ -638,10 +690,10 @@ BlPhysicalAddressToVirtual(IN PVOID PhysicalAddress, */ XTCDECL EFI_STATUS -BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap, - IN OUT PLIST_ENTRY ListHead, - IN PVOID PhysicalBase, - IN PVOID VirtualBase) +Memory::PhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap, + IN OUT PLIST_ENTRY ListHead, + IN PVOID PhysicalBase, + IN PVOID VirtualBase) { PLIST_ENTRY ListEntry, NextEntry; @@ -663,12 +715,12 @@ BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap, if(ListEntry->Blink == ListHead) { /* Find virtual address of list head */ - ListEntry->Blink = BlGetVirtualAddress(PageMap, ListEntry->Blink); + ListEntry->Blink = (PLIST_ENTRY)GetVirtualAddress(PageMap, ListEntry->Blink); } else { /* 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) { @@ -678,7 +730,7 @@ BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap, else { /* 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*/ @@ -686,57 +738,9 @@ BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap, } /* Convert list head */ - ListHead->Blink = BlPhysicalAddressToVirtual(ListHead->Blink, (PVOID)PhysicalBase, VirtualBase); - ListHead->Flink = BlPhysicalAddressToVirtual(ListHead->Flink, (PVOID)PhysicalBase, VirtualBase); + ListHead->Blink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListHead->Blink, (PVOID)PhysicalBase, VirtualBase); + ListHead->Flink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListHead->Flink, (PVOID)PhysicalBase, VirtualBase); /* Return 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; -} diff --git a/xtldr/modules/acpi/CMakeLists.txt b/xtldr/modules/acpi/CMakeLists.txt index d94f9d0..d726689 100644 --- a/xtldr/modules/acpi/CMakeLists.txt +++ b/xtldr/modules/acpi/CMakeLists.txt @@ -8,8 +8,8 @@ include_directories( # Specify list of source code files list(APPEND XTLDR_ACPI_SOURCE - ${XTLDR_ACPI_SOURCE_DIR}/acpi.c - ${XTLDR_ACPI_SOURCE_DIR}/globals.c) + ${XTLDR_ACPI_SOURCE_DIR}/acpi.cc + ${XTLDR_ACPI_SOURCE_DIR}/data.cc) # Link module executable add_executable(acpi ${XTLDR_ACPI_SOURCE}) diff --git a/xtldr/modules/acpi/acpi.c b/xtldr/modules/acpi/acpi.cc similarity index 74% rename from xtldr/modules/acpi/acpi.c rename to xtldr/modules/acpi/acpi.cc index aceb8ac..cc89d2e 100644 --- a/xtldr/modules/acpi/acpi.c +++ b/xtldr/modules/acpi/acpi.cc @@ -1,20 +1,21 @@ /** * PROJECT: ExectOS * 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 * DEVELOPERS: Rafal Kupiec */ -#include +#include -/* Dummy module information */ +/* ACPI module information */ MODULE_AUTHOR(L"Rafal Kupiec "); MODULE_DESCRIPTION(L"ACPI support"); MODULE_LICENSE(L"GPLv3"); MODULE_VERSION(L"0.1"); + /** * 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 EFI_STATUS -AcGetAcpiDescriptionPointer(OUT PVOID *AcpiTable) +Acpi::GetAcpiDescriptionPointer(OUT PVOID *AcpiTable) { PVOID Rsdp; /* 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 */ *AcpiTable = Rsdp; @@ -40,7 +41,7 @@ AcGetAcpiDescriptionPointer(OUT PVOID *AcpiTable) } /* 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 */ *AcpiTable = Rsdp; @@ -61,7 +62,7 @@ AcGetAcpiDescriptionPointer(OUT PVOID *AcpiTable) * Supplies a pointer to the table to start searching from. * * @param AcpiTable - * Supplies a pointer to memory area where ACPI table address will be stored, or NULL if not found. + * 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. * @@ -69,9 +70,9 @@ AcGetAcpiDescriptionPointer(OUT PVOID *AcpiTable) */ XTCDECL EFI_STATUS -AcGetAcpiTable(IN CONST UINT Signature, - IN PVOID PreviousTable, - OUT PVOID *AcpiTable) +Acpi::GetAcpiTable(IN CONST UINT Signature, + IN PVOID PreviousTable, + OUT PVOID *AcpiTable) { PACPI_DESCRIPTION_HEADER TableHeader; SIZE_T RsdtIndex, TableIndex; @@ -81,11 +82,11 @@ AcGetAcpiTable(IN CONST UINT Signature, PACPI_RSDT Rsdt; BOOLEAN Xsdp; - /* Return NULL address by default if requested table not found */ - *AcpiTable = NULL; + /* Return NULLPTR by default if requested table not found */ + *AcpiTable = NULLPTR; /* Get Root System Description Table Pointer */ - Status = AcGetAcpiDescriptionPointer((PVOID)&Rsdp); + Status = GetAcpiDescriptionPointer((PVOID*)&Rsdp); if(Status != STATUS_EFI_SUCCESS) { /* ACPI tables not found, return error */ @@ -127,13 +128,13 @@ AcGetAcpiTable(IN CONST UINT Signature, } /* Check if previous table provided */ - if(PreviousTable != NULL) + if(PreviousTable != NULLPTR) { /* Check if this is a table previously found */ if(TableHeader == (PVOID)PreviousTable) { /* Unset previous table */ - PreviousTable = NULL; + PreviousTable = NULLPTR; } /* Skip to next ACPI table */ @@ -159,7 +160,7 @@ AcGetAcpiTable(IN CONST UINT Signature, if(TableHeader->Signature != ACPI_FADT_SIGNATURE || TableHeader->Revision > 2) { /* Validate table checksum */ - if(!AcpValidateAcpiTable(TableHeader, TableHeader->Length)) + if(!ValidateAcpiTable(TableHeader, TableHeader->Length)) { /* Checksum mismatch, return error */ return STATUS_EFI_CRC_ERROR; @@ -183,16 +184,16 @@ AcGetAcpiTable(IN CONST UINT Signature, */ XTCDECL EFI_STATUS -AcGetApicBase(OUT PVOID *ApicBase) +Acpi::GetApicBase(OUT PVOID *ApicBase) { CPUID_REGISTERS CpuRegisters; /* 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; /* Query CPUID */ - ArCpuId(&CpuRegisters); + XtLdrProtocol->Cpu.CpuId(&CpuRegisters); /* Check if APIC present */ if((CpuRegisters.Edx & CPUID_FEATURES_EDX_APIC) == 0) @@ -202,7 +203,7 @@ AcGetApicBase(OUT PVOID *ApicBase) } /* Get APIC base address */ - *ApicBase = (PVOID)((UINT_PTR)ArReadModelSpecificRegister(0x1B) & 0xFFFFF000); + *ApicBase = (PVOID)((UINT_PTR)XtLdrProtocol->Cpu.ReadModelSpecificRegister(0x1B) & 0xFFFFF000); /* Return success */ return STATUS_EFI_SUCCESS; @@ -220,18 +221,18 @@ AcGetApicBase(OUT PVOID *ApicBase) */ XTCDECL EFI_STATUS -AcGetRsdpTable(OUT PVOID *AcpiTable) +Acpi::GetRsdpTable(OUT PVOID *AcpiTable) { EFI_GUID AcpiGuid = EFI_CONFIG_TABLE_ACPI_TABLE_GUID; EFI_STATUS Status; PVOID RsdpTable; /* Get RSDP (ACPI 1.0) table from system configuration tables */ - Status = XtLdrProtocol->Util.GetConfigurationTable(&AcpiGuid, &RsdpTable); - if(Status != STATUS_EFI_SUCCESS || !AcpValidateAcpiTable(RsdpTable, 20)) + Status = XtLdrProtocol->Utils.GetConfigurationTable(&AcpiGuid, &RsdpTable); + if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(RsdpTable, 20)) { /* RSDP not found or checksum mismatch */ - *AcpiTable = NULL; + *AcpiTable = NULLPTR; return STATUS_EFI_NOT_FOUND; } @@ -252,18 +253,18 @@ AcGetRsdpTable(OUT PVOID *AcpiTable) */ XTCDECL EFI_STATUS -AcGetSMBiosTable(OUT PVOID *SmBiosTable) +Acpi::GetSMBiosTable(OUT PVOID *SmBiosTable) { EFI_GUID SmBiosGuid = EFI_CONFIG_TABLE_SMBIOS_TABLE_GUID; PSMBIOS_TABLE_HEADER SmBios; EFI_STATUS Status; /* Get SMBIOS table from system configuration tables */ - Status = XtLdrProtocol->Util.GetConfigurationTable(&SmBiosGuid, (PVOID)&SmBios); - if(Status != STATUS_EFI_SUCCESS || !AcpValidateAcpiTable(SmBios, SmBios->Length)) + Status = XtLdrProtocol->Utils.GetConfigurationTable(&SmBiosGuid, (PVOID*)&SmBios); + if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(SmBios, SmBios->Length)) { /* SMBIOS not found or checksum mismatch */ - *SmBiosTable = NULL; + *SmBiosTable = NULLPTR; return STATUS_EFI_NOT_FOUND; } @@ -284,18 +285,18 @@ AcGetSMBiosTable(OUT PVOID *SmBiosTable) */ XTCDECL EFI_STATUS -AcGetSMBios3Table(OUT PVOID *SmBiosTable) +Acpi::GetSMBios3Table(OUT PVOID *SmBiosTable) { EFI_GUID SmBios3Guid = EFI_CONFIG_TABLE_SMBIOS3_TABLE_GUID; PSMBIOS3_TABLE_HEADER SmBios; EFI_STATUS Status; /* Get SMBIOS3 table from system configuration tables */ - Status = XtLdrProtocol->Util.GetConfigurationTable(&SmBios3Guid, (PVOID)&SmBios); - if(Status != STATUS_EFI_SUCCESS || !AcpValidateAcpiTable(SmBios, SmBios->Length)) + Status = XtLdrProtocol->Utils.GetConfigurationTable(&SmBios3Guid, (PVOID*)&SmBios); + if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(SmBios, SmBios->Length)) { /* SMBIOS3 not found or checksum mismatch */ - *SmBiosTable = NULL; + *SmBiosTable = NULLPTR; return STATUS_EFI_NOT_FOUND; } @@ -316,18 +317,18 @@ AcGetSMBios3Table(OUT PVOID *SmBiosTable) */ XTCDECL EFI_STATUS -AcGetXsdpTable(OUT PVOID *AcpiTable) +Acpi::GetXsdpTable(OUT PVOID *AcpiTable) { EFI_GUID AcpiGuid = EFI_CONFIG_TABLE_ACPI20_TABLE_GUID; EFI_STATUS Status; PVOID XsdpTable; /* Get XSDP (ACPI 2.0) from system configuration tables */ - Status = XtLdrProtocol->Util.GetConfigurationTable(&AcpiGuid, &XsdpTable); - if(Status != STATUS_EFI_SUCCESS || !AcpValidateAcpiTable(XsdpTable, 36)) + Status = XtLdrProtocol->Utils.GetConfigurationTable(&AcpiGuid, &XsdpTable); + if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(XsdpTable, 36)) { /* XSDP not found or checksum mismatch */ - *AcpiTable = NULL; + *AcpiTable = NULLPTR; return STATUS_EFI_NOT_FOUND; } @@ -336,6 +337,48 @@ AcGetXsdpTable(OUT PVOID *AcpiTable) 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. * @@ -351,15 +394,15 @@ AcGetXsdpTable(OUT PVOID *AcpiTable) */ XTCDECL BOOLEAN -AcpValidateAcpiTable(IN PVOID Buffer, - IN UINT_PTR Size) +Acpi::ValidateAcpiTable(IN PVOID Buffer, + IN UINT_PTR Size) { PUCHAR Pointer; UCHAR Sum; /* Initialize variables */ Sum = 0; - Pointer = Buffer; + Pointer = (PUCHAR)Buffer; /* Calculate checksum of given table */ while(Size != 0) @@ -391,26 +434,6 @@ EFI_STATUS XtLdrModuleMain(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 */ - 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); + /* Initialize ACPI module */ + return Acpi::InitializeModule(ImageHandle, SystemTable); } diff --git a/xtldr/modules/acpi/globals.c b/xtldr/modules/acpi/data.cc similarity index 51% rename from xtldr/modules/acpi/globals.c rename to xtldr/modules/acpi/data.cc index abfd269..f5fef75 100644 --- a/xtldr/modules/acpi/globals.c +++ b/xtldr/modules/acpi/data.cc @@ -1,16 +1,16 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/acpi/globals.c - * DESCRIPTION: ACPI module global variables + * FILE: xtldr/modules/acpi/data.cc + * DESCRIPTION: ACPI module global and static data * DEVELOPERS: Rafal Kupiec */ -#include +#include /* ACPI Protocol */ -XTBL_ACPI_PROTOCOL AcpAcpiProtocol; +XTBL_ACPI_PROTOCOL Acpi::AcpiProtocol; /* XTLDR protocol handler */ -PXTBL_LOADER_PROTOCOL XtLdrProtocol; +PXTBL_LOADER_PROTOCOL Acpi::XtLdrProtocol; diff --git a/xtldr/modules/acpi/includes/acpi.h b/xtldr/modules/acpi/includes/acpi.h deleted file mode 100644 index f7b8ee0..0000000 --- a/xtldr/modules/acpi/includes/acpi.h +++ /dev/null @@ -1,57 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/acpi/includes/acpi.h - * DESCRIPTION: XTLDR ACPI module header file - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTLDR_ACPI_ACPI_H -#define __XTLDR_ACPI_ACPI_H - -#include -#include - - -/* ACPI module routines forward references */ -XTCDECL -EFI_STATUS -AcGetAcpiDescriptionPointer(OUT PVOID *AcpiTable); - -XTCDECL -EFI_STATUS -AcGetAcpiTable(IN CONST UINT Signature, - IN PVOID PreviousTable, - OUT PVOID *AcpiTable); - -XTCDECL -EFI_STATUS -AcGetApicBase(OUT PVOID *ApicBase); - -XTCDECL -EFI_STATUS -AcGetRsdpTable(OUT PVOID *AcpiTable); - -XTCDECL -EFI_STATUS -AcGetSMBiosTable(OUT PVOID *SmBiosTable); - -XTCDECL -EFI_STATUS -AcGetSMBios3Table(OUT PVOID *SmBiosTable); - -XTCDECL -EFI_STATUS -AcGetXsdpTable(OUT PVOID *AcpiTable); - -XTCDECL -BOOLEAN -AcpValidateAcpiTable(IN PVOID Buffer, - IN UINT_PTR Size); - -XTCDECL -EFI_STATUS -XtLdrModuleMain(IN EFI_HANDLE ImageHandle, - IN PEFI_SYSTEM_TABLE SystemTable); - -#endif/* __XTLDR_ACPI_ACPI_H */ diff --git a/xtldr/modules/acpi/includes/acpi.hh b/xtldr/modules/acpi/includes/acpi.hh new file mode 100644 index 0000000..80a2e6f --- /dev/null +++ b/xtldr/modules/acpi/includes/acpi.hh @@ -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 + */ + +#ifndef __XTLDR_ACPI_ACPI_HH +#define __XTLDR_ACPI_ACPI_HH + +#include + + +/* 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 */ diff --git a/xtldr/modules/acpi/includes/globals.h b/xtldr/modules/acpi/includes/globals.h deleted file mode 100644 index 417b26d..0000000 --- a/xtldr/modules/acpi/includes/globals.h +++ /dev/null @@ -1,21 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/acpi/includes/globals.h - * DESCRIPTION: ACPI Module global variables - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTLDR_ACPI_GLOBALS_H -#define __XTLDR_ACPI_GLOBALS_H - -#include - - -/* ACPI Protocol */ -EXTERN XTBL_ACPI_PROTOCOL AcpAcpiProtocol; - -/* XTLDR protocol handler */ -EXTERN PXTBL_LOADER_PROTOCOL XtLdrProtocol; - -#endif/* __XTLDR_ACPI_GLOBALS_H */ diff --git a/xtldr/modules/beep/CMakeLists.txt b/xtldr/modules/beep/CMakeLists.txt index 1c132bd..5cd4140 100644 --- a/xtldr/modules/beep/CMakeLists.txt +++ b/xtldr/modules/beep/CMakeLists.txt @@ -8,8 +8,8 @@ include_directories( # Specify list of source code files list(APPEND XTLDR_BEEP_SOURCE - ${XTLDR_BEEP_SOURCE_DIR}/beep.c - ${XTLDR_BEEP_SOURCE_DIR}/globals.c) + ${XTLDR_BEEP_SOURCE_DIR}/beep.cc + ${XTLDR_BEEP_SOURCE_DIR}/data.cc) # Link module executable add_executable(beep ${XTLDR_BEEP_SOURCE}) diff --git a/xtldr/modules/beep/beep.c b/xtldr/modules/beep/beep.cc similarity index 68% rename from xtldr/modules/beep/beep.c rename to xtldr/modules/beep/beep.cc index 596f3ee..d1e548b 100644 --- a/xtldr/modules/beep/beep.c +++ b/xtldr/modules/beep/beep.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * 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 * DEVELOPERS: Rafal Kupiec */ -#include +#include /* Beep module information */ @@ -15,6 +15,7 @@ MODULE_DESCRIPTION(L"Plays a GRUB compatible tune via PC speaker"); MODULE_LICENSE(L"GPLv3"); MODULE_VERSION(L"0.1"); + /** * Disables the PC speaker. * @@ -24,13 +25,13 @@ MODULE_VERSION(L"0.1"); */ XTCDECL VOID -BpDisableToneBeep() +Beep::DisableToneBeep() { UCHAR Status; /* Stop the PC speaker */ - Status = HlIoPortInByte(0x61); - HlIoPortOutByte(0x61, Status & 0xFC); + Status = XtLdrProtocol->IoPort.Read8(0x61); + XtLdrProtocol->IoPort.Write8(0x61, Status & 0xFC); } /** @@ -45,7 +46,7 @@ BpDisableToneBeep() */ XTCDECL VOID -BpEnableToneBeep(IN UINT Pitch) +Beep::EnableToneBeep(IN UINT Pitch) { UINT Counter; UCHAR Status; @@ -62,14 +63,51 @@ BpEnableToneBeep(IN UINT Pitch) /* Set the desired frequency of the PIT clock */ Counter = 0x1234DD / Pitch; - HlIoPortOutByte(0x43, 0xB6); - HlIoPortOutByte(0x43, 0xB6); - HlIoPortOutByte(0x42, (UCHAR) Counter & 0xFF); - HlIoPortOutByte(0x42, (UCHAR) (Counter >> 8) & 0xFF); + XtLdrProtocol->IoPort.Write8(0x43, 0xB6); + XtLdrProtocol->IoPort.Write8(0x43, 0xB6); + XtLdrProtocol->IoPort.Write8(0x42, (UCHAR) Counter & 0xFF); + XtLdrProtocol->IoPort.Write8(0x42, (UCHAR) (Counter >> 8) & 0xFF); /* Start the PC speaker */ - Status = HlIoPortInByte(0x61); - HlIoPortOutByte(0x61, Status | 0x03); + Status = XtLdrProtocol->IoPort.Read8(0x61); + 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 VOID -BpPlayTune(IN PWCHAR Arguments) +Beep::PlayTune(IN PWCHAR Arguments) { LONG Pitch, Duration, Tempo; PWCHAR Argument, LastArgument; @@ -95,41 +133,41 @@ BpPlayTune(IN PWCHAR Arguments) Tempo = -1; /* Tokenize provided list of arguments */ - Argument = RtlTokenizeWideString(Arguments, L" ", &LastArgument); + Argument = XtLdrProtocol->WideString.Tokenize(Arguments, L" ", &LastArgument); /* Iterate over all arguments */ - while(Argument != NULL) + while(Argument != NULLPTR) { /* Check if tempo, pitch and duration are set */ if(Tempo < 0) { /* Set the tempo */ - Tempo = BpWideStringToNumber(Argument); + Tempo = WideStringToNumber(Argument); } else if(Pitch < 0) { /* Set the pitch */ - Pitch = BpWideStringToNumber(Argument); + Pitch = WideStringToNumber(Argument); } else { /* Set the duration */ - Duration = BpWideStringToNumber(Argument); + Duration = WideStringToNumber(Argument); /* Check pitch value */ if(Pitch > 0) { /* Emit the beep tone */ - BpEnableToneBeep(Pitch); + EnableToneBeep(Pitch); } else { /* Stop emitting beep tone */ - BpDisableToneBeep(); + DisableToneBeep(); } /* Wait for duration time */ - XtLdrProtocol->Util.SleepExecution(60000 * Duration / Tempo); + XtLdrProtocol->Utils.SleepExecution(60000 * Duration / Tempo); /* Reset pitch and duration */ Pitch = -1; @@ -137,11 +175,11 @@ BpPlayTune(IN PWCHAR Arguments) } /* Get next argument */ - Argument = RtlTokenizeWideString(NULL, L" ", &LastArgument); + Argument = XtLdrProtocol->WideString.Tokenize(NULLPTR, L" ", &LastArgument); } /* Stop emitting beep tone */ - BpDisableToneBeep(); + DisableToneBeep(); } /** @@ -156,7 +194,7 @@ BpPlayTune(IN PWCHAR Arguments) */ XTCDECL UINT -BpWideStringToNumber(IN PWCHAR String) +Beep::WideStringToNumber(IN PWCHAR String) { ULONG Number = 0; @@ -195,21 +233,6 @@ EFI_STATUS XtLdrModuleMain(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); - BpPlayTune(Tune); - - /* Return success */ - return STATUS_EFI_SUCCESS; + /* Initialize BEEP module */ + return Beep::InitializeModule(ImageHandle, SystemTable); } diff --git a/xtldr/modules/beep/globals.c b/xtldr/modules/beep/data.cc similarity index 54% rename from xtldr/modules/beep/globals.c rename to xtldr/modules/beep/data.cc index 1c58f21..92e95f5 100644 --- a/xtldr/modules/beep/globals.c +++ b/xtldr/modules/beep/data.cc @@ -1,13 +1,13 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/beep/globals.c - * DESCRIPTION: Beep module global variables + * FILE: xtldr/modules/beep/data.cc + * DESCRIPTION: BEEP module global and static data * DEVELOPERS: Rafal Kupiec */ -#include +#include /* XTLDR protocol handler */ -PXTBL_LOADER_PROTOCOL XtLdrProtocol; +PXTBL_LOADER_PROTOCOL Beep::XtLdrProtocol; diff --git a/xtldr/modules/beep/includes/beep.h b/xtldr/modules/beep/includes/beep.h deleted file mode 100644 index db0af8f..0000000 --- a/xtldr/modules/beep/includes/beep.h +++ /dev/null @@ -1,38 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/beep/includes/beep.h - * DESCRIPTION: XTLDR Beep Module header file - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTLDR_BEEP_BEEP_H -#define __XTLDR_BEEP_BEEP_H - -#include -#include - - -/* Beep module routines forward references */ -XTCDECL -VOID -BpDisableToneBeep(); - -XTCDECL -VOID -BpEnableToneBeep(IN UINT Pitch); - -XTCDECL -VOID -BpPlayTune(IN PWCHAR Arguments); - -XTCDECL -UINT -BpWideStringToNumber(IN PWCHAR String); - -XTCDECL -EFI_STATUS -XtLdrModuleMain(IN EFI_HANDLE ImageHandle, - IN PEFI_SYSTEM_TABLE SystemTable); - -#endif/* __XTLDR_BEEP_BEEP_H */ diff --git a/xtldr/modules/beep/includes/beep.hh b/xtldr/modules/beep/includes/beep.hh new file mode 100644 index 0000000..9b613d1 --- /dev/null +++ b/xtldr/modules/beep/includes/beep.hh @@ -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 + */ + +#ifndef __XTLDR_BEEP_BEEP_HH +#define __XTLDR_BEEP_BEEP_HH + +#include + + +/* 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 */ diff --git a/xtldr/modules/beep/includes/globals.h b/xtldr/modules/beep/includes/globals.h deleted file mode 100644 index abd4894..0000000 --- a/xtldr/modules/beep/includes/globals.h +++ /dev/null @@ -1,18 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/beep/includes/globals.h - * DESCRIPTION: XTLDR Beep Module global variables - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTLDR_BEEP_GLOBALS_H -#define __XTLDR_BEEP_GLOBALS_H - -#include - - -/* XTLDR protocol handler */ -EXTERN PXTBL_LOADER_PROTOCOL XtLdrProtocol; - -#endif/* __XTLDR_BEEP_GLOBALS_H */ diff --git a/xtldr/modules/chainldr/CMakeLists.txt b/xtldr/modules/chainldr/CMakeLists.txt index 5fcb8de..63cbdb9 100644 --- a/xtldr/modules/chainldr/CMakeLists.txt +++ b/xtldr/modules/chainldr/CMakeLists.txt @@ -8,8 +8,8 @@ include_directories( # Specify list of source code files list(APPEND XTLDR_CHAINLDR_SOURCE - ${XTLDR_CHAINLDR_SOURCE_DIR}/chainldr.c - ${XTLDR_CHAINLDR_SOURCE_DIR}/globals.c) + ${XTLDR_CHAINLDR_SOURCE_DIR}/chainldr.cc + ${XTLDR_CHAINLDR_SOURCE_DIR}/data.cc) # Link module executable add_executable(chainldr ${XTLDR_CHAINLDR_SOURCE}) diff --git a/xtldr/modules/chainldr/chainldr.c b/xtldr/modules/chainldr/chainldr.cc similarity index 79% rename from xtldr/modules/chainldr/chainldr.c rename to xtldr/modules/chainldr/chainldr.cc index e902cda..b2c0604 100644 --- a/xtldr/modules/chainldr/chainldr.c +++ b/xtldr/modules/chainldr/chainldr.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * 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 * DEVELOPERS: Rafal Kupiec */ -#include +#include /* ChainLoader module information */ @@ -15,6 +15,7 @@ MODULE_DESCRIPTION(L"XTLDR Chain Loader"); MODULE_LICENSE(L"GPLv3"); MODULE_VERSION(L"0.1"); + /** * Chainloads another boot loader. * @@ -27,7 +28,7 @@ MODULE_VERSION(L"0.1"); */ XTCDECL EFI_STATUS -ChBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters) +ChainLoader::BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters) { EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; EFI_MEMMAP_DEVICE_PATH MemoryDevicePath[2]; @@ -39,7 +40,7 @@ ChBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters) PVOID LoaderData; /* Check if image file is provided */ - if(Parameters->KernelFile == NULL) + if(Parameters->KernelFile == NULLPTR) { /* No image filename provided, return error code */ 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); /* Close volume and return error code */ - XtLdrProtocol->Disk.CloseVolume(DiskHandle); + XtLdrProtocol->Disk.CloseVolume(&DiskHandle); return Status; } /* Read EFI image file from disk and close both directory and EFI volume */ Status = XtLdrProtocol->Disk.ReadFile(BootDir, Parameters->KernelFile, &LoaderData, &LoaderSize); BootDir->Close(BootDir); - XtLdrProtocol->Disk.CloseVolume(DiskHandle); + XtLdrProtocol->Disk.CloseVolume(&DiskHandle); /* Setup device path for EFI image */ MemoryDevicePath[0].Header.Length[0] = sizeof(EFI_MEMMAP_DEVICE_PATH); @@ -89,8 +90,8 @@ ChBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters) MemoryDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP; /* Load EFI image */ - Status = XtLdrProtocol->Util.LoadEfiImage((PEFI_DEVICE_PATH_PROTOCOL)MemoryDevicePath, - LoaderData, LoaderSize, &LoaderHandle); + Status = XtLdrProtocol->Utils.LoadEfiImage((PEFI_DEVICE_PATH_PROTOCOL)MemoryDevicePath, + LoaderData, LoaderSize, &LoaderHandle); if(Status != STATUS_EFI_SUCCESS) { /* Failed to chainload EFI binary, return error code */ @@ -112,7 +113,7 @@ ChBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters) if(Parameters->Parameters) { /* 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; } @@ -120,7 +121,46 @@ ChBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters) LoadedImage->DeviceHandle = DiskHandle; /* 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, 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 */ - ChpBootProtocol.BootSystem = ChBootSystem; - - /* Register XTOS boot protocol */ - XtLdrProtocol->Boot.RegisterProtocol(L"CHAINLOADER", &Guid); - - /* Install XTOS protocol */ - return XtLdrProtocol->Protocol.Install(&ChpBootProtocol, &Guid); + /* Initialize CHAINLDR module */ + return ChainLoader::InitializeModule(ImageHandle, SystemTable); } diff --git a/xtldr/modules/chainldr/globals.c b/xtldr/modules/chainldr/data.cc similarity index 50% rename from xtldr/modules/chainldr/globals.c rename to xtldr/modules/chainldr/data.cc index 7380ca3..7b89e80 100644 --- a/xtldr/modules/chainldr/globals.c +++ b/xtldr/modules/chainldr/data.cc @@ -1,16 +1,16 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/chainldr/globals.c - * DESCRIPTION: XTLDR Chain Loader global variables + * FILE: xtldr/modules/chainldr/data.cc + * DESCRIPTION: CHAINLDR module global and static data * DEVELOPERS: Rafal Kupiec */ -#include +#include /* ChainLoader Boot Protocol */ -XTBL_BOOT_PROTOCOL ChpBootProtocol; +XTBL_BOOT_PROTOCOL ChainLoader::BootProtocol; /* XTLDR protocol handler */ -PXTBL_LOADER_PROTOCOL XtLdrProtocol; +PXTBL_LOADER_PROTOCOL ChainLoader::XtLdrProtocol; diff --git a/xtldr/modules/chainldr/includes/chainldr.h b/xtldr/modules/chainldr/includes/chainldr.h deleted file mode 100644 index 9fdf0c5..0000000 --- a/xtldr/modules/chainldr/includes/chainldr.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/chainldr/includes/chainldr.h - * DESCRIPTION: XTLDR Chain Loader header file - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTLDR_CHAINLDR_CHAINLDR_H -#define __XTLDR_CHAINLDR_CHAINLDR_H - -#include -#include - - -/* ChainLoader module routines forward references */ -XTCDECL -EFI_STATUS -ChBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters); - -XTCDECL -EFI_STATUS -XtLdrModuleMain(IN EFI_HANDLE ImageHandle, - IN PEFI_SYSTEM_TABLE SystemTable); - -#endif/* __XTLDR_CHAINLDR_CHAINLDR_H */ diff --git a/xtldr/modules/chainldr/includes/chainldr.hh b/xtldr/modules/chainldr/includes/chainldr.hh new file mode 100644 index 0000000..b0e18b0 --- /dev/null +++ b/xtldr/modules/chainldr/includes/chainldr.hh @@ -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 + */ + +#ifndef __XTLDR_CHAINLDR_CHAINLDR_HH +#define __XTLDR_CHAINLDR_CHAINLDR_HH + +#include + + +/* 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 */ diff --git a/xtldr/modules/chainldr/includes/globals.h b/xtldr/modules/chainldr/includes/globals.h deleted file mode 100644 index 89f379b..0000000 --- a/xtldr/modules/chainldr/includes/globals.h +++ /dev/null @@ -1,21 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/chainldr/includes/globals.h - * DESCRIPTION: XTLDR Chain Loader global variables - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTLDR_CHAINLDR_GLOBALS_H -#define __XTLDR_CHAINLDR_GLOBALS_H - -#include - - -/* ChainLoader Boot Protocol */ -EXTERN XTBL_BOOT_PROTOCOL ChpBootProtocol; - -/* XTLDR protocol handler */ -EXTERN PXTBL_LOADER_PROTOCOL XtLdrProtocol; - -#endif/* __XTLDR_CHAINLDR_GLOBALS_H */ diff --git a/xtldr/modules/dummy/CMakeLists.txt b/xtldr/modules/dummy/CMakeLists.txt index 2583b64..8b0e3a1 100644 --- a/xtldr/modules/dummy/CMakeLists.txt +++ b/xtldr/modules/dummy/CMakeLists.txt @@ -8,8 +8,8 @@ include_directories( # Specify list of source code files list(APPEND XTLDR_DUMMY_SOURCE - ${XTLDR_DUMMY_SOURCE_DIR}/dummy.c - ${XTLDR_DUMMY_SOURCE_DIR}/globals.c) + ${XTLDR_DUMMY_SOURCE_DIR}/dummy.cc + ${XTLDR_DUMMY_SOURCE_DIR}/data.cc) # Link module executable add_executable(dummy ${XTLDR_DUMMY_SOURCE}) diff --git a/xtldr/modules/dummy/globals.c b/xtldr/modules/dummy/data.cc similarity index 51% rename from xtldr/modules/dummy/globals.c rename to xtldr/modules/dummy/data.cc index 071747c..457a937 100644 --- a/xtldr/modules/dummy/globals.c +++ b/xtldr/modules/dummy/data.cc @@ -1,16 +1,16 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/dummy/globals.c - * DESCRIPTION: Dummy XTLDR module global variables + * FILE: xtldr/modules/dummy/data.cc + * DESCRIPTION: Dummy XTLDR module global and static data * DEVELOPERS: Rafal Kupiec */ -#include +#include -/* XTLDR protocol handler */ -PXTBL_LOADER_PROTOCOL XtLdrProtocol; - /* Dummy Boot Protocol handler */ -XTBL_BOOT_PROTOCOL BlpDummyProtocol; +XTBL_BOOT_PROTOCOL Dummy::DummyProtocol; + +/* XTLDR protocol handler */ +PXTBL_LOADER_PROTOCOL Dummy::XtLdrProtocol; diff --git a/xtldr/modules/dummy/dummy.c b/xtldr/modules/dummy/dummy.cc similarity index 67% rename from xtldr/modules/dummy/dummy.c rename to xtldr/modules/dummy/dummy.cc index fdd0ee1..52a8e83 100644 --- a/xtldr/modules/dummy/dummy.c +++ b/xtldr/modules/dummy/dummy.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * 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 * DEVELOPERS: Rafal Kupiec */ -#include +#include /* Dummy module information */ @@ -15,6 +15,7 @@ MODULE_DESCRIPTION(L"XTLDR Dummy Module"); MODULE_LICENSE(L"GPLv3"); MODULE_VERSION(L"0.1"); + /** * Stub boot routine. * @@ -27,11 +28,50 @@ MODULE_VERSION(L"0.1"); */ XTCDECL EFI_STATUS -DmBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters) +Dummy::BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters) { 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. * @@ -50,23 +90,6 @@ EFI_STATUS XtLdrModuleMain(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 */ - 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); + /* Initialize DUMMY module */ + return Dummy::InitializeModule(ImageHandle, SystemTable); } diff --git a/xtldr/modules/dummy/includes/dummy.h b/xtldr/modules/dummy/includes/dummy.h deleted file mode 100644 index f027427..0000000 --- a/xtldr/modules/dummy/includes/dummy.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/dummy/includes/dummy.h - * DESCRIPTION: XTLDR Dummy Module header file - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTLDR_DUMMY_DUMMY_H -#define __XTLDR_DUMMY_DUMMY_H - -#include -#include - - -/* Dummy module routines forward references */ -XTCDECL -EFI_STATUS -DmBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters); - -XTCDECL -EFI_STATUS -XtLdrModuleMain(IN EFI_HANDLE ImageHandle, - IN PEFI_SYSTEM_TABLE SystemTable); - -#endif/* __XTLDR_DUMMY_DUMMY_H */ diff --git a/xtldr/modules/dummy/includes/dummy.hh b/xtldr/modules/dummy/includes/dummy.hh new file mode 100644 index 0000000..1dc2891 --- /dev/null +++ b/xtldr/modules/dummy/includes/dummy.hh @@ -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 + */ + +#ifndef __XTLDR_DUMMY_DUMMY_HH +#define __XTLDR_DUMMY_DUMMY_HH + +#include + + +/* 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 */ diff --git a/xtldr/modules/dummy/includes/globals.h b/xtldr/modules/dummy/includes/globals.h deleted file mode 100644 index aab86ed..0000000 --- a/xtldr/modules/dummy/includes/globals.h +++ /dev/null @@ -1,21 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/dummy/includes/globals.h - * DESCRIPTION: XTLDR Dummy Module global variables - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTLDR_DUMMY_GLOBALS_H -#define __XTLDR_DUMMY_GLOBALS_H - -#include - - -/* XTLDR protocol handler */ -EXTERN PXTBL_LOADER_PROTOCOL XtLdrProtocol; - -/* Dummy Boot Protocol handler */ -EXTERN XTBL_BOOT_PROTOCOL BlpDummyProtocol; - -#endif/* __XTLDR_DUMMY_GLOBALS_H */ diff --git a/xtldr/modules/framebuf/CMakeLists.txt b/xtldr/modules/framebuf/CMakeLists.txt index 451bd55..f81d21f 100644 --- a/xtldr/modules/framebuf/CMakeLists.txt +++ b/xtldr/modules/framebuf/CMakeLists.txt @@ -8,8 +8,8 @@ include_directories( # Specify list of source code files list(APPEND XTLDR_FRAMEBUF_SOURCE - ${XTLDR_FRAMEBUF_SOURCE_DIR}/framebuf.c - ${XTLDR_FRAMEBUF_SOURCE_DIR}/globals.c) + ${XTLDR_FRAMEBUF_SOURCE_DIR}/framebuf.cc + ${XTLDR_FRAMEBUF_SOURCE_DIR}/data.cc) # Link bootloader executable add_executable(framebuf ${XTLDR_FRAMEBUF_SOURCE}) diff --git a/xtldr/modules/framebuf/data.cc b/xtldr/modules/framebuf/data.cc new file mode 100644 index 0000000..6bcc7fb --- /dev/null +++ b/xtldr/modules/framebuf/data.cc @@ -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 + */ + +#include + + +/* Framebuffer display information */ +XTBL_FRAMEBUFFER_INFORMATION FrameBuffer::DisplayInfo; + +/* Framebuffer protocol handler */ +XTBL_FRAMEBUFFER_PROTOCOL FrameBuffer::FbProtocol; + +/* XTLDR protocol handler */ +PXTBL_LOADER_PROTOCOL FrameBuffer::XtLdrProtocol; diff --git a/xtldr/modules/framebuf/framebuf.c b/xtldr/modules/framebuf/framebuf.cc similarity index 62% rename from xtldr/modules/framebuf/framebuf.c rename to xtldr/modules/framebuf/framebuf.cc index de5c1b2..8763636 100644 --- a/xtldr/modules/framebuf/framebuf.c +++ b/xtldr/modules/framebuf/framebuf.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/framebuf/framebuf.c + * FILE: xtldr/modules/framebuf/framebuf.cc * DESCRIPTION: EFI framebuffer support module for XTLDR * DEVELOPERS: Rafal Kupiec */ -#include +#include /* PE/COFF_O module information */ @@ -15,404 +15,6 @@ MODULE_DESCRIPTION(L"EFI FB (FrameBuffer) support"); MODULE_LICENSE(L"GPLv3"); MODULE_VERSION(L"0.2"); -/** - * Provides an EFI Frame Buffer protocol driver name used for initialization. - * - * @param Protocol - * Supplies a pointer to the memory area where framebuffer driver information will be stored. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -FbGetDisplayDriver(OUT PEFI_GRAPHICS_PROTOCOL Protocol) -{ - /* Check if framebuffer is initialized */ - if(!FbpDisplayInfo.Initialized) - { - /* Return error if framebuffer is not initialized */ - return STATUS_EFI_NOT_READY; - } - - /* Copy framebuffer driver information */ - *Protocol = FbpDisplayInfo.Protocol; - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * Returns information about EFI Frame Buffer. - * - * @param FbInfo - * Supplies a pointer to the memory area where framebuffer information will be stored. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -FbGetDisplayInformation(OUT PEFI_PHYSICAL_ADDRESS FrameBufferBase, - OUT PULONG_PTR FrameBufferSize, - OUT PXTBL_FRAMEBUFFER_MODE_INFORMATION ModeInfo) -{ - /* Check if framebuffer is initialized */ - if(!FbpDisplayInfo.Initialized) - { - /* Return error if framebuffer is not initialized */ - return STATUS_EFI_NOT_READY; - } - - /* Set basic framebuffer information */ - *FrameBufferBase = FbpDisplayInfo.FrameBufferBase; - *FrameBufferSize = FbpDisplayInfo.FrameBufferSize; - - /* Set framebuffer mode information */ - ModeInfo->Width = FbpDisplayInfo.ModeInfo.Width; - ModeInfo->Height = FbpDisplayInfo.ModeInfo.Height; - ModeInfo->Depth = FbpDisplayInfo.ModeInfo.Depth; - ModeInfo->RefreshRate = FbpDisplayInfo.ModeInfo.RefreshRate; - ModeInfo->BitsPerPixel = FbpDisplayInfo.ModeInfo.BitsPerPixel; - ModeInfo->BytesPerPixel = FbpDisplayInfo.ModeInfo.BytesPerPixel; - ModeInfo->PixelsPerScanLine = FbpDisplayInfo.ModeInfo.PixelsPerScanLine; - ModeInfo->Pitch = FbpDisplayInfo.ModeInfo.Pitch; - ModeInfo->PixelFormat = FbpDisplayInfo.ModeInfo.PixelFormat; - ModeInfo->PixelInformation = FbpDisplayInfo.ModeInfo.PixelInformation; - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * Determines the preferred (native) screen resolution from EDID. This works only with GOP. - * - * @param PreferredWidth - * Supplies a pointer to the memory area where preferred screen width will be stored. - * - * @param PreferredHeight - * Supplies a pointer to the memory area where preferred screen height will be stored. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -FbGetPreferredScreenResolution(OUT PUINT PreferredWidth, - OUT PUINT PreferredHeight) -{ - EFI_GUID GopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; - EFI_GUID EdidGuid = EFI_EDID_ACTIVE_PROTOCOL_GUID; - PEFI_EDID_ACTIVE_PROTOCOL ActiveEdid; - EFI_STATUS Status; - - /* Check if framebuffer is initialized */ - if(!FbpDisplayInfo.Initialized) - { - /* Framebuffer not ready to use EDID protocol */ - return STATUS_EFI_NOT_READY; - } - - /* Check if GOP device driver is used */ - if(FbpDisplayInfo.Protocol != GOP) - { - /* Unsupported device driver */ - return STATUS_EFI_UNSUPPORTED; - } - - /* Open EDID protocol */ - Status = XtLdrProtocol->Protocol.OpenHandle(FbpDisplayInfo.Handle, (PVOID *)&ActiveEdid, &EdidGuid); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open EDID protocol, close GOP protocol and return */ - XtLdrProtocol->Protocol.Close(FbpDisplayInfo.Handle, &GopGuid); - return Status; - } - - /* Return preferred screen resolution */ - *PreferredWidth = ActiveEdid->Edid[0x38] | ((ActiveEdid->Edid[0x3A] & 0xF0) << 4); - *PreferredHeight = ActiveEdid->Edid[0x3B] | ((ActiveEdid->Edid[0x3D] & 0xF0) << 4); - - /* Close EDID & GOP protocols */ - XtLdrProtocol->Protocol.Close(FbpDisplayInfo.Handle, &EdidGuid); - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * Initializes FrameBuffer device on GOP and UGA compatible adapters. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -FbInitializeDisplay() -{ - EFI_GUID GopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; - EFI_GUID UgaGuid = EFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL_GUID; - PEFI_GRAPHICS_OUTPUT_MODE_INFORMATION GopModeInfo; - UINT Depth, QueryMode, Refresh; - UINT_PTR InfoSize; - EFI_STATUS Status; - - /* Check if framebuffer already initialized */ - if(!FbpDisplayInfo.Initialized) - { - /* Print debug message */ - XtLdrProtocol->Debug.Print(L"Initializing framebuffer device\n"); - - /* Attempt to open EFI GOP protocol */ - Status = XtLdrProtocol->Protocol.Open(&FbpDisplayInfo.Handle, (PVOID*)&FbpDisplayInfo.Driver.Gop, &GopGuid); - - /* Check if Graphics Output Protocol (GOP) is available */ - if(Status == STATUS_EFI_SUCCESS) - { - /* Check if there are any video modes available */ - if(FbpDisplayInfo.Driver.Gop->Mode->MaxMode == 0) - { - /* No video modes available */ - XtLdrProtocol->Debug.Print(L"ERROR: No GOP video mode available\n"); - - /* Close GOP protocol and return error */ - XtLdrProtocol->Protocol.Close(FbpDisplayInfo.Handle, &GopGuid); - return STATUS_EFI_UNSUPPORTED; - } - - /* Query current graphics mode */ - QueryMode = FbpDisplayInfo.Driver.Gop->Mode == NULL ? 0 : FbpDisplayInfo.Driver.Gop->Mode->Mode; - Status = FbpDisplayInfo.Driver.Gop->QueryMode(FbpDisplayInfo.Driver.Gop, QueryMode, &InfoSize, &GopModeInfo); - if(Status == STATUS_EFI_NOT_STARTED) - { - /* Set the mode to circumvent buggy UEFI firmware */ - Status = FbpDisplayInfo.Driver.Gop->SetMode(FbpDisplayInfo.Driver.Gop, 0); - } - if(Status != STATUS_EFI_SUCCESS) - { - /* Unable to query GOP modes */ - XtLdrProtocol->Debug.Print(L"ERROR: Failed to get GOP native mode (Status Code: 0x%zX)\n"); - - /* Close GOP protocol and return error */ - XtLdrProtocol->Protocol.Close(FbpDisplayInfo.Handle, &GopGuid); - return STATUS_EFI_UNSUPPORTED; - } - - /* Store frame buffer base address and protocol used */ - FbpDisplayInfo.FrameBufferBase = FbpDisplayInfo.Driver.Gop->Mode->FrameBufferBase; - FbpDisplayInfo.DefaultMode = FbpDisplayInfo.Driver.Gop->Mode->Mode; - FbpDisplayInfo.Protocol = GOP; - - /* Get current mode information */ - Status = FbpGetModeInfo(); - if(Status != STATUS_EFI_SUCCESS) - { - /* Unable to get mode information */ - XtLdrProtocol->Debug.Print(L"ERROR: Failed to get GOP mode information (Status Code: 0x%zX)\n"); - - /* Close GOP protocol and return error */ - XtLdrProtocol->Protocol.Close(FbpDisplayInfo.Handle, &GopGuid); - return STATUS_EFI_UNSUPPORTED; - } - - /* Found GOP */ - XtLdrProtocol->Debug.Print(L"Found EFI-GOP compatible display adapter @ %P (%zu bytes)\n", - FbpDisplayInfo.FrameBufferBase, FbpDisplayInfo.FrameBufferSize); - - /* Close GOP protocol */ - Status = XtLdrProtocol->Protocol.Close(FbpDisplayInfo.Handle, &GopGuid); - } - else - { - /* GOP is unavailable, attempt to open UGA protocol */ - Status = XtLdrProtocol->Protocol.Open(&FbpDisplayInfo.Handle, (PVOID*)&FbpDisplayInfo.Driver.Uga, &UgaGuid); - - /* Check if Universal Graphics Adapter (UGA) is available */ - if(Status == STATUS_EFI_SUCCESS) - { - /* Get current video mode */ - Status = FbpDisplayInfo.Driver.Uga->GetMode(FbpDisplayInfo.Driver.Uga, &FbpDisplayInfo.ModeInfo.Width, - &FbpDisplayInfo.ModeInfo.Height, &Depth, &Refresh); - if(Status != STATUS_EFI_SUCCESS) - { - /* Unable to get current UGA mode */ - XtLdrProtocol->Debug.Print(L"ERROR: Failed to get current UGA mode (Status Code: 0x%zX)\n", Status); - - /* Close UGA protocol and return error */ - XtLdrProtocol->Protocol.Close(FbpDisplayInfo.Handle, &UgaGuid); - return STATUS_EFI_DEVICE_ERROR; - } - - /* Find framebuffer address */ - Status = FbpFindFramebufferAddress(&FbpDisplayInfo.FrameBufferBase); - if(Status != STATUS_EFI_SUCCESS) - { - /* Unable to find framebuffer address */ - XtLdrProtocol->Debug.Print(L"ERROR: Failed to get EFI FB address (Status Code: 0x%zX)\n", Status); - - /* Close UGA protocol and return error */ - XtLdrProtocol->Protocol.Close(FbpDisplayInfo.Handle, &UgaGuid); - return STATUS_EFI_DEVICE_ERROR; - } - - /* Store framebuffer protocol information */ - FbpDisplayInfo.DefaultMode = 0; - FbpDisplayInfo.Protocol = UGA; - - /* Get mode information */ - Status = FbpGetModeInfo(); - if(Status != STATUS_EFI_SUCCESS) - { - /* Unable to get mode information */ - XtLdrProtocol->Debug.Print(L"ERROR: Failed to get UGA mode information (Status Code: 0x%zX)\n"); - return STATUS_EFI_UNSUPPORTED; - } - - /* Found UGA */ - XtLdrProtocol->Debug.Print(L"Found EFI-UGA compatible display adapter @ %P (%zu bytes)\n", - FbpDisplayInfo.FrameBufferBase, FbpDisplayInfo.FrameBufferSize); - - /* Close UGA protocol */ - XtLdrProtocol->Protocol.Close(FbpDisplayInfo.Handle, &UgaGuid); - } - } - - /* Make sure framebuffer initialized properly */ - if(FbpDisplayInfo.Protocol == NONE) - { - /* GOP and UGA unavailable */ - XtLdrProtocol->Debug.Print(L"WARNING: No display adapter found!\n"); - return STATUS_EFI_NOT_FOUND; - } - - XtLdrProtocol->Debug.Print(L"Current screen resolution is %ux%ux%u\n", FbpDisplayInfo.ModeInfo.Width, - FbpDisplayInfo.ModeInfo.Height, FbpDisplayInfo.ModeInfo.BitsPerPixel); - - /* Set framebuffer initialization flag */ - FbpDisplayInfo.Initialized = TRUE; - } - - /* Return success */ - return STATUS_SUCCESS; -} - -/** - * Sets custom screen resolution, based on the provided width and height. - * - * @param Width - * Supplies the width of the screen. - * - * @param Height - * Supplies the height of the screen. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -FbSetScreenResolution(IN UINT Width, - IN UINT Height) -{ - PEFI_GRAPHICS_OUTPUT_MODE_INFORMATION ModeInfo; - BOOLEAN ModeChanged; - EFI_STATUS Status; - UINT_PTR Size; - UINT Mode; - - /* Check if framebuffer is initialized */ - if(!FbpDisplayInfo.Initialized) - { - /* Framebuffer not ready to change screen mode */ - return STATUS_EFI_NOT_READY; - } - - ModeChanged = FALSE; - - /* Change screen mode depending on display adapter protocol */ - switch(FbpDisplayInfo.Protocol) - { - case GOP: - /* GOP available, check if user specified screen resolution */ - if(Width == 0 || Height == 0) - { - /* No resolution specified, temporarily set lowest supported screen resolution */ - Status = FbpDisplayInfo.Driver.Gop->SetMode(FbpDisplayInfo.Driver.Gop, 1); - if(Status == STATUS_EFI_SUCCESS) - { - /* Restore default graphics mode */ - Status = FbpDisplayInfo.Driver.Gop->SetMode(FbpDisplayInfo.Driver.Gop, FbpDisplayInfo.DefaultMode); - ModeChanged = (Status == STATUS_EFI_SUCCESS); - } - } - else - { - /* User specified screen resolution, find a corresponding mode */ - Mode = 1; - while(Mode <= FbpDisplayInfo.Driver.Gop->Mode->MaxMode) - { - /* Get mode information */ - Status = FbpDisplayInfo.Driver.Gop->QueryMode(FbpDisplayInfo.Driver.Gop, Mode, &Size, &ModeInfo); - if(Status == STATUS_EFI_SUCCESS && Size >= sizeof(*ModeInfo) && ModeInfo != NULL) - { - /* Check if match found */ - if(ModeInfo->HorizontalResolution == Width && ModeInfo->VerticalResolution == Height) - { - /* Found corresponding mode, attempt to set it */ - Status = FbpDisplayInfo.Driver.Gop->SetMode(FbpDisplayInfo.Driver.Gop, Mode); - if(Status == STATUS_EFI_SUCCESS) - { - /* New mode set correctly, use it */ - ModeChanged = TRUE; - break; - } - } - } - - /* Try with next mode */ - Mode++; - } - } - break; - case UGA: - /* Set UGA screen mode, trying to keep current color depth and refresh rate */ - Status = FbpDisplayInfo.Driver.Uga->SetMode(FbpDisplayInfo.Driver.Uga, Width, Height, - FbpDisplayInfo.ModeInfo.Depth, - FbpDisplayInfo.ModeInfo.RefreshRate); - if(Status == STATUS_EFI_SUCCESS) - { - /* New mode set correctly, use it */ - ModeChanged = TRUE; - } - break; - default: - /* This should never be reached */ - break; - } - - if(!ModeChanged) - { - /* Failed to change screen mode */ - XtLdrProtocol->Debug.Print(L"ERROR: Failed to change screen mode to %ux%u (Status Code: 0x%zX)\n", - Width, Height, Status); - return STATUS_EFI_UNSUPPORTED; - } - - /* Get new screen mode information */ - Status = FbpGetModeInfo(); - if(Status == STATUS_EFI_SUCCESS) - { - XtLdrProtocol->Debug.Print(L"Changed screen resolution to %ux%ux%u\n", FbpDisplayInfo.ModeInfo.Width, - FbpDisplayInfo.ModeInfo.Height, FbpDisplayInfo.ModeInfo.BitsPerPixel); - } - - /* Return success */ - return STATUS_EFI_SUCCESS; -} /** * Finds a PCI Display Adapter and returns its framebuffer address. @@ -426,7 +28,7 @@ FbSetScreenResolution(IN UINT Width, */ XTCDECL EFI_STATUS -FbpFindFramebufferAddress(OUT PEFI_PHYSICAL_ADDRESS Address) +FrameBuffer::FindFramebufferAddress(OUT PEFI_PHYSICAL_ADDRESS Address) { EFI_GUID PciIoGuid = EFI_PCI_IO_PROTOCOL_GUID; PEFI_ACPI_ADDRESS_SPACE_DESCRIPTOR BarInfo; @@ -441,7 +43,7 @@ FbpFindFramebufferAddress(OUT PEFI_PHYSICAL_ADDRESS Address) /* Initialize variables */ FramebufAddressLength = 0; - Handles = NULL; + Handles = NULLPTR; /* Locate EFI_PCI_IO_PROTOCOL handles */ Status = XtLdrProtocol->Protocol.LocateHandles(&Handles, &HandlesCount, &PciIoGuid); @@ -472,7 +74,7 @@ FbpFindFramebufferAddress(OUT PEFI_PHYSICAL_ADDRESS Address) XtLdrProtocol->Debug.Print(L"ERROR: Failed to read class (Status Code: 0x%zX)\n", Status); /* Close protocol and continue with next handle */ - XtLdrProtocol->Protocol.Close(Handles[Index], &PciIoGuid); + XtLdrProtocol->Protocol.Close(&Handles[Index], &PciIoGuid); continue; } @@ -480,7 +82,7 @@ FbpFindFramebufferAddress(OUT PEFI_PHYSICAL_ADDRESS Address) if(PciDevice.Hdr.ClassCode[2] != 0x03) { /* Not a graphics adapter, close protocol and continue with next handle */ - XtLdrProtocol->Protocol.Close(Handles[Index], &PciIoGuid); + XtLdrProtocol->Protocol.Close(&Handles[Index], &PciIoGuid); continue; } @@ -488,7 +90,7 @@ FbpFindFramebufferAddress(OUT PEFI_PHYSICAL_ADDRESS Address) for(UINT Bars = 0; Bars < 6; Bars++) { /* Get BAR attributes */ - Status = IoProtocol->GetBarAttributes(IoProtocol, Bars, NULL, (VOID **)&BarInfo); + Status = IoProtocol->GetBarAttributes(IoProtocol, Bars, NULLPTR, (VOID **)&BarInfo); if(Status != STATUS_EFI_SUCCESS) { /* Failed to get BAR attributes, continue with next BAR */ @@ -510,7 +112,7 @@ FbpFindFramebufferAddress(OUT PEFI_PHYSICAL_ADDRESS Address) } /* Close handle and continue with next one */ - XtLdrProtocol->Protocol.Close(Handles[Index], &PciIoGuid); + XtLdrProtocol->Protocol.Close(&Handles[Index], &PciIoGuid); } /* Set framebuffer address and return success */ @@ -536,9 +138,9 @@ FbpFindFramebufferAddress(OUT PEFI_PHYSICAL_ADDRESS Address) */ XTCDECL VOID -FbpGetColorMask(IN UINT PixelBitMask, - OUT PUSHORT ColorSize, - OUT PUSHORT ColorShift) +FrameBuffer::GetColorMask(IN UINT PixelBitMask, + OUT PUSHORT ColorSize, + OUT PUSHORT ColorShift) { UINT Shift, Size; @@ -570,6 +172,78 @@ FbpGetColorMask(IN UINT PixelBitMask, *ColorSize = Size; } +/** + * Provides an EFI Frame Buffer protocol driver name used for initialization. + * + * @param Protocol + * Supplies a pointer to the memory area where framebuffer driver information will be stored. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +FrameBuffer::GetDisplayDriver(OUT PEFI_GRAPHICS_PROTOCOL Protocol) +{ + /* Check if framebuffer is initialized */ + if(!DisplayInfo.Initialized) + { + /* Return error if framebuffer is not initialized */ + return STATUS_EFI_NOT_READY; + } + + /* Copy framebuffer driver information */ + *Protocol = DisplayInfo.Protocol; + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Returns information about EFI Frame Buffer. + * + * @param FbInfo + * Supplies a pointer to the memory area where framebuffer information will be stored. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +FrameBuffer::GetDisplayInformation(OUT PEFI_PHYSICAL_ADDRESS FrameBufferBase, + OUT PULONG_PTR FrameBufferSize, + OUT PXTBL_FRAMEBUFFER_MODE_INFORMATION ModeInfo) +{ + /* Check if framebuffer is initialized */ + if(!DisplayInfo.Initialized) + { + /* Return error if framebuffer is not initialized */ + return STATUS_EFI_NOT_READY; + } + + /* Set basic framebuffer information */ + *FrameBufferBase = DisplayInfo.FrameBufferBase; + *FrameBufferSize = DisplayInfo.FrameBufferSize; + + /* Set framebuffer mode information */ + ModeInfo->Width = DisplayInfo.ModeInfo.Width; + ModeInfo->Height = DisplayInfo.ModeInfo.Height; + ModeInfo->Depth = DisplayInfo.ModeInfo.Depth; + ModeInfo->RefreshRate = DisplayInfo.ModeInfo.RefreshRate; + ModeInfo->BitsPerPixel = DisplayInfo.ModeInfo.BitsPerPixel; + ModeInfo->BytesPerPixel = DisplayInfo.ModeInfo.BytesPerPixel; + ModeInfo->PixelsPerScanLine = DisplayInfo.ModeInfo.PixelsPerScanLine; + ModeInfo->Pitch = DisplayInfo.ModeInfo.Pitch; + ModeInfo->PixelFormat = DisplayInfo.ModeInfo.PixelFormat; + ModeInfo->PixelInformation = DisplayInfo.ModeInfo.PixelInformation; + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + + /** * Gets information about the current display mode and stores it in internal structure. * @@ -579,19 +253,19 @@ FbpGetColorMask(IN UINT PixelBitMask, */ XTCDECL EFI_STATUS -FbpGetModeInfo() +FrameBuffer::GetModeInformation() { PEFI_GRAPHICS_OUTPUT_MODE_INFORMATION ModeInfo; EFI_PIXEL_BITMASK PixelBitMask; XTSTATUS Status; UINT_PTR Size; - switch(FbpDisplayInfo.Protocol) + switch(DisplayInfo.Protocol) { case GOP: /* Query GOP mode information */ - Status = FbpDisplayInfo.Driver.Gop->QueryMode(FbpDisplayInfo.Driver.Gop, - FbpDisplayInfo.Driver.Gop->Mode->Mode, + Status = DisplayInfo.Driver.Gop->QueryMode(DisplayInfo.Driver.Gop, + DisplayInfo.Driver.Gop->Mode->Mode, &Size, &ModeInfo); if(Status != STATUS_EFI_SUCCESS) { @@ -600,26 +274,26 @@ FbpGetModeInfo() } /* Get pixel bit mask information */ - FbpGetPixelInformation(&FbpDisplayInfo.Driver.Gop->Mode->Info->PixelInformation); + GetPixelInformation(&DisplayInfo.Driver.Gop->Mode->Info->PixelInformation); /* Store GOP framebuffer information */ - FbpDisplayInfo.ModeInfo.Width = FbpDisplayInfo.Driver.Gop->Mode->Info->HorizontalResolution; - FbpDisplayInfo.ModeInfo.Height = FbpDisplayInfo.Driver.Gop->Mode->Info->VerticalResolution; - FbpDisplayInfo.ModeInfo.Depth = FbpDisplayInfo.ModeInfo.BitsPerPixel; - FbpDisplayInfo.ModeInfo.PixelsPerScanLine = FbpDisplayInfo.Driver.Gop->Mode->Info->PixelsPerScanLine; - FbpDisplayInfo.ModeInfo.Pitch = FbpDisplayInfo.ModeInfo.PixelsPerScanLine * - (FbpDisplayInfo.ModeInfo.BitsPerPixel / 8); - FbpDisplayInfo.ModeInfo.RefreshRate = 0; + DisplayInfo.ModeInfo.Width = DisplayInfo.Driver.Gop->Mode->Info->HorizontalResolution; + DisplayInfo.ModeInfo.Height = DisplayInfo.Driver.Gop->Mode->Info->VerticalResolution; + DisplayInfo.ModeInfo.Depth = DisplayInfo.ModeInfo.BitsPerPixel; + DisplayInfo.ModeInfo.PixelsPerScanLine = DisplayInfo.Driver.Gop->Mode->Info->PixelsPerScanLine; + DisplayInfo.ModeInfo.Pitch = DisplayInfo.ModeInfo.PixelsPerScanLine * + (DisplayInfo.ModeInfo.BitsPerPixel / 8); + DisplayInfo.ModeInfo.RefreshRate = 0; /* Store pixel format information and frame buffer size */ - FbpDisplayInfo.ModeInfo.PixelFormat = FbpDisplayInfo.Driver.Gop->Mode->Info->PixelFormat; - FbpDisplayInfo.FrameBufferSize = FbpDisplayInfo.Driver.Gop->Mode->FrameBufferSize; + DisplayInfo.ModeInfo.PixelFormat = DisplayInfo.Driver.Gop->Mode->Info->PixelFormat; + DisplayInfo.FrameBufferSize = DisplayInfo.Driver.Gop->Mode->FrameBufferSize; break; case UGA: /* Query UGA mode information */ - Status = FbpDisplayInfo.Driver.Uga->GetMode(FbpDisplayInfo.Driver.Uga, &FbpDisplayInfo.ModeInfo.Width, - &FbpDisplayInfo.ModeInfo.Height, &FbpDisplayInfo.ModeInfo.Depth, - &FbpDisplayInfo.ModeInfo.RefreshRate); + Status = DisplayInfo.Driver.Uga->GetMode(DisplayInfo.Driver.Uga, &DisplayInfo.ModeInfo.Width, + &DisplayInfo.ModeInfo.Height, &DisplayInfo.ModeInfo.Depth, + &DisplayInfo.ModeInfo.RefreshRate); if(Status != STATUS_EFI_SUCCESS) { /* Failed to get UGA mode information, return error */ @@ -628,18 +302,18 @@ FbpGetModeInfo() /* Get pixel bit mask information */ PixelBitMask = (EFI_PIXEL_BITMASK){0, 0, 0, 0}; - FbpGetPixelInformation(&PixelBitMask); + GetPixelInformation(&PixelBitMask); /* Store UGA framebuffer information */ - FbpDisplayInfo.ModeInfo.PixelsPerScanLine = FbpDisplayInfo.ModeInfo.Width; - FbpDisplayInfo.ModeInfo.Pitch = FbpDisplayInfo.ModeInfo.PixelsPerScanLine * - (FbpDisplayInfo.ModeInfo.BitsPerPixel / 8); + DisplayInfo.ModeInfo.PixelsPerScanLine = DisplayInfo.ModeInfo.Width; + DisplayInfo.ModeInfo.Pitch = DisplayInfo.ModeInfo.PixelsPerScanLine * + (DisplayInfo.ModeInfo.BitsPerPixel / 8); /* Store pixel format information and recalculate frame buffer size */ - FbpDisplayInfo.ModeInfo.PixelFormat = PixelBlueGreenRedReserved8BitPerColor; - FbpDisplayInfo.FrameBufferSize = FbpDisplayInfo.ModeInfo.Width * - FbpDisplayInfo.ModeInfo.Height * - FbpDisplayInfo.ModeInfo.BytesPerPixel + 1024; + DisplayInfo.ModeInfo.PixelFormat = PixelBlueGreenRedReserved8BitPerColor; + DisplayInfo.FrameBufferSize = DisplayInfo.ModeInfo.Width * + DisplayInfo.ModeInfo.Height * + DisplayInfo.ModeInfo.BytesPerPixel + 1024; break; default: /* This should never be reached as no other display driver is supported */ @@ -665,40 +339,40 @@ FbpGetModeInfo() */ XTCDECL VOID -FbpGetPixelInformation(IN PEFI_PIXEL_BITMASK PixelsBitMask) +FrameBuffer::GetPixelInformation(IN PEFI_PIXEL_BITMASK PixelsBitMask) { UINT CompoundMask; /* Check reported pixel format */ - switch(FbpDisplayInfo.ModeInfo.PixelFormat) + switch(DisplayInfo.ModeInfo.PixelFormat) { case PixelBlueGreenRedReserved8BitPerColor: /* BGRR, 32 bits per pixel */ - FbpDisplayInfo.ModeInfo.BitsPerPixel = 32; - FbpDisplayInfo.ModeInfo.PixelInformation.BlueShift = 0; - FbpDisplayInfo.ModeInfo.PixelInformation.BlueSize = 8; - FbpDisplayInfo.ModeInfo.PixelInformation.GreenShift = 8; - FbpDisplayInfo.ModeInfo.PixelInformation.GreenSize = 8; - FbpDisplayInfo.ModeInfo.PixelInformation.RedShift = 16; - FbpDisplayInfo.ModeInfo.PixelInformation.RedSize = 8; - FbpDisplayInfo.ModeInfo.PixelInformation.ReservedShift = 24; - FbpDisplayInfo.ModeInfo.PixelInformation.ReservedSize = 8; + DisplayInfo.ModeInfo.BitsPerPixel = 32; + DisplayInfo.ModeInfo.PixelInformation.BlueShift = 0; + DisplayInfo.ModeInfo.PixelInformation.BlueSize = 8; + DisplayInfo.ModeInfo.PixelInformation.GreenShift = 8; + DisplayInfo.ModeInfo.PixelInformation.GreenSize = 8; + DisplayInfo.ModeInfo.PixelInformation.RedShift = 16; + DisplayInfo.ModeInfo.PixelInformation.RedSize = 8; + DisplayInfo.ModeInfo.PixelInformation.ReservedShift = 24; + DisplayInfo.ModeInfo.PixelInformation.ReservedSize = 8; break; case PixelRedGreenBlueReserved8BitPerColor: /* RGBR, 32 bits per pixel */ - FbpDisplayInfo.ModeInfo.BitsPerPixel = 32; - FbpDisplayInfo.ModeInfo.PixelInformation.BlueShift = 16; - FbpDisplayInfo.ModeInfo.PixelInformation.BlueSize = 8; - FbpDisplayInfo.ModeInfo.PixelInformation.GreenShift = 8; - FbpDisplayInfo.ModeInfo.PixelInformation.GreenSize = 8; - FbpDisplayInfo.ModeInfo.PixelInformation.RedShift = 0; - FbpDisplayInfo.ModeInfo.PixelInformation.RedSize = 8; - FbpDisplayInfo.ModeInfo.PixelInformation.ReservedShift = 24; - FbpDisplayInfo.ModeInfo.PixelInformation.ReservedSize = 8; + DisplayInfo.ModeInfo.BitsPerPixel = 32; + DisplayInfo.ModeInfo.PixelInformation.BlueShift = 16; + DisplayInfo.ModeInfo.PixelInformation.BlueSize = 8; + DisplayInfo.ModeInfo.PixelInformation.GreenShift = 8; + DisplayInfo.ModeInfo.PixelInformation.GreenSize = 8; + DisplayInfo.ModeInfo.PixelInformation.RedShift = 0; + DisplayInfo.ModeInfo.PixelInformation.RedSize = 8; + DisplayInfo.ModeInfo.PixelInformation.ReservedShift = 24; + DisplayInfo.ModeInfo.PixelInformation.ReservedSize = 8; break; case PixelBitMask: /* Assume 32 bits per pixel */ - FbpDisplayInfo.ModeInfo.BitsPerPixel = 32; + DisplayInfo.ModeInfo.BitsPerPixel = 32; /* Calculate compound mask */ CompoundMask = PixelsBitMask->RedMask | @@ -709,36 +383,408 @@ FbpGetPixelInformation(IN PEFI_PIXEL_BITMASK PixelsBitMask) /* Recalculate bits per pixel */ while((CompoundMask & (1 << 31)) == 0) { - FbpDisplayInfo.ModeInfo.BitsPerPixel--; + DisplayInfo.ModeInfo.BitsPerPixel--; CompoundMask <<= 1; } /* Set pixel information */ - FbpGetColorMask(PixelsBitMask->RedMask, &FbpDisplayInfo.ModeInfo.PixelInformation.RedSize, - &FbpDisplayInfo.ModeInfo.PixelInformation.RedShift); - FbpGetColorMask(PixelsBitMask->GreenMask, &FbpDisplayInfo.ModeInfo.PixelInformation.GreenSize, - &FbpDisplayInfo.ModeInfo.PixelInformation.GreenShift); - FbpGetColorMask(PixelsBitMask->BlueMask, &FbpDisplayInfo.ModeInfo.PixelInformation.BlueSize, - &FbpDisplayInfo.ModeInfo.PixelInformation.BlueShift); - FbpGetColorMask(PixelsBitMask->ReservedMask, &FbpDisplayInfo.ModeInfo.PixelInformation.ReservedSize, - &FbpDisplayInfo.ModeInfo.PixelInformation.ReservedShift); + GetColorMask(PixelsBitMask->RedMask, &DisplayInfo.ModeInfo.PixelInformation.RedSize, + &DisplayInfo.ModeInfo.PixelInformation.RedShift); + GetColorMask(PixelsBitMask->GreenMask, &DisplayInfo.ModeInfo.PixelInformation.GreenSize, + &DisplayInfo.ModeInfo.PixelInformation.GreenShift); + GetColorMask(PixelsBitMask->BlueMask, &DisplayInfo.ModeInfo.PixelInformation.BlueSize, + &DisplayInfo.ModeInfo.PixelInformation.BlueShift); + GetColorMask(PixelsBitMask->ReservedMask, &DisplayInfo.ModeInfo.PixelInformation.ReservedSize, + &DisplayInfo.ModeInfo.PixelInformation.ReservedShift); break; default: /* Unknown pixel format */ - FbpDisplayInfo.ModeInfo.BitsPerPixel = 0; - FbpDisplayInfo.ModeInfo.PixelInformation.BlueShift = 0; - FbpDisplayInfo.ModeInfo.PixelInformation.BlueSize = 0; - FbpDisplayInfo.ModeInfo.PixelInformation.GreenShift = 0; - FbpDisplayInfo.ModeInfo.PixelInformation.GreenSize = 0; - FbpDisplayInfo.ModeInfo.PixelInformation.RedShift = 0; - FbpDisplayInfo.ModeInfo.PixelInformation.RedSize = 0; - FbpDisplayInfo.ModeInfo.PixelInformation.ReservedShift = 0; - FbpDisplayInfo.ModeInfo.PixelInformation.ReservedSize = 0; + DisplayInfo.ModeInfo.BitsPerPixel = 0; + DisplayInfo.ModeInfo.PixelInformation.BlueShift = 0; + DisplayInfo.ModeInfo.PixelInformation.BlueSize = 0; + DisplayInfo.ModeInfo.PixelInformation.GreenShift = 0; + DisplayInfo.ModeInfo.PixelInformation.GreenSize = 0; + DisplayInfo.ModeInfo.PixelInformation.RedShift = 0; + DisplayInfo.ModeInfo.PixelInformation.RedSize = 0; + DisplayInfo.ModeInfo.PixelInformation.ReservedShift = 0; + DisplayInfo.ModeInfo.PixelInformation.ReservedSize = 0; break; } /* Calculate bytes per pixel based on bits per pixel */ - FbpDisplayInfo.ModeInfo.BytesPerPixel = FbpDisplayInfo.ModeInfo.BitsPerPixel >> 3; + DisplayInfo.ModeInfo.BytesPerPixel = DisplayInfo.ModeInfo.BitsPerPixel >> 3; +} + +/** + * Determines the preferred (native) screen resolution from EDID. This works only with GOP. + * + * @param PreferredWidth + * Supplies a pointer to the memory area where preferred screen width will be stored. + * + * @param PreferredHeight + * Supplies a pointer to the memory area where preferred screen height will be stored. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +FrameBuffer::GetPreferredScreenResolution(OUT PUINT PreferredWidth, + OUT PUINT PreferredHeight) +{ + EFI_GUID GopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; + EFI_GUID EdidGuid = EFI_EDID_ACTIVE_PROTOCOL_GUID; + PEFI_EDID_ACTIVE_PROTOCOL ActiveEdid; + EFI_STATUS Status; + + /* Check if framebuffer is initialized */ + if(!DisplayInfo.Initialized) + { + /* Framebuffer not ready to use EDID protocol */ + return STATUS_EFI_NOT_READY; + } + + /* Check if GOP device driver is used */ + if(DisplayInfo.Protocol != GOP) + { + /* Unsupported device driver */ + return STATUS_EFI_UNSUPPORTED; + } + + /* Open EDID protocol */ + Status = XtLdrProtocol->Protocol.OpenHandle(DisplayInfo.Handle, (PVOID *)&ActiveEdid, &EdidGuid); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open EDID protocol, close GOP protocol and return */ + XtLdrProtocol->Protocol.Close(&DisplayInfo.Handle, &GopGuid); + return Status; + } + + /* Return preferred screen resolution */ + *PreferredWidth = ActiveEdid->Edid[0x38] | ((ActiveEdid->Edid[0x3A] & 0xF0) << 4); + *PreferredHeight = ActiveEdid->Edid[0x3B] | ((ActiveEdid->Edid[0x3D] & 0xF0) << 4); + + /* Close EDID & GOP protocols */ + XtLdrProtocol->Protocol.Close(&DisplayInfo.Handle, &EdidGuid); + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Initializes FrameBuffer device on GOP and UGA compatible adapters. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +FrameBuffer::InitializeDisplay() +{ + EFI_GUID GopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; + EFI_GUID UgaGuid = EFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL_GUID; + PEFI_GRAPHICS_OUTPUT_MODE_INFORMATION GopModeInfo; + UINT Depth, QueryMode, Refresh; + UINT_PTR InfoSize; + EFI_STATUS Status; + + /* Check if framebuffer already initialized */ + if(!DisplayInfo.Initialized) + { + /* Print debug message */ + XtLdrProtocol->Debug.Print(L"Initializing framebuffer device\n"); + + /* Attempt to open EFI GOP protocol */ + Status = XtLdrProtocol->Protocol.Open(&DisplayInfo.Handle, (PVOID*)&DisplayInfo.Driver.Gop, &GopGuid); + + /* Check if Graphics Output Protocol (GOP) is available */ + if(Status == STATUS_EFI_SUCCESS) + { + /* Check if there are any video modes available */ + if(DisplayInfo.Driver.Gop->Mode->MaxMode == 0) + { + /* No video modes available */ + XtLdrProtocol->Debug.Print(L"ERROR: No GOP video mode available\n"); + + /* Close GOP protocol and return error */ + XtLdrProtocol->Protocol.Close(&DisplayInfo.Handle, &GopGuid); + return STATUS_EFI_UNSUPPORTED; + } + + /* Query current graphics mode */ + QueryMode = DisplayInfo.Driver.Gop->Mode == NULLPTR ? 0 : DisplayInfo.Driver.Gop->Mode->Mode; + Status = DisplayInfo.Driver.Gop->QueryMode(DisplayInfo.Driver.Gop, QueryMode, &InfoSize, &GopModeInfo); + if(Status == STATUS_EFI_NOT_STARTED) + { + /* Set the mode to circumvent buggy UEFI firmware */ + Status = DisplayInfo.Driver.Gop->SetMode(DisplayInfo.Driver.Gop, 0); + } + if(Status != STATUS_EFI_SUCCESS) + { + /* Unable to query GOP modes */ + XtLdrProtocol->Debug.Print(L"ERROR: Failed to get GOP native mode (Status Code: 0x%zX)\n"); + + /* Close GOP protocol and return error */ + XtLdrProtocol->Protocol.Close(&DisplayInfo.Handle, &GopGuid); + return STATUS_EFI_UNSUPPORTED; + } + + /* Store frame buffer base address and protocol used */ + DisplayInfo.FrameBufferBase = DisplayInfo.Driver.Gop->Mode->FrameBufferBase; + DisplayInfo.DefaultMode = DisplayInfo.Driver.Gop->Mode->Mode; + DisplayInfo.Protocol = GOP; + + /* Get current mode information */ + Status = GetModeInformation(); + if(Status != STATUS_EFI_SUCCESS) + { + /* Unable to get mode information */ + XtLdrProtocol->Debug.Print(L"ERROR: Failed to get GOP mode information (Status Code: 0x%zX)\n"); + + /* Close GOP protocol and return error */ + XtLdrProtocol->Protocol.Close(&DisplayInfo.Handle, &GopGuid); + return STATUS_EFI_UNSUPPORTED; + } + + /* Found GOP */ + XtLdrProtocol->Debug.Print(L"Found EFI-GOP compatible display adapter @ %P (%zu bytes)\n", + DisplayInfo.FrameBufferBase, DisplayInfo.FrameBufferSize); + + /* Close GOP protocol */ + Status = XtLdrProtocol->Protocol.Close(&DisplayInfo.Handle, &GopGuid); + } + else + { + /* GOP is unavailable, attempt to open UGA protocol */ + Status = XtLdrProtocol->Protocol.Open(&DisplayInfo.Handle, (PVOID*)&DisplayInfo.Driver.Uga, &UgaGuid); + + /* Check if Universal Graphics Adapter (UGA) is available */ + if(Status == STATUS_EFI_SUCCESS) + { + /* Get current video mode */ + Status = DisplayInfo.Driver.Uga->GetMode(DisplayInfo.Driver.Uga, &DisplayInfo.ModeInfo.Width, + &DisplayInfo.ModeInfo.Height, &Depth, &Refresh); + if(Status != STATUS_EFI_SUCCESS) + { + /* Unable to get current UGA mode */ + XtLdrProtocol->Debug.Print(L"ERROR: Failed to get current UGA mode (Status Code: 0x%zX)\n", Status); + + /* Close UGA protocol and return error */ + XtLdrProtocol->Protocol.Close(&DisplayInfo.Handle, &UgaGuid); + return STATUS_EFI_DEVICE_ERROR; + } + + /* Find framebuffer address */ + Status = FindFramebufferAddress(&DisplayInfo.FrameBufferBase); + if(Status != STATUS_EFI_SUCCESS) + { + /* Unable to find framebuffer address */ + XtLdrProtocol->Debug.Print(L"ERROR: Failed to get EFI FB address (Status Code: 0x%zX)\n", Status); + + /* Close UGA protocol and return error */ + XtLdrProtocol->Protocol.Close(&DisplayInfo.Handle, &UgaGuid); + return STATUS_EFI_DEVICE_ERROR; + } + + /* Store framebuffer protocol information */ + DisplayInfo.DefaultMode = 0; + DisplayInfo.Protocol = UGA; + + /* Get mode information */ + Status = GetModeInformation(); + if(Status != STATUS_EFI_SUCCESS) + { + /* Unable to get mode information */ + XtLdrProtocol->Debug.Print(L"ERROR: Failed to get UGA mode information (Status Code: 0x%zX)\n"); + return STATUS_EFI_UNSUPPORTED; + } + + /* Found UGA */ + XtLdrProtocol->Debug.Print(L"Found EFI-UGA compatible display adapter @ %P (%zu bytes)\n", + DisplayInfo.FrameBufferBase, DisplayInfo.FrameBufferSize); + + /* Close UGA protocol */ + XtLdrProtocol->Protocol.Close(&DisplayInfo.Handle, &UgaGuid); + } + } + + /* Make sure framebuffer initialized properly */ + if(DisplayInfo.Protocol == NONE) + { + /* GOP and UGA unavailable */ + XtLdrProtocol->Debug.Print(L"WARNING: No display adapter found!\n"); + return STATUS_EFI_NOT_FOUND; + } + + XtLdrProtocol->Debug.Print(L"Current screen resolution is %ux%ux%u\n", DisplayInfo.ModeInfo.Width, + DisplayInfo.ModeInfo.Height, DisplayInfo.ModeInfo.BitsPerPixel); + + /* Set framebuffer initialization flag */ + DisplayInfo.Initialized = TRUE; + } + + /* Return success */ + return STATUS_SUCCESS; +} + +/** + * Initializes FRAMEBUF module by opening XTLDR protocol and installing FRAMEBUF 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 +FrameBuffer::InitializeModule(IN EFI_HANDLE ImageHandle, + IN PEFI_SYSTEM_TABLE SystemTable) +{ + EFI_GUID Guid = XT_FRAMEBUFFER_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 initial framebuffer state */ + DisplayInfo.Protocol = NONE; + DisplayInfo.Initialized = FALSE; + + /* Set routines available via XTLDR framebuffer protocol */ + FbProtocol.GetDisplayDriver = GetDisplayDriver; + FbProtocol.GetDisplayInformation = GetDisplayInformation; + FbProtocol.GetPreferredScreenResolution = GetPreferredScreenResolution; + FbProtocol.Initialize = InitializeDisplay; + FbProtocol.SetScreenResolution = SetScreenResolution; + + /* Register XTOS boot protocol */ + return XtLdrProtocol->Protocol.Install(&FbProtocol, &Guid); +} + +/** + * Sets custom screen resolution, based on the provided width and height. + * + * @param Width + * Supplies the width of the screen. + * + * @param Height + * Supplies the height of the screen. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +FrameBuffer::SetScreenResolution(IN UINT Width, + IN UINT Height) +{ + PEFI_GRAPHICS_OUTPUT_MODE_INFORMATION ModeInfo; + BOOLEAN ModeChanged; + EFI_STATUS Status; + UINT_PTR Size; + UINT Mode; + + /* Check if framebuffer is initialized */ + if(!DisplayInfo.Initialized) + { + /* Framebuffer not ready to change screen mode */ + return STATUS_EFI_NOT_READY; + } + + ModeChanged = FALSE; + + /* Change screen mode depending on display adapter protocol */ + switch(DisplayInfo.Protocol) + { + case GOP: + /* GOP available, check if user specified screen resolution */ + if(Width == 0 || Height == 0) + { + /* No resolution specified, temporarily set lowest supported screen resolution */ + Status = DisplayInfo.Driver.Gop->SetMode(DisplayInfo.Driver.Gop, 1); + if(Status == STATUS_EFI_SUCCESS) + { + /* Restore default graphics mode */ + Status = DisplayInfo.Driver.Gop->SetMode(DisplayInfo.Driver.Gop, DisplayInfo.DefaultMode); + ModeChanged = (Status == STATUS_EFI_SUCCESS) ? TRUE : FALSE; + } + } + else + { + /* User specified screen resolution, find a corresponding mode */ + Mode = 1; + while(Mode <= DisplayInfo.Driver.Gop->Mode->MaxMode) + { + /* Get mode information */ + Status = DisplayInfo.Driver.Gop->QueryMode(DisplayInfo.Driver.Gop, Mode, &Size, &ModeInfo); + if(Status == STATUS_EFI_SUCCESS && Size >= sizeof(*ModeInfo) && ModeInfo != NULLPTR) + { + /* Check if match found */ + if(ModeInfo->HorizontalResolution == Width && ModeInfo->VerticalResolution == Height) + { + /* Found corresponding mode, attempt to set it */ + Status = DisplayInfo.Driver.Gop->SetMode(DisplayInfo.Driver.Gop, Mode); + if(Status == STATUS_EFI_SUCCESS) + { + /* New mode set correctly, use it */ + ModeChanged = TRUE; + break; + } + } + } + + /* Try with next mode */ + Mode++; + } + } + break; + case UGA: + /* Set UGA screen mode, trying to keep current color depth and refresh rate */ + Status = DisplayInfo.Driver.Uga->SetMode(DisplayInfo.Driver.Uga, Width, Height, + DisplayInfo.ModeInfo.Depth, + DisplayInfo.ModeInfo.RefreshRate); + if(Status == STATUS_EFI_SUCCESS) + { + /* New mode set correctly, use it */ + ModeChanged = TRUE; + } + break; + default: + /* This should never be reached */ + break; + } + + if(!ModeChanged) + { + /* Failed to change screen mode */ + XtLdrProtocol->Debug.Print(L"ERROR: Failed to change screen mode to %ux%u (Status Code: 0x%zX)\n", + Width, Height, Status); + return STATUS_EFI_UNSUPPORTED; + } + + /* Get new screen mode information */ + Status = GetModeInformation(); + if(Status == STATUS_EFI_SUCCESS) + { + XtLdrProtocol->Debug.Print(L"Changed screen resolution to %ux%ux%u\n", DisplayInfo.ModeInfo.Width, + DisplayInfo.ModeInfo.Height, DisplayInfo.ModeInfo.BitsPerPixel); + } + + /* Return success */ + return STATUS_EFI_SUCCESS; } /** @@ -759,28 +805,6 @@ EFI_STATUS XtLdrModuleMain(IN EFI_HANDLE ImageHandle, IN PEFI_SYSTEM_TABLE SystemTable) { - EFI_GUID Guid = XT_FRAMEBUFFER_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 initial framebuffer state */ - FbpDisplayInfo.Protocol = NONE; - FbpDisplayInfo.Initialized = FALSE; - - /* Set routines available via XTLDR framebuffer protocol */ - FbpFrameBufferProtocol.GetDisplayDriver = FbGetDisplayDriver; - FbpFrameBufferProtocol.GetDisplayInformation = FbGetDisplayInformation; - FbpFrameBufferProtocol.GetPreferredScreenResolution = FbGetPreferredScreenResolution; - FbpFrameBufferProtocol.Initialize = FbInitializeDisplay; - FbpFrameBufferProtocol.SetScreenResolution = FbSetScreenResolution; - - /* Register XTOS boot protocol */ - return XtLdrProtocol->Protocol.Install(&FbpFrameBufferProtocol, &Guid); + /* Initialize FRAMEBUF module */ + return FrameBuffer::InitializeModule(ImageHandle, SystemTable); } diff --git a/xtldr/modules/framebuf/globals.c b/xtldr/modules/framebuf/globals.c deleted file mode 100644 index c3fd84e..0000000 --- a/xtldr/modules/framebuf/globals.c +++ /dev/null @@ -1,19 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/framebuf/globals.c - * DESCRIPTION: EFI framebuffer module global variables - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/* Framebuffer display information */ -XTBL_FRAMEBUFFER_INFORMATION FbpDisplayInfo; - -/* Framebuffer protocol handler */ -XTBL_FRAMEBUFFER_PROTOCOL FbpFrameBufferProtocol; - -/* XTLDR protocol handler */ -PXTBL_LOADER_PROTOCOL XtLdrProtocol; diff --git a/xtldr/modules/framebuf/includes/framebuf.h b/xtldr/modules/framebuf/includes/framebuf.h deleted file mode 100644 index b99b7f5..0000000 --- a/xtldr/modules/framebuf/includes/framebuf.h +++ /dev/null @@ -1,64 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/framebuf/includes/framebuf.h - * DESCRIPTION: EFI Framebuffer support module header file - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTLDR_MODULES_FRAMEBUF_H -#define __XTLDR_MODULES_FRAMEBUF_H - -#include -#include - - -/* FrameBuffer support protocol related routines forward references */ -XTCDECL -EFI_STATUS -FbGetDisplayDriver(OUT PEFI_GRAPHICS_PROTOCOL Protocol); - -XTCDECL -EFI_STATUS -FbGetDisplayInformation(OUT PEFI_PHYSICAL_ADDRESS FrameBufferBase, - OUT PULONG_PTR FrameBufferSize, - OUT PXTBL_FRAMEBUFFER_MODE_INFORMATION ModeInfo); - -XTCDECL -EFI_STATUS -FbGetPreferredScreenResolution(OUT PUINT PreferredWidth, - OUT PUINT PreferredHeight); - -XTCDECL -EFI_STATUS -FbInitializeDisplay(); - -XTCDECL -EFI_STATUS -FbSetScreenResolution(IN UINT Width, - IN UINT Height); - -XTCDECL -EFI_STATUS -FbpFindFramebufferAddress(OUT PEFI_PHYSICAL_ADDRESS Address); - -XTCDECL -VOID -FbpGetColorMask(IN UINT EfiMask, - OUT PUSHORT ColorSize, - OUT PUSHORT ColorShift); - -XTCDECL -EFI_STATUS -FbpGetModeInfo(); - -XTCDECL -VOID -FbpGetPixelInformation(IN PEFI_PIXEL_BITMASK PixelsBitMask); - -XTCDECL -EFI_STATUS -XtLdrModuleMain(IN EFI_HANDLE ImageHandle, - IN PEFI_SYSTEM_TABLE SystemTable); - -#endif /* __XTLDR_MODULES_FRAMEBUF_H */ diff --git a/xtldr/modules/framebuf/includes/framebuf.hh b/xtldr/modules/framebuf/includes/framebuf.hh new file mode 100644 index 0000000..7188d58 --- /dev/null +++ b/xtldr/modules/framebuf/includes/framebuf.hh @@ -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 + */ + +#ifndef __XTLDR_MODULES_FRAMEBUF_HH +#define __XTLDR_MODULES_FRAMEBUF_HH + +#include + + +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 */ diff --git a/xtldr/modules/framebuf/includes/globals.h b/xtldr/modules/framebuf/includes/globals.h deleted file mode 100644 index df939a6..0000000 --- a/xtldr/modules/framebuf/includes/globals.h +++ /dev/null @@ -1,24 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/framebuf/includes/globals.h - * DESCRIPTION: EFI Framebuffer module global variables - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTLDR_MODULES_GLOBALS_H -#define __XTLDR_MODULES_GLOBALS_H - -#include - - -/* Framebuffer display information */ -EXTERN XTBL_FRAMEBUFFER_INFORMATION FbpDisplayInfo; - -/* Framebuffer protocol handler */ -EXTERN XTBL_FRAMEBUFFER_PROTOCOL FbpFrameBufferProtocol; - -/* XTLDR protocol handler */ -EXTERN PXTBL_LOADER_PROTOCOL XtLdrProtocol; - -#endif /* __XTLDR_MODULES_GLOBALS_H */ diff --git a/xtldr/modules/pecoff/CMakeLists.txt b/xtldr/modules/pecoff/CMakeLists.txt index e13db3c..aa8920d 100644 --- a/xtldr/modules/pecoff/CMakeLists.txt +++ b/xtldr/modules/pecoff/CMakeLists.txt @@ -8,8 +8,8 @@ include_directories( # Specify list of source code files list(APPEND XTLDR_PECOFF_SOURCE - ${XTLDR_PECOFF_SOURCE_DIR}/globals.c - ${XTLDR_PECOFF_SOURCE_DIR}/pecoff.c) + ${XTLDR_PECOFF_SOURCE_DIR}/data.cc + ${XTLDR_PECOFF_SOURCE_DIR}/pecoff.cc) # Link module executable add_executable(pecoff ${XTLDR_PECOFF_SOURCE}) diff --git a/xtldr/modules/pecoff/data.cc b/xtldr/modules/pecoff/data.cc new file mode 100644 index 0000000..f919194 --- /dev/null +++ b/xtldr/modules/pecoff/data.cc @@ -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 + */ + +#include + + +/* XTOS PE/COFF Image Protocol */ +XTBL_EXECUTABLE_IMAGE_PROTOCOL PeCoff::PeProtocol; + +/* EFI XT Loader Protocol */ +PXTBL_LOADER_PROTOCOL PeCoff::XtLdrProtocol; diff --git a/xtldr/modules/pecoff/globals.c b/xtldr/modules/pecoff/globals.c deleted file mode 100644 index 6c3afc4..0000000 --- a/xtldr/modules/pecoff/globals.c +++ /dev/null @@ -1,16 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/pecoff/globals.c - * DESCRIPTION: Basic PE/COFF executable file format support global variables - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/* XTOS PE/COFF Image Protocol */ -XTBL_EXECUTABLE_IMAGE_PROTOCOL PeCoffProtocol; - -/* EFI XT Loader Protocol */ -PXTBL_LOADER_PROTOCOL XtLdrProtocol; diff --git a/xtldr/modules/pecoff/includes/globals.h b/xtldr/modules/pecoff/includes/globals.h deleted file mode 100644 index 5f2af34..0000000 --- a/xtldr/modules/pecoff/includes/globals.h +++ /dev/null @@ -1,21 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/pecoff/includes/globals.h - * DESCRIPTION: Basic PE/COFF executable file format support global variables - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTLDR_PECOFF_GLOBALS_H -#define __XTLDR_PECOFF_GLOBALS_H - -#include - - -/* XTOS PE/COFF Image Protocol */ -EXTERN XTBL_EXECUTABLE_IMAGE_PROTOCOL PeCoffProtocol; - -/* EFI XT Loader Protocol */ -EXTERN PXTBL_LOADER_PROTOCOL XtLdrProtocol; - -#endif /* __XTLDR_PECOFF_GLOBALS_H */ diff --git a/xtldr/modules/pecoff/includes/pecoff.h b/xtldr/modules/pecoff/includes/pecoff.h deleted file mode 100644 index 8dbaf95..0000000 --- a/xtldr/modules/pecoff/includes/pecoff.h +++ /dev/null @@ -1,82 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/pecoff/includes/pecoff.h - * DESCRIPTION: Basic PE/COFF executable file format support header - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTLDR_PECOFF_H -#define __XTLDR_PECOFF_H - -#include -#include - - -/* PE/COFF image protocol related routines forward references */ -XTCDECL -EFI_STATUS -PeGetEntryPoint(IN PVOID ImagePointer, - OUT PVOID *EntryPoint); - -XTCDECL -EFI_STATUS -PeGetFileSize(IN PVOID ImagePointer, - OUT PULONGLONG FileSize); - -XTCDECL -EFI_STATUS -PeGetImageSize(IN PVOID ImagePointer, - OUT PUINT ImageSize); - -XTCDECL -EFI_STATUS -PeGetMachineType(IN PVOID ImagePointer, - OUT PUSHORT MachineType); - -XTCDECL -EFI_STATUS -PeGetSection(IN PVOID ImagePointer, - IN PCHAR SectionName, - OUT PULONG *RawData); - -XTCDECL -EFI_STATUS -PeGetSubSystem(IN PVOID ImagePointer, - OUT PUSHORT SubSystem); - -XTCDECL -EFI_STATUS -PeGetVersion(IN PVOID ImagePointer, - OUT PUSHORT Version); - -XTCDECL -EFI_STATUS -PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, - IN LOADER_MEMORY_TYPE MemoryType, - IN PVOID VirtualAddress, - OUT PVOID *ImagePointer); - -XTCDECL -EFI_STATUS -PeRelocateImage(IN PVOID ImagePointer, - IN EFI_VIRTUAL_ADDRESS Address); - -XTCDECL -EFI_STATUS -PeUnloadImage(IN PVOID ImagePointer); - -XTCDECL -EFI_STATUS -PeVerifyImage(IN PVOID ImagePointer); - -XTCDECL -EFI_STATUS -PepRelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image); - -XTCDECL -EFI_STATUS -BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle, - IN PEFI_SYSTEM_TABLE SystemTable); - -#endif /* __XTLDR_PECOFF_H */ diff --git a/xtldr/modules/pecoff/includes/pecoff.hh b/xtldr/modules/pecoff/includes/pecoff.hh new file mode 100644 index 0000000..78defde --- /dev/null +++ b/xtldr/modules/pecoff/includes/pecoff.hh @@ -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 + */ + +#ifndef __XTLDR_PECOFF_HH +#define __XTLDR_PECOFF_HH + +#include + + +/* 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 */ diff --git a/xtldr/modules/pecoff/pecoff.c b/xtldr/modules/pecoff/pecoff.cc similarity index 85% rename from xtldr/modules/pecoff/pecoff.c rename to xtldr/modules/pecoff/pecoff.cc index aac0208..00f105a 100644 --- a/xtldr/modules/pecoff/pecoff.c +++ b/xtldr/modules/pecoff/pecoff.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * 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 * DEVELOPERS: Rafal Kupiec */ -#include +#include /* PE/COFF_O module information */ @@ -15,6 +15,7 @@ MODULE_DESCRIPTION(L"Basic PE/COFF executable file format support"); MODULE_LICENSE(L"GPLv3"); MODULE_VERSION(L"0.1"); + /** * Returns the address of the entry point. * @@ -30,10 +31,13 @@ MODULE_VERSION(L"0.1"); */ XTCDECL EFI_STATUS -PeGetEntryPoint(IN PVOID ImagePointer, - OUT PVOID *EntryPoint) +PeCoff::GetEntryPoint(IN PVOID ImagePointer, + 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 */ if(!Image || !Image->PeHeader) @@ -46,12 +50,12 @@ PeGetEntryPoint(IN PVOID ImagePointer, if(Image->PeHeader->OptionalHeader32.Magic == PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC) { /* 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 { /* 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 */ @@ -73,13 +77,13 @@ PeGetEntryPoint(IN PVOID ImagePointer, */ XTCDECL EFI_STATUS -PeGetFileSize(IN PVOID ImagePointer, - OUT PULONGLONG FileSize) +PeCoff::GetFileSize(IN PVOID ImagePointer, + OUT PULONGLONG FileSize) { PPECOFF_IMAGE_CONTEXT Image; /* Get PE/COFF image pointer*/ - Image = ImagePointer; + Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer; /* Validate input data */ if(!Image || !Image->ImageSize) @@ -108,13 +112,13 @@ PeGetFileSize(IN PVOID ImagePointer, */ XTCDECL EFI_STATUS -PeGetImageSize(IN PVOID ImagePointer, - OUT PUINT ImageSize) +PeCoff::GetImageSize(IN PVOID ImagePointer, + OUT PUINT ImageSize) { PPECOFF_IMAGE_CONTEXT Image; /* Get PE/COFF image pointer*/ - Image = ImagePointer; + Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer; /* Validate input data */ if(!Image || !Image->ImageSize) @@ -143,10 +147,13 @@ PeGetImageSize(IN PVOID ImagePointer, */ XTCDECL EFI_STATUS -PeGetMachineType(IN PVOID ImagePointer, - OUT PUSHORT MachineType) +PeCoff::GetMachineType(IN PVOID ImagePointer, + 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 */ if(!Image || !Image->PeHeader) @@ -178,9 +185,9 @@ PeGetMachineType(IN PVOID ImagePointer, */ XTCDECL EFI_STATUS -PeGetSection(IN PVOID ImagePointer, - IN PCHAR SectionName, - OUT PULONG *RawData) +PeCoff::GetSection(IN PVOID ImagePointer, + IN PCHAR SectionName, + OUT PULONG *RawData) { PPECOFF_IMAGE_SECTION_HEADER SectionHeader; PPECOFF_IMAGE_CONTEXT Image; @@ -188,7 +195,7 @@ PeGetSection(IN PVOID ImagePointer, USHORT SectionIndex; /* Get PE/COFF image pointer*/ - Image = ImagePointer; + Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer; /* Validate input data */ if(!Image || !Image->PeHeader) @@ -212,16 +219,16 @@ PeGetSection(IN PVOID ImagePointer, } /* Get section name length */ - SectionNameLength = RtlStringLength(SectionName, 0); + SectionNameLength = XtLdrProtocol->String.Length(SectionName, 0); /* Iterate through all image sections */ for(SectionIndex = 0; SectionIndex < Image->PeHeader->FileHeader.NumberOfSections; SectionIndex++) { /* 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 */ - *RawData = Image->Data + SectionHeader[SectionIndex].PointerToRawData; + *RawData = (PULONG)((PUCHAR)Image->Data + SectionHeader[SectionIndex].PointerToRawData); return STATUS_EFI_SUCCESS; } } @@ -245,10 +252,13 @@ PeGetSection(IN PVOID ImagePointer, */ XTCDECL EFI_STATUS -PeGetSubSystem(IN PVOID ImagePointer, - OUT PUSHORT SubSystem) +PeCoff::GetSubSystem(IN PVOID ImagePointer, + 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 */ if(!Image || !Image->PeHeader) @@ -288,10 +298,13 @@ PeGetSubSystem(IN PVOID ImagePointer, */ XTCDECL EFI_STATUS -PeGetVersion(IN PVOID ImagePointer, - OUT PUSHORT Version) +PeCoff::GetVersion(IN PVOID ImagePointer, + 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 */ if(!Image || !Image->PeHeader) @@ -316,6 +329,52 @@ PeGetVersion(IN PVOID ImagePointer, 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. * @@ -337,10 +396,10 @@ PeGetVersion(IN PVOID ImagePointer, */ XTCDECL EFI_STATUS -PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, - IN LOADER_MEMORY_TYPE MemoryType, - IN PVOID VirtualAddress, - OUT PVOID *ImagePointer) +PeCoff::LoadImage(IN PEFI_FILE_HANDLE FileHandle, + IN LOADER_MEMORY_TYPE MemoryType, + IN PVOID VirtualAddress, + OUT PVOID *ImagePointer) { EFI_GUID FileInfoGuid = EFI_FILE_INFO_PROTOCOL_GUID; PPECOFF_IMAGE_SECTION_HEADER SectionHeader; @@ -400,7 +459,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, } /* Store file size and memory type, nullify data and free up memory */ - ImageData->Data = NULL; + ImageData->Data = NULLPTR; ImageData->FileSize = FileInfo->FileSize; ImageData->MemoryType = MemoryType; XtLdrProtocol->Memory.FreePool(FileInfo); @@ -433,10 +492,10 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, /* Extract DOS and PE headers */ 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 */ - Status = PeVerifyImage(ImageData); + Status = PeCoff::VerifyImage(ImageData); if(Status != STATUS_EFI_SUCCESS) { /* Header validation failed, probably broken or invalid PE/COFF image */ @@ -482,7 +541,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, } /* Store image data and virtual address */ - ImageData->Data = (PUINT8)(UINT_PTR)Address; + ImageData->Data = (PUCHAR)(UINT_PTR)Address; ImageData->PhysicalAddress = (PVOID)(UINT_PTR)Address; if(VirtualAddress) { @@ -534,7 +593,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, if(SectionSize > 0 && SectionHeader[Index].PointerToRawData != 0) { /* 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); } @@ -542,7 +601,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, if(SectionSize < SectionHeader[Index].Misc.VirtualSize) { /* 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); } } @@ -551,7 +610,7 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, XtLdrProtocol->Memory.FreePages((EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data, Pages); /* Perform relocation fixups */ - Status = PepRelocateLoadedImage(ImageData); + Status = PeCoff::RelocateLoadedImage(ImageData); if(Status != STATUS_EFI_SUCCESS) { /* Failed to relocate image */ @@ -581,14 +640,16 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle, */ XTCDECL EFI_STATUS -PeRelocateImage(IN PVOID ImagePointer, - IN EFI_VIRTUAL_ADDRESS Address) +PeCoff::RelocateImage(IN PVOID ImagePointer, + IN EFI_VIRTUAL_ADDRESS Address) { - PPECOFF_IMAGE_CONTEXT Image = ImagePointer; - - UINT64 ImageBase, OldVirtualAddress; + PPECOFF_IMAGE_CONTEXT Image; + ULONGLONG ImageBase, OldVirtualAddress; EFI_STATUS Status; + /* Get PE/COFF image pointer*/ + Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer; + /* Store original virtual address */ OldVirtualAddress = (UINT_PTR)Image->VirtualAddress; @@ -606,7 +667,7 @@ PeRelocateImage(IN PVOID ImagePointer, /* Overwrite virtual address and relocate image once again */ Image->VirtualAddress = (PVOID)(Address - OldVirtualAddress + ImageBase); - Status = PepRelocateLoadedImage(Image); + Status = PeCoff::RelocateLoadedImage(Image); if(Status != STATUS_EFI_SUCCESS) { /* Relocation failed */ @@ -620,98 +681,6 @@ PeRelocateImage(IN PVOID ImagePointer, 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. * @@ -724,15 +693,15 @@ PeVerifyImage(IN PVOID ImagePointer) */ XTCDECL EFI_STATUS -PepRelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image) +PeCoff::RelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image) { PPECOFF_IMAGE_BASE_RELOCATION RelocationDir, RelocationEnd; PPECOFF_IMAGE_DATA_DIRECTORY DataDirectory; USHORT Offset, Type, Count; PUSHORT TypeOffset; - UINT64 ImageBase; - PUINT32 Address; - PUINT64 LongPtr; + ULONGLONG ImageBase; + PUINT Address; + PULONGLONG LongPtr; PUINT ShortPtr; /* Make sure image is not stripped */ @@ -793,7 +762,7 @@ PepRelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image) Type = *TypeOffset >> 12; /* 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 */ break; @@ -816,7 +785,7 @@ PepRelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image) break; case PECOFF_IMAGE_REL_BASED_HIGHLOW: /* 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; break; default: @@ -836,6 +805,101 @@ PepRelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image) 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. * @@ -854,30 +918,6 @@ EFI_STATUS XtLdrModuleMain(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 */ - 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); + /* Initialize PECOFF module */ + return PeCoff::InitializeModule(ImageHandle, SystemTable); } diff --git a/xtldr/modules/xtos_o/CMakeLists.txt b/xtldr/modules/xtos_o/CMakeLists.txt index 57bda16..b292deb 100644 --- a/xtldr/modules/xtos_o/CMakeLists.txt +++ b/xtldr/modules/xtos_o/CMakeLists.txt @@ -8,8 +8,9 @@ include_directories( # Specify list of source code files list(APPEND XTLDR_XTOS_O_SOURCE - ${XTLDR_XTOS_O_SOURCE_DIR}/${ARCH}/memory.c - ${XTLDR_XTOS_O_SOURCE_DIR}/xtos.c) + ${XTLDR_XTOS_O_SOURCE_DIR}/${ARCH}/memory.cc + ${XTLDR_XTOS_O_SOURCE_DIR}/data.cc + ${XTLDR_XTOS_O_SOURCE_DIR}/xtos.cc) # Link bootloader executable add_executable(xtos_o ${XTLDR_XTOS_O_SOURCE}) diff --git a/xtldr/modules/xtos_o/amd64/memory.c b/xtldr/modules/xtos_o/amd64/memory.cc similarity index 84% rename from xtldr/modules/xtos_o/amd64/memory.c rename to xtldr/modules/xtos_o/amd64/memory.cc index 55f8ec8..02335aa 100644 --- a/xtldr/modules/xtos_o/amd64/memory.c +++ b/xtldr/modules/xtos_o/amd64/memory.cc @@ -1,13 +1,13 @@ /** * PROJECT: ExectOS * 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 * DEVELOPERS: Rafal Kupiec * Aiken Harris */ -#include +#include /** @@ -22,30 +22,30 @@ */ XTCDECL ULONG -XtpDeterminePagingLevel(IN CONST PWCHAR Parameters) +Xtos::DeterminePagingLevel(IN CONST PWCHAR Parameters) { CPUID_REGISTERS CpuRegisters; /* 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; /* Query CPUID */ - ArCpuId(&CpuRegisters); + XtLdrProtocol->Cpu.CpuId(&CpuRegisters); /* Verify if the CPU supports the STD7 feature leaf (0x00000007) */ if(CpuRegisters.Eax >= CPUID_GET_STANDARD7_FEATURES) { /* Prepare CPUID registers to query for LA57 support */ - RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); + XtLdrProtocol->Memory.ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); CpuRegisters.Leaf = CPUID_GET_STANDARD7_FEATURES; /* Query CPUID */ - ArCpuId(&CpuRegisters); + XtLdrProtocol->Cpu.CpuId(&CpuRegisters); /* Check if eXtended Physical Addressing (XPA) is enabled and if LA57 is supported by the CPU */ if((CpuRegisters.Ecx & CPUID_FEATURES_ECX_LA57) && - !(XtLdrProtocol->BootUtil.GetBooleanParameter(Parameters, L"NOXPA"))) + !(XtLdrProtocol->BootUtils.GetBooleanParameter(Parameters, L"NOXPA"))) { /* Enable LA57 (PML5) */ return 5; @@ -56,6 +56,106 @@ XtpDeterminePagingLevel(IN CONST PWCHAR Parameters) 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. * @@ -68,7 +168,7 @@ XtpDeterminePagingLevel(IN CONST PWCHAR Parameters) */ XTCDECL EFI_STATUS -XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap) +Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap) { PHARDWARE_PTE P5eBase, PdeBase, PpeBase, PxeBase; EFI_PHYSICAL_ADDRESS Address; @@ -91,7 +191,7 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap) } /* Zero fill memory used by P5E */ - RtlZeroMemory((PVOID)Address, EFI_PAGE_SIZE); + XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE); /* Make P5E valid */ P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].Valid = 1; @@ -125,7 +225,7 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap) } /* Zero fill memory used by PXE */ - RtlZeroMemory((PVOID)Address, EFI_PAGE_SIZE); + XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE); /* Make PXE valid */ PxeBase[(MM_HARDWARE_VA_START >> MM_PXI_SHIFT) & 0x1FF].Valid = 1; @@ -153,7 +253,7 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap) } /* Zero fill memory used by PPE */ - RtlZeroMemory((PVOID)Address, EFI_PAGE_SIZE); + XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE); /* Make PPE valid */ PpeBase[(MM_HARDWARE_VA_START >> MM_PPI_SHIFT) & 0x1FF].Valid = 1; @@ -184,7 +284,7 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap) } /* Zero fill memory used by PDE */ - RtlZeroMemory((PVOID)Address, EFI_PAGE_SIZE); + XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE); /* Make PDE valid */ PdeBase[((MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF) + Index].Valid = 1; @@ -196,96 +296,3 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap) /* Return 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; - EFI_PHYSICAL_ADDRESS TrampolineAddress; - PXT_TRAMPOLINE_ENTRY TrampolineEntry; - ULONG_PTR TrampolineSize; - - /* 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 = XtpMapHardwareMemoryPool(PageMap); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to map memory for hardware layer */ - XtLdrProtocol->Debug.Print(L"Failed to map memory for hardware leyer (Status code: %zX)\n", Status); - return Status; - } - - /* Check the configured page map level to set the LA57 state accordingly */ - if(PageMap->PageMapLevel == 5) - { - /* Set the address of the trampoline code below 1MB */ - TrampolineAddress = MM_TRAMPOLINE_ADDRESS; - - /* Calculate the size of the trampoline code */ - TrampolineSize = (ULONG_PTR)ArEnableExtendedPhysicalAddressingEnd - (ULONG_PTR)ArEnableExtendedPhysicalAddressing; - - /* Allocate pages for the trampoline */ - Status = XtLdrProtocol->Memory.AllocatePages(AllocateAddress, EFI_SIZE_TO_PAGES(TrampolineSize), &TrampolineAddress); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to allocate memory for trampoline code */ - XtLdrProtocol->Debug.Print(L"Failed to allocate memory for trampoline code (Status code: %zX)\n", Status); - return Status; - } - - /* Set the trampoline entry point and copy its code into the allocated buffer */ - TrampolineEntry = (PXT_TRAMPOLINE_ENTRY)(UINT_PTR)TrampolineAddress; - RtlCopyMemory(TrampolineEntry, ArEnableExtendedPhysicalAddressing, TrampolineSize); - } - - /* Exit EFI Boot Services */ - 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"); - - /* Execute the trampoline to enable LA57 and write PML5 to CR3 */ - TrampolineEntry((UINT64)PageMap->PtePointer); - } - else - { - /* Disable Linear Address 57-bit (LA57) extension */ - XtLdrProtocol->Debug.Print(L"Disabling Linear Address 57-bit (LA57)\n"); - - /* Write PML4 to CR3 and enable paging */ - ArWriteControlRegister(3, (UINT_PTR)PageMap->PtePointer); - ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_PG); - } - - /* Return success */ - return STATUS_EFI_SUCCESS; -} diff --git a/xtldr/modules/xtos_o/data.cc b/xtldr/modules/xtos_o/data.cc new file mode 100644 index 0000000..9a66a53 --- /dev/null +++ b/xtldr/modules/xtos_o/data.cc @@ -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 + */ + +#include + + +/* 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; diff --git a/xtldr/modules/xtos_o/i686/memory.c b/xtldr/modules/xtos_o/i686/memory.cc similarity index 78% rename from xtldr/modules/xtos_o/i686/memory.c rename to xtldr/modules/xtos_o/i686/memory.cc index 959ac8c..c2b2e1c 100644 --- a/xtldr/modules/xtos_o/i686/memory.c +++ b/xtldr/modules/xtos_o/i686/memory.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * 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 * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -21,20 +21,20 @@ */ XTCDECL ULONG -XtpDeterminePagingLevel(IN CONST PWCHAR Parameters) +Xtos::DeterminePagingLevel(IN CONST PWCHAR Parameters) { CPUID_REGISTERS CpuRegisters; /* 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; /* Query CPUID */ - ArCpuId(&CpuRegisters); + XtLdrProtocol->Cpu.CpuId(&CpuRegisters); /* Check if eXtended Physical Addressing (XPA) is enabled and if PAE is supported by the CPU */ if((CpuRegisters.Edx & CPUID_FEATURES_EDX_PAE) && - !(XtLdrProtocol->BootUtil.GetBooleanParameter(Parameters, L"NOXPA"))) + !(XtLdrProtocol->BootUtils.GetBooleanParameter(Parameters, L"NOXPA"))) { /* Enable PAE (PML3) */ return 3; @@ -44,6 +44,77 @@ XtpDeterminePagingLevel(IN CONST PWCHAR Parameters) 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. * @@ -56,7 +127,7 @@ XtpDeterminePagingLevel(IN CONST PWCHAR Parameters) */ XTCDECL EFI_STATUS -XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap) +Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap) { EFI_PHYSICAL_ADDRESS Address; PHARDWARE_LEGACY_PTE LegacyPdeBase; @@ -72,7 +143,7 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap) } /* 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) */ if(PageMap->PageMapLevel == 3) @@ -81,7 +152,7 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap) PdeBase = (PHARDWARE_MODERN_PTE)(((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[MM_HARDWARE_VA_START >> MM_PPI_SHIFT].PageFrameNumber << MM_PAGE_SHIFT); /* Make PDE valid */ - RtlZeroMemory(&PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF], sizeof(HARDWARE_MODERN_PTE)); + 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].Valid = 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 */ - 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].PageFrameNumber = Address >> MM_PAGE_SHIFT; LegacyPdeBase[MM_HARDWARE_VA_START >> MM_PDI_LEGACY_SHIFT].Writable = 1; @@ -108,74 +179,3 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap) /* Return 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, 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 = 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; -} diff --git a/xtldr/modules/xtos_o/includes/xtos.h b/xtldr/modules/xtos_o/includes/xtos.h deleted file mode 100644 index 2f4da6a..0000000 --- a/xtldr/modules/xtos_o/includes/xtos.h +++ /dev/null @@ -1,118 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/modules/xtos/includes/xtos.h - * DESCRIPTION: XTOS boot protocol support header - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTLDR_MODULES_XTOS_H -#define __XTLDR_MODULES_XTOS_H - -#include - - -typedef VOID (*PXT_FRAMEBUFFER_GET_DISPLAY_DRIVER)(OUT PWCHAR DriverName); -typedef VOID (*PXT_FRAMEBUFFER_GET_DISPLAY_INFORMATION)(OUT PLOADER_GRAPHICS_INFORMATION_BLOCK InformationBlock); -typedef EFI_STATUS (*PXT_FRAMEBUFFER_INITIALIZE)(); -typedef VOID (*PXT_FRAMEBUFFER_PRINT_DISPLAY_INFORMATION)(); - -/* XT framebuffer support protocol */ -typedef struct _XT_FRAMEBUFFER_PROTOCOL -{ - PXT_FRAMEBUFFER_GET_DISPLAY_DRIVER GetDisplayDriver; - PXT_FRAMEBUFFER_GET_DISPLAY_INFORMATION GetDisplayInformation; - PXT_FRAMEBUFFER_INITIALIZE Initialize; - PXT_FRAMEBUFFER_PRINT_DISPLAY_INFORMATION PrintDisplayInformation; -} XT_FRAMEBUFFER_PROTOCOL, *PXT_FRAMEBUFFER_PROTOCOL; - -/* EFI XT Loader Protocol */ -EXTERN PXTBL_LOADER_PROTOCOL XtLdrProtocol; - -/* XTOS trampoline end address to calculate trampoline size */ -EXTERN PVOID ArEnableExtendedPhysicalAddressingEnd[]; - -/* 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 boot protocol related routines forward references */ -XTCDECL -EFI_STATUS -XtAddVirtualMemoryMapping(IN PLIST_ENTRY MemoryMappings, - IN PVOID VirtualAddress, - IN PVOID PhysicalAddress, - IN UINT NumberOfPages, - IN LOADER_MEMORY_TYPE MemoryType); - -XTCDECL -EFI_STATUS -XtBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters); - -XTCDECL -LOADER_MEMORY_TYPE -XtConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType); - -XTCDECL -ULONG -XtpDeterminePagingLevel(IN CONST PWCHAR Parameters); - -XTCDECL -EFI_STATUS -XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap); - -XTCDECL -EFI_STATUS -XtGetVirtualAddress(IN PLIST_ENTRY MemoryMappings, - IN PVOID PhysicalAddress, - OUT PVOID *VirtualAddress); - -XTCDECL -EFI_STATUS -XtInitializeVirtualMemory(IN OUT PLIST_ENTRY MemoryMappings, - IN OUT PVOID *MemoryMapAddress); - -XTCDECL -EFI_STATUS -XtMapVirtualMemory(IN PLIST_ENTRY MemoryMappings, - IN UINT_PTR VirtualAddress, - IN UINT_PTR PhysicalAddress, - IN UINT NumberOfPages, - IN OUT PVOID *PtePointer); - -XTCDECL -EFI_STATUS -XtpBootSequence(IN PEFI_FILE_HANDLE BootDir, - IN PXTBL_BOOT_PARAMETERS Parameters); - - -XTCDECL -EFI_STATUS -XtpInitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap); - -XTCDECL -EFI_STATUS -XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap, - IN PVOID *VirtualAddress, - IN PXTBL_BOOT_PARAMETERS Parameters); - -XTCDECL -EFI_STATUS -XtpLoadModule(IN PEFI_FILE_HANDLE BootDir, - IN PWCHAR FileName, - IN PVOID VirtualAddress, - IN LOADER_MEMORY_TYPE MemoryType, - OUT PPECOFF_IMAGE_CONTEXT *ImageContext); - -XTCDECL -EFI_STATUS -XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap); - -XTCDECL -EFI_STATUS -BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle, - IN PEFI_SYSTEM_TABLE SystemTable); - -#endif /* __XTLDR_MODULES_XTOS_H */ diff --git a/xtldr/modules/xtos_o/includes/xtos.hh b/xtldr/modules/xtos_o/includes/xtos.hh new file mode 100644 index 0000000..4d70606 --- /dev/null +++ b/xtldr/modules/xtos_o/includes/xtos.hh @@ -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 + */ + +#ifndef __XTLDR_MODULES_XTOS_HH +#define __XTLDR_MODULES_XTOS_HH + +#include + + +/* 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 */ diff --git a/xtldr/modules/xtos_o/xtos.c b/xtldr/modules/xtos_o/xtos.cc similarity index 80% rename from xtldr/modules/xtos_o/xtos.c rename to xtldr/modules/xtos_o/xtos.cc index 12e4353..60bbf7c 100644 --- a/xtldr/modules/xtos_o/xtos.c +++ b/xtldr/modules/xtos_o/xtos.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * 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 * DEVELOPERS: Rafal Kupiec */ -#include +#include /* XTOS module information */ @@ -16,14 +16,139 @@ MODULE_DEPENDENCY(L"acpi framebuf pecoff"); MODULE_LICENSE(L"GPLv3"); MODULE_VERSION(L"0.1"); -/* EFI XT Loader Protocol */ -PXTBL_LOADER_PROTOCOL XtLdrProtocol; -/* XTOS PE/COFF Image Protocol */ -PXTBL_EXECUTABLE_IMAGE_PROTOCOL XtPeCoffProtocol; +/** + * Starts the operating system according to the provided parameters using XTOS boot protocol. + * + * @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::BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters) +{ + EFI_GUID PeCoffProtocolGuid = XT_PECOFF_IMAGE_PROTOCOL_GUID; + EFI_HANDLE DiskHandle, ProtocolHandle; + PEFI_FILE_HANDLE FsHandle, BootDir; + PWCHAR SystemPath; + EFI_STATUS Status; -/* XTOS Boot Protocol */ -XTBL_BOOT_PROTOCOL XtBootProtocol; + /* Print debug message */ + XtLdrProtocol->Debug.Print(L"XTOS boot protocol activated\n"); + + /* Open the XT PE/COFF protocol */ + Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID *)&PeCoffProtocol, &PeCoffProtocolGuid); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open loader protocol */ + XtLdrProtocol->Debug.Print(L"ERROR: Unable to load PE/COFF image protocol\n"); + return STATUS_EFI_PROTOCOL_ERROR; + } + + /* Check device path */ + if(Parameters->DevicePath == NULLPTR) + { + /* No device path set */ + XtLdrProtocol->Debug.Print(L"ERROR: No device path provided, unable to boot system\n"); + return STATUS_EFI_INVALID_PARAMETER; + } + + /* Check if system path is set */ + if(Parameters->SystemPath != NULLPTR) + { + /* Make sure system path begins with backslash, the only separator supported by EFI */ + if(Parameters->SystemPath[0] == '/') + { + /* Replace directory separator if needed */ + Parameters->SystemPath[0] = '\\'; + } + + /* Validate system path */ + SystemPath = &Parameters->SystemPath[1]; + while(*SystemPath) + { + /* Make sure it does not point to any subdirectory and not contains special characters */ + if(((*SystemPath | 32) - 'a' >= 26) && ((*SystemPath - '0') >= 10)) + { + /* Invalid path specified */ + XtLdrProtocol->Debug.Print(L"ERROR: System path does not point to the valid XTOS installation\n"); + return STATUS_EFI_INVALID_PARAMETER; + } + /* Check next character in the path */ + SystemPath++; + } + } + else + { + /* Fallback to '/ExectOS' by default */ + XtLdrProtocol->Debug.Print(L"WARNING: No system path set, falling back to defaults\n"); + Parameters->SystemPath = (PWCHAR)L"\\ExectOS"; + } + + /* Check if kernel file is set */ + if(Parameters->KernelFile == NULLPTR) + { + /* No kernel filename set, fallback to default */ + XtLdrProtocol->Debug.Print(L"WARNING: No kernel file specified, falling back to defaults\n"); + Parameters->KernelFile = (PWCHAR)L"xtoskrnl.exe"; + } + + /* Check if provided any kernel boot arguments */ + if(Parameters->Parameters == NULLPTR) + { + /* No argument supplied */ + Parameters->Parameters = (PWCHAR)L""; + } + + /* Print a debug message */ + XtLdrProtocol->Debug.Print(L"[XTOS] ARC Path: %S\n" + L"[XTOS] System Path: %S\n" + L"[XTOS] Kernel File: %S\n" + L"[XTOS] Boot Arguments: %S\n", + Parameters->ArcName, Parameters->SystemPath, + Parameters->KernelFile, Parameters->Parameters); + + /* Open EFI volume */ + Status = XtLdrProtocol->Disk.OpenVolume(Parameters->DevicePath, &DiskHandle, &FsHandle); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open a volume */ + XtLdrProtocol->Debug.Print(L"ERROR: Unable to open boot volume\n"); + return Status; + } + + /* System path has to point to the boot directory */ + XtLdrProtocol->WideString.Concatenate(Parameters->SystemPath, (PWCHAR)L"\\Boot", 0); + + /* Open XTOS system boot directory */ + Status = FsHandle->Open(FsHandle, &BootDir, Parameters->SystemPath, EFI_FILE_MODE_READ, 0); + FsHandle->Close(FsHandle); + + /* Check if system path directory opened successfully */ + if(Status == STATUS_EFI_NOT_FOUND) + { + /* Directory not found, nothing to load */ + XtLdrProtocol->Debug.Print(L"ERROR: System boot directory not found\n"); + + /* Close volume */ + XtLdrProtocol->Disk.CloseVolume(&DiskHandle); + return Status; + } + else if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open directory */ + XtLdrProtocol->Debug.Print(L"ERROR: Unable to open system boot directory\n"); + XtLdrProtocol->Disk.CloseVolume(&DiskHandle); + return Status; + } + + /* Start boot sequence */ + return RunBootSequence(BootDir, Parameters); +} /** * Returns information about frame buffer in XTOS compatible format. @@ -37,10 +162,10 @@ XTBL_BOOT_PROTOCOL XtBootProtocol; */ XTCDECL VOID -XtGetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource, - IN PEFI_PHYSICAL_ADDRESS FrameBufferBase, - IN PULONG_PTR FrameBufferSize, - IN PXTBL_FRAMEBUFFER_MODE_INFORMATION FrameBufferModeInfo) +Xtos::GetDisplayInformation(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; @@ -65,9 +190,9 @@ XtGetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource, XTCDECL EFI_STATUS -XtGetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap, - IN PVOID *VirtualAddress, - OUT PLIST_ENTRY MemoryDescriptorList) +Xtos::GetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap, + IN PVOID *VirtualAddress, + OUT PLIST_ENTRY MemoryDescriptorList) { EFI_PHYSICAL_ADDRESS Address; EFI_STATUS Status; @@ -101,7 +226,7 @@ XtGetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap, MemoryDescriptor->BasePage = (UINT_PTR)MemoryMapping->PhysicalAddress / EFI_PAGE_SIZE; MemoryDescriptor->PageCount = MemoryMapping->NumberOfPages; - RtlInsertTailList(MemoryDescriptorList, &MemoryDescriptor->ListEntry); + XtLdrProtocol->LinkedList.InsertTail(MemoryDescriptorList, &MemoryDescriptor->ListEntry); Address = Address + sizeof(LOADER_MEMORY_DESCRIPTOR); ListEntry = ListEntry->Flink; @@ -114,9 +239,9 @@ XtGetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap, XTCDECL EFI_STATUS -XtGetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap, - IN PVOID *VirtualAddress, - OUT PLIST_ENTRY SystemResourcesList) +Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap, + IN PVOID *VirtualAddress, + OUT PLIST_ENTRY SystemResourcesList) { XTSTATUS Status; EFI_HANDLE ProtocolHandle; @@ -152,11 +277,11 @@ XtGetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap, VirtualBase = *VirtualAddress; /* Calculate next valid virtual address */ - *VirtualAddress += (UINT_PTR)(Pages * EFI_PAGE_SIZE); + *VirtualAddress = (PUINT8)*VirtualAddress + (Pages * EFI_PAGE_SIZE); AcpiResource = (PSYSTEM_RESOURCE_ACPI)Address; - RtlZeroMemory(AcpiResource, sizeof(SYSTEM_RESOURCE_ACPI)); + XtLdrProtocol->Memory.ZeroMemory(AcpiResource, sizeof(SYSTEM_RESOURCE_ACPI)); /* Load FrameBuffer protocol */ Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&AcpiProtocol, &AcpiGuid); @@ -175,16 +300,16 @@ XtGetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap, /* No need to map ACPI */ AcpiResource->Header.VirtualAddress = 0; - RtlInsertTailList(SystemResourcesList, &AcpiResource->Header.ListEntry); + XtLdrProtocol->LinkedList.InsertTail(SystemResourcesList, &AcpiResource->Header.ListEntry); /* Close FrameBuffer protocol */ - XtLdrProtocol->Protocol.Close(ProtocolHandle, &FrameBufGuid); + XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid); Address = Address + sizeof(SYSTEM_RESOURCE_ACPI); FrameBufferResource = (PSYSTEM_RESOURCE_FRAMEBUFFER)Address; - RtlZeroMemory(FrameBufferResource, sizeof(SYSTEM_RESOURCE_FRAMEBUFFER)); + XtLdrProtocol->Memory.ZeroMemory(FrameBufferResource, sizeof(SYSTEM_RESOURCE_FRAMEBUFFER)); /* Load FrameBuffer protocol */ Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&FrameBufProtocol, &FrameBufGuid); @@ -196,7 +321,7 @@ XtGetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap, { /* Store information about FrameBuffer device */ - XtGetDisplayInformation(FrameBufferResource, &FbAddress, &FbSize, &FbModeInfo); + GetDisplayInformation(FrameBufferResource, &FbAddress, &FbSize, &FbModeInfo); } } if(Status != STATUS_EFI_SUCCESS) @@ -216,272 +341,17 @@ XtGetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap, FrameBufferPages, LoaderFirmwarePermanent); /* Close FrameBuffer protocol */ - XtLdrProtocol->Protocol.Close(ProtocolHandle, &FrameBufGuid); + XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid); - *VirtualAddress += (UINT_PTR)(FrameBufferPages * EFI_PAGE_SIZE); + *VirtualAddress = (PUINT8)*VirtualAddress + (FrameBufferPages * EFI_PAGE_SIZE); - RtlInsertTailList(SystemResourcesList, &FrameBufferResource->Header.ListEntry); + XtLdrProtocol->LinkedList.InsertTail(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. - * - * @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 -XtBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters) -{ - EFI_GUID PeCoffProtocolGuid = XT_PECOFF_IMAGE_PROTOCOL_GUID; - EFI_HANDLE DiskHandle, ProtocolHandle; - PEFI_FILE_HANDLE FsHandle, BootDir; - PWCHAR SystemPath; - EFI_STATUS Status; - - /* Print debug message */ - XtLdrProtocol->Debug.Print(L"XTOS boot protocol activated\n"); - - /* Open the XT PE/COFF protocol */ - Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID *)&XtPeCoffProtocol, &PeCoffProtocolGuid); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open loader protocol */ - XtLdrProtocol->Debug.Print(L"ERROR: Unable to load PE/COFF image protocol\n"); - return STATUS_EFI_PROTOCOL_ERROR; - } - - /* Check device path */ - if(Parameters->DevicePath == NULL) - { - /* No device path set */ - XtLdrProtocol->Debug.Print(L"ERROR: No device path provided, unable to boot system\n"); - return STATUS_EFI_INVALID_PARAMETER; - } - - /* Check if system path is set */ - if(Parameters->SystemPath != NULL) - { - /* Make sure system path begins with backslash, the only separator supported by EFI */ - if(Parameters->SystemPath[0] == '/') - { - /* Replace directory separator if needed */ - Parameters->SystemPath[0] = '\\'; - } - - /* Validate system path */ - SystemPath = &Parameters->SystemPath[1]; - while(*SystemPath) - { - /* Make sure it does not point to any subdirectory and not contains special characters */ - if(((*SystemPath | 32) - 'a' >= 26) && ((*SystemPath - '0') >= 10)) - { - /* Invalid path specified */ - XtLdrProtocol->Debug.Print(L"ERROR: System path does not point to the valid XTOS installation\n"); - return STATUS_EFI_INVALID_PARAMETER; - } - /* Check next character in the path */ - SystemPath++; - } - } - else - { - /* Fallback to '/ExectOS' by default */ - XtLdrProtocol->Debug.Print(L"WARNING: No system path set, falling back to defaults\n"); - Parameters->SystemPath = L"\\ExectOS"; - } - - /* Check if kernel file is set */ - if(Parameters->KernelFile == NULL) - { - /* No kernel filename set, fallback to default */ - XtLdrProtocol->Debug.Print(L"WARNING: No kernel file specified, falling back to defaults\n"); - Parameters->KernelFile = L"xtoskrnl.exe"; - } - - /* Check if provided any kernel boot arguments */ - if(Parameters->Parameters == NULL) - { - /* No argument supplied */ - Parameters->Parameters = L""; - } - - /* Print a debug message */ - XtLdrProtocol->Debug.Print(L"[XTOS] ARC Path: %S\n" - L"[XTOS] System Path: %S\n" - L"[XTOS] Kernel File: %S\n" - L"[XTOS] Boot Arguments: %S\n", - Parameters->ArcName, Parameters->SystemPath, - Parameters->KernelFile, Parameters->Parameters); - - /* Open EFI volume */ - Status = XtLdrProtocol->Disk.OpenVolume(Parameters->DevicePath, &DiskHandle, &FsHandle); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open a volume */ - XtLdrProtocol->Debug.Print(L"ERROR: Unable to open boot volume\n"); - return Status; - } - - /* System path has to point to the boot directory */ - RtlConcatenateWideString(Parameters->SystemPath, L"\\Boot", 0); - - /* Open XTOS system boot directory */ - Status = FsHandle->Open(FsHandle, &BootDir, Parameters->SystemPath, EFI_FILE_MODE_READ, 0); - FsHandle->Close(FsHandle); - - /* Check if system path directory opened successfully */ - if(Status == STATUS_EFI_NOT_FOUND) - { - /* Directory not found, nothing to load */ - XtLdrProtocol->Debug.Print(L"ERROR: System boot directory not found\n"); - - /* Close volume */ - XtLdrProtocol->Disk.CloseVolume(DiskHandle); - return Status; - } - else if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open directory */ - XtLdrProtocol->Debug.Print(L"ERROR: Unable to open system boot directory\n"); - XtLdrProtocol->Disk.CloseVolume(DiskHandle); - return Status; - } - - /* Start boot sequence */ - return XtpBootSequence(BootDir, Parameters); -} - -/** - * 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 -XtpBootSequence(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 = NULL; - 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, XtpDeterminePagingLevel(Parameters->Parameters), Size4K); - - Status = XtLdrProtocol->Memory.MapEfiMemory(&PageMap, &VirtualMemoryArea, NULL); - 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; -} - /** * Checks if APIC is present in the system and finds its base address. * @@ -494,7 +364,7 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir, */ XTCDECL EFI_STATUS -XtpInitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap) +Xtos::InitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap) { EFI_GUID AcpiGuid = XT_ACPI_PROTOCOL_GUID; PXTBL_ACPI_PROTOCOL AcpiProtocol; @@ -538,9 +408,9 @@ XtpInitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap) */ XTCDECL EFI_STATUS -XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap, - IN PVOID *VirtualAddress, - IN PXTBL_BOOT_PARAMETERS Parameters) +Xtos::InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap, + IN PVOID *VirtualAddress, + IN PXTBL_BOOT_PARAMETERS Parameters) { PKERNEL_INITIALIZATION_BLOCK LoaderBlock; EFI_PHYSICAL_ADDRESS Address; @@ -550,7 +420,7 @@ XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap, UINT ParametersSize; /* Calculate size of parameters */ - ParametersSize = (RtlWideStringLength(Parameters->Parameters, 0) + 1) * sizeof(WCHAR); + ParametersSize = (XtLdrProtocol->WideString.Length(Parameters->Parameters, 0) + 1) * sizeof(WCHAR); /* Calculate number of pages needed for initialization block */ BlockPages = EFI_SIZE_TO_PAGES(sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize); @@ -565,7 +435,7 @@ XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap, /* Initialize and zero-fill kernel initialization block */ LoaderBlock = (PKERNEL_INITIALIZATION_BLOCK)(UINT_PTR)Address; - RtlZeroMemory(LoaderBlock, sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize); + XtLdrProtocol->Memory.ZeroMemory(LoaderBlock, sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize); /* Set basic loader block properties */ LoaderBlock->BlockSize = sizeof(KERNEL_INITIALIZATION_BLOCK); @@ -573,7 +443,7 @@ XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap, LoaderBlock->ProtocolVersion = BOOT_PROTOCOL_VERSION; /* Set LoaderInformation block properties */ - LoaderBlock->LoaderInformation.DbgPrint = XtLdrProtocol->Debug.Print; + LoaderBlock->LoaderInformation.DbgPrint = (PVOID)XtLdrProtocol->Debug.Print; /* Attempt to find virtual address of the EFI Runtime Services */ // Status = XtLdrProtocol->GetVirtualAddress(MemoryMappings, &EfiSystemTable->RuntimeServices->Hdr, &RuntimeServices); @@ -582,7 +452,7 @@ XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap, /* Set FirmwareInformation block properties */ LoaderBlock->FirmwareInformation.FirmwareType = SystemFirmwareEfi; LoaderBlock->FirmwareInformation.EfiFirmware.EfiVersion = 0; //EfiSystemTable->Hdr.Revision; - LoaderBlock->FirmwareInformation.EfiFirmware.EfiRuntimeServices = NULL; + LoaderBlock->FirmwareInformation.EfiFirmware.EfiRuntimeServices = NULLPTR; // } // else // { @@ -592,7 +462,7 @@ XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap, /* Copy parameters to kernel initialization block */ LoaderBlock->KernelParameters = (PWCHAR)((UINT_PTR)*VirtualAddress + sizeof(KERNEL_INITIALIZATION_BLOCK)); - RtlCopyMemory((PVOID)((UINT_PTR)LoaderBlock + sizeof(KERNEL_INITIALIZATION_BLOCK)), + XtLdrProtocol->Memory.CopyMemory((PVOID)((UINT_PTR)LoaderBlock + sizeof(KERNEL_INITIALIZATION_BLOCK)), Parameters->Parameters, ParametersSize); @@ -601,19 +471,45 @@ XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap, BlockPages, LoaderSystemBlock); /* Calculate next valid virtual address */ - *VirtualAddress += (UINT_PTR)(BlockPages * EFI_PAGE_SIZE); + *VirtualAddress = (PUINT8)*VirtualAddress + (BlockPages * EFI_PAGE_SIZE); - RtlInitializeListHead(&LoaderBlock->SystemResourcesListHead); - XtGetSystemResourcesList(PageMap, VirtualAddress, &LoaderBlock->SystemResourcesListHead); + XtLdrProtocol->LinkedList.InitializeHead(&LoaderBlock->SystemResourcesListHead); + GetSystemResourcesList(PageMap, VirtualAddress, &LoaderBlock->SystemResourcesListHead); /* Initialize memory descriptor list */ - RtlInitializeListHead(&LoaderBlock->MemoryDescriptorListHead); - XtGetMemoryDescriptorList(PageMap, VirtualAddress, &LoaderBlock->MemoryDescriptorListHead); + XtLdrProtocol->LinkedList.InitializeHead(&LoaderBlock->MemoryDescriptorListHead); + GetMemoryDescriptorList(PageMap, VirtualAddress, &LoaderBlock->MemoryDescriptorListHead); /* Return 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. * @@ -638,11 +534,11 @@ XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap, */ XTCDECL EFI_STATUS -XtpLoadModule(IN PEFI_FILE_HANDLE SystemDir, - IN PWCHAR FileName, - IN PVOID VirtualAddress, - IN LOADER_MEMORY_TYPE MemoryType, - OUT PPECOFF_IMAGE_CONTEXT *ImageContext) +Xtos::LoadModule(IN PEFI_FILE_HANDLE SystemDir, + IN PWCHAR FileName, + IN PVOID VirtualAddress, + IN LOADER_MEMORY_TYPE MemoryType, + OUT PPECOFF_IMAGE_CONTEXT *ImageContext) { PEFI_FILE_HANDLE ModuleHandle; USHORT MachineType, SubSystem; @@ -661,7 +557,7 @@ XtpLoadModule(IN PEFI_FILE_HANDLE SystemDir, } /* 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) { /* Unable to load the file */ @@ -673,7 +569,7 @@ XtpLoadModule(IN PEFI_FILE_HANDLE SystemDir, ModuleHandle->Close(ModuleHandle); /* Check PE/COFF image machine type compatibility */ - XtPeCoffProtocol->GetMachineType(*ImageContext, &MachineType); + PeCoffProtocol->GetMachineType(*ImageContext, &MachineType); if(MachineType != _ARCH_IMAGE_MACHINE_TYPE) { /* Machine type mismatch */ @@ -682,7 +578,7 @@ XtpLoadModule(IN PEFI_FILE_HANDLE SystemDir, } /* Check PE/COFF image subsystem */ - XtPeCoffProtocol->GetSubSystem(*ImageContext, &SubSystem); + PeCoffProtocol->GetSubSystem(*ImageContext, &SubSystem); if(SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_KERNEL && SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_APPLICATION && SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_DRIVER) @@ -698,6 +594,129 @@ XtpLoadModule(IN PEFI_FILE_HANDLE SystemDir, 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, + LoaderExceptionBlock); // 0 is LoaderExceptionBlock?! Should be 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. * @@ -716,23 +735,6 @@ EFI_STATUS XtLdrModuleMain(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 */ - XtBootProtocol.BootSystem = XtBootSystem; - - /* Register XTOS boot protocol */ - XtLdrProtocol->Boot.RegisterProtocol(L"XTOS", &Guid); - - /* Install XTOS protocol */ - return XtLdrProtocol->Protocol.Install(&XtBootProtocol, &Guid); + /* Initialize XTOS module */ + return Xtos::InitializeModule(ImageHandle, SystemTable); } diff --git a/xtldr/protocol.c b/xtldr/protocol.c deleted file mode 100644 index 5988b9f..0000000 --- a/xtldr/protocol.c +++ /dev/null @@ -1,938 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/protocol.c - * DESCRIPTION: XT Boot Loader protocol support - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/** - * Closes a protocol on a provided handle. - * - * @param Handle - * Supplies a handle for the protocol interface that was previously opened. - * - * @param ProtocolGuid - * Supplies a unique protocol GUID. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlCloseProtocol(IN PEFI_HANDLE Handle, - IN PEFI_GUID ProtocolGuid) -{ - return EfiSystemTable->BootServices->CloseProtocol(Handle, ProtocolGuid, EfiImageHandle, NULL); -} - -/** - * Finds a boot protocol for specified system type. - * - * @param SystemType - * Specifies the system type to search for. - * - * @param BootProtocolGuid - * Receives the GUID of the registered boot protocol, that supports specified system. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlFindBootProtocol(IN PWCHAR SystemType, - OUT PEFI_GUID BootProtocolGuid) -{ - PXTBL_KNOWN_BOOT_PROTOCOL ProtocolEntry; - PLIST_ENTRY ProtocolListEntry; - - ProtocolListEntry = BlpBootProtocols.Flink; - while(ProtocolListEntry != &BlpBootProtocols) - { - /* Get boot protocol entry */ - ProtocolEntry = CONTAIN_RECORD(ProtocolListEntry, XTBL_KNOWN_BOOT_PROTOCOL, Flink); - - /* Check if this boot protocol supports specified system */ - if(RtlCompareWideStringInsensitive(ProtocolEntry->SystemType, SystemType, 0) == 0) - { - /* Boot protocol matched, return success */ - *BootProtocolGuid = ProtocolEntry->Guid; - return STATUS_EFI_SUCCESS; - } - - /* Move to the next registered boot protocol */ - ProtocolListEntry = ProtocolListEntry->Flink; - } - - /* Boot protocol not found, return error */ - return STATUS_EFI_NOT_FOUND; -} - -/** - * Returns a linked list of all loaded modules. - * - * @return This routine returns a pointer to a linked list of all loaded modules. - * - * @since XT 1.0 - * - * @todo This is a temporary solution and it should be replaced by a complex API allowing to map modules. - */ -XTCDECL -PLIST_ENTRY -BlGetModulesList() -{ - /* Return a pointer to a list of all loaded modules */ - return &BlpLoadedModules; -} - -/** - * Installs XTLDR protocol interface. - * - * @param Guid - * Specifies a unique protocol GUID. - * - * @param Interface - * Supplies a pointer to the protocol interface, or NULL if there is no structure associated. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlInstallProtocol(IN PVOID Interface, - IN PEFI_GUID Guid) -{ - EFI_HANDLE Handle = NULL; - - /* Install protocol interface */ - return EfiSystemTable->BootServices->InstallProtocolInterface(&Handle, Guid, EFI_NATIVE_INTERFACE, Interface); -} - -/** - * Loads a specified XTLDR module from disk. - * - * @param ModuleName - * Specifies the name of the module to load. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlLoadModule(IN PWCHAR ModuleName) -{ - EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; - PLIST_ENTRY DepsListEntry, ModuleListEntry; - EFI_MEMMAP_DEVICE_PATH ModuleDevicePath[2]; - PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; - PEFI_FILE_HANDLE DirHandle, FsHandle; - EFI_HANDLE DiskHandle, ModuleHandle; - PPECOFF_IMAGE_SECTION_HEADER SectionHeader; - PPECOFF_IMAGE_DOS_HEADER DosHeader; - PPECOFF_IMAGE_PE_HEADER PeHeader; - PXTBL_MODULE_DEPS ModuleDependency; - PXTBL_MODULE_INFO ModuleInfo; - WCHAR ModuleFileName[24]; - USHORT SectionIndex; - PWCHAR SectionData; - SIZE_T ModuleSize; - EFI_STATUS Status; - PVOID ModuleData; - - ModuleListEntry = BlpLoadedModules.Flink; - while(ModuleListEntry != &BlpLoadedModules) - { - /* Get module information */ - ModuleInfo = CONTAIN_RECORD(ModuleListEntry, XTBL_MODULE_INFO, Flink); - - if(RtlCompareWideStringInsensitive(ModuleInfo->ModuleName, ModuleName, 0) == 0) - { - /* Module already loaded */ - BlDebugPrint(L"WARNING: Module '%S' already loaded!\n", ModuleName); - return STATUS_EFI_SUCCESS; - } - - /* Move to next module */ - ModuleListEntry = ModuleListEntry->Flink; - } - - /* Print debug message */ - BlDebugPrint(L"Loading module '%S' ...\n", ModuleName); - - /* Set module path */ - RtlCopyMemory(ModuleFileName, ModuleName, sizeof(ModuleFileName) / sizeof(WCHAR)); - RtlConcatenateWideString(ModuleFileName, L".EFI", 0); - - /* Open EFI volume */ - Status = BlOpenVolume(NULL, &DiskHandle, &FsHandle); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open a volume */ - return Status; - } - - /* Open XTLDR modules common directory */ - Status = FsHandle->Open(FsHandle, &DirHandle, XTBL_MODULES_DIRECTORY_PATH, EFI_FILE_MODE_READ, 0); - if(Status != STATUS_EFI_SUCCESS) - { - /* Modules directory not found, attempt to open XTLDR architecture specific modules directory */ - Status = FsHandle->Open(FsHandle, &DirHandle, XTBL_ARCH_MODULES_DIRECTORY_PATH, EFI_FILE_MODE_READ, 0); - } - - /* Close FS handle */ - FsHandle->Close(FsHandle); - - /* Check if modules directory opened successfully */ - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open directory */ - BlCloseVolume(DiskHandle); - return Status; - } - - /* Read module file from disk and close directory and EFI volume */ - Status = BlReadFile(DirHandle, ModuleFileName, &ModuleData, &ModuleSize); - DirHandle->Close(DirHandle); - BlCloseVolume(DiskHandle); - - /* Make sure module file was read successfully */ - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to read file */ - return Status; - } - - /* Allocate memory for module information block */ - Status = BlAllocateMemoryPool(sizeof(XTBL_MODULE_INFO), (PVOID*)&ModuleInfo); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to allocate memory */ - return Status; - } - - /* Zero module information block */ - RtlZeroMemory(ModuleInfo, sizeof(XTBL_MODULE_INFO)); - - /* Setup PE/COFF EFI image headers */ - DosHeader = (PPECOFF_IMAGE_DOS_HEADER)ModuleData; - PeHeader = (PPECOFF_IMAGE_PE_HEADER)(ModuleData + DosHeader->PeHeaderOffset); - - /* Check PE/COFF image type*/ - if(PeHeader->OptionalHeader32.Magic == PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC) - { - /* Get PE32+ (64-bit) image section headers */ - SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&PeHeader->OptionalHeader64 + - PeHeader->FileHeader.SizeOfOptionalHeader); - } - else - { - /* Get PE32 (32-bit) image section headers */ - SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&PeHeader->OptionalHeader32 + - PeHeader->FileHeader.SizeOfOptionalHeader); - } - - /* Look for .modinfo section */ - for(SectionIndex = 0; SectionIndex < PeHeader->FileHeader.NumberOfSections; SectionIndex++) - { - if(RtlCompareString((PCHAR)SectionHeader[SectionIndex].Name, ".modinfo", 8) == 0) - { - /* Module information section found */ - SectionData = ModuleData + SectionHeader[SectionIndex].PointerToRawData; - - /* Get module information */ - Status = BlpGetModuleInformation(SectionData, SectionHeader[SectionIndex].SizeOfRawData, ModuleInfo); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to read module information */ - return Status; - } - } - } - - /* Iterate through module dependencies */ - DepsListEntry = ModuleInfo->Dependencies.Flink; - while(DepsListEntry != &ModuleInfo->Dependencies) - { - /* Get module dependency information */ - ModuleDependency = CONTAIN_RECORD(DepsListEntry, XTBL_MODULE_DEPS, Flink); - - /* Make sure dependency list contains a valid module name */ - if(ModuleDependency->ModuleName == NULL || ModuleDependency->ModuleName[0] == L'\0') - { - /* Invalid module name found, just skip this step */ - break; - } - - /* Load dependency module */ - BlDebugPrint(L"Module '%S' requires '%S' ...\n", ModuleName, ModuleDependency->ModuleName); - Status = BlLoadModule(ModuleDependency->ModuleName); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to load module, print error message and return status code */ - BlDebugPrint(L"Failed to load dependency module '%S' (Status Code: 0x%zX)\n", ModuleDependency->ModuleName, Status); - return STATUS_EFI_UNSUPPORTED; - } - - /* Move to the next dependency */ - DepsListEntry = DepsListEntry->Flink; - } - - /* Setup module device path */ - ModuleDevicePath[0].Header.Length[0] = sizeof(EFI_MEMMAP_DEVICE_PATH); - ModuleDevicePath[0].Header.Length[1] = sizeof(EFI_MEMMAP_DEVICE_PATH) >> 8; - ModuleDevicePath[0].Header.Type = EFI_HARDWARE_DEVICE_PATH; - ModuleDevicePath[0].Header.SubType = EFI_HARDWARE_MEMMAP_DP; - ModuleDevicePath[0].MemoryType = EfiLoaderData; - ModuleDevicePath[0].StartingAddress = (UINT_PTR)ModuleData; - ModuleDevicePath[0].EndingAddress = (UINT_PTR)ModuleData + ModuleSize; - ModuleDevicePath[1].Header.Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL); - ModuleDevicePath[1].Header.Length[1] = sizeof(EFI_DEVICE_PATH_PROTOCOL) >> 8; - ModuleDevicePath[1].Header.Type = EFI_END_DEVICE_PATH; - ModuleDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP; - - /* Load EFI image */ - BlDebugPrint(L"Starting module '%S' ...\n", ModuleName); - Status = BlLoadEfiImage((PEFI_DEVICE_PATH_PROTOCOL)ModuleDevicePath, ModuleData, ModuleSize, &ModuleHandle); - if(Status != STATUS_EFI_SUCCESS) - { - /* Check if caused by secure boot */ - if(Status == STATUS_EFI_ACCESS_DENIED && BlpStatus.SecureBoot >= 1) - { - /* SecureBoot signature validation failed */ - BlDebugPrint(L"ERROR: SecureBoot signature validation failed, module '%S' will not be loaded\n", ModuleName); - } - else - { - /* Failed to load module */ - BlDebugPrint(L"ERROR: Unable to load module '%S' (Status Code: 0x%zX)\n", ModuleName, Status); - } - - /* Return error status code */ - return Status; - } - - /* Access module interface for further module type check */ - Status = EfiSystemTable->BootServices->OpenProtocol(ModuleHandle, &LIPGuid, (PVOID *)&LoadedImage, - EfiImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open LoadedImage protocol */ - BlDebugPrint(L"ERROR: Unable to access module interface (Status Code: 0x%zX)\n", Status); - return Status; - } - - /* Some firmwares do not allow to start drivers which are not of 'boot system driver' type, so check it */ - if(LoadedImage->ImageCodeType != EfiBootServicesCode) - { - /* Different type set, probably 'runtime driver', refuse to load it */ - BlDebugPrint(L"ERROR: Loaded module is not a boot system driver\n"); - - /* Close protocol and skip module */ - EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL); - } - - /* Save additional module information, not found in '.modinfo' section */ - ModuleInfo->ModuleName = ModuleName; - ModuleInfo->ModuleBase = LoadedImage->ImageBase; - ModuleInfo->ModuleSize = LoadedImage->ImageSize; - ModuleInfo->Revision = LoadedImage->Revision; - ModuleInfo->UnloadModule = LoadedImage->Unload; - - /* Close loaded image protocol */ - EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL); - - /* Start EFI image */ - Status = BlStartEfiImage(ModuleHandle); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to start module image */ - BlDebugPrint(L"ERROR: Failed to start module '%S' (Status Code: 0x%zX)\n", ModuleName, Status); - return Status; - } - - /* Add module to the list of loaded modules */ - RtlInsertTailList(&BlpLoadedModules, &ModuleInfo->Flink); - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * Helper routine to load all modules supplied in the configuration file. - * - * @param ModulesList - * Supplies a space separated list of XTLDR modules to load (mostly read from configuration file). - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlLoadModules(IN PWCHAR ModulesList) -{ - PWCHAR LastModule, Module; - EFI_STATUS ReturnStatus, Status; - - /* Set default return value */ - ReturnStatus = STATUS_EFI_SUCCESS; - - if(ModulesList != NULL) - { - /* Tokenize provided list of modules */ - Module = RtlTokenizeWideString(ModulesList, L" ", &LastModule); - - /* Iterate over all arguments passed to boot loader */ - while(Module != NULL) - { - Status = BlLoadModule(Module); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to load module, print error message and set new return value */ - BlDebugPrint(L"ERROR: Failed to load module '%S' (Status Code: 0x%zX)\n", Module, Status); - ReturnStatus = STATUS_EFI_LOAD_ERROR; - } - - /* Take next module from the list */ - Module = RtlTokenizeWideString(NULL, L" ", &LastModule); - } - } - - /* Return success */ - return ReturnStatus; -} - -/** - * Returns an array of handles that support the requested protocol. - * - * @param Handles - * Supplies the address where a pointer to all handles found for the protocol interface. - * - * @param Count - * Provides a number of the returned handles. - * - * @param ProtocolGuid - * Supplies a pointer to the unique protocol GUID. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlLocateProtocolHandles(OUT PEFI_HANDLE *Handles, - OUT PUINT_PTR Count, - IN PEFI_GUID ProtocolGuid) -{ - return EfiSystemTable->BootServices->LocateHandleBuffer(ByProtocol, ProtocolGuid, NULL, Count, Handles); -} - -/** - * Locates and opens the requested XT Boot Loader or EFI protocol. - * - * @param Handle - * Supplies the address where a pointer to the handle for the protocol interface. - * - * @param ProtocolHandler - * Supplies the address where a pointer to the opened protocol is returned. - * - * @param ProtocolGuid - * Supplies a pointer to the unique protocol GUID. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlOpenProtocol(OUT PEFI_HANDLE Handle, - OUT PVOID *ProtocolHandler, - IN PEFI_GUID ProtocolGuid) -{ - PEFI_HANDLE Handles = NULL; - EFI_STATUS Status; - UINT_PTR Count; - UINT Index; - - /* Try to locate the handles */ - Status = BlLocateProtocolHandles(&Handles, &Count, ProtocolGuid); - if(Status != STATUS_EFI_SUCCESS) - { - /* Unable to get handles */ - return Status; - } - - /* Check if any handles returned */ - if(Count > 0) - { - /* Iterate through all given handles */ - for(Index = 0; Index < Count; Index++) - { - /* Try to open protocol */ - Status = BlOpenProtocolHandle(Handles[Index], ProtocolHandler, ProtocolGuid); - - /* Check if successfully opened the loader protocol */ - if(Status == STATUS_EFI_SUCCESS) - { - /* Protocol found and successfully opened */ - *Handle = Handles[Index]; - break; - } - } - } - - /* Free handles */ - EfiSystemTable->BootServices->FreePool(Handles); - - /* Make sure the loaded protocol has been found */ - if(*ProtocolHandler == NULL) - { - /* Protocol not found */ - return STATUS_EFI_NOT_FOUND; - } - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * Opens the requested XT Boot Loader or EFI protocol, if it is supported by the handle. - * - * @param Handle - * Supplies a handle for the protocol interface that is being opened. - * - * @param ProtocolHandler - * Supplies the address where a pointer to the opened protocol is returned. - * - * @param ProtocolGuid - * Supplies a pointer to the unique protocol GUID. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlOpenProtocolHandle(IN EFI_HANDLE Handle, - OUT PVOID *ProtocolHandler, - IN PEFI_GUID ProtocolGuid) -{ - return EfiSystemTable->BootServices->OpenProtocol(Handle, ProtocolGuid, ProtocolHandler, EfiImageHandle, - NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); -} - -/** - * 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 -BlRegisterBootMenu(IN PVOID BootMenuRoutine) -{ - /* Set boot menu routine */ - BlpStatus.BootMenu = BootMenuRoutine; -} - -/** - * Registers a known boot protocol for a specified OS. - * - * @param SystemType - * Supplies the type of the OS, such as "LINUX", "XTOS", etc. that is supported by the boot protocol. - * - * @param BootProtocolGuid - * Supplies a pointer to the unique protocol GUID. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlRegisterBootProtocol(IN PWCHAR SystemType, - IN PEFI_GUID BootProtocolGuid) -{ - PXTBL_KNOWN_BOOT_PROTOCOL ProtocolEntry; - PLIST_ENTRY ProtocolListEntry; - EFI_STATUS Status; - - ProtocolListEntry = BlpBootProtocols.Flink; - while(ProtocolListEntry != &BlpBootProtocols) - { - /* Get boot protocol entry */ - ProtocolEntry = CONTAIN_RECORD(ProtocolListEntry, XTBL_KNOWN_BOOT_PROTOCOL, Flink); - - /* Check if boot protocol already registered for specified system */ - if(RtlCompareWideStringInsensitive(ProtocolEntry->SystemType, SystemType, 0) == 0) - { - /* Boot protocol already registered */ - return STATUS_EFI_ABORTED; - } - - /* Move to the next registered boot protocol */ - ProtocolListEntry = ProtocolListEntry->Flink; - } - - /* Create new boot protocol entry */ - Status = BlAllocateMemoryPool(sizeof(XTBL_BOOT_PROTOCOL), (PVOID *)&ProtocolEntry); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure */ - return STATUS_EFI_OUT_OF_RESOURCES; - } - - /* Set protocol properties and add it to the list */ - ProtocolEntry->SystemType = SystemType; - ProtocolEntry->Guid = *BootProtocolGuid; - RtlInsertTailList(&BlpBootProtocols, &ProtocolEntry->Flink); - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * Reads information from the '.modinfo' section and populates the module information structure. - * - * @param SectionData - * Supplies a pointer to the module's information section data. - * - * @param SectionSize - * Supplies an expected size of the section data. - * - * @param ModuleInfo - * Supplies a pointer to the module information structure that will be filled by data from module's info section. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlpGetModuleInformation(IN PWCHAR SectionData, - IN ULONG SectionSize, - OUT PXTBL_MODULE_INFO ModuleInfo) -{ - PXTBL_MODULE_DEPS ModuleDependencies; - PXTBL_MODULE_AUTHORS ModuleAuthors; - PWCHAR Dependency, Key, LastStr; - ULONG Index, Count; - EFI_STATUS Status; - PWCHAR *Strings; - - /* Initialize authors and dependencies lists */ - RtlInitializeListHead(&ModuleInfo->Authors); - RtlInitializeListHead(&ModuleInfo->Dependencies); - - /* Get information strings from '.modinfo' section */ - Status = BlpGetModuleInfoStrings(SectionData, SectionSize, &Strings, &Count); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to get information strings */ - return Status; - } - - /* Parse information strings */ - for(Index = 0; Index < Count; Index++) - { - /* Store the key */ - Key = Strings[Index]; - - /* Find the end of the key and the beginning of the value */ - while(*Strings[Index] != L'=' && *Strings[Index] != L'\0' && *Strings[Index] != L'\n') - { - /* Move to the next character */ - Strings[Index]++; - } - - /* Make sure value is NULL-terminated */ - *Strings[Index] = L'\0'; - Strings[Index]++; - - /* Parse information string key */ - if(RtlCompareWideString(Key, L"author", 6) == 0) - { - /* Allocate memory for module author */ - Status = BlAllocateMemoryPool(sizeof(XTBL_MODULE_AUTHORS), (PVOID*)&ModuleAuthors); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure */ - return Status; - } - - /* Store module's author */ - ModuleAuthors->AuthorName = Strings[Index]; - RtlInsertTailList(&ModuleInfo->Authors, &ModuleAuthors->Flink); - } - else if(RtlCompareWideString(Key, L"description", 11) == 0) - { - /* Store module's description */ - ModuleInfo->ModuleDescription = Strings[Index]; - } - else if(RtlCompareWideString(Key, L"license", 7) == 0) - { - /* Store module's license */ - ModuleInfo->License = Strings[Index]; - } - else if(RtlCompareWideString(Key, L"softdeps", 6) == 0) - { - /* Tokenize value to get module's single dependency */ - Dependency = RtlTokenizeWideString(Strings[Index], L" ", &LastStr); - while(Dependency != NULL) - { - /* Allocate memory for module dependency */ - Status = BlAllocateMemoryPool(sizeof(XTBL_MODULE_DEPS), (PVOID*)&ModuleDependencies); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure */ - return Status; - } - - /* Store module's dependency */ - ModuleDependencies->ModuleName = Dependency; - RtlInsertTailList(&ModuleInfo->Dependencies, &ModuleDependencies->Flink); - - /* Get next dependency from single value if available */ - Dependency = RtlTokenizeWideString(NULL, L" ", &LastStr); - } - } - else if(RtlCompareWideString(Key, L"version", 7) == 0) - { - /* Store module's version */ - ModuleInfo->Version = Strings[Index]; - } - } - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * Reads raw data from the '.modinfo' section and populates an array of strings. - * - * @param SectionData - * Supplies a pointer to the module's information section data. - * - * @param SectionSize - * Supplies an expected size of the section data. - * - * @param ModInfo - * Supplies a pointer to memory area, where an array of strings read from the section will be stored. - * - * @param InfoCount - * Supplies a pointer to variable that will receive the number of strings found in the section. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlpGetModuleInfoStrings(IN PWCHAR SectionData, - IN ULONG SectionSize, - OUT PWCHAR **ModInfo, - OUT PULONG InfoCount) -{ - ULONG Count, Index, ArrayIndex; - PCWSTR InfoStrings; - EFI_STATUS Status; - PWCHAR *Array; - PWCHAR String; - ULONG DataSize; - - /* Check input parameters */ - InfoStrings = SectionData; - if(!InfoStrings || !SectionSize) - { - /* Invalid input parameters */ - *ModInfo = NULL; - *InfoCount = 0; - return STATUS_EFI_INVALID_PARAMETER; - } - - /* Calculate the size of the data based on the size of the section */ - DataSize = SectionSize / sizeof(WCHAR); - - /* Skip zero padding at the beginning */ - while(DataSize > 0 && *InfoStrings == L'\0') - { - InfoStrings++; - DataSize--; - } - - /* Make sure there is at least one string available */ - if(DataSize < 1) - { - /* No strings found */ - *ModInfo = NULL; - *InfoCount = 0; - return STATUS_EFI_END_OF_FILE; - } - - /* Count number of strings */ - Index = 0; - Count = 0; - while(Index < DataSize) - { - /* Found start of a new string */ - Count++; - - /* Go to the end of the string */ - while(Index < DataSize && InfoStrings[Index] != L'\0') - { - Index++; - } - /* Skip all null terminators */ - while(Index < DataSize && InfoStrings[Index] == L'\0') - { - Index++; - } - } - - /* Allocate memory for the pointer array and the string data */ - Status = BlAllocateMemoryPool(sizeof(PWCHAR) * (Count + 1) + (DataSize + 1) * sizeof(WCHAR), (PVOID *)&Array); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to allocate memory */ - return STATUS_EFI_OUT_OF_RESOURCES; - } - - /* The string buffer is located right after the pointer array */ - String = (PWCHAR)(Array + Count + 1); - - /* Copy the raw string data */ - RtlCopyMemory(String, InfoStrings, DataSize * sizeof(WCHAR)); - - /* Ensure the entire buffer is null-terminated for safety */ - String[DataSize] = L'\0'; - - /* Set the last element of the pointer array to NULL */ - Array[Count] = NULL; - - /* Populate the array with pointers to the strings within the buffer */ - Index = 0; - ArrayIndex = 0; - while(Index < DataSize && ArrayIndex < Count) - { - /* Set pointer to the beginning of the string */ - Array[ArrayIndex++] = &String[Index]; - - /* Find the end of the current string */ - while(Index < DataSize && String[Index] != L'\0') - { - Index++; - } - - /* Skip all null terminators to find the beginning of the next string */ - while(Index < DataSize && String[Index] == L'\0') - { - Index++; - } - } - - /* Return array of strings and its size */ - *ModInfo = Array; - *InfoCount = Count; - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * This routine installs XTLDR protocol for further usage by modules. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlpInstallXtLoaderProtocol() -{ - EFI_GUID Guid = XT_BOOT_LOADER_PROTOCOL_GUID; - - /* Set all routines available via loader protocol */ - BlpLdrProtocol.Boot.FindProtocol = BlFindBootProtocol; - BlpLdrProtocol.Boot.InitializeMenuList = BlInitializeBootMenuList; - BlpLdrProtocol.Boot.InvokeProtocol = BlInvokeBootProtocol; - BlpLdrProtocol.Boot.RegisterMenu = BlRegisterBootMenu; - BlpLdrProtocol.Boot.RegisterProtocol = BlRegisterBootProtocol; - BlpLdrProtocol.BootUtil.GetBooleanParameter = BlGetBooleanParameter; - BlpLdrProtocol.Config.GetBooleanValue = BlGetConfigBooleanValue; - BlpLdrProtocol.Config.GetBootOptionValue = BlGetBootOptionValue; - BlpLdrProtocol.Config.GetEditableOptions = BlGetEditableOptions; - BlpLdrProtocol.Config.GetValue = BlGetConfigValue; - BlpLdrProtocol.Config.SetBootOptionValue = BlSetBootOptionValue; - BlpLdrProtocol.Console.ClearLine = BlClearConsoleLine; - BlpLdrProtocol.Console.ClearScreen = BlClearConsoleScreen; - BlpLdrProtocol.Console.DisableCursor = BlDisableConsoleCursor; - BlpLdrProtocol.Console.EnableCursor = BlEnableConsoleCursor; - BlpLdrProtocol.Console.Print = BlConsolePrint; - BlpLdrProtocol.Console.QueryMode = BlQueryConsoleMode; - BlpLdrProtocol.Console.ReadKeyStroke = BlReadKeyStroke; - BlpLdrProtocol.Console.ResetInputBuffer = BlResetConsoleInputBuffer; - BlpLdrProtocol.Console.SetAttributes = BlSetConsoleAttributes; - BlpLdrProtocol.Console.SetCursorPosition = BlSetCursorPosition; - BlpLdrProtocol.Console.Write = BlConsoleWrite; - BlpLdrProtocol.Debug.Print = BlDebugPrint; - BlpLdrProtocol.Disk.CloseVolume = BlCloseVolume; - BlpLdrProtocol.Disk.OpenVolume = BlOpenVolume; - BlpLdrProtocol.Disk.ReadFile = BlReadFile; - BlpLdrProtocol.Memory.AllocatePages = BlAllocateMemoryPages; - BlpLdrProtocol.Memory.AllocatePool = BlAllocateMemoryPool; - BlpLdrProtocol.Memory.BuildPageMap = BlBuildPageMap; - BlpLdrProtocol.Memory.CopyMemory = RtlCopyMemory; - BlpLdrProtocol.Memory.FreePages = BlFreeMemoryPages; - BlpLdrProtocol.Memory.FreePool = BlFreeMemoryPool; - BlpLdrProtocol.Memory.GetMappingsCount = BlGetMappingsCount; - BlpLdrProtocol.Memory.GetMemoryMap = BlGetMemoryMap; - BlpLdrProtocol.Memory.GetVirtualAddress = BlGetVirtualAddress; - BlpLdrProtocol.Memory.InitializePageMap = BlInitializePageMap; - BlpLdrProtocol.Memory.MapEfiMemory = BlMapEfiMemory; - BlpLdrProtocol.Memory.MapPage = BlMapPage; - BlpLdrProtocol.Memory.MapVirtualMemory = BlMapVirtualMemory; - BlpLdrProtocol.Memory.PhysicalAddressToVirtual = BlPhysicalAddressToVirtual; - BlpLdrProtocol.Memory.PhysicalListToVirtual = BlPhysicalListToVirtual; - BlpLdrProtocol.Memory.SetMemory = RtlSetMemory; - BlpLdrProtocol.Memory.ZeroMemory = RtlZeroMemory; - BlpLdrProtocol.Protocol.Close = BlCloseProtocol; - BlpLdrProtocol.Protocol.GetModulesList = BlGetModulesList; - BlpLdrProtocol.Protocol.Install = BlInstallProtocol; - BlpLdrProtocol.Protocol.LocateHandles = BlLocateProtocolHandles; - BlpLdrProtocol.Protocol.Open = BlOpenProtocol; - BlpLdrProtocol.Protocol.OpenHandle = BlOpenProtocolHandle; - BlpLdrProtocol.Tui.DisplayErrorDialog = BlDisplayErrorDialog; - BlpLdrProtocol.Tui.DisplayInfoDialog = BlDisplayInfoDialog; - BlpLdrProtocol.Tui.DisplayInputDialog = BlDisplayInputDialog; - BlpLdrProtocol.Tui.DisplayProgressDialog = BlDisplayProgressDialog; - BlpLdrProtocol.Tui.UpdateProgressBar = BlUpdateProgressBar; - BlpLdrProtocol.Util.EnterFirmwareSetup = BlEnterFirmwareSetup; - BlpLdrProtocol.Util.ExitBootServices = BlExitBootServices; - BlpLdrProtocol.Util.GetConfigurationTable = BlGetConfigurationTable; - BlpLdrProtocol.Util.GetEfiVariable = BlGetEfiVariable; - BlpLdrProtocol.Util.GetRandomValue = BlGetRandomValue; - BlpLdrProtocol.Util.GetSecureBootStatus = BlGetSecureBootStatus; - BlpLdrProtocol.Util.InitializeEntropy = BlInitializeEntropy; - BlpLdrProtocol.Util.LoadEfiImage = BlLoadEfiImage; - BlpLdrProtocol.Util.RebootSystem = BlRebootSystem; - BlpLdrProtocol.Util.SetEfiVariable = BlSetEfiVariable; - BlpLdrProtocol.Util.ShutdownSystem = BlShutdownSystem; - BlpLdrProtocol.Util.SleepExecution = BlSleepExecution; - BlpLdrProtocol.Util.StartEfiImage = BlStartEfiImage; - BlpLdrProtocol.Util.WaitForEfiEvent = BlWaitForEfiEvent; - - /* Register XTLDR loader protocol */ - BlDebugPrint(L"Registering XT loader protocol\n"); - return BlInstallProtocol(&BlpLdrProtocol, &Guid); -} diff --git a/xtldr/protocol.cc b/xtldr/protocol.cc new file mode 100644 index 0000000..6593e4a --- /dev/null +++ b/xtldr/protocol.cc @@ -0,0 +1,1112 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/protocol.cc + * DESCRIPTION: XT Boot Loader protocol support + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * Closes a protocol on a provided handle. + * + * @param Handle + * Supplies a handle for the protocol interface that was previously opened. + * + * @param ProtocolGuid + * Supplies a unique protocol GUID. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +Protocol::CloseProtocol(IN PEFI_HANDLE Handle, + IN PEFI_GUID ProtocolGuid) +{ + return XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(Handle, ProtocolGuid, + XtLoader::GetEfiImageHandle(), NULLPTR); +} + +/** + * Finds a boot protocol for specified system type. + * + * @param SystemType + * Specifies the system type to search for. + * + * @param BootProtocolGuid + * Receives the GUID of the registered boot protocol, that supports specified system. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +Protocol::FindBootProtocol(IN PCWSTR SystemType, + OUT PEFI_GUID BootProtocolGuid) +{ + PXTBL_KNOWN_BOOT_PROTOCOL ProtocolEntry; + PLIST_ENTRY ProtocolListEntry; + + ProtocolListEntry = BootProtocols.Flink; + while(ProtocolListEntry != &BootProtocols) + { + /* Get boot protocol entry */ + ProtocolEntry = CONTAIN_RECORD(ProtocolListEntry, XTBL_KNOWN_BOOT_PROTOCOL, Flink); + + /* Check if this boot protocol supports specified system */ + if(RTL::WideString::CompareWideStringInsensitive(ProtocolEntry->SystemType, SystemType, 0) == 0) + { + /* Boot protocol matched, return success */ + *BootProtocolGuid = ProtocolEntry->Guid; + return STATUS_EFI_SUCCESS; + } + + /* Move to the next registered boot protocol */ + ProtocolListEntry = ProtocolListEntry->Flink; + } + + /* Boot protocol not found, return error */ + return STATUS_EFI_NOT_FOUND; +} + +/** + * Returns a linked list of all loaded modules. + * + * @return This routine returns a pointer to a linked list of all loaded modules. + * + * @since XT 1.0 + * + * @todo This is a temporary solution and it should be replaced by a complex API allowing to map modules. + */ +XTCDECL +PLIST_ENTRY +Protocol::GetModulesList() +{ + /* Return a pointer to a list of all loaded modules */ + return &LoadedModules; +} + +XTCDECL +VOID +Protocol::InitializeProtocol() +{ + /* Initialize list of loaded modules and boot protocols */ + RTL::LinkedList::InitializeListHead(&BootProtocols); + RTL::LinkedList::InitializeListHead(&LoadedModules); +} + +/** + * Installs XTLDR protocol interface. + * + * @param Guid + * Specifies a unique protocol GUID. + * + * @param Interface + * Supplies a pointer to the protocol interface, or NULLPTR if there is no structure associated. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +Protocol::InstallProtocol(IN PVOID Interface, + IN PEFI_GUID Guid) +{ + EFI_HANDLE Handle = NULLPTR; + + /* Install protocol interface */ + return XtLoader::GetEfiSystemTable()->BootServices->InstallProtocolInterface(&Handle, Guid, EFI_NATIVE_INTERFACE, + Interface); +} + +/** + * Loads all necessary modules and invokes boot protocol. + * + * @param ShortName + * Supplies a pointer to a short name of the chosen boot menu entry. + * + * @param OptionsList + * Supplies a pointer to list of options associated with chosen boot menu entry. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +Protocol::InvokeBootProtocol(IN PWCHAR ShortName, + IN PLIST_ENTRY OptionsList) +{ + EFI_GUID VendorGuid = XT_BOOT_LOADER_PROTOCOL_GUID; + XTBL_BOOT_PARAMETERS BootParameters; + PXTBL_BOOT_PROTOCOL BootProtocol; + PLIST_ENTRY OptionsListEntry; + PXTBL_CONFIG_ENTRY Option; + EFI_GUID BootProtocolGuid; + SIZE_T ModuleListLength; + PWCHAR ModulesList; + EFI_HANDLE Handle; + EFI_STATUS Status; + + /* Initialize boot parameters and a list of modules */ + RTL::Memory::ZeroMemory(&BootParameters, sizeof(XTBL_BOOT_PARAMETERS)); + ModulesList = NULLPTR; + + /* Iterate through all options provided by boot menu entry and propagate boot parameters */ + OptionsListEntry = OptionsList->Flink; + while(OptionsListEntry != OptionsList) + { + /* Get option */ + Option = CONTAIN_RECORD(OptionsListEntry, XTBL_CONFIG_ENTRY, Flink); + + /* Look for boot protocol and modules list */ + if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"BOOTMODULES", 0) == 0) + { + /* Check a length of modules list */ + ModuleListLength = RTL::WideString::WideStringLength(Option->Value, 0); + + Status = Memory::AllocatePool(sizeof(WCHAR) * (ModuleListLength + 1), (PVOID *)&ModulesList); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to allocate memory, print error message and return status code */ + Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); + return STATUS_EFI_OUT_OF_RESOURCES; + } + + /* Make a copy of modules list */ + RTL::Memory::CopyMemory(ModulesList, Option->Value, sizeof(WCHAR) * (ModuleListLength + 1)); + } + else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"SYSTEMTYPE", 0) == 0) + { + /* Boot protocol found */ + BootParameters.SystemType = Option->Value; + } + else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"SYSTEMPATH", 0) == 0) + { + /* System path found, get volume device path */ + Status = Volume::GetDevicePath(Option->Value, &BootParameters.DevicePath, + &BootParameters.ArcName, &BootParameters.SystemPath); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to find volume */ + Debug::Print(L"ERROR: Failed to find volume device path (Status Code: 0x%zX)\n", Status); + return Status; + } + + /* Get EFI compatible system path */ + Status = Volume::GetEfiPath(BootParameters.SystemPath, &BootParameters.EfiPath); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to get EFI path */ + Debug::Print(L"ERROR: Failed to get EFI path (Status Code: 0x%zX)\n", Status); + return Status; + } + } + else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"KERNELFILE", 0) == 0) + { + /* Kernel file name found */ + BootParameters.KernelFile = Option->Value; + } + else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"INITRDFILE", 0) == 0) + { + /* Initrd file name found */ + BootParameters.InitrdFile = Option->Value; + } + else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"HALFILE", 0) == 0) + { + /* Hal file name found */ + BootParameters.HalFile = Option->Value; + } + else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"PARAMETERS", 0) == 0) + { + /* Kernel parameters found */ + BootParameters.Parameters = Option->Value; + } + + /* Move to the next option entry */ + OptionsListEntry = OptionsListEntry->Flink; + } + + /* Load all necessary modules */ + Status = LoadModules(ModulesList); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to load modules, print error message and return status code */ + Debug::Print(L"ERROR: Failed to load XTLDR modules (Status Code: 0x%zX)\n", Status); + return STATUS_EFI_NOT_READY; + } + + /* Attempt to get boot protocol GUID */ + Status = FindBootProtocol(BootParameters.SystemType, &BootProtocolGuid); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to get boot protocol GUID */ + Debug::Print(L"ERROR: Unable to find appropriate boot protocol (Status Code: 0x%zX)\n", Status); + return STATUS_EFI_UNSUPPORTED; + } + + /* Open boot protocol */ + Status = OpenProtocol(&Handle, (PVOID *)&BootProtocol, &BootProtocolGuid); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open boot protocol */ + Debug::Print(L"ERROR: Failed to open boot protocol (Status Code: 0x%zX)\n", Status); + return Status; + } + + /* Check if chosen operating system should be saved */ + if(Configuration::GetBooleanValue(L"KEEPLASTBOOT")) + { + /* Save chosen operating system in NVRAM */ + Status = EfiUtils::SetEfiVariable(&VendorGuid, L"XtLdrLastBootOS", (PVOID)ShortName, RTL::WideString::WideStringLength(ShortName, 0) * sizeof(WCHAR)); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to save chosen Operating System */ + Debug::Print(L"WARNING: Failed to save chosen Operating System in NVRAM (Status Code: 0x%zX)\n", Status); + } + } + + /* Boot Operating System */ + return BootProtocol->BootSystem(&BootParameters); +} + +/** + * Loads a specified XTLDR module from disk. + * + * @param ModuleName + * Specifies the name of the module to load. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +Protocol::LoadModule(IN PWCHAR ModuleName) +{ + EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; + PLIST_ENTRY DepsListEntry, ModuleListEntry; + EFI_MEMMAP_DEVICE_PATH ModuleDevicePath[2]; + PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; + PEFI_FILE_HANDLE DirHandle, FsHandle; + EFI_HANDLE DiskHandle, ModuleHandle; + PPECOFF_IMAGE_SECTION_HEADER SectionHeader; + PPECOFF_IMAGE_DOS_HEADER DosHeader; + PPECOFF_IMAGE_PE_HEADER PeHeader; + PXTBL_MODULE_DEPS ModuleDependency; + PXTBL_MODULE_INFO ModuleInfo; + WCHAR ModuleFileName[24]; + USHORT SectionIndex; + PWCHAR SectionData; + SIZE_T ModuleSize; + EFI_STATUS Status; + PVOID ModuleData; + + ModuleListEntry = LoadedModules.Flink; + while(ModuleListEntry != &LoadedModules) + { + /* Get module information */ + ModuleInfo = CONTAIN_RECORD(ModuleListEntry, XTBL_MODULE_INFO, Flink); + + if(RTL::WideString::CompareWideStringInsensitive(ModuleInfo->ModuleName, ModuleName, 0) == 0) + { + /* Module already loaded */ + Debug::Print(L"WARNING: Module '%S' already loaded!\n", ModuleName); + return STATUS_EFI_SUCCESS; + } + + /* Move to next module */ + ModuleListEntry = ModuleListEntry->Flink; + } + + /* Print debug message */ + Debug::Print(L"Loading module '%S' ...\n", ModuleName); + + /* Set module path */ + RTL::Memory::CopyMemory(ModuleFileName, ModuleName, (RTL::WideString::WideStringLength(ModuleName, 0) + 1) * sizeof(WCHAR)); + RTL::WideString::ConcatenateWideString(ModuleFileName, (PWCHAR)L".EFI", 0); + + /* Open EFI volume */ + Status = Volume::OpenVolume(NULLPTR, &DiskHandle, &FsHandle); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open a volume */ + return Status; + } + + /* Open XTLDR modules common directory */ + Status = FsHandle->Open(FsHandle, &DirHandle, (PWCHAR)XTBL_MODULES_DIRECTORY_PATH, EFI_FILE_MODE_READ, 0); + if(Status != STATUS_EFI_SUCCESS) + { + /* Modules directory not found, attempt to open XTLDR architecture specific modules directory */ + Status = FsHandle->Open(FsHandle, &DirHandle, (PWCHAR)XTBL_ARCH_MODULES_DIRECTORY_PATH, EFI_FILE_MODE_READ, 0); + } + + /* Close FS handle */ + FsHandle->Close(FsHandle); + + /* Check if modules directory opened successfully */ + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open directory */ + Volume::CloseVolume(&DiskHandle); + return Status; + } + + /* Read module file from disk and close directory and EFI volume */ + Status = Volume::ReadFile(DirHandle, ModuleFileName, &ModuleData, &ModuleSize); + DirHandle->Close(DirHandle); + Volume::CloseVolume(&DiskHandle); + + /* Make sure module file was read successfully */ + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to read file */ + return Status; + } + + /* Allocate memory for module information block */ + Status = Memory::AllocatePool(sizeof(XTBL_MODULE_INFO), (PVOID*)&ModuleInfo); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to allocate memory */ + return Status; + } + + /* Zero module information block */ + RTL::Memory::ZeroMemory(ModuleInfo, sizeof(XTBL_MODULE_INFO)); + + /* Setup PE/COFF EFI image headers */ + DosHeader = (PPECOFF_IMAGE_DOS_HEADER)ModuleData; + PeHeader = (PPECOFF_IMAGE_PE_HEADER)((PUCHAR)ModuleData + DosHeader->PeHeaderOffset); + + /* Check PE/COFF image type*/ + if(PeHeader->OptionalHeader32.Magic == PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC) + { + /* Get PE32+ (64-bit) image section headers */ + SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&PeHeader->OptionalHeader64 + + PeHeader->FileHeader.SizeOfOptionalHeader); + } + else + { + /* Get PE32 (32-bit) image section headers */ + SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&PeHeader->OptionalHeader32 + + PeHeader->FileHeader.SizeOfOptionalHeader); + } + + /* Look for .modinfo section */ + for(SectionIndex = 0; SectionIndex < PeHeader->FileHeader.NumberOfSections; SectionIndex++) + { + if(RTL::String::CompareString((PCHAR)SectionHeader[SectionIndex].Name, ".modinfo", 8) == 0) + { + /* Module information section found */ + SectionData = (PWCHAR)((PUCHAR)ModuleData + SectionHeader[SectionIndex].PointerToRawData); + + /* Get module information */ + Status = GetModuleInformation(SectionData, SectionHeader[SectionIndex].SizeOfRawData, ModuleInfo); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to read module information */ + return Status; + } + } + } + + /* Iterate through module dependencies */ + DepsListEntry = ModuleInfo->Dependencies.Flink; + while(DepsListEntry != &ModuleInfo->Dependencies) + { + /* Get module dependency information */ + ModuleDependency = CONTAIN_RECORD(DepsListEntry, XTBL_MODULE_DEPS, Flink); + + /* Make sure dependency list contains a valid module name */ + if(ModuleDependency->ModuleName == NULLPTR || ModuleDependency->ModuleName[0] == L'\0') + { + /* Invalid module name found, just skip this step */ + break; + } + + /* Load dependency module */ + Debug::Print(L"Module '%S' requires '%S' ...\n", ModuleName, ModuleDependency->ModuleName); + Status = LoadModule(ModuleDependency->ModuleName); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to load module, print error message and return status code */ + Debug::Print(L"Failed to load dependency module '%S' (Status Code: 0x%zX)\n", ModuleDependency->ModuleName, Status); + return STATUS_EFI_UNSUPPORTED; + } + + /* Move to the next dependency */ + DepsListEntry = DepsListEntry->Flink; + } + + /* Setup module device path */ + ModuleDevicePath[0].Header.Length[0] = sizeof(EFI_MEMMAP_DEVICE_PATH); + ModuleDevicePath[0].Header.Length[1] = sizeof(EFI_MEMMAP_DEVICE_PATH) >> 8; + ModuleDevicePath[0].Header.Type = EFI_HARDWARE_DEVICE_PATH; + ModuleDevicePath[0].Header.SubType = EFI_HARDWARE_MEMMAP_DP; + ModuleDevicePath[0].MemoryType = EfiLoaderData; + ModuleDevicePath[0].StartingAddress = (UINT_PTR)ModuleData; + ModuleDevicePath[0].EndingAddress = (UINT_PTR)ModuleData + ModuleSize; + ModuleDevicePath[1].Header.Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL); + ModuleDevicePath[1].Header.Length[1] = sizeof(EFI_DEVICE_PATH_PROTOCOL) >> 8; + ModuleDevicePath[1].Header.Type = EFI_END_DEVICE_PATH; + ModuleDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP; + + /* Load EFI image */ + Debug::Print(L"Starting module '%S' ...\n", ModuleName); + Status = EfiUtils::LoadEfiImage((PEFI_DEVICE_PATH_PROTOCOL)ModuleDevicePath, ModuleData, ModuleSize, &ModuleHandle); + if(Status != STATUS_EFI_SUCCESS) + { + /* Check if caused by secure boot */ + if(Status == STATUS_EFI_ACCESS_DENIED && XtLoader::GetSecureBootStatus() >= 1) + { + /* SecureBoot signature validation failed */ + Debug::Print(L"ERROR: SecureBoot signature validation failed, module '%S' will not be loaded\n", ModuleName); + } + else + { + /* Failed to load module */ + Debug::Print(L"ERROR: Unable to load module '%S' (Status Code: 0x%zX)\n", ModuleName, Status); + } + + /* Return error status code */ + return Status; + } + + /* Access module interface for further module type check */ + Status = XtLoader::GetEfiSystemTable()->BootServices->OpenProtocol(ModuleHandle, &LIPGuid, (PVOID *)&LoadedImage, + XtLoader::GetEfiImageHandle(), NULLPTR, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to open LoadedImage protocol */ + Debug::Print(L"ERROR: Unable to access module interface (Status Code: 0x%zX)\n", Status); + return Status; + } + + /* Some firmwares do not allow to start drivers which are not of 'boot system driver' type, so check it */ + if(LoadedImage->ImageCodeType != EfiBootServicesCode) + { + /* Different type set, probably 'runtime driver', refuse to load it */ + Debug::Print(L"ERROR: Loaded module is not a boot system driver\n"); + + /* Close protocol and skip module */ + XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULLPTR); + } + + /* Save additional module information, not found in '.modinfo' section */ + ModuleInfo->ModuleName = ModuleName; + ModuleInfo->ModuleBase = LoadedImage->ImageBase; + ModuleInfo->ModuleSize = LoadedImage->ImageSize; + ModuleInfo->Revision = LoadedImage->Revision; + ModuleInfo->UnloadModule = LoadedImage->Unload; + + /* Close loaded image protocol */ + XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULLPTR); + + /* Start EFI image */ + Status = EfiUtils::StartEfiImage(ModuleHandle); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to start module image */ + Debug::Print(L"ERROR: Failed to start module '%S' (Status Code: 0x%zX)\n", ModuleName, Status); + return Status; + } + + /* Add module to the list of loaded modules */ + RTL::LinkedList::InsertTailList(&LoadedModules, &ModuleInfo->Flink); + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Helper routine to load all modules supplied in the configuration file. + * + * @param ModulesList + * Supplies a space separated list of XTLDR modules to load (mostly read from configuration file). + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +Protocol::LoadModules(IN PWCHAR ModulesList) +{ + PWCHAR LastModule, Module; + EFI_STATUS ReturnStatus, Status; + + /* Set default return value */ + ReturnStatus = STATUS_EFI_SUCCESS; + + if(ModulesList != NULLPTR) + { + /* Tokenize provided list of modules */ + Module = RTL::WideString::TokenizeWideString(ModulesList, L" ", &LastModule); + + /* Iterate over all arguments passed to boot loader */ + while(Module != NULLPTR) + { + Status = LoadModule(Module); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to load module, print error message and set new return value */ + Debug::Print(L"ERROR: Failed to load module '%S' (Status Code: 0x%zX)\n", Module, Status); + ReturnStatus = STATUS_EFI_LOAD_ERROR; + } + + /* Take next module from the list */ + Module = RTL::WideString::TokenizeWideString(NULLPTR, L" ", &LastModule); + } + } + + /* Return success */ + return ReturnStatus; +} + +/** + * Returns an array of handles that support the requested protocol. + * + * @param Handles + * Supplies the address where a pointer to all handles found for the protocol interface. + * + * @param Count + * Provides a number of the returned handles. + * + * @param ProtocolGuid + * Supplies a pointer to the unique protocol GUID. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +Protocol::LocateProtocolHandles(OUT PEFI_HANDLE *Handles, + OUT PUINT_PTR Count, + IN PEFI_GUID ProtocolGuid) +{ + return XtLoader::GetEfiSystemTable()->BootServices->LocateHandleBuffer(ByProtocol, ProtocolGuid, NULLPTR, + Count, Handles); +} + +/** + * Locates and opens the requested XT Boot Loader or EFI protocol. + * + * @param Handle + * Supplies the address where a pointer to the handle for the protocol interface. + * + * @param ProtocolHandler + * Supplies the address where a pointer to the opened protocol is returned. + * + * @param ProtocolGuid + * Supplies a pointer to the unique protocol GUID. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +Protocol::OpenProtocol(OUT PEFI_HANDLE Handle, + OUT PVOID *ProtocolHandler, + IN PEFI_GUID ProtocolGuid) +{ + PEFI_HANDLE Handles = NULLPTR; + EFI_STATUS Status; + UINT_PTR Count; + UINT Index; + + /* Try to locate the handles */ + Status = LocateProtocolHandles(&Handles, &Count, ProtocolGuid); + if(Status != STATUS_EFI_SUCCESS) + { + /* Unable to get handles */ + return Status; + } + + /* Check if any handles returned */ + if(Count > 0) + { + /* Iterate through all given handles */ + for(Index = 0; Index < Count; Index++) + { + /* Try to open protocol */ + Status = OpenProtocolHandle(Handles[Index], ProtocolHandler, ProtocolGuid); + + /* Check if successfully opened the loader protocol */ + if(Status == STATUS_EFI_SUCCESS) + { + /* Protocol found and successfully opened */ + *Handle = Handles[Index]; + break; + } + } + } + + /* Free handles */ + XtLoader::GetEfiSystemTable()->BootServices->FreePool(Handles); + + /* Make sure the loaded protocol has been found */ + if(*ProtocolHandler == NULLPTR) + { + /* Protocol not found */ + return STATUS_EFI_NOT_FOUND; + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Opens the requested XT Boot Loader or EFI protocol, if it is supported by the handle. + * + * @param Handle + * Supplies a handle for the protocol interface that is being opened. + * + * @param ProtocolHandler + * Supplies the address where a pointer to the opened protocol is returned. + * + * @param ProtocolGuid + * Supplies a pointer to the unique protocol GUID. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +Protocol::OpenProtocolHandle(IN EFI_HANDLE Handle, + OUT PVOID *ProtocolHandler, + IN PEFI_GUID ProtocolGuid) +{ + return XtLoader::GetEfiSystemTable()->BootServices->OpenProtocol(Handle, ProtocolGuid, ProtocolHandler, + XtLoader::GetEfiImageHandle(), + NULLPTR, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); +} + +/** + * Registers a known boot protocol for a specified OS. + * + * @param SystemType + * Supplies the type of the OS, such as "LINUX", "XTOS", etc. that is supported by the boot protocol. + * + * @param BootProtocolGuid + * Supplies a pointer to the unique protocol GUID. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +Protocol::RegisterBootProtocol(IN PCWSTR SystemType, + IN PEFI_GUID BootProtocolGuid) +{ + PXTBL_KNOWN_BOOT_PROTOCOL ProtocolEntry; + PLIST_ENTRY ProtocolListEntry; + EFI_STATUS Status; + + ProtocolListEntry = BootProtocols.Flink; + while(ProtocolListEntry != &BootProtocols) + { + /* Get boot protocol entry */ + ProtocolEntry = CONTAIN_RECORD(ProtocolListEntry, XTBL_KNOWN_BOOT_PROTOCOL, Flink); + + /* Check if boot protocol already registered for specified system */ + if(RTL::WideString::CompareWideStringInsensitive(ProtocolEntry->SystemType, SystemType, 0) == 0) + { + /* Boot protocol already registered */ + return STATUS_EFI_ABORTED; + } + + /* Move to the next registered boot protocol */ + ProtocolListEntry = ProtocolListEntry->Flink; + } + + /* Create new boot protocol entry */ + Status = Memory::AllocatePool(sizeof(XTBL_BOOT_PROTOCOL), (PVOID *)&ProtocolEntry); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + return STATUS_EFI_OUT_OF_RESOURCES; + } + + /* Set protocol properties and add it to the list */ + ProtocolEntry->SystemType = (PWCHAR)SystemType; + ProtocolEntry->Guid = *BootProtocolGuid; + RTL::LinkedList::InsertTailList(&BootProtocols, &ProtocolEntry->Flink); + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Reads information from the '.modinfo' section and populates the module information structure. + * + * @param SectionData + * Supplies a pointer to the module's information section data. + * + * @param SectionSize + * Supplies an expected size of the section data. + * + * @param ModuleInfo + * Supplies a pointer to the module information structure that will be filled by data from module's info section. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +Protocol::GetModuleInformation(IN PWCHAR SectionData, + IN ULONG SectionSize, + OUT PXTBL_MODULE_INFO ModuleInfo) +{ + PXTBL_MODULE_DEPS ModuleDependencies; + PXTBL_MODULE_AUTHORS ModuleAuthors; + PWCHAR Dependency, Key, LastStr; + ULONG Index, Count; + EFI_STATUS Status; + PWCHAR *Strings; + + /* Initialize authors and dependencies lists */ + RTL::LinkedList::InitializeListHead(&ModuleInfo->Authors); + RTL::LinkedList::InitializeListHead(&ModuleInfo->Dependencies); + + /* Get information strings from '.modinfo' section */ + Status = GetModuleInfoStrings(SectionData, SectionSize, &Strings, &Count); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to get information strings */ + return Status; + } + + /* Parse information strings */ + for(Index = 0; Index < Count; Index++) + { + /* Store the key */ + Key = Strings[Index]; + + /* Find the end of the key and the beginning of the value */ + while(*Strings[Index] != L'=' && *Strings[Index] != L'\0' && *Strings[Index] != L'\n') + { + /* Move to the next character */ + Strings[Index]++; + } + + /* Make sure value is NULL-terminated */ + *Strings[Index] = L'\0'; + Strings[Index]++; + + /* Parse information string key */ + if(RTL::WideString::CompareWideString(Key, L"author", 6) == 0) + { + /* Allocate memory for module author */ + Status = Memory::AllocatePool(sizeof(XTBL_MODULE_AUTHORS), (PVOID*)&ModuleAuthors); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + return Status; + } + + /* Store module's author */ + ModuleAuthors->AuthorName = Strings[Index]; + RTL::LinkedList::InsertTailList(&ModuleInfo->Authors, &ModuleAuthors->Flink); + } + else if(RTL::WideString::CompareWideString(Key, L"description", 11) == 0) + { + /* Store module's description */ + ModuleInfo->ModuleDescription = Strings[Index]; + } + else if(RTL::WideString::CompareWideString(Key, L"license", 7) == 0) + { + /* Store module's license */ + ModuleInfo->License = Strings[Index]; + } + else if(RTL::WideString::CompareWideString(Key, L"softdeps", 6) == 0) + { + /* Tokenize value to get module's single dependency */ + Dependency = RTL::WideString::TokenizeWideString(Strings[Index], L" ", &LastStr); + while(Dependency != NULLPTR) + { + /* Allocate memory for module dependency */ + Status = Memory::AllocatePool(sizeof(XTBL_MODULE_DEPS), (PVOID*)&ModuleDependencies); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + return Status; + } + + /* Store module's dependency */ + ModuleDependencies->ModuleName = Dependency; + RTL::LinkedList::InsertTailList(&ModuleInfo->Dependencies, &ModuleDependencies->Flink); + + /* Get next dependency from single value if available */ + Dependency = RTL::WideString::TokenizeWideString(NULLPTR, L" ", &LastStr); + } + } + else if(RTL::WideString::CompareWideString(Key, L"version", 7) == 0) + { + /* Store module's version */ + ModuleInfo->Version = Strings[Index]; + } + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Reads raw data from the '.modinfo' section and populates an array of strings. + * + * @param SectionData + * Supplies a pointer to the module's information section data. + * + * @param SectionSize + * Supplies an expected size of the section data. + * + * @param ModInfo + * Supplies a pointer to memory area, where an array of strings read from the section will be stored. + * + * @param InfoCount + * Supplies a pointer to variable that will receive the number of strings found in the section. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +Protocol::GetModuleInfoStrings(IN PWCHAR SectionData, + IN ULONG SectionSize, + OUT PWCHAR **ModInfo, + OUT PULONG InfoCount) +{ + ULONG Count, Index, ArrayIndex; + PCWSTR InfoStrings; + EFI_STATUS Status; + PWCHAR *Array; + PWCHAR String; + ULONG DataSize; + + /* Check input parameters */ + InfoStrings = SectionData; + if(!InfoStrings || !SectionSize) + { + /* Invalid input parameters */ + *ModInfo = NULLPTR; + *InfoCount = 0; + return STATUS_EFI_INVALID_PARAMETER; + } + + /* Calculate the size of the data based on the size of the section */ + DataSize = SectionSize / sizeof(WCHAR); + + /* Skip zero padding at the beginning */ + while(DataSize > 0 && *InfoStrings == L'\0') + { + InfoStrings++; + DataSize--; + } + + /* Make sure there is at least one string available */ + if(DataSize < 1) + { + /* No strings found */ + *ModInfo = NULLPTR; + *InfoCount = 0; + return STATUS_EFI_END_OF_FILE; + } + + /* Count number of strings */ + Index = 0; + Count = 0; + while(Index < DataSize) + { + /* Found start of a new string */ + Count++; + + /* Go to the end of the string */ + while(Index < DataSize && InfoStrings[Index] != L'\0') + { + Index++; + } + /* Skip all NULL terminators */ + while(Index < DataSize && InfoStrings[Index] == L'\0') + { + Index++; + } + } + + /* Allocate memory for the pointer array and the string data */ + Status = Memory::AllocatePool(sizeof(PWCHAR) * (Count + 1) + (DataSize + 1) * sizeof(WCHAR), (PVOID *)&Array); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to allocate memory */ + return STATUS_EFI_OUT_OF_RESOURCES; + } + + /* The string buffer is located right after the pointer array */ + String = (PWCHAR)(Array + Count + 1); + + /* Copy the raw string data */ + RTL::Memory::CopyMemory(String, InfoStrings, DataSize * sizeof(WCHAR)); + + /* Ensure the entire buffer is NULL-terminated for safety */ + String[DataSize] = L'\0'; + + /* Set the last element of the pointer array to NULLPTR */ + Array[Count] = NULLPTR; + + /* Populate the array with pointers to the strings within the buffer */ + Index = 0; + ArrayIndex = 0; + while(Index < DataSize && ArrayIndex < Count) + { + /* Set pointer to the beginning of the string */ + Array[ArrayIndex++] = &String[Index]; + + /* Find the end of the current string */ + while(Index < DataSize && String[Index] != L'\0') + { + Index++; + } + + /* Skip all NULL terminators to find the beginning of the next string */ + while(Index < DataSize && String[Index] == L'\0') + { + Index++; + } + } + + /* Return array of strings and its size */ + *ModInfo = Array; + *InfoCount = Count; + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * This routine installs XTLDR protocol for further usage by modules. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +Protocol::InstallXtLoaderProtocol() +{ + EFI_GUID Guid = XT_BOOT_LOADER_PROTOCOL_GUID; + + /* Set all routines available via loader protocol */ + LoaderProtocol.Boot.FindProtocol = FindBootProtocol; + LoaderProtocol.Boot.InitializeMenuList = Configuration::InitializeBootMenuList; + LoaderProtocol.Boot.InvokeProtocol = InvokeBootProtocol; + LoaderProtocol.Boot.RegisterMenu = XtLoader::RegisterBootMenu; + LoaderProtocol.Boot.RegisterProtocol = RegisterBootProtocol; + LoaderProtocol.BootUtils.GetBooleanParameter = BootUtils::GetBooleanParameter; + LoaderProtocol.BootUtils.GetTrampolineInformation = AR::ProcSup::GetTrampolineInformation; + LoaderProtocol.Config.GetBooleanValue = Configuration::GetBooleanValue; + LoaderProtocol.Config.GetBootOptionValue = Configuration::GetBootOptionValue; + LoaderProtocol.Config.GetEditableOptions = Configuration::GetEditableOptions; + LoaderProtocol.Config.GetValue = Configuration::GetValue; + LoaderProtocol.Config.SetBootOptionValue = Configuration::SetBootOptionValue; + LoaderProtocol.Console.ClearLine = Console::ClearLine; + LoaderProtocol.Console.ClearScreen = Console::ClearScreen; + LoaderProtocol.Console.DisableCursor = Console::DisableCursor; + LoaderProtocol.Console.EnableCursor = Console::EnableCursor; + LoaderProtocol.Console.Print = Console::Print; + LoaderProtocol.Console.QueryMode = Console::QueryMode; + LoaderProtocol.Console.ReadKeyStroke = Console::ReadKeyStroke; + LoaderProtocol.Console.ResetInputBuffer = Console::ResetInputBuffer; + LoaderProtocol.Console.SetAttributes = Console::SetAttributes; + LoaderProtocol.Console.SetCursorPosition = Console::SetCursorPosition; + LoaderProtocol.Console.Write = Console::Write; + LoaderProtocol.Cpu.CpuId = AR::CpuFunc::CpuId; + LoaderProtocol.Cpu.ReadControlRegister = AR::CpuFunc::ReadControlRegister; + LoaderProtocol.Cpu.ReadModelSpecificRegister = AR::CpuFunc::ReadModelSpecificRegister; + LoaderProtocol.Cpu.WriteControlRegister = AR::CpuFunc::WriteControlRegister; + LoaderProtocol.Debug.Print = Debug::Print; + LoaderProtocol.Disk.CloseVolume = Volume::CloseVolume; + LoaderProtocol.Disk.OpenVolume = Volume::OpenVolume; + LoaderProtocol.Disk.ReadFile = Volume::ReadFile; + LoaderProtocol.IoPort.Read8 = HL::IoPort::ReadPort8; + LoaderProtocol.IoPort.Read16 = HL::IoPort::ReadPort16; + LoaderProtocol.IoPort.Read32 = HL::IoPort::ReadPort32; + LoaderProtocol.IoPort.Write8 = HL::IoPort::WritePort8; + LoaderProtocol.IoPort.Write16 = HL::IoPort::WritePort16; + LoaderProtocol.IoPort.Write32 = HL::IoPort::WritePort32; + LoaderProtocol.LinkedList.InitializeHead = RTL::LinkedList::InitializeListHead; + LoaderProtocol.LinkedList.InsertHead = RTL::LinkedList::InsertHeadList; + LoaderProtocol.LinkedList.InsertTail = RTL::LinkedList::InsertTailList; + LoaderProtocol.LinkedList.RemoveEntry = RTL::LinkedList::RemoveEntryList; + LoaderProtocol.Memory.AllocatePages = Memory::AllocatePages; + LoaderProtocol.Memory.AllocatePool = Memory::AllocatePool; + LoaderProtocol.Memory.BuildPageMap = Memory::BuildPageMap; + LoaderProtocol.Memory.CompareMemory = RTL::Memory::CompareMemory; + LoaderProtocol.Memory.CopyMemory = RTL::Memory::CopyMemory; + LoaderProtocol.Memory.FreePages = Memory::FreePages; + LoaderProtocol.Memory.FreePool = Memory::FreePool; + LoaderProtocol.Memory.GetMappingsCount = Memory::GetMappingsCount; + LoaderProtocol.Memory.GetMemoryMap = Memory::GetMemoryMap; + LoaderProtocol.Memory.GetVirtualAddress = Memory::GetVirtualAddress; + LoaderProtocol.Memory.InitializePageMap = Memory::InitializePageMap; + LoaderProtocol.Memory.MapEfiMemory = Memory::MapEfiMemory; + LoaderProtocol.Memory.MapPage = Memory::MapPage; + LoaderProtocol.Memory.MapVirtualMemory = Memory::MapVirtualMemory; + LoaderProtocol.Memory.MoveMemory = RTL::Memory::MoveMemory; + LoaderProtocol.Memory.PhysicalAddressToVirtual = Memory::PhysicalAddressToVirtual; + LoaderProtocol.Memory.PhysicalListToVirtual = Memory::PhysicalListToVirtual; + LoaderProtocol.Memory.SetMemory = RTL::Memory::SetMemory; + LoaderProtocol.Memory.ZeroMemory = RTL::Memory::ZeroMemory; + LoaderProtocol.Protocol.Close = CloseProtocol; + LoaderProtocol.Protocol.GetModulesList = GetModulesList; + LoaderProtocol.Protocol.Install = InstallProtocol; + LoaderProtocol.Protocol.LocateHandles = LocateProtocolHandles; + LoaderProtocol.Protocol.Open = OpenProtocol; + LoaderProtocol.Protocol.OpenHandle = OpenProtocolHandle; + LoaderProtocol.String.Compare = RTL::String::CompareString; + LoaderProtocol.String.Length = RTL::String::StringLength; + LoaderProtocol.String.ToWideString = RTL::String::StringToWideString; + LoaderProtocol.String.Trim = RTL::String::TrimString; + LoaderProtocol.Tui.DisplayErrorDialog = TextUi::DisplayErrorDialog; + LoaderProtocol.Tui.DisplayInfoDialog = TextUi::DisplayInfoDialog; + LoaderProtocol.Tui.DisplayInputDialog = TextUi::DisplayInputDialog; + LoaderProtocol.Tui.DisplayProgressDialog = TextUi::DisplayProgressDialog; + LoaderProtocol.Tui.UpdateProgressBar = TextUi::UpdateProgressBar; + LoaderProtocol.Utils.EnterFirmwareSetup = EfiUtils::EnterFirmwareSetup; + LoaderProtocol.Utils.ExitBootServices = EfiUtils::ExitBootServices; + LoaderProtocol.Utils.GetConfigurationTable = EfiUtils::GetConfigurationTable; + LoaderProtocol.Utils.GetEfiVariable = EfiUtils::GetEfiVariable; + LoaderProtocol.Utils.GetRandomValue = EfiUtils::GetRandomValue; + LoaderProtocol.Utils.GetSecureBootStatus = EfiUtils::GetSecureBootStatus; + LoaderProtocol.Utils.InitializeEntropy = EfiUtils::InitializeEntropy; + LoaderProtocol.Utils.LoadEfiImage = EfiUtils::LoadEfiImage; + LoaderProtocol.Utils.RebootSystem = EfiUtils::RebootSystem; + LoaderProtocol.Utils.SetEfiVariable = EfiUtils::SetEfiVariable; + LoaderProtocol.Utils.ShutdownSystem = EfiUtils::ShutdownSystem; + LoaderProtocol.Utils.SleepExecution = EfiUtils::SleepExecution; + LoaderProtocol.Utils.StartEfiImage = EfiUtils::StartEfiImage; + LoaderProtocol.Utils.WaitForEfiEvent = EfiUtils::WaitForEfiEvent; + LoaderProtocol.WideString.Compare = RTL::WideString::CompareWideString; + LoaderProtocol.WideString.CompareInsensitive = RTL::WideString::CompareWideStringInsensitive; + LoaderProtocol.WideString.Concatenate = RTL::WideString::ConcatenateWideString; + LoaderProtocol.WideString.Format = RTL::WideString::FormatWideString; + LoaderProtocol.WideString.Length = RTL::WideString::WideStringLength; + LoaderProtocol.WideString.Tokenize = RTL::WideString::TokenizeWideString; + + /* Register XTLDR loader protocol */ + Debug::Print(L"Registering XT loader protocol\n"); + return InstallProtocol(&LoaderProtocol, &Guid); +} diff --git a/xtldr/shell.c b/xtldr/shell.cc similarity index 67% rename from xtldr/shell.c rename to xtldr/shell.cc index bd1d159..1e9c6cd 100644 --- a/xtldr/shell.c +++ b/xtldr/shell.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/shell.c + * FILE: xtldr/shell.cc * DESCRIPTION: XT Boot Loader shell * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -18,13 +18,13 @@ */ XTCDECL VOID -BlStartLoaderShell() +Shell::StartLoaderShell() { /* Initialize console */ - BlInitializeConsole(); + Console::InitializeConsole(); /* Print prompt */ - BlpPrintShellPrompt(); + PrintPrompt(); for(;;); } @@ -37,14 +37,14 @@ BlStartLoaderShell() */ XTCDECL VOID -BlpPrintShellPrompt() +Shell::PrintPrompt() { /* Set prompt color */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_YELLOW); + Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_YELLOW); /* Print prompt */ - BlConsolePrint(L"XTLDR> "); + Console::Print(L"XTLDR> "); /* Reset standard shell colors */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); } diff --git a/xtldr/textui.c b/xtldr/textui.cc similarity index 70% rename from xtldr/textui.c rename to xtldr/textui.cc index eb77811..577ee6d 100644 --- a/xtldr/textui.c +++ b/xtldr/textui.cc @@ -1,15 +1,135 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/textui.c + * FILE: xtldr/textui.cc * DESCRIPTION: Text console User Interface (TUI) support for XT Boot Loader * DEVELOPERS: Rafal Kupiec * Aiken Harris */ -#include +#include +/** + * Determines dialog box size based on enabled components and message length. + * + * @param Handle + * Supplies a pointer to the dialog box handle. + * + * @param Message + * Supplies a pointer to the message string put on the dialog box. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +TextUi::DetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle, + IN PCWSTR Message) +{ + UINT_PTR Width, Height, LineLength; + SIZE_T Index, MessageLength; + UCHAR Attributes; + ULONG Mask; + + /* Set minimum dialog window size */ + Height = 4; + Width = 36; + + /* Zero line length */ + LineLength = 0; + + /* Adjust window height according to enabled components */ + Mask = 1; + Attributes = Handle->Attributes; + while(Mask) + { + /* Check enabled components that affect dialog window size */ + switch(Attributes & Mask) + { + case XTBL_TUI_DIALOG_ACTIVE_BUTTON: + case XTBL_TUI_DIALOG_INACTIVE_BUTTON: + Height += 1; + break; + case XTBL_TUI_DIALOG_ACTIVE_INPUT: + case XTBL_TUI_DIALOG_INACTIVE_INPUT: + case XTBL_TUI_DIALOG_PROGRESS_BAR: + Height += 2; + break; + } + + /* Update component attributes mask */ + Attributes &= ~Mask; + Mask <<= 1; + } + + /* Check if input field is active */ + if(Handle->Attributes & (XTBL_TUI_DIALOG_ACTIVE_INPUT | XTBL_TUI_DIALOG_INACTIVE_INPUT)) + { + /* Set maximum dialog window width to fit input field */ + Width = XTBL_TUI_MAX_DIALOG_WIDTH; + } + + /* Get message length and count dialog window dimensions */ + MessageLength = RTL::WideString::WideStringLength(Message, 0); + for(Index = 0; Index < MessageLength; Index++) + { + /* Check if this is multiline message */ + if(Message[Index] == L'\n' || Index == MessageLength - 1) + { + /* Check if this line exceeds current dialog window width */ + if(LineLength > Width) + { + /* Update dialog window width */ + Width = LineLength; + } + + /* Increase dialog window height to fit next line */ + Height++; + LineLength = 0; + } + else + { + /* Increase dialog window width to fit next character */ + LineLength++; + } + } + + /* Add more space to dialog window to fit side borders */ + Width += 4; + + /* Get console resolution */ + Console::QueryMode(&Handle->ResX, &Handle->ResY); + + /* Make sure dialog window fits in the buffer */ + if(Width > XTBL_TUI_MAX_DIALOG_WIDTH) + { + /* Set maximum dialog window width */ + Width = XTBL_TUI_MAX_DIALOG_WIDTH; + } + + /* Make sure dialog window fits on the screen (X axis) and it is not too small for input field */ + if(Width > (Handle->ResX - 2)) + { + /* Set maximum dialog window width */ + Width = Handle->ResX - 2; + } + + /* Make sure dialog window fits on the screen (Y axis)*/ + if(Height > (Handle->ResY - 2)) + { + /* Set maximum dialog window height */ + Height = Handle->ResY - 2; + } + + /* Set dialog window final dimensions */ + Handle->PosX = (Handle->ResX - Width) / 2; + Handle->PosY = (Handle->ResY - Height) / 2; + Handle->Width = Width; + Handle->Height = Height; +} + /** * Displays a simple TUI-based boot menu. * @@ -19,10 +139,10 @@ */ XTCDECL VOID -BlDisplayBootMenu() +TextUi::DisplayBootMenu() { XTBL_DIALOG_HANDLE Handle; - PXTBL_BOOTMENU_ITEM MenuEntries = NULL; + PXTBL_BOOTMENU_ITEM MenuEntries = NULLPTR; ULONG Index; ULONG HighligtedEntryId, OldHighligtedEntryId, NumberOfEntries, TopVisibleEntry, VisibleEntries; BOOLEAN RedrawBootMenu, RedrawEntries; @@ -35,11 +155,11 @@ BlDisplayBootMenu() PWCHAR TimeOutString; /* Draw boot menu */ - BlpDrawBootMenu(&Handle); + DrawBootMenu(&Handle); /* Initialize boot menu list */ TopVisibleEntry = 0; - Status = BlInitializeBootMenuList(Handle.Width - 4, &MenuEntries, &NumberOfEntries, &HighligtedEntryId); + Status = Configuration::InitializeBootMenuList(Handle.Width - 4, &MenuEntries, &NumberOfEntries, &HighligtedEntryId); if(Status != STATUS_EFI_SUCCESS) { /* Failed to initialize boot menu list, exit into XTLDR shell */ @@ -57,11 +177,11 @@ BlDisplayBootMenu() } /* Get timeout from the configuration */ - BlGetConfigValue(L"TIMEOUT", &TimeOutString); + Configuration::GetValue(L"TIMEOUT", &TimeOutString); TimeOut = -1; /* Check if timeout is specified */ - if(TimeOutString != NULL) + if(TimeOutString != NULLPTR) { /* Convert timeout string to number */ TimeOut = 0; @@ -83,7 +203,7 @@ BlDisplayBootMenu() /* Redraw boot menu frame if requested */ if(RedrawBootMenu) { - BlpDrawBootMenu(&Handle); + DrawBootMenu(&Handle); RedrawBootMenu = FALSE; RedrawEntries = TRUE; } @@ -104,8 +224,8 @@ BlDisplayBootMenu() for(Index = 0; Index < VisibleEntries; Index++) { /* Draw menu entry */ - BlpDrawBootMenuEntry(&Handle, MenuEntries[TopVisibleEntry + Index].EntryName, - Index, (TopVisibleEntry + Index) == HighligtedEntryId); + DrawBootMenuEntry(&Handle, MenuEntries[TopVisibleEntry + Index].EntryName, + Index, (BOOLEAN)((TopVisibleEntry + Index) == HighligtedEntryId)); } /* Clear redraw entries flag */ @@ -115,18 +235,19 @@ BlDisplayBootMenu() else { /* No menu entries found, show error message */ - BlDisplayErrorDialog(L"XTLDR", L"No boot menu entries found in the configuration. Falling back to shell."); + DisplayErrorDialog(L"XTLDR", L"No boot menu entries found in the configuration. Falling back to shell."); /* Exit into XTLDR shell */ return; } /* Create a timer event for controlling the timeout of the boot menu */ - Status = EfiSystemTable->BootServices->CreateEvent(EFI_EVENT_TIMER, EFI_TPL_CALLBACK, NULL, NULL, &TimerEvent); + Status = XtLoader::GetEfiSystemTable()->BootServices->CreateEvent(EFI_EVENT_TIMER, EFI_TPL_CALLBACK, + NULLPTR, NULLPTR, &TimerEvent); if(Status == STATUS_EFI_SUCCESS) { /* Setup new EFI timer */ - Status = EfiSystemTable->BootServices->SetTimer(TimerEvent, TimerPeriodic, 10000000); + Status = XtLoader::GetEfiSystemTable()->BootServices->SetTimer(TimerEvent, TimerPeriodic, 10000000); } /* Check is EFI timer was successfully created */ @@ -137,11 +258,11 @@ BlDisplayBootMenu() } /* Initialize EFI events */ - Events[0] = EfiSystemTable->ConIn->WaitForKey; + Events[0] = XtLoader::GetEfiSystemTable()->ConIn->WaitForKey; Events[1] = TimerEvent; /* Flush keyboard buffer out of any keystrokes */ - EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, FALSE); + XtLoader::GetEfiSystemTable()->ConIn->Reset(XtLoader::GetEfiSystemTable()->ConIn, FALSE); /* Store old highlighted entry */ OldHighligtedEntryId = HighligtedEntryId; @@ -150,7 +271,7 @@ BlDisplayBootMenu() while(TRUE) { /* Wait for EFI event */ - BlWaitForEfiEvent(2, Events, &EventIndex); + EfiUtils::WaitForEfiEvent(2, Events, &EventIndex); /* Check which event was received */ if(EventIndex == 0) @@ -162,32 +283,32 @@ BlDisplayBootMenu() TimeOut = -1; /* Cancel timer event */ - EfiSystemTable->BootServices->SetTimer(TimerEvent, TimerCancel, 0); + XtLoader::GetEfiSystemTable()->BootServices->SetTimer(TimerEvent, TimerCancel, 0); /* Remove the timer message */ - BlClearConsoleLine(Handle.PosY + Handle.Height + 4); + Console::ClearLine(Handle.PosY + Handle.Height + 4); } /* Read key stroke */ - BlReadKeyStroke(&Key); + Console::ReadKeyStroke(&Key); if(Key.ScanCode == 0x03 || Key.UnicodeChar == 0x0D) { /* ENTER or RightArrow key pressed, boot the highlighted OS */ - BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor); - BlClearConsoleLine(Handle.PosY + Handle.Height + 4); - BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); - BlConsolePrint(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].FullName); + Console::SetAttributes(Handle.DialogColor | Handle.TextColor); + Console::ClearLine(Handle.PosY + Handle.Height + 4); + Console::SetCursorPosition(4, Handle.PosY + Handle.Height + 4); + Console::Print(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].FullName); /* Boot the highlighted (chosen) OS */ - Status = BlInvokeBootProtocol(MenuEntries[HighligtedEntryId].ShortName, - MenuEntries[HighligtedEntryId].Options); + Status = Protocol::InvokeBootProtocol(MenuEntries[HighligtedEntryId].ShortName, + MenuEntries[HighligtedEntryId].Options); if(Status != STATUS_SUCCESS) { /* Failed to boot OS */ - BlDebugPrint(L"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\n", + Debug::Print(L"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\n", MenuEntries[HighligtedEntryId].FullName, Status); - BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); + DisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); RedrawBootMenu = TRUE; } @@ -213,10 +334,10 @@ BlDisplayBootMenu() } /* Redraw new highlighted entry and the old one */ - BlpDrawBootMenuEntry(&Handle, MenuEntries[OldHighligtedEntryId].EntryName, - OldHighligtedEntryId - TopVisibleEntry, FALSE); - BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, - HighligtedEntryId - TopVisibleEntry, TRUE); + DrawBootMenuEntry(&Handle, MenuEntries[OldHighligtedEntryId].EntryName, + OldHighligtedEntryId - TopVisibleEntry, (BOOLEAN)FALSE); + DrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, + HighligtedEntryId - TopVisibleEntry, (BOOLEAN)TRUE); } } else if(Key.ScanCode == 0x02) @@ -238,10 +359,10 @@ BlDisplayBootMenu() } /* Redraw new highlighted entry and the old one */ - BlpDrawBootMenuEntry(&Handle, MenuEntries[OldHighligtedEntryId].EntryName, - OldHighligtedEntryId - TopVisibleEntry, FALSE); - BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, - HighligtedEntryId - TopVisibleEntry, TRUE); + DrawBootMenuEntry(&Handle, MenuEntries[OldHighligtedEntryId].EntryName, + OldHighligtedEntryId - TopVisibleEntry, (BOOLEAN)FALSE); + DrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, + HighligtedEntryId - TopVisibleEntry, (BOOLEAN)TRUE); } } else if(Key.ScanCode == 0x09) @@ -271,21 +392,21 @@ BlDisplayBootMenu() else if(Key.ScanCode == 0x0B) { /* F1 key pressed, show help */ - BlDisplayInfoDialog(L"XTLDR", L"XTLDR, the XTOS Boot Loader for UEFI and EFI-based machines.\n" - L" \n" - L"Use arrow keys (Up/Down) to change the highlighted entry and\n" - L"PgUp/PgDown keys to jump to the first/last position.\n" - L" \n" - L"Press ENTER key to boot the highlighted boot menu entry.\n" - L"Press 'e' key to edit the highlighted menu entry.\n" - L"Press 's' key to exit into XTLDR shell (enters advanced mode).\n" - L" \n" - L"F1 shows this help, F10 reboots into UEFI firmware interface,\n" - L"F11 reboots the machine and F12 turns it off.\n" - L" \n" - L" \n" - L"XTLDR is a part of the ExectOS Operating System.\n" - L"Visit https://exectos.eu.org/ for more information."); + DisplayInfoDialog(L"XTLDR", L"XTLDR, the XTOS Boot Loader for UEFI and EFI-based machines.\n" + L" \n" + L"Use arrow keys (Up/Down) to change the highlighted entry and\n" + L"PgUp/PgDown keys to jump to the first/last position.\n" + L" \n" + L"Press ENTER key to boot the highlighted boot menu entry.\n" + L"Press 'e' key to edit the highlighted menu entry.\n" + L"Press 's' key to exit into XTLDR shell (enters advanced mode).\n" + L" \n" + L"F1 shows this help, F10 reboots into UEFI firmware interface,\n" + L"F11 reboots the machine and F12 turns it off.\n" + L" \n" + L" \n" + L"XTLDR is a part of the ExectOS Operating System.\n" + L"Visit https://exectos.eu.org/ for more information."); /* Break from boot menu event loop to redraw whole boot menu */ RedrawBootMenu = TRUE; @@ -294,8 +415,8 @@ BlDisplayBootMenu() else if(Key.ScanCode == 0x14) { /* F10 key pressed, reboot into UEFI setup interface */ - BlEnterFirmwareSetup(); - BlDisplayErrorDialog(L"XTLDR", L"Reboot into firmware setup interface not supported!"); + EfiUtils::EnterFirmwareSetup(); + DisplayErrorDialog(L"XTLDR", L"Reboot into firmware setup interface not supported!"); RedrawBootMenu = TRUE; /* Break from boot menu event loop to redraw whole boot menu */ @@ -304,8 +425,8 @@ BlDisplayBootMenu() else if(Key.ScanCode == 0x15) { /* F11 key pressed, reboot the machine */ - BlRebootSystem(); - BlDisplayErrorDialog(L"XTLDR", L"Failed to reboot the machine!"); + EfiUtils::RebootSystem(); + DisplayErrorDialog(L"XTLDR", L"Failed to reboot the machine!"); RedrawBootMenu = TRUE; /* Break from boot menu event loop to redraw whole boot menu */ @@ -314,8 +435,8 @@ BlDisplayBootMenu() else if(Key.ScanCode == 0x16) { /* F12 key pressed, shutdown the machine */ - BlShutdownSystem(); - BlDisplayErrorDialog(L"XTLDR", L"Failed to shutdown the machine!"); + EfiUtils::ShutdownSystem(); + DisplayErrorDialog(L"XTLDR", L"Failed to shutdown the machine!"); RedrawBootMenu = TRUE; /* Break from boot menu event loop to redraw whole boot menu */ @@ -324,7 +445,7 @@ BlDisplayBootMenu() else if(Key.UnicodeChar == 0x65) { /* 'e' key pressed, edit the highlighted entry */ - BlDisplayEditMenu(&MenuEntries[HighligtedEntryId]); + DisplayEditMenu(&MenuEntries[HighligtedEntryId]); RedrawBootMenu = TRUE; /* Break from boot menu event loop to redraw whole boot menu */ @@ -342,32 +463,32 @@ BlDisplayBootMenu() if(TimeOut > 0) { /* Update a message and decrease timeout value */ - BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor); - BlClearConsoleLine(Handle.PosY + Handle.Height + 4); - BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); - BlConsolePrint(L"The highlighted position will be booted automatically in %ld seconds.", TimeOut); + Console::SetAttributes(Handle.DialogColor | Handle.TextColor); + Console::ClearLine(Handle.PosY + Handle.Height + 4); + Console::SetCursorPosition(4, Handle.PosY + Handle.Height + 4); + Console::Print(L"The highlighted position will be booted automatically in %ld seconds.", TimeOut); TimeOut--; } else if(TimeOut == 0) { /* Time out expired, update a message */ - BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor); - BlClearConsoleLine(Handle.PosY + Handle.Height + 4); - BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); - BlConsolePrint(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].FullName); + Console::SetAttributes(Handle.DialogColor | Handle.TextColor); + Console::ClearLine(Handle.PosY + Handle.Height + 4); + Console::SetCursorPosition(4, Handle.PosY + Handle.Height + 4); + Console::Print(L"Booting '%S' now...\n", MenuEntries[HighligtedEntryId].FullName); /* Disable the timer just in case booting OS fails */ TimeOut = -1; /* Boot the highlighted (default) OS */ - Status = BlInvokeBootProtocol(MenuEntries[HighligtedEntryId].ShortName, - MenuEntries[HighligtedEntryId].Options); + Status = Protocol::InvokeBootProtocol(MenuEntries[HighligtedEntryId].ShortName, + MenuEntries[HighligtedEntryId].Options); if(Status != STATUS_SUCCESS) { /* Failed to boot OS */ - BlDebugPrint(L"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\n", + Debug::Print(L"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\n", MenuEntries[HighligtedEntryId].FullName, Status); - BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); + DisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); RedrawBootMenu = TRUE; } break; @@ -386,22 +507,22 @@ BlDisplayBootMenu() */ XTCDECL VOID -BlDisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry) +TextUi::DisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry) { ULONG HighligtedOptionId, Index, NumberOfOptions, OldHighligtedOptionId, TopVisibleEntry, VisibleEntries; XTBL_DIALOG_HANDLE Handle; BOOLEAN RedrawEditMenu, RedrawEntries; EFI_INPUT_KEY Key; UINT_PTR EventIndex; - PWCHAR NewValue, OptionName, OriginalValue, Value, ValueToEdit; - CONST PWCHAR *EditableOptions; + PWCHAR NewValue, OriginalValue, Value, ValueToEdit; + PCWSTR OptionName, *EditableOptions; EFI_STATUS Status; /* Draw edit menu */ - BlpDrawEditMenu(&Handle); + DrawEditMenu(&Handle); /* Get the list of user editable options */ - BlGetEditableOptions(&EditableOptions, &NumberOfOptions); + Configuration::GetEditableOptions(&EditableOptions, &NumberOfOptions); /* Calculate how many entries can be visible in the menu box */ VisibleEntries = Handle.Height - 2; @@ -421,7 +542,7 @@ BlDisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry) /* Redraw edit menu frame if requested */ if(RedrawEditMenu) { - BlpDrawEditMenu(&Handle); + DrawEditMenu(&Handle); RedrawEditMenu = FALSE; RedrawEntries = TRUE; } @@ -439,14 +560,14 @@ BlDisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry) for(Index = 0; Index < VisibleEntries; Index++) { /* Draw menu entry */ - BlGetBootOptionValue(MenuEntry->Options, EditableOptions[TopVisibleEntry + Index], &Value); - BlpDrawEditMenuEntry(&Handle, EditableOptions[TopVisibleEntry + Index], Value, Index, - (TopVisibleEntry + Index) == HighligtedOptionId); + Configuration::GetBootOptionValue(MenuEntry->Options, EditableOptions[TopVisibleEntry + Index], &Value); + DrawEditMenuEntry(&Handle, EditableOptions[TopVisibleEntry + Index], Value, Index, + (BOOLEAN)((TopVisibleEntry + Index) == HighligtedOptionId)); /* Free allocated value string if needed */ - if(Value != NULL) + if(Value != NULLPTR) { - BlFreeMemoryPool(Value); + Memory::FreePool(Value); } } @@ -455,20 +576,20 @@ BlDisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry) } /* Wait for EFI event and read key stroke */ - BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &EventIndex); - BlReadKeyStroke(&Key); + EfiUtils::WaitForEfiEvent(1, &(XtLoader::GetEfiSystemTable()->ConIn->WaitForKey), &EventIndex); + Console::ReadKeyStroke(&Key); /* Check key press scan code */ if(Key.UnicodeChar == 0x0D || Key.UnicodeChar == 0x65) { /* ENTER or 'e' key pressed, edit the highlighted option */ OptionName = EditableOptions[HighligtedOptionId]; - BlGetBootOptionValue(MenuEntry->Options, OptionName, &OriginalValue); + Configuration::GetBootOptionValue(MenuEntry->Options, OptionName, &OriginalValue); - /* If the original value is NULL, use an empty string for editing */ - if(OriginalValue == NULL) + /* If the original value is NULLPTR, use an empty string for editing */ + if(OriginalValue == NULLPTR) { - ValueToEdit = L""; + ValueToEdit = (PWCHAR)L""; } else { @@ -477,20 +598,20 @@ BlDisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry) /* Display input dialog to edit the option value */ NewValue = ValueToEdit; - BlDisplayInputDialog(OptionName, L"Enter new value:", &NewValue); + DisplayInputDialog(OptionName, L"Enter new value:", &NewValue); /* Check if the value was changed */ if(NewValue != ValueToEdit) { /* Update the boot option with the new value and free the old value */ - BlSetBootOptionValue(MenuEntry->Options, OptionName, NewValue); - BlFreeMemoryPool(NewValue); + Configuration::SetBootOptionValue(MenuEntry->Options, OptionName, NewValue); + Memory::FreePool(NewValue); } /* Free the original value if it was allocated */ - if(OriginalValue != NULL) + if(OriginalValue != NULLPTR) { - BlFreeMemoryPool(OriginalValue); + Memory::FreePool(OriginalValue); } /* Mark the edit menu for redraw */ @@ -515,23 +636,23 @@ BlDisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry) } /* Redraw old highlighted entry */ - BlGetBootOptionValue(MenuEntry->Options, EditableOptions[OldHighligtedOptionId], &Value); - BlpDrawEditMenuEntry(&Handle, EditableOptions[OldHighligtedOptionId], Value, OldHighligtedOptionId - TopVisibleEntry, FALSE); + Configuration::GetBootOptionValue(MenuEntry->Options, EditableOptions[OldHighligtedOptionId], &Value); + DrawEditMenuEntry(&Handle, EditableOptions[OldHighligtedOptionId], Value, OldHighligtedOptionId - TopVisibleEntry, (BOOLEAN)FALSE); /* Free allocated value string if needed */ - if(Value != NULL) + if(Value != NULLPTR) { - BlFreeMemoryPool(Value); + Memory::FreePool(Value); } /* Redraw new highlighted entry */ - BlGetBootOptionValue(MenuEntry->Options, EditableOptions[HighligtedOptionId], &Value); - BlpDrawEditMenuEntry(&Handle, EditableOptions[HighligtedOptionId], Value, HighligtedOptionId - TopVisibleEntry, TRUE); + Configuration::GetBootOptionValue(MenuEntry->Options, EditableOptions[HighligtedOptionId], &Value); + DrawEditMenuEntry(&Handle, EditableOptions[HighligtedOptionId], Value, HighligtedOptionId - TopVisibleEntry, (BOOLEAN)TRUE); /* Free allocated value string if needed */ - if(Value != NULL) + if(Value != NULLPTR) { - BlFreeMemoryPool(Value); + Memory::FreePool(Value); } } } @@ -554,23 +675,23 @@ BlDisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry) } /* Redraw old highlighted entry */ - BlGetBootOptionValue(MenuEntry->Options, EditableOptions[OldHighligtedOptionId], &Value); - BlpDrawEditMenuEntry(&Handle, EditableOptions[OldHighligtedOptionId], Value, OldHighligtedOptionId - TopVisibleEntry, FALSE); + Configuration::GetBootOptionValue(MenuEntry->Options, EditableOptions[OldHighligtedOptionId], &Value); + DrawEditMenuEntry(&Handle, EditableOptions[OldHighligtedOptionId], Value, OldHighligtedOptionId - TopVisibleEntry, (BOOLEAN)FALSE); /* Free allocated value string if needed */ - if(Value != NULL) + if(Value != NULLPTR) { - BlFreeMemoryPool(Value); + Memory::FreePool(Value); } /* Redraw new highlighted entry */ - BlGetBootOptionValue(MenuEntry->Options, EditableOptions[HighligtedOptionId], &Value); - BlpDrawEditMenuEntry(&Handle, EditableOptions[HighligtedOptionId], Value, HighligtedOptionId - TopVisibleEntry, TRUE); + Configuration::GetBootOptionValue(MenuEntry->Options, EditableOptions[HighligtedOptionId], &Value); + DrawEditMenuEntry(&Handle, EditableOptions[HighligtedOptionId], Value, HighligtedOptionId - TopVisibleEntry, (BOOLEAN)TRUE); /* Free allocated value string if needed */ - if(Value != NULL) + if(Value != NULLPTR) { - BlFreeMemoryPool(Value); + Memory::FreePool(Value); } } } @@ -599,18 +720,18 @@ BlDisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry) else if(Key.UnicodeChar == 0x02) { /* CTRL-B key pressed, boot the OS */ - BlSetConsoleAttributes(Handle.DialogColor | Handle.TextColor); - BlClearConsoleLine(Handle.PosY + Handle.Height + 4); - BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4); - BlConsolePrint(L"Booting '%S' now...\n", MenuEntry->FullName); + Console::SetAttributes(Handle.DialogColor | Handle.TextColor); + Console::ClearLine(Handle.PosY + Handle.Height + 4); + Console::SetCursorPosition(4, Handle.PosY + Handle.Height + 4); + Console::Print(L"Booting '%S' now...\n", MenuEntry->FullName); /* Boot the OS */ - Status = BlInvokeBootProtocol(MenuEntry->ShortName, MenuEntry->Options); + Status = Protocol::InvokeBootProtocol(MenuEntry->ShortName, MenuEntry->Options); if(Status != STATUS_SUCCESS) { /* Failed to boot OS */ - BlDebugPrint(L"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\n", MenuEntry->FullName, Status); - BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); + Debug::Print(L"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\n", MenuEntry->FullName, Status); + DisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System."); RedrawEditMenu = TRUE; } @@ -640,8 +761,8 @@ BlDisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry) */ XTCDECL VOID -BlDisplayErrorDialog(IN PWCHAR Caption, - IN PWCHAR Message) +TextUi::DisplayErrorDialog(IN PCWSTR Caption, + IN PCWSTR Message) { XTBL_DIALOG_HANDLE Handle; EFI_INPUT_KEY Key; @@ -651,14 +772,14 @@ BlDisplayErrorDialog(IN PWCHAR Caption, Handle.Attributes = XTBL_TUI_DIALOG_ERROR_BOX | XTBL_TUI_DIALOG_ACTIVE_BUTTON; /* Determine dialog window size and position */ - BlpDetermineDialogBoxSize(&Handle, Message); + DetermineDialogBoxSize(&Handle, Message); /* Disable cursor and draw dialog box */ - BlDisableConsoleCursor(); - BlpDrawDialogBox(&Handle, Caption, Message); + Console::DisableCursor(); + DrawDialogBox(&Handle, Caption, Message); /* Draw active button */ - BlpDrawDialogButton(&Handle); + DrawButton(&Handle); /* Initialize key stroke */ Key.ScanCode = 0; @@ -668,14 +789,14 @@ BlDisplayErrorDialog(IN PWCHAR Caption, while(Key.ScanCode != 0x17 && Key.UnicodeChar != 0x0D) { /* Wait for key press and read key stroke */ - BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); - BlReadKeyStroke(&Key); - BlResetConsoleInputBuffer(); + EfiUtils::WaitForEfiEvent(1, &(XtLoader::GetEfiSystemTable()->ConIn->WaitForKey), &Index); + Console::ReadKeyStroke(&Key); + Console::ResetInputBuffer(); } /* Clear screen to remove dialog box */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); - BlClearConsoleScreen(); + Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + Console::ClearScreen(); } /** @@ -693,8 +814,8 @@ BlDisplayErrorDialog(IN PWCHAR Caption, */ XTCDECL VOID -BlDisplayInfoDialog(IN PWCHAR Caption, - IN PWCHAR Message) +TextUi::DisplayInfoDialog(IN PCWSTR Caption, + IN PCWSTR Message) { XTBL_DIALOG_HANDLE Handle; EFI_INPUT_KEY Key; @@ -704,14 +825,14 @@ BlDisplayInfoDialog(IN PWCHAR Caption, Handle.Attributes = XTBL_TUI_DIALOG_GENERIC_BOX | XTBL_TUI_DIALOG_ACTIVE_BUTTON; /* Determine dialog window size and position */ - BlpDetermineDialogBoxSize(&Handle, Message); + DetermineDialogBoxSize(&Handle, Message); /* Disable cursor and draw dialog box */ - BlDisableConsoleCursor(); - BlpDrawDialogBox(&Handle, Caption, Message); + Console::DisableCursor(); + DrawDialogBox(&Handle, Caption, Message); /* Draw active button */ - BlpDrawDialogButton(&Handle); + DrawButton(&Handle); /* Initialize key stroke */ Key.ScanCode = 0; @@ -721,14 +842,14 @@ BlDisplayInfoDialog(IN PWCHAR Caption, while(Key.ScanCode != 0x17 && Key.UnicodeChar != 0x0D) { /* Wait for key press and read key stroke */ - BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); - BlReadKeyStroke(&Key); - BlResetConsoleInputBuffer(); + EfiUtils::WaitForEfiEvent(1, &(XtLoader::GetEfiSystemTable()->ConIn->WaitForKey), &Index); + Console::ReadKeyStroke(&Key); + Console::ResetInputBuffer(); } /* Clear screen to remove dialog box */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); - BlClearConsoleScreen(); + Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + Console::ClearScreen(); } /** @@ -749,9 +870,9 @@ BlDisplayInfoDialog(IN PWCHAR Caption, */ XTCDECL VOID -BlDisplayInputDialog(IN PWCHAR Caption, - IN PWCHAR Message, - IN OUT PWCHAR *InputFieldText) +TextUi::DisplayInputDialog(IN PCWSTR Caption, + IN PCWSTR Message, + IN OUT PWCHAR *InputFieldText) { SIZE_T InputFieldLength, TextCursorPosition, TextIndex, TextPosition; XTBL_DIALOG_HANDLE Handle; @@ -764,49 +885,49 @@ BlDisplayInputDialog(IN PWCHAR Caption, Handle.Attributes = XTBL_TUI_DIALOG_GENERIC_BOX | XTBL_TUI_DIALOG_ACTIVE_INPUT | XTBL_TUI_DIALOG_INACTIVE_BUTTON; /* Determine dialog window size and position */ - BlpDetermineDialogBoxSize(&Handle, Message); + DetermineDialogBoxSize(&Handle, Message); /* Disable cursor and draw dialog box */ - BlDisableConsoleCursor(); - BlpDrawDialogBox(&Handle, Caption, Message); + Console::DisableCursor(); + DrawDialogBox(&Handle, Caption, Message); /* Draw inactive button */ - BlpDrawDialogButton(&Handle); + DrawButton(&Handle); /* Draw active input field */ - BlpDrawDialogInputField(&Handle, *InputFieldText); + DrawInputField(&Handle, *InputFieldText); /* Initialize key stroke */ Key.ScanCode = 0; Key.UnicodeChar = 0; /* Determine input field length */ - InputFieldLength = RtlWideStringLength(*InputFieldText, 0); + InputFieldLength = RTL::WideString::WideStringLength(*InputFieldText, 0); /* Allocate a buffer for storing the input field text */ - Status = BlAllocateMemoryPool(2048 * sizeof(WCHAR), (PVOID *)&InputFieldBuffer); + Status = Memory::AllocatePool(2048 * sizeof(WCHAR), (PVOID *)&InputFieldBuffer); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure, print error message and return */ - BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); - BlDisplayErrorDialog(L"XTLDR", L"Failed to allocate memory for input field buffer."); + Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); + DisplayErrorDialog(L"XTLDR", L"Failed to allocate memory for input field buffer."); return; } /* Copy input text into edit buffer */ - RtlCopyMemory(InputFieldBuffer, *InputFieldText, InputFieldLength * sizeof(WCHAR)); + RTL::Memory::CopyMemory(InputFieldBuffer, *InputFieldText, InputFieldLength * sizeof(WCHAR)); InputFieldBuffer[InputFieldLength] = L'\0'; /* Start at first character */ TextPosition = 0; - BlSetCursorPosition(Handle.PosX + 4 + TextPosition, Handle.PosY + Handle.Height - 4); + Console::SetCursorPosition(Handle.PosX + 4 + TextPosition, Handle.PosY + Handle.Height - 4); /* Wait until ENTER or ESC key is pressed */ while(TRUE) { /* Wait for key press and read key stroke */ - BlWaitForEfiEvent(1, &EfiSystemTable->ConIn->WaitForKey, &Index); - BlReadKeyStroke(&Key); + EfiUtils::WaitForEfiEvent(1, &(XtLoader::GetEfiSystemTable()->ConIn->WaitForKey), &Index); + Console::ReadKeyStroke(&Key); /* Check key press scan code */ if(Key.ScanCode == 0x17) @@ -861,10 +982,10 @@ BlDisplayInputDialog(IN PWCHAR Caption, if(InputFieldLength > 0 && TextPosition < InputFieldLength) { /* Delete character */ - RtlMoveMemory(InputFieldBuffer + TextPosition, InputFieldBuffer + TextPosition + 1, + RTL::Memory::MoveMemory(InputFieldBuffer + TextPosition, InputFieldBuffer + TextPosition + 1, (InputFieldLength - TextPosition) * sizeof(WCHAR)); - /* Decrement length and null terminate string */ + /* Decrement length and NULL terminate string */ InputFieldLength--; InputFieldBuffer[InputFieldLength] = L'\0'; } @@ -879,10 +1000,10 @@ BlDisplayInputDialog(IN PWCHAR Caption, if(InputFieldLength > 0 && TextPosition > 0 && TextPosition <= InputFieldLength) { /* Move memory to overwrite the character to the left of the cursor */ - RtlMoveMemory(InputFieldBuffer + TextPosition - 1, InputFieldBuffer + TextPosition, + RTL::Memory::MoveMemory(InputFieldBuffer + TextPosition - 1, InputFieldBuffer + TextPosition, (InputFieldLength - TextPosition + 1) * sizeof(WCHAR)); - /* Decrement length, position and null terminate string */ + /* Decrement length, position and NULL terminate string */ TextPosition--; InputFieldLength--; InputFieldBuffer[InputFieldLength] = L'\0'; @@ -904,11 +1025,11 @@ BlDisplayInputDialog(IN PWCHAR Caption, if(InputFieldLength < 2047) { /* Insert character at current position */ - RtlMoveMemory(InputFieldBuffer + TextPosition + 1, InputFieldBuffer + TextPosition, + RTL::Memory::MoveMemory(InputFieldBuffer + TextPosition + 1, InputFieldBuffer + TextPosition, (InputFieldLength - TextPosition) * sizeof(WCHAR)); InputFieldBuffer[TextPosition] = Key.UnicodeChar; - /* Increment length, position and null terminate string */ + /* Increment length, position and NULL terminate string */ TextPosition++; InputFieldLength++; InputFieldBuffer[InputFieldLength] = L'\0'; @@ -929,19 +1050,19 @@ BlDisplayInputDialog(IN PWCHAR Caption, } /* Redraw input field and button */ - BlpDrawDialogButton(&Handle); - BlpDrawDialogInputField(&Handle, &InputFieldBuffer[TextIndex]); + DrawButton(&Handle); + DrawInputField(&Handle, &InputFieldBuffer[TextIndex]); /* Set cursor position if input field is active */ if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) { - BlSetCursorPosition(Handle.PosX + 4 + TextCursorPosition, Handle.PosY + Handle.Height - 4); + Console::SetCursorPosition(Handle.PosX + 4 + TextCursorPosition, Handle.PosY + Handle.Height - 4); } } /* Clear screen to remove dialog box */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); - BlClearConsoleScreen(); + Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + Console::ClearScreen(); } /** @@ -962,9 +1083,9 @@ BlDisplayInputDialog(IN PWCHAR Caption, */ XTCDECL XTBL_DIALOG_HANDLE -BlDisplayProgressDialog(IN PWCHAR Caption, - IN PWCHAR Message, - IN UCHAR Percentage) +TextUi::DisplayProgressDialog(IN PCWSTR Caption, + IN PCWSTR Message, + IN UCHAR Percentage) { XTBL_DIALOG_HANDLE Handle; @@ -972,172 +1093,19 @@ BlDisplayProgressDialog(IN PWCHAR Caption, Handle.Attributes = XTBL_TUI_DIALOG_GENERIC_BOX | XTBL_TUI_DIALOG_PROGRESS_BAR; /* Determine dialog window size and position */ - BlpDetermineDialogBoxSize(&Handle, Message); + DetermineDialogBoxSize(&Handle, Message); /* Disable cursor and draw dialog box */ - BlDisableConsoleCursor(); - BlpDrawDialogBox(&Handle, Caption, Message); + Console::DisableCursor(); + DrawDialogBox(&Handle, Caption, Message); /* Draw active button */ - BlpDrawDialogProgressBar(&Handle, Percentage); + DrawProgressBar(&Handle, Percentage); /* Return dialog handle */ return Handle; } -/** - * Updates the progress bar on the dialog box. - * - * @param Handle - * Supplies a pointer to the dialog box handle. - * - * @param Message - * Supplies a new message that will be put on the dialog box, while updating the progress bar. - * - * @param Percentage - * Specifies the new percentage progress of the progress bar. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlUpdateProgressBar(IN PXTBL_DIALOG_HANDLE Handle, - IN PWCHAR Message, - IN UCHAR Percentage) -{ - /* Check if message needs an update */ - if(Message != NULL) - { - /* Update a message on the dialog box */ - BlpDrawDialogMessage(Handle, Message); - } - - /* Update progress bar */ - BlpDrawDialogProgressBar(Handle, Percentage); -} - -/** - * Determines dialog box size based on enabled components and message length. - * - * @param Handle - * Supplies a pointer to the dialog box handle. - * - * @param Message - * Supplies a pointer to the message string put on the dialog box. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlpDetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle, - IN PWCHAR Message) -{ - UINT_PTR Width, Height, LineLength; - SIZE_T Index, MessageLength; - UCHAR Attributes; - ULONG Mask; - - /* Set minimum dialog window size */ - Height = 4; - Width = 36; - - /* Zero line length */ - LineLength = 0; - - /* Adjust window height according to enabled components */ - Mask = 1; - Attributes = Handle->Attributes; - while(Mask) - { - /* Check enabled components that affect dialog window size */ - switch(Attributes & Mask) - { - case XTBL_TUI_DIALOG_ACTIVE_BUTTON: - case XTBL_TUI_DIALOG_INACTIVE_BUTTON: - Height += 1; - break; - case XTBL_TUI_DIALOG_ACTIVE_INPUT: - case XTBL_TUI_DIALOG_INACTIVE_INPUT: - case XTBL_TUI_DIALOG_PROGRESS_BAR: - Height += 2; - break; - } - - /* Update component attributes mask */ - Attributes &= ~Mask; - Mask <<= 1; - } - - /* Check if input field is active */ - if(Handle->Attributes & (XTBL_TUI_DIALOG_ACTIVE_INPUT | XTBL_TUI_DIALOG_INACTIVE_INPUT)) - { - /* Set maximum dialog window width to fit input field */ - Width = XTBL_TUI_MAX_DIALOG_WIDTH; - } - - /* Get message length and count dialog window dimensions */ - MessageLength = RtlWideStringLength(Message, 0); - for(Index = 0; Index < MessageLength; Index++) - { - /* Check if this is multiline message */ - if(Message[Index] == L'\n' || Index == MessageLength - 1) - { - /* Check if this line exceeds current dialog window width */ - if(LineLength > Width) - { - /* Update dialog window width */ - Width = LineLength; - } - - /* Increase dialog window height to fit next line */ - Height++; - LineLength = 0; - } - else - { - /* Increase dialog window width to fit next character */ - LineLength++; - } - } - - /* Add more space to dialog window to fit side borders */ - Width += 4; - - /* Get console resolution */ - BlQueryConsoleMode(&Handle->ResX, &Handle->ResY); - - /* Make sure dialog window fits in the buffer */ - if(Width > XTBL_TUI_MAX_DIALOG_WIDTH) - { - /* Set maximum dialog window width */ - Width = XTBL_TUI_MAX_DIALOG_WIDTH; - } - - /* Make sure dialog window fits on the screen (X axis) and it is not too small for input field */ - if(Width > (Handle->ResX - 2)) - { - /* Set maximum dialog window width */ - Width = Handle->ResX - 2; - } - - /* Make sure dialog window fits on the screen (Y axis)*/ - if(Height > (Handle->ResY - 2)) - { - /* Set maximum dialog window height */ - Height = Handle->ResY - 2; - } - - /* Set dialog window final dimensions */ - Handle->PosX = (Handle->ResX - Width) / 2; - Handle->PosY = (Handle->ResY - Height) / 2; - Handle->Width = Width; - Handle->Height = Height; -} - /** * Draws a text UI-based boot menu. * @@ -1150,10 +1118,10 @@ BlpDetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle, */ XTCDECL VOID -BlpDrawBootMenu(OUT PXTBL_DIALOG_HANDLE Handle) +TextUi::DrawBootMenu(OUT PXTBL_DIALOG_HANDLE Handle) { /* Query console screen resolution */ - BlQueryConsoleMode(&Handle->ResX, &Handle->ResY); + Console::QueryMode(&Handle->ResX, &Handle->ResY); /* Set boot menu parameters */ Handle->Attributes = 0; @@ -1165,32 +1133,32 @@ BlpDrawBootMenu(OUT PXTBL_DIALOG_HANDLE Handle) Handle->Height = Handle->ResY - 10; /* Clear screen and disable cursor */ - BlSetConsoleAttributes(Handle->DialogColor | Handle->TextColor); - BlClearConsoleScreen(); - BlDisableConsoleCursor(); + Console::SetAttributes(Handle->DialogColor | Handle->TextColor); + Console::ClearScreen(); + Console::DisableCursor(); /* Check if debugging enabled */ if(DEBUG) { /* Print debug version of XTLDR banner */ - BlSetCursorPosition((Handle->ResX - 44) / 2, 1); - BlConsolePrint(L"XTLDR Boot Loader v%d.%d (%s-%s)\n", + Console::SetCursorPosition((Handle->ResX - 44) / 2, 1); + Console::Print(L"XTLDR Boot Loader v%d.%d (%s-%s)\n", XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR, XTOS_VERSION_DATE, XTOS_VERSION_HASH); } else { /* Print standard XTLDR banner */ - BlSetCursorPosition((Handle->ResX - 22) / 2, 1); - BlConsolePrint(L"XTLDR Boot Loader v%d.%d\n", XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR); + Console::SetCursorPosition((Handle->ResX - 22) / 2, 1); + Console::Print(L"XTLDR Boot Loader v%d.%d\n", XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR); } /* Draw empty dialog box for boot menu */ - BlpDrawDialogBox(Handle, NULL, NULL); + DrawDialogBox(Handle, NULLPTR, NULLPTR); /* Print help message below the boot menu */ - BlSetCursorPosition(0, Handle->PosY + Handle->Height); - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); - BlConsolePrint(L" Use cursors to change the selection. Press ENTER key to boot the chosen\n" + Console::SetCursorPosition(0, Handle->PosY + Handle->Height); + Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + Console::Print(L" Use cursors to change the selection. Press ENTER key to boot the chosen\n" L" Operating System, 'e' to edit it before booting or 's' for XTLDR shell.\n" L" Additional help available after pressing F1 key."); } @@ -1216,37 +1184,37 @@ BlpDrawBootMenu(OUT PXTBL_DIALOG_HANDLE Handle) */ XTCDECL VOID -BlpDrawBootMenuEntry(IN PXTBL_DIALOG_HANDLE Handle, - IN PWCHAR MenuEntry, - IN UINT Position, - IN BOOLEAN Highlighted) +TextUi::DrawBootMenuEntry(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR MenuEntry, + IN UINT Position, + IN BOOLEAN Highlighted) { UINT Index; /* Move cursor to the right position */ - BlSetCursorPosition(5, 4 + Position); + Console::SetCursorPosition(5, 4 + Position); /* Check whether this entry should be highlighted */ if(Highlighted) { /* Highlight this entry */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_LIGHTGRAY | EFI_TEXT_FGCOLOR_BLACK); + Console::SetAttributes(EFI_TEXT_BGCOLOR_LIGHTGRAY | EFI_TEXT_FGCOLOR_BLACK); } else { /* Set default colors */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); } /* Clear menu entry */ for(Index = 0; Index < Handle->Width - 4; Index++) { - BlConsolePrint(L" "); + Console::Print(L" "); } /* Print menu entry */ - BlSetCursorPosition(5, 4 + Position); - BlConsolePrint(L"%S\n", MenuEntry); + Console::SetCursorPosition(5, 4 + Position); + Console::Print(L"%S\n", MenuEntry); } /** @@ -1267,9 +1235,9 @@ BlpDrawBootMenuEntry(IN PXTBL_DIALOG_HANDLE Handle, */ XTCDECL VOID -BlpDrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, - IN PWCHAR Caption, - IN PWCHAR Message) +TextUi::DrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, + IN PCWSTR Caption, + IN PCWSTR Message) { WCHAR BoxLine[XTBL_TUI_MAX_DIALOG_WIDTH]; SIZE_T CaptionLength; @@ -1290,13 +1258,13 @@ BlpDrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, } /* Set dialog box colors */ - BlSetConsoleAttributes(Handle->DialogColor | 0x0F); + Console::SetAttributes(Handle->DialogColor | 0x0F); /* Iterate through dialog box lines */ for(PosY = Handle->PosY; PosY < Handle->PosY + Handle->Height; PosY++) { /* Set cursor position in the appropriate place */ - BlSetCursorPosition(Handle->PosX, PosY); + Console::SetCursorPosition(Handle->PosX, PosY); /* Draw dialog box */ if(PosY == Handle->PosY) @@ -1305,10 +1273,10 @@ BlpDrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, BoxLine[0] = EFI_TEXT_BOX_DOWN_RIGHT; /* Check if there is a caption for this dialog */ - if(Caption != NULL) + if(Caption != NULLPTR) { /* Get caption length */ - CaptionLength = RtlWideStringLength(Caption, 0); + CaptionLength = RTL::WideString::WideStringLength(Caption, 0); /* Start caption area with vertical line */ BoxLine[1] = EFI_TEXT_BOX_VERTICAL_LEFT; @@ -1366,26 +1334,26 @@ BlpDrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, BoxLine[Handle->Width - 1] = EFI_TEXT_BOX_VERTICAL; } - /* Add null terminator to the end of the line */ + /* Add NULL terminator to the end of the line */ BoxLine[Handle->Width] = 0; /* Write the line to the console */ - BlConsoleWrite(BoxLine); + Console::Write(BoxLine); } /* Make sure there is a caption to print */ - if(Caption != NULL) + if(Caption != NULLPTR) { /* Write dialog box caption */ - BlSetCursorPosition(Handle->PosX + 3, Handle->PosY); - BlConsolePrint(L"%S", Caption); + Console::SetCursorPosition(Handle->PosX + 3, Handle->PosY); + Console::Print(L"%S", Caption); } /* Make sure there is a message to print */ - if(Message != NULL) + if(Message != NULLPTR) { /* Write a message on the dialog box */ - BlpDrawDialogMessage(Handle, Message); + DrawMessage(Handle, Message); } } @@ -1401,7 +1369,7 @@ BlpDrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle, */ XTCDECL VOID -BlpDrawDialogButton(IN PXTBL_DIALOG_HANDLE Handle) +TextUi::DrawButton(IN PXTBL_DIALOG_HANDLE Handle) { ULONG ButtonColor, TextColor; @@ -1430,10 +1398,10 @@ BlpDrawDialogButton(IN PXTBL_DIALOG_HANDLE Handle) } /* Disable cursor and draw dialog button */ - BlDisableConsoleCursor(); - BlSetConsoleAttributes(ButtonColor | TextColor); - BlSetCursorPosition(Handle->ResX / 2 - 4, Handle->PosY + Handle->Height - 2); - BlConsolePrint(L"[ OK ]"); + Console::DisableCursor(); + Console::SetAttributes(ButtonColor | TextColor); + Console::SetCursorPosition(Handle->ResX / 2 - 4, Handle->PosY + Handle->Height - 2); + Console::Print(L"[ OK ]"); } /** @@ -1451,8 +1419,8 @@ BlpDrawDialogButton(IN PXTBL_DIALOG_HANDLE Handle) */ XTCDECL VOID -BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, - IN PWCHAR InputFieldText) +TextUi::DrawInputField(IN PXTBL_DIALOG_HANDLE Handle, + IN PWCHAR InputFieldText) { WCHAR InputField[XTBL_TUI_MAX_DIALOG_WIDTH]; ULONG InputColor, TextColor; @@ -1484,9 +1452,9 @@ BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, } /* Set progress bar color and position */ - BlSetConsoleAttributes(InputColor | TextColor); + Console::SetAttributes(InputColor | TextColor); Position = (Handle->Attributes & (XTBL_TUI_DIALOG_ACTIVE_BUTTON | XTBL_TUI_DIALOG_INACTIVE_BUTTON)) ? 4 : 3; - BlSetCursorPosition(Handle->PosX + 4, Handle->PosY + Handle->Height - Position); + Console::SetCursorPosition(Handle->PosX + 4, Handle->PosY + Handle->Height - Position); /* Draw input field */ for(Index = 0; Index < Handle->Width - 8; Index++) @@ -1496,11 +1464,11 @@ BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, } /* Disable cursor and write input field to console */ - BlDisableConsoleCursor(); - BlConsoleWrite(InputField); + Console::DisableCursor(); + Console::Write(InputField); /* Check input field text length */ - Length = RtlWideStringLength(InputFieldText, 0); + Length = RTL::WideString::WideStringLength(InputFieldText, 0); if(Length > (Handle->Width - 9)) { /* Text longer than input field width, display only part of it */ @@ -1514,18 +1482,18 @@ BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, InputField[Index] = InputFieldText[Index]; } - /* Add null terminator to the end of the line */ + /* Add NULL terminator to the end of the line */ InputField[Handle->Width] = 0; /* Write input field text */ - BlSetCursorPosition(Handle->PosX + 4, Handle->PosY + Handle->Height - Position); - BlConsoleWrite(InputField); + Console::SetCursorPosition(Handle->PosX + 4, Handle->PosY + Handle->Height - Position); + Console::Write(InputField); /* Check if this is an active input field */ if(Handle->Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT) { /* Enable cursor for active input field */ - BlEnableConsoleCursor(); + Console::EnableCursor(); } } @@ -1544,8 +1512,8 @@ BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle, */ XTCDECL VOID -BlpDrawDialogMessage(IN PXTBL_DIALOG_HANDLE Handle, - IN PWCHAR Message) +TextUi::DrawMessage(IN PXTBL_DIALOG_HANDLE Handle, + IN PCWSTR Message) { PWCHAR Msg, MsgLine, LastMsgLine; SIZE_T Index, Length, LineLength; @@ -1553,33 +1521,33 @@ BlpDrawDialogMessage(IN PXTBL_DIALOG_HANDLE Handle, ULONG Line; /* Allocate memory for dialog box message */ - Length = RtlWideStringLength(Message, 0); - Status = BlAllocateMemoryPool(Length * sizeof(WCHAR), (PVOID *)&Msg); + Length = RTL::WideString::WideStringLength(Message, 0); + Status = Memory::AllocatePool(Length * sizeof(WCHAR), (PVOID *)&Msg); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure, print debug message and return */ - BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); + Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); return; } /* Make a copy of dialog box message */ - RtlCopyMemory(Msg, Message, Length * sizeof(WCHAR)); + RTL::Memory::CopyMemory(Msg, Message, Length * sizeof(WCHAR)); Msg[Length] = 0; /* Tokenize dialog box message */ - MsgLine = RtlTokenizeWideString(Msg, L"\n", &LastMsgLine); + MsgLine = RTL::WideString::TokenizeWideString(Msg, L"\n", &LastMsgLine); /* Iterate through message lines */ Line = 0; while(MsgLine) { /* Determine line length */ - LineLength = RtlWideStringLength(MsgLine, 0); + LineLength = RTL::WideString::WideStringLength(MsgLine, 0); /* Write line in the dialog box */ - BlSetCursorPosition(Handle->PosX + 2, Handle->PosY + 2 + Line); - BlSetConsoleAttributes(Handle->DialogColor | Handle->TextColor); - BlConsolePrint(L"%S", MsgLine); + Console::SetCursorPosition(Handle->PosX + 2, Handle->PosY + 2 + Line); + Console::SetAttributes(Handle->DialogColor | Handle->TextColor); + Console::Print(L"%S", MsgLine); /* Check if message line is shorter than the dialog box working area */ if(LineLength < Handle->Width - 4) @@ -1587,12 +1555,12 @@ BlpDrawDialogMessage(IN PXTBL_DIALOG_HANDLE Handle, /* Fill the rest of the line with spaces */ for(Index = LineLength; Index < Handle->Width - 4; Index++) { - BlConsolePrint(L" "); + Console::Print(L" "); } } /* Get next line */ - MsgLine = RtlTokenizeWideString(NULL, L"\n", &LastMsgLine); + MsgLine = RTL::WideString::TokenizeWideString(NULLPTR, L"\n", &LastMsgLine); Line++; } } @@ -1612,8 +1580,8 @@ BlpDrawDialogMessage(IN PXTBL_DIALOG_HANDLE Handle, */ XTCDECL VOID -BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle, - IN UCHAR Percentage) +TextUi::DrawProgressBar(IN PXTBL_DIALOG_HANDLE Handle, + IN UCHAR Percentage) { UINT_PTR Index, ProgressLength, ProgressBarLength; WCHAR ProgressBar[XTBL_TUI_MAX_DIALOG_WIDTH]; @@ -1624,9 +1592,9 @@ BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle, ProgressLength = (ProgressBarLength * Percentage) / 100; /* Set progress bar color and position */ - BlSetConsoleAttributes(EFI_TEXT_FGCOLOR_YELLOW); + Console::SetAttributes(EFI_TEXT_FGCOLOR_YELLOW); Position = (Handle->Attributes & (XTBL_TUI_DIALOG_ACTIVE_BUTTON | XTBL_TUI_DIALOG_INACTIVE_BUTTON)) ? 4 : 3; - BlSetCursorPosition(Handle->PosX + 4, Handle->PosY + Handle->Height - Position); + Console::SetCursorPosition(Handle->PosX + 4, Handle->PosY + Handle->Height - Position); /* Draw progress bar */ for(Index = 0; Index < ProgressBarLength; Index++) @@ -1648,8 +1616,8 @@ BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle, ProgressBar[Index] = 0; /* Disable cursor and write progress bar to console */ - BlDisableConsoleCursor(); - BlConsoleWrite(ProgressBar); + Console::DisableCursor(); + Console::Write(ProgressBar); } /** @@ -1664,10 +1632,10 @@ BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle, */ XTCDECL VOID -BlpDrawEditMenu(OUT PXTBL_DIALOG_HANDLE Handle) +TextUi::DrawEditMenu(OUT PXTBL_DIALOG_HANDLE Handle) { /* Query console screen resolution */ - BlQueryConsoleMode(&Handle->ResX, &Handle->ResY); + Console::QueryMode(&Handle->ResX, &Handle->ResY); /* Set boot menu parameters */ Handle->Attributes = 0; @@ -1679,32 +1647,32 @@ BlpDrawEditMenu(OUT PXTBL_DIALOG_HANDLE Handle) Handle->Height = Handle->ResY - 10; /* Clear screen and disable cursor */ - BlSetConsoleAttributes(Handle->DialogColor | Handle->TextColor); - BlClearConsoleScreen(); - BlDisableConsoleCursor(); + Console::SetAttributes(Handle->DialogColor | Handle->TextColor); + Console::ClearScreen(); + Console::DisableCursor(); /* Check if debugging enabled */ if(DEBUG) { /* Print debug version of XTLDR banner */ - BlSetCursorPosition((Handle->ResX - 44) / 2, 1); - BlConsolePrint(L"XTLDR Boot Loader v%d.%d (%s-%s)\n", + Console::SetCursorPosition((Handle->ResX - 44) / 2, 1); + Console::Print(L"XTLDR Boot Loader v%d.%d (%s-%s)\n", XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR, XTOS_VERSION_DATE, XTOS_VERSION_HASH); } else { /* Print standard XTLDR banner */ - BlSetCursorPosition((Handle->ResX - 22) / 2, 1); - BlConsolePrint(L"XTLDR Boot Loader v%d.%d\n", XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR); + Console::SetCursorPosition((Handle->ResX - 22) / 2, 1); + Console::Print(L"XTLDR Boot Loader v%d.%d\n", XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR); } /* Draw empty dialog box for boot menu */ - BlpDrawDialogBox(Handle, L"Edit Options", NULL); + DrawDialogBox(Handle, L"Edit Options", NULLPTR); /* Print help message below the edit menu */ - BlSetCursorPosition(0, Handle->PosY + Handle->Height); - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); - BlConsolePrint(L" Use cursors to change the selection. Press ENTER key to edit the chosen\n" + Console::SetCursorPosition(0, Handle->PosY + Handle->Height); + Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + Console::Print(L" Use cursors to change the selection. Press ENTER key to edit the chosen\n" L" option, ESC to return to the main boot menu or CTRL-B to boot.\n"); } @@ -1732,14 +1700,14 @@ BlpDrawEditMenu(OUT PXTBL_DIALOG_HANDLE Handle) */ XTCDECL EFI_STATUS -BlpDrawEditMenuEntry(IN PXTBL_DIALOG_HANDLE Handle, - IN PWCHAR OptionName, - IN PWCHAR OptionValue, - IN UINT Position, - IN BOOLEAN Highlighted) +TextUi::DrawEditMenuEntry(IN PXTBL_DIALOG_HANDLE Handle, + IN PCWSTR OptionName, + IN PCWSTR OptionValue, + IN UINT Position, + IN BOOLEAN Highlighted) { BOOLEAN Allocation; - PWCHAR DisplayValue, ShortValue; + PCWSTR DisplayValue, ShortValue; UINT Index; ULONG OptionNameLength, OptionValueLength, OptionWidth; EFI_STATUS Status; @@ -1748,29 +1716,29 @@ BlpDrawEditMenuEntry(IN PXTBL_DIALOG_HANDLE Handle, Allocation = FALSE; /* Set display value depending on input */ - DisplayValue = (OptionValue != NULL) ? OptionValue : L""; + DisplayValue = (OptionValue != NULLPTR) ? OptionValue : L""; /* Determine lengths */ - OptionNameLength = RtlWideStringLength(OptionName, 0); - OptionValueLength = RtlWideStringLength(DisplayValue, 0); + OptionNameLength = RTL::WideString::WideStringLength(OptionName, 0); + OptionValueLength = RTL::WideString::WideStringLength(DisplayValue, 0); OptionWidth = Handle->Width - 4 - (OptionNameLength + 2); /* Check if value needs to be truncated */ if(OptionValueLength > OptionWidth) { /* Allocate buffer for new, shortened value */ - Status = BlAllocateMemoryPool((OptionWidth + 1) * sizeof(WCHAR), (PVOID *)&ShortValue); + Status = Memory::AllocatePool((OptionWidth + 1) * sizeof(WCHAR), (PVOID *)&ShortValue); // This allocates PWCHAR if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure, print debug message and return */ - BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); + Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); return Status; } /* Copy a desired value length into the allocated buffer and append "..." */ - RtlCopyMemory(ShortValue, DisplayValue, (OptionWidth - 3) * sizeof(WCHAR)); - RtlCopyMemory(ShortValue + OptionWidth - 3, L"...", 3 * sizeof(WCHAR)); - ShortValue[OptionWidth] = L'\0'; + RTL::Memory::CopyMemory((PWCHAR)ShortValue, DisplayValue, (OptionWidth - 3) * sizeof(WCHAR)); + RTL::Memory::CopyMemory((PWCHAR)ShortValue + OptionWidth - 3, L"...", 3 * sizeof(WCHAR)); + ((PWCHAR)ShortValue)[OptionWidth] = L'\0'; /* Mark that allocation was made and set new display value */ Allocation = TRUE; @@ -1778,37 +1746,70 @@ BlpDrawEditMenuEntry(IN PXTBL_DIALOG_HANDLE Handle, } /* Move cursor to the right position */ - BlSetCursorPosition(5, 4 + Position); + Console::SetCursorPosition(5, 4 + Position); /* Check whether this entry should be highlighted */ if(Highlighted) { /* Highlight this entry */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_LIGHTGRAY | EFI_TEXT_FGCOLOR_BLACK); + Console::SetAttributes(EFI_TEXT_BGCOLOR_LIGHTGRAY | EFI_TEXT_FGCOLOR_BLACK); } else { /* Set default colors */ - BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); + Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); } /* Clear menu entry */ for(Index = 0; Index < Handle->Width - 4; Index++) { - BlConsolePrint(L" "); + Console::Print(L" "); } /* Print menu entry */ - BlSetCursorPosition(5, 4 + Position); - BlConsolePrint(L"%S: %S", OptionName, DisplayValue); + Console::SetCursorPosition(5, 4 + Position); + Console::Print(L"%S: %S", OptionName, DisplayValue); /* Check if allocation was made */ if(Allocation) { /* Free allocated memory */ - BlFreeMemoryPool(DisplayValue); + Memory::FreePool((PVOID)DisplayValue); } /* Return success */ return STATUS_EFI_SUCCESS; } + +/** + * Updates the progress bar on the dialog box. + * + * @param Handle + * Supplies a pointer to the dialog box handle. + * + * @param Message + * Supplies a new message that will be put on the dialog box, while updating the progress bar. + * + * @param Percentage + * Specifies the new percentage progress of the progress bar. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +TextUi::UpdateProgressBar(IN PXTBL_DIALOG_HANDLE Handle, + IN PCWSTR Message, + IN UCHAR Percentage) +{ + /* Check if message needs an update */ + if(Message != NULLPTR) + { + /* Update a message on the dialog box */ + DrawMessage(Handle, Message); + } + + /* Update progress bar */ + DrawProgressBar(Handle, Percentage); +} diff --git a/xtldr/volume.c b/xtldr/volume.cc similarity index 76% rename from xtldr/volume.c rename to xtldr/volume.cc index 74b6166..a2867b7 100644 --- a/xtldr/volume.c +++ b/xtldr/volume.cc @@ -1,13 +1,13 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/volume.c + * FILE: xtldr/volume.cc * DESCRIPTION: XTLDR volume support * DEVELOPERS: Rafal Kupiec * Aiken Harris */ -#include +#include /** @@ -22,15 +22,16 @@ */ XTCDECL EFI_STATUS -BlCloseVolume(IN PEFI_HANDLE VolumeHandle) +Volume::CloseVolume(IN PEFI_HANDLE VolumeHandle) { EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; /* Make sure a handle specified */ - if(VolumeHandle != NULL) + if(VolumeHandle != NULLPTR) { /* Close a handle */ - return EfiSystemTable->BootServices->CloseProtocol(VolumeHandle, &LIPGuid, EfiImageHandle, NULL); + return XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(VolumeHandle, &LIPGuid, + XtLoader::GetEfiImageHandle(), NULLPTR); } /* Return success */ @@ -46,14 +47,14 @@ BlCloseVolume(IN PEFI_HANDLE VolumeHandle) */ XTCDECL EFI_STATUS -BlEnumerateBlockDevices() +Volume::EnumerateBlockDevices() { EFI_GUID LoadedImageProtocolGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; EFI_GUID BlockIoGuid = EFI_BLOCK_IO_PROTOCOL_GUID; - EFI_HANDLE BootDeviceHandle = NULL, DeviceHandle = NULL; + EFI_HANDLE BootDeviceHandle = NULLPTR, DeviceHandle = NULLPTR; EFI_LOADED_IMAGE_PROTOCOL* LoadedImage; - PEFI_DEVICE_PATH_PROTOCOL DevicePath = NULL, LastNode = NULL; - PEFI_BLOCK_DEVICE_DATA ParentNode = NULL; + PEFI_DEVICE_PATH_PROTOCOL DevicePath = NULLPTR, LastNode = NULLPTR; + PEFI_BLOCK_DEVICE_DATA ParentNode = NULLPTR; PEFI_BLOCK_DEVICE_DATA BlockDeviceData; PEFI_BLOCK_DEVICE BlockDevice; LIST_ENTRY BlockDevices; @@ -68,11 +69,12 @@ BlEnumerateBlockDevices() ULONG CDCount = 0, FDCount = 0, HDCount = 0, RDCount = 0; /* Get the device handle of the image that is running */ - Status = EfiSystemTable->BootServices->HandleProtocol(EfiImageHandle, &LoadedImageProtocolGuid, (VOID**)&LoadedImage); + Status = XtLoader::GetEfiSystemTable()->BootServices->HandleProtocol(XtLoader::GetEfiImageHandle(), &LoadedImageProtocolGuid, + (VOID**)&LoadedImage); if(Status != STATUS_EFI_SUCCESS) { /* Failed to get boot device handle */ - BlDebugPrint(L"ERROR: Failed to get boot device handle (Status Code: 0x%zX)\n", Status); + Debug::Print(L"ERROR: Failed to get boot device handle (Status Code: 0x%zX)\n", Status); return Status; } @@ -80,14 +82,14 @@ BlEnumerateBlockDevices() BootDeviceHandle = LoadedImage->DeviceHandle; /* Initialize list entries */ - RtlInitializeListHead(&BlockDevices); - RtlInitializeListHead(&EfiBlockDevices); + RTL::LinkedList::InitializeListHead(&BlockDevices); + RTL::LinkedList::InitializeListHead(&EfiBlockDevices); /* Discover EFI block devices and store them in linked list */ - Status = BlpDiscoverEfiBlockDevices(&BlockDevices); + Status = DiscoverEfiBlockDevices(&BlockDevices); if(Status != STATUS_EFI_SUCCESS) { - BlDebugPrint(L"ERROR: Failed to discover EFI block devices (Status Code: 0x%zX)\n", Status); + Debug::Print(L"ERROR: Failed to discover EFI block devices (Status Code: 0x%zX)\n", Status); return Status; } @@ -97,14 +99,14 @@ BlEnumerateBlockDevices() { /* Get data for the next discovered device. */ BlockDeviceData = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE_DATA, ListEntry); - PartitionGuid = NULL; + PartitionGuid = NULLPTR; /* Find last node */ - Status = BlpFindLastBlockDeviceNode(BlockDeviceData->DevicePath, &LastNode); + Status = FindLastBlockDeviceNode(BlockDeviceData->DevicePath, &LastNode); if(Status != STATUS_EFI_SUCCESS) { /* Skip this device if its last node cannot be found, as it is required for classification */ - BlDebugPrint(L"WARNING: Block device last node not found\n"); + Debug::Print(L"WARNING: Block device last node not found\n"); ListEntry = ListEntry->Flink; continue; } @@ -113,10 +115,10 @@ BlEnumerateBlockDevices() DriveType = XTBL_BOOT_DEVICE_UNKNOWN; /* Locate the parent for this block device to ensure it is not an orphaned entry */ - if(!BlpFindParentBlockDevice(&BlockDevices, BlockDeviceData, &ParentNode)) + if(!FindParentBlockDevice(&BlockDevices, BlockDeviceData, &ParentNode)) { /* Orphaned device found. Log a warning and skip it as it cannot be properly classified */ - BlDebugPrint(L"WARNING: No parent device found, skipping orphaned media device path\n"); + Debug::Print(L"WARNING: No parent device found, skipping orphaned media device path\n"); ListEntry = ListEntry->Flink; continue; } @@ -125,7 +127,7 @@ BlEnumerateBlockDevices() if(!BlockDeviceData->BlockIo->Media) { /* The device is unusable without media info, log a warning and skip it */ - BlDebugPrint(L"WARNING: Block device is missing media information\n"); + Debug::Print(L"WARNING: Block device is missing media information\n"); ListEntry = ListEntry->Flink; continue; } @@ -144,7 +146,7 @@ BlEnumerateBlockDevices() PartitionNumber = 0; /* 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); } } @@ -159,7 +161,7 @@ BlEnumerateBlockDevices() PartitionNumber = 0; /* 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); } else if(LastNode->Type == EFI_MEDIA_DEVICE_PATH && LastNode->SubType == EFI_MEDIA_HARDDRIVE_DP) @@ -172,15 +174,15 @@ BlEnumerateBlockDevices() PartitionGuid = (PEFI_GUID)HDPath->Signature; /* Check if this is the EFI System Partition (ESP) */ - if(BootDeviceHandle != NULL) + if(BootDeviceHandle != NULLPTR) { /* Allocate memory for device path */ - DevicePath = BlpDuplicateDevicePath(BlockDeviceData->DevicePath); - if(DevicePath != NULL) + DevicePath = DuplicateDevicePath(BlockDeviceData->DevicePath); + if(DevicePath != NULLPTR) { /* Check if this is the boot device */ - Status = EfiSystemTable->BootServices->LocateDevicePath(&BlockIoGuid, &DevicePath, - &DeviceHandle); + Status = XtLoader::GetEfiSystemTable()->BootServices->LocateDevicePath(&BlockIoGuid, &DevicePath, + &DeviceHandle); if(Status == STATUS_EFI_SUCCESS && DeviceHandle == BootDeviceHandle) { /* Mark partition as ESP */ @@ -190,7 +192,7 @@ BlEnumerateBlockDevices() } /* 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: %lluB) %S\n", DriveNumber, PartitionNumber, HDPath->MBRType, PartitionGuid, HDPath->PartitionSize * Media->BlockSize, @@ -204,7 +206,7 @@ BlEnumerateBlockDevices() PartitionNumber = 0; /* 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); } @@ -212,22 +214,22 @@ BlEnumerateBlockDevices() if(DriveType != XTBL_BOOT_DEVICE_UNKNOWN) { /* 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) { - 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; } /* Initialize block device */ - BlockDevice->DevicePath = BlpDuplicateDevicePath(BlockDeviceData->DevicePath); + BlockDevice->DevicePath = DuplicateDevicePath(BlockDeviceData->DevicePath); BlockDevice->DriveType = DriveType; BlockDevice->DriveNumber = DriveNumber; BlockDevice->PartitionNumber = PartitionNumber; BlockDevice->PartitionGuid = PartitionGuid; /* Add block device to global list */ - RtlInsertTailList(&EfiBlockDevices, &BlockDevice->ListEntry); + RTL::LinkedList::InsertTailList(&EfiBlockDevices, &BlockDevice->ListEntry); } /* Get next entry from linked list */ @@ -256,13 +258,13 @@ BlEnumerateBlockDevices() */ XTCDECL EFI_STATUS -BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, +Volume::FindDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, IN CONST PWCHAR FileSystemPath, OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath) { EFI_STATUS Status; 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 DevicePathHandle; @@ -291,10 +293,10 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, } /* Check real path length */ - FsPathLength = RtlWideStringLength(FileSystemPath, 0) * sizeof(WCHAR); + FsPathLength = RTL::WideString::WideStringLength(FileSystemPath, 0) * sizeof(WCHAR); /* 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); if(Status != STATUS_EFI_SUCCESS) { @@ -303,7 +305,7 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, } /* Set file path */ - RtlCopyMemory(*DevicePath, FsHandle, DevicePathLength); + RTL::Memory::CopyMemory(*DevicePath, FsHandle, DevicePathLength); FilePath = (PEFI_FILEPATH_DEVICE_PATH)((PUCHAR)*DevicePath + DevicePathLength); FilePath->Header.Type = EFI_MEDIA_DEVICE_PATH; FilePath->Header.SubType = EFI_MEDIA_FILEPATH_DP; @@ -311,7 +313,7 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, FilePath->Header.Length[1] = FilePath->Header.Length[0] >> 8; /* 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->Type = EFI_END_DEVICE_PATH; EndDevicePath->SubType = EFI_END_ENTIRE_DP; @@ -337,26 +339,26 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, */ XTCDECL EFI_STATUS -BlGetEfiPath(IN PWCHAR SystemPath, - OUT PWCHAR *EfiPath) +Volume::GetEfiPath(IN PWCHAR SystemPath, + OUT PWCHAR *EfiPath) { SIZE_T Index, PathLength; EFI_STATUS Status; /* Get system path length */ - PathLength = RtlWideStringLength(SystemPath, 0); + PathLength = RTL::WideString::WideStringLength(SystemPath, 0); /* 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) { /* 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; } /* 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 */ for(Index = 0; Index < PathLength; Index++) @@ -390,7 +392,7 @@ BlGetEfiPath(IN PWCHAR SystemPath, */ XTCDECL EFI_STATUS -BlGetVolumeDevicePath(IN PWCHAR SystemPath, +Volume::GetDevicePath(IN PWCHAR SystemPath, OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT PWCHAR *ArcName, OUT PWCHAR *Path) @@ -405,7 +407,7 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath, EFI_STATUS Status; /* Make sure this is not set */ - *DevicePath = NULL; + *DevicePath = NULLPTR; /* Find volume path and its length */ Volume = SystemPath; @@ -429,13 +431,13 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath, if(PathLength == GUID_STRING_LENGTH) { /* 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; } else if(PathLength == PARTUUID_STRING_LENGTH) { /* 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; } else @@ -447,14 +449,14 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath, else { /* 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 */ if(Status != STATUS_EFI_SUCCESS) { /* 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; } @@ -489,10 +491,10 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath, } /* Check if volume was found */ - if(*DevicePath == NULL) + if(*DevicePath == NULLPTR) { /* 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); return STATUS_EFI_NOT_FOUND; } @@ -519,9 +521,9 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath, */ XTCDECL EFI_STATUS -BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, - OUT PEFI_HANDLE DiskHandle, - OUT PEFI_FILE_HANDLE *FsHandle) +Volume::OpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, + OUT PEFI_HANDLE DiskHandle, + OUT PEFI_FILE_HANDLE *FsHandle) { EFI_GUID SFSGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; @@ -530,10 +532,10 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, EFI_STATUS Status; /* Check if device path has been passed or not */ - if(DevicePath != NULL) + if(DevicePath != NULLPTR) { /* Locate the device path */ - Status = EfiSystemTable->BootServices->LocateDevicePath(&SFSGuid, &DevicePath, DiskHandle); + Status = XtLoader::GetEfiSystemTable()->BootServices->LocateDevicePath(&SFSGuid, &DevicePath, DiskHandle); if(Status != STATUS_EFI_SUCCESS) { /* Failed to locate device path */ @@ -543,8 +545,12 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, else { /* Open the image protocol if no device path specified */ - Status = EfiSystemTable->BootServices->OpenProtocol(EfiImageHandle, &LIPGuid, (PVOID *)&ImageProtocol, - EfiImageHandle, NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); + Status = XtLoader::GetEfiSystemTable()->BootServices->OpenProtocol(XtLoader::GetEfiImageHandle(), + &LIPGuid, + (PVOID *)&ImageProtocol, + XtLoader::GetEfiImageHandle(), + NULLPTR, + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); if(Status != STATUS_EFI_SUCCESS) { /* Failed to open image protocol */ @@ -556,14 +562,16 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, } /* Open the filesystem protocol */ - Status = EfiSystemTable->BootServices->OpenProtocol(*DiskHandle, &SFSGuid, (PVOID *)&FileSystemProtocol, - EfiImageHandle, NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); + Status = XtLoader::GetEfiSystemTable()->BootServices->OpenProtocol(*DiskHandle, &SFSGuid, + (PVOID *)&FileSystemProtocol, + XtLoader::GetEfiImageHandle(), NULLPTR, + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); /* Check if filesystem protocol opened successfully */ if(Status != STATUS_EFI_SUCCESS) { /* Failed to open the filesystem protocol, close volume */ - BlCloseVolume(*DiskHandle); + CloseVolume(DiskHandle); return Status; } @@ -572,7 +580,7 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, if(Status != STATUS_EFI_SUCCESS) { /* Failed to open the filesystem, close volume */ - BlCloseVolume(*DiskHandle); + CloseVolume(DiskHandle); return Status; } @@ -601,10 +609,10 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, */ XTCDECL EFI_STATUS -BlReadFile(IN PEFI_FILE_HANDLE DirHandle, - IN CONST PWCHAR FileName, - OUT PVOID *FileData, - OUT PSIZE_T FileSize) +Volume::ReadFile(IN PEFI_FILE_HANDLE DirHandle, + IN PCWSTR FileName, + OUT PVOID *FileData, + OUT PSIZE_T FileSize) { EFI_GUID FileInfoGuid = EFI_FILE_INFO_PROTOCOL_GUID; EFI_PHYSICAL_ADDRESS Address; @@ -614,7 +622,7 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle, UINT_PTR ReadSize; 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); if(Status != STATUS_EFI_SUCCESS) { @@ -626,7 +634,7 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle, ReadSize = sizeof(EFI_FILE_INFO) + 32; /* Allocate necessary amount of memory */ - Status = BlAllocateMemoryPool(ReadSize, (PVOID *)&FileInfo); + Status = Memory::AllocatePool(ReadSize, (PVOID *)&FileInfo); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ @@ -639,8 +647,8 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle, if(Status == STATUS_EFI_BUFFER_TOO_SMALL) { /* Buffer is too small, but EFI tells the required size, so reallocate */ - BlFreeMemoryPool(&FileInfo); - Status = BlAllocateMemoryPool(ReadSize, (PVOID *)&FileInfo); + Memory::FreePool(&FileInfo); + Status = Memory::AllocatePool(ReadSize, (PVOID *)&FileInfo); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ @@ -657,7 +665,7 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle, { /* Unable to get file information */ FileHandle->Close(FileHandle); - BlFreeMemoryPool(&FileInfo); + Memory::FreePool(&FileInfo); return Status; } @@ -666,19 +674,19 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle, Pages = EFI_SIZE_TO_PAGES(FileInfo->FileSize); /* Allocate pages */ - Status = BlAllocateMemoryPages(AllocateAnyPages, Pages, &Address); + Status = Memory::AllocatePages(AllocateAnyPages, Pages, &Address); if(Status != STATUS_EFI_SUCCESS) { /* Pages allocation failure */ FileHandle->Close(FileHandle); - BlFreeMemoryPool(&FileInfo); + Memory::FreePool(&FileInfo); return Status; } /* Calculate number of bytes to read and zero memory */ ReadSize = Pages * EFI_PAGE_SIZE; *FileData = (PCHAR)(UINT_PTR)Address; - RtlZeroMemory(*FileData, ReadSize); + RTL::Memory::ZeroMemory(*FileData, ReadSize); /* Read data from the file */ Status = FileHandle->Read(FileHandle, &ReadSize, *FileData); @@ -686,14 +694,14 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle, { /* Failed to read data */ FileHandle->Close(FileHandle); - BlFreeMemoryPool(&FileInfo); - BlFreeMemoryPages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)*FileData); + Memory::FreePool(&FileInfo); + Memory::FreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)*FileData); return Status; } /* Close handle and free memory */ FileHandle->Close(FileHandle); - BlFreeMemoryPool(FileInfo); + Memory::FreePool(FileInfo); /* Return success */ return STATUS_EFI_SUCCESS; @@ -711,23 +719,23 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle, */ XTCDECL EFI_STATUS -BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) +Volume::DiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) { EFI_GUID DevicePathGuid = EFI_DEVICE_PATH_PROTOCOL_GUID; EFI_GUID IoGuid = EFI_BLOCK_IO_PROTOCOL_GUID; PEFI_DEVICE_PATH_PROTOCOL DevicePath; PEFI_BLOCK_DEVICE_DATA BlockDevice; UINT_PTR HandlesCount, Index; - PEFI_HANDLE Handles = NULL; + PEFI_HANDLE Handles = NULLPTR; PEFI_BLOCK_IO_PROTOCOL Io; EFI_STATUS Status; /* 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) { /* 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; } @@ -735,15 +743,15 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) for(Index = 0; Index < HandlesCount; Index++) { /* 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 */ - Io = NULL; - Status = BlOpenProtocolHandle(Handles[Index], (PVOID *)&Io, &IoGuid); - if(Status != STATUS_EFI_SUCCESS || Io == NULL) + Io = NULLPTR; + Status = Protocol::OpenProtocolHandle(Handles[Index], (PVOID *)&Io, &IoGuid); + if(Status != STATUS_EFI_SUCCESS || Io == NULLPTR) { /* 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; } @@ -751,40 +759,44 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) if(Io->Media && Io->Media->BlockSize == 1 && Io->Media->MediaId == 0x69505845U) { /* 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; } /* Check if DevicePath protocol is supported by this handle */ - DevicePath = NULL; - Status = EfiSystemTable->BootServices->HandleProtocol(Handles[Index], &DevicePathGuid, (PVOID *)&DevicePath); - if(Status != STATUS_EFI_SUCCESS || DevicePath == NULL) + DevicePath = NULLPTR; + Status = XtLoader::GetEfiSystemTable()->BootServices->HandleProtocol(Handles[Index], &DevicePathGuid, + (PVOID *)&DevicePath); + if(Status != STATUS_EFI_SUCCESS || DevicePath == NULLPTR) { /* Device failed to handle DP protocol */ - BlDebugPrint(L"WARNING: Unable to open DevicePath protocol (Status Code: 0x%zX)\n", Status); - EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &IoGuid, EfiImageHandle, NULL); + Debug::Print(L"WARNING: Unable to open DevicePath protocol (Status Code: 0x%zX)\n", Status); + XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(Handles[Index], &IoGuid, + XtLoader::GetEfiImageHandle(), NULLPTR); continue; } /* Allocate memory for block device */ - Status = BlAllocateMemoryPool(sizeof(*BlockDevice), (PVOID *)&BlockDevice); + Status = Memory::AllocatePool(sizeof(*BlockDevice), (PVOID *)&BlockDevice); if(Status != STATUS_EFI_SUCCESS) { /* Memory allocation failure */ - BlDebugPrint(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%zX)\n", Status); - EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &DevicePathGuid, EfiImageHandle, NULL); - EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &IoGuid, EfiImageHandle, NULL); + Debug::Print(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%zX)\n", Status); + XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(Handles[Index], &DevicePathGuid, + XtLoader::GetEfiImageHandle(), NULLPTR); + XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(Handles[Index], &IoGuid, + XtLoader::GetEfiImageHandle(), NULLPTR); return Status; } /* Store new block device into a linked list */ BlockDevice->BlockIo = Io; BlockDevice->DevicePath = DevicePath; - RtlInsertTailList(BlockDevices, &BlockDevice->ListEntry); + RTL::LinkedList::InsertTailList(BlockDevices, &BlockDevice->ListEntry); } /* Free handles buffer */ - BlFreeMemoryPool(Handles); + Memory::FreePool(Handles); /* Return success */ return STATUS_EFI_SUCCESS; @@ -814,12 +826,12 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) */ XTCDECL EFI_STATUS -BlpDissectVolumeArcPath(IN PWCHAR SystemPath, - OUT PWCHAR *ArcName, - OUT PWCHAR *Path, - OUT PUSHORT DriveType, - OUT PULONG DriveNumber, - OUT PULONG PartNumber) +Volume::DissectArcPath(IN PWCHAR SystemPath, + OUT PWCHAR *ArcName, + OUT PWCHAR *Path, + OUT PUSHORT DriveType, + OUT PULONG DriveNumber, + OUT PULONG PartNumber) { PWCHAR ArcPath, LocalArcName; ULONG ArcLength = 0; @@ -830,26 +842,26 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath, *PartNumber = 0; /* 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 */ ArcLength = 10; *DriveType = XTBL_BOOT_DEVICE_RAMDISK; } - else if(RtlCompareWideStringInsensitive(SystemPath, L"multi(0)esp(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(RtlCompareWideStringInsensitive(SystemPath, L"multi(0)disk(0)", 0) == 0) + else if(RTL::WideString::CompareWideStringInsensitive(SystemPath, L"multi(0)disk(0)", 0) == 0) { /* This is a multi-disk port */ ArcLength = 15; ArcPath = SystemPath + ArcLength; /* 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 */ ArcLength += 6; @@ -870,7 +882,7 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath, *DriveType = XTBL_BOOT_DEVICE_CDROM; ArcLength++; } - else if(RtlCompareWideStringInsensitive(ArcPath, L"fdisk(", 0) == 0) + else if(RTL::WideString::CompareWideStringInsensitive(ArcPath, L"fdisk(", 0) == 0) { /* This is a floppy drive */ ArcLength += 6; @@ -891,7 +903,7 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath, *DriveType = XTBL_BOOT_DEVICE_FLOPPY; ArcLength++; } - else if(RtlCompareWideStringInsensitive(ArcPath, L"rdisk(", 0) == 0) + else if(RTL::WideString::CompareWideStringInsensitive(ArcPath, L"rdisk(", 0) == 0) { /* This is a hard disk */ ArcLength += 6; @@ -914,7 +926,7 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath, ArcPath = SystemPath + ArcLength; /* Look for a partition */ - if(RtlCompareWideStringInsensitive(ArcPath, L"partition(", 0) == 0) + if(RTL::WideString::CompareWideStringInsensitive(ArcPath, L"partition(", 0) == 0) { /* Partition information found */ ArcLength += 10; @@ -954,8 +966,8 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath, /* Store ARC name if possible */ if(ArcName) { - BlAllocateMemoryPool(ArcLength * sizeof(WCHAR), (PVOID *)&LocalArcName); - RtlCopyMemory(LocalArcName, SystemPath, ArcLength * sizeof(WCHAR)); + Memory::AllocatePool(ArcLength * sizeof(WCHAR), (PVOID *)&LocalArcName); + RTL::Memory::CopyMemory(LocalArcName, SystemPath, ArcLength * sizeof(WCHAR)); LocalArcName[ArcLength] = '\0'; *ArcName = LocalArcName; } @@ -976,18 +988,18 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath, */ XTCDECL 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 DevicePathClone; EFI_STATUS Status; UINT Length = 0; - /* Check if the input device path is NULL */ + /* Check if the input device path is NULL pointer */ if(!DevicePath) { /* Nothing to duplicate */ - return NULL; + return NULLPTR; } /* Start iterating from the beginning of the device path */ @@ -1008,20 +1020,20 @@ BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath) if(Length == 0) { /* Nothing to duplicate */ - return NULL; + return NULLPTR; } /* Allocate memory for the new device path */ - Status = BlAllocateMemoryPool(Length, (PVOID *)&DevicePathClone); + Status = Memory::AllocatePool(Length, (PVOID *)&DevicePathClone); if(Status != STATUS_EFI_SUCCESS) { /* Failed to allocate memory */ - BlDebugPrint(L"ERROR: Failed to allocate memory pool for device path duplicate (Status Code: 0x%zX)\n", Status); - return NULL; + Debug::Print(L"ERROR: Failed to allocate memory pool for device path duplicate (Status Code: 0x%zX)\n", Status); + return NULLPTR; } /* Copy the device path */ - RtlCopyMemory(DevicePathClone, DevicePath, Length); + RTL::Memory::CopyMemory(DevicePathClone, DevicePath, Length); /* Return the cloned object */ return DevicePathClone; @@ -1042,8 +1054,8 @@ BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath) */ XTCDECL EFI_STATUS -BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, - OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode) +Volume::FindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, + OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode) { PEFI_DEVICE_PATH_PROTOCOL EndNode, NextNode; @@ -1051,7 +1063,7 @@ BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, if(DevicePath->Type == EFI_END_DEVICE_PATH) { /* End reached, nothing to do */ - LastNode = NULL; + LastNode = NULLPTR; return STATUS_EFI_INVALID_PARAMETER; } @@ -1088,9 +1100,9 @@ BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, */ XTCDECL BOOLEAN -BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices, - IN PEFI_BLOCK_DEVICE_DATA ChildNode, - OUT PEFI_BLOCK_DEVICE_DATA *ParentNode) +Volume::FindParentBlockDevice(IN PLIST_ENTRY BlockDevices, + IN PEFI_BLOCK_DEVICE_DATA ChildNode, + OUT PEFI_BLOCK_DEVICE_DATA *ParentNode) { PEFI_DEVICE_PATH_PROTOCOL ChildDevicePath, ParentDevicePath; PEFI_BLOCK_DEVICE_DATA BlockDeviceData; @@ -1131,7 +1143,7 @@ BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices, /* Check if nodes match */ if((ChildLength != ParentLength) || - (RtlCompareMemory(ChildDevicePath, ParentDevicePath, ParentLength) != ParentLength)) + (RTL::Memory::CompareMemory(ChildDevicePath, ParentDevicePath, ParentLength) != ParentLength)) { /* Nodes do not match, this is not a valid parent */ break; diff --git a/xtldr/xtldr.c b/xtldr/xtldr.c deleted file mode 100644 index dadc0c3..0000000 --- a/xtldr/xtldr.c +++ /dev/null @@ -1,499 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/xtldr.c - * DESCRIPTION: XTOS UEFI Boot Loader - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/** - * Initializes EFI Boot Loader (XTLDR). - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlInitializeBootLoader() -{ - EFI_GUID LipGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; - PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; - EFI_HANDLE Handle; - EFI_STATUS Status; - - /* Set current XTLDR's EFI BootServices status */ - BlpStatus.BootServices = TRUE; - - /* Initialize console */ - BlInitializeConsole(); - - /* Print XTLDR version */ - BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); - - /* Initialize XTLDR configuration linked lists */ - RtlInitializeListHead(&BlpBootProtocols); - RtlInitializeListHead(&BlpConfig); - RtlInitializeListHead(&BlpLoadedModules); - - /* Store SecureBoot status */ - BlpStatus.SecureBoot = BlGetSecureBootStatus(); - - /* Attempt to open EFI LoadedImage protocol */ - Status = BlOpenProtocol(&Handle, (PVOID *)&LoadedImage, &LipGuid); - if(Status == STATUS_EFI_SUCCESS) - { - /* Store boot loader image base and size */ - BlpStatus.LoaderBase = LoadedImage->ImageBase; - BlpStatus.LoaderSize = LoadedImage->ImageSize; - - /* Check if debug is enabled */ - if(DEBUG) - { - /* Protocol opened successfully, print useful debug information */ - BlConsolePrint(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"--------------------------------------\n", - sizeof(PVOID), - LoadedImage->ImageBase, - LoadedImage->ImageSize, - LoadedImage->Revision); - BlSleepExecution(3000); - } - - /* Close EFI LoadedImage protocol */ - BlCloseProtocol(&Handle, &LipGuid); - } -} - -/** - * Initializes a list of operating systems for XTLDR boot menu. - * - * @param MenuEntries - * Supplies a pointer to memory area where operating systems list will be stored. - * - * @param EntriesCount - * Supplies a pointer to memory area where number of menu entries will be stored. - * - * @param DefaultId - * Supplies a pointer to memory area where ID of default menu entry will be stored. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlInitializeBootMenuList(IN ULONG MaxNameLength, - OUT PXTBL_BOOTMENU_ITEM *MenuEntries, - OUT PULONG EntriesCount, - OUT PULONG DefaultId) -{ - EFI_GUID VendorGuid = XT_BOOT_LOADER_PROTOCOL_GUID; - PWCHAR DefaultMenuEntry, LastBooted, MenuEntryName, VisibleName; - PLIST_ENTRY MenuEntrySectionList, MenuEntryList; - PXTBL_CONFIG_SECTION MenuEntrySection; - PXTBL_CONFIG_ENTRY MenuEntryOption; - ULONG DefaultOS, NameLength,NumberOfEntries; - PXTBL_BOOTMENU_ITEM OsList; - EFI_STATUS Status; - - /* Set default values */ - DefaultOS = 0; - NumberOfEntries = 0; - - /* Get default menu entry from configuration */ - BlGetConfigValue(L"DEFAULT", &DefaultMenuEntry); - - /* Check if configuration allows to use last booted OS */ - if(BlGetConfigBooleanValue(L"KEEPLASTBOOT")) - { - /* Attempt to get last booted Operating System from NVRAM */ - Status = BlGetEfiVariable(&VendorGuid, L"XtLdrLastBootOS", (PVOID*)&LastBooted); - if(Status == STATUS_EFI_SUCCESS) - { - /* Set default menu entry to last booted OS */ - DefaultMenuEntry = LastBooted; - } - } - - /* Iterate through menu items to get a total number of entries */ - MenuEntrySectionList = BlpMenuList->Flink; - while(MenuEntrySectionList != BlpMenuList) - { - /* Increase number of menu entries, and simply get next item */ - NumberOfEntries++; - MenuEntrySectionList = MenuEntrySectionList->Flink; - } - - /* Allocate memory for the OS list depending on the item count */ - Status = BlAllocateMemoryPool(NumberOfEntries * sizeof(XTBL_BOOTMENU_ITEM), (PVOID*)&OsList); - if(Status != STATUS_EFI_SUCCESS || !OsList) - { - /* Memory allocation failure */ - return STATUS_EFI_OUT_OF_RESOURCES; - } - - /* Reset counter and iterate through all menu items once again */ - NumberOfEntries = 0; - MenuEntrySectionList = BlpMenuList->Flink; - while(MenuEntrySectionList != BlpMenuList) - { - /* NULLify menu entry name */ - MenuEntryName = NULL; - - /* Get menu section */ - MenuEntrySection = CONTAIN_RECORD(MenuEntrySectionList, XTBL_CONFIG_SECTION, Flink); - - /* Check if this is the default menu entry */ - if((RtlWideStringLength(MenuEntrySection->SectionName, 0) == RtlWideStringLength(DefaultMenuEntry, 0)) && - (RtlCompareWideStringInsensitive(MenuEntrySection->SectionName, DefaultMenuEntry, 0) == 0)) - { - /* Set default OS ID */ - DefaultOS = NumberOfEntries; - } - - /* Iterate through all entry parameters */ - MenuEntryList = MenuEntrySection->Options.Flink; - while(MenuEntryList != &MenuEntrySection->Options) - { - /* Get menu entry parameter */ - MenuEntryOption = CONTAIN_RECORD(MenuEntryList, XTBL_CONFIG_ENTRY, Flink); - - /* Check if this is the menu entry display name */ - if(RtlCompareWideStringInsensitive(MenuEntryOption->Name, L"SYSTEMNAME", 0) == 0) - { - /* Set menu entry display name */ - MenuEntryName = MenuEntryOption->Value; - } - - /* Get next parameter for this menu entry */ - MenuEntryList = MenuEntryList->Flink; - } - - /* Add OS to the boot menu list */ - OsList[NumberOfEntries].FullName = MenuEntryName; - OsList[NumberOfEntries].ShortName = MenuEntrySection->SectionName; - OsList[NumberOfEntries].Options = &MenuEntrySection->Options; - - /* Check if the menu entry name fits the maximum length */ - NameLength = RtlWideStringLength(MenuEntryName, 0); - if(NameLength > MaxNameLength) - { - /* Menu entry name is too long, allocate memory for shorter name visible in the boot menu */ - Status = BlAllocateMemoryPool((MaxNameLength + 1) * sizeof(WCHAR), (PVOID*)&VisibleName); - if(Status != STATUS_EFI_SUCCESS) - { - /* Memory allocation failure */ - return STATUS_EFI_OUT_OF_RESOURCES; - } - - /* Copy shorter name and append "..." at the end */ - RtlCopyMemory(VisibleName, MenuEntryName, (MaxNameLength - 3) * sizeof(WCHAR)); - RtlCopyMemory(VisibleName + MaxNameLength - 3, L"...", 3 * sizeof(WCHAR)); - VisibleName[MaxNameLength] = L'\0'; - - /* Set visible menu entry name */ - OsList[NumberOfEntries].EntryName = VisibleName; - } - else - { - /* Menu entry name fits the maximum length, use it as is */ - OsList[NumberOfEntries].EntryName = MenuEntryName; - } - - /* Get next menu entry */ - MenuEntrySectionList = MenuEntrySectionList->Flink; - NumberOfEntries++; - } - - /* Set return values */ - *DefaultId = DefaultOS; - *EntriesCount = NumberOfEntries; - *MenuEntries = OsList; - - /* Return success */ - return STATUS_EFI_SUCCESS; -} - -/** - * Loads all necessary modules and invokes boot protocol. - * - * @param ShortName - * Supplies a pointer to a short name of the chosen boot menu entry. - * - * @param OptionsList - * Supplies a pointer to list of options associated with chosen boot menu entry. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -EFI_STATUS -BlInvokeBootProtocol(IN PWCHAR ShortName, - IN PLIST_ENTRY OptionsList) -{ - EFI_GUID VendorGuid = XT_BOOT_LOADER_PROTOCOL_GUID; - XTBL_BOOT_PARAMETERS BootParameters; - PXTBL_BOOT_PROTOCOL BootProtocol; - PLIST_ENTRY OptionsListEntry; - PXTBL_CONFIG_ENTRY Option; - EFI_GUID BootProtocolGuid; - SIZE_T ModuleListLength; - PWCHAR ModulesList; - EFI_HANDLE Handle; - EFI_STATUS Status; - - /* Initialize boot parameters and a list of modules */ - RtlZeroMemory(&BootParameters, sizeof(XTBL_BOOT_PARAMETERS)); - ModulesList = NULL; - - /* Iterate through all options provided by boot menu entry and propagate boot parameters */ - OptionsListEntry = OptionsList->Flink; - while(OptionsListEntry != OptionsList) - { - /* Get option */ - Option = CONTAIN_RECORD(OptionsListEntry, XTBL_CONFIG_ENTRY, Flink); - - /* Look for boot protocol and modules list */ - if(RtlCompareWideStringInsensitive(Option->Name, L"BOOTMODULES", 0) == 0) - { - /* Check a length of modules list */ - ModuleListLength = RtlWideStringLength(Option->Value, 0); - - Status = BlAllocateMemoryPool(sizeof(WCHAR) * (ModuleListLength + 1), (PVOID *)&ModulesList); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to allocate memory, print error message and return status code */ - BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); - return STATUS_EFI_OUT_OF_RESOURCES; - } - - /* Make a copy of modules list */ - RtlCopyMemory(ModulesList, Option->Value, sizeof(WCHAR) * (ModuleListLength + 1)); - } - else if(RtlCompareWideStringInsensitive(Option->Name, L"SYSTEMTYPE", 0) == 0) - { - /* Boot protocol found */ - BootParameters.SystemType = Option->Value; - } - else if(RtlCompareWideStringInsensitive(Option->Name, L"SYSTEMPATH", 0) == 0) - { - /* System path found, get volume device path */ - Status = BlGetVolumeDevicePath(Option->Value, &BootParameters.DevicePath, - &BootParameters.ArcName, &BootParameters.SystemPath); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to find volume */ - BlDebugPrint(L"ERROR: Failed to find volume device path (Status Code: 0x%zX)\n", Status); - return Status; - } - - /* Get EFI compatible system path */ - Status = BlGetEfiPath(BootParameters.SystemPath, &BootParameters.EfiPath); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to get EFI path */ - BlDebugPrint(L"ERROR: Failed to get EFI path (Status Code: 0x%zX)\n", Status); - return Status; - } - } - else if(RtlCompareWideStringInsensitive(Option->Name, L"KERNELFILE", 0) == 0) - { - /* Kernel file name found */ - BootParameters.KernelFile = Option->Value; - } - else if(RtlCompareWideStringInsensitive(Option->Name, L"INITRDFILE", 0) == 0) - { - /* Initrd file name found */ - BootParameters.InitrdFile = Option->Value; - } - else if(RtlCompareWideStringInsensitive(Option->Name, L"HALFILE", 0) == 0) - { - /* Hal file name found */ - BootParameters.HalFile = Option->Value; - } - else if(RtlCompareWideStringInsensitive(Option->Name, L"PARAMETERS", 0) == 0) - { - /* Kernel parameters found */ - BootParameters.Parameters = Option->Value; - } - - /* Move to the next option entry */ - OptionsListEntry = OptionsListEntry->Flink; - } - - /* Load all necessary modules */ - Status = BlLoadModules(ModulesList); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to load modules, print error message and return status code */ - BlDebugPrint(L"ERROR: Failed to load XTLDR modules (Status Code: 0x%zX)\n", Status); - return STATUS_EFI_NOT_READY; - } - - /* Attempt to get boot protocol GUID */ - Status = BlFindBootProtocol(BootParameters.SystemType, &BootProtocolGuid); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to get boot protocol GUID */ - BlDebugPrint(L"ERROR: Unable to find appropriate boot protocol (Status Code: 0x%zX)\n", Status); - return STATUS_EFI_UNSUPPORTED; - } - - /* Open boot protocol */ - Status = BlOpenProtocol(&Handle, (PVOID *)&BootProtocol, &BootProtocolGuid); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to open boot protocol */ - BlDebugPrint(L"ERROR: Failed to open boot protocol (Status Code: 0x%zX)\n", Status); - return Status; - } - - /* Check if chosen operating system should be saved */ - if(BlGetConfigBooleanValue(L"KEEPLASTBOOT")) - { - /* Save chosen operating system in NVRAM */ - Status = BlSetEfiVariable(&VendorGuid, L"XtLdrLastBootOS", (PVOID)ShortName, RtlWideStringLength(ShortName, 0) * sizeof(WCHAR)); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to save chosen Operating System */ - BlDebugPrint(L"WARNING: Failed to save chosen Operating System in NVRAM (Status Code: 0x%zX)\n", Status); - } - } - - /* Boot Operating System */ - return BootProtocol->BootSystem(&BootParameters); -} - -/** - * 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; - - /* Set the system table and image handle */ - EfiImageHandle = ImageHandle; - EfiSystemTable = SystemTable; - - /* Initialize XTLDR and */ - BlInitializeBootLoader(); - - /* Parse configuration options passed from UEFI shell */ - Status = BlpParseCommandLine(); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to parse command line options */ - BlDisplayErrorDialog(L"XTLDR", L"Failed to parse command line parameters."); - } - - /* Attempt to early initialize debug console */ - if(DEBUG) - { - Status = BlpInitializeDebugConsole(); - if(Status != STATUS_EFI_SUCCESS) - { - /* Initialization failed, notify user on stdout */ - BlDisplayErrorDialog(L"XTLDR", L"Failed to initialize debug console."); - } - } - - /* Load XTLDR configuration file */ - Status = BlpLoadConfiguration(); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to load/parse config file */ - BlDisplayErrorDialog(L"XTLDR", L"Failed to load and parse configuration file "); - } - - /* Reinitialize debug console if it was not initialized earlier */ - if(DEBUG) - { - Status = BlpInitializeDebugConsole(); - if(Status != STATUS_EFI_SUCCESS) - { - /* Initialization failed, notify user on stdout */ - BlDisplayErrorDialog(L"XTLDR", L"Failed to initialize debug console."); - } - } - - /* Disable watchdog timer */ - Status = EfiSystemTable->BootServices->SetWatchdogTimer(0, 0x10000, 0, NULL); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to disable the timer, print message */ - BlDebugPrint(L"WARNING: Failed to disable watchdog timer (Status Code: 0x%zX)\n", Status); - } - - /* Install loader protocol */ - Status = BlpInstallXtLoaderProtocol(); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to register loader protocol */ - BlDebugPrint(L"ERROR: Failed to register XTLDR loader protocol (Status Code: 0x%zX)\n", Status); - return Status; - } - - /* Load all necessary modules */ - BlGetConfigValue(L"MODULES", &Modules); - Status = BlLoadModules(Modules); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to load modules */ - BlDebugPrint(L"ERROR: Failed to load XTLDR modules (Status Code: 0x%zX)\n", Status); - BlDisplayErrorDialog(L"XTLDR", L"Failed to load some XTLDR modules."); - } - - /* Discover and enumerate EFI block devices */ - Status = BlEnumerateBlockDevices(); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to enumerate block devices */ - BlDebugPrint(L"ERROR: Failed to discover and enumerate block devices (Status Code: 0x%zX)\n", Status); - return Status; - } - - /* Main boot loader loop */ - while(TRUE) - { - /* Check if custom boot menu registered */ - if(BlpStatus.BootMenu != NULL) - { - /* Display alternative boot menu */ - BlpStatus.BootMenu(); - } - else - { - /* Display default boot menu */ - BlDisplayBootMenu(); - } - - /* Fallback to shell, if boot menu returned */ - BlStartLoaderShell(); - } - - /* This point should be never reached, if this happen return error code */ - return STATUS_EFI_LOAD_ERROR; -} diff --git a/xtldr/xtldr.cc b/xtldr/xtldr.cc new file mode 100644 index 0000000..2e960f6 --- /dev/null +++ b/xtldr/xtldr.cc @@ -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 + */ + +#include + + +/** + * 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; +} diff --git a/xtoskrnl/CMakeLists.txt b/xtoskrnl/CMakeLists.txt index 5037c0e..07f9468 100644 --- a/xtoskrnl/CMakeLists.txt +++ b/xtoskrnl/CMakeLists.txt @@ -7,89 +7,78 @@ include_directories( ${EXECTOS_SOURCE_DIR}/sdk/xtdk ${XTOSKRNL_SOURCE_DIR}/includes) -# Specify list of library source code files -list(APPEND LIBXTOS_SOURCE - ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/boot.S - ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.c - ${XTOSKRNL_SOURCE_DIR}/hl/cport.c - ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.c - ${XTOSKRNL_SOURCE_DIR}/rtl/globals.c - ${XTOSKRNL_SOURCE_DIR}/rtl/guid.c - ${XTOSKRNL_SOURCE_DIR}/rtl/math.c - ${XTOSKRNL_SOURCE_DIR}/rtl/memory.c - ${XTOSKRNL_SOURCE_DIR}/rtl/plist.c - ${XTOSKRNL_SOURCE_DIR}/rtl/string.c - ${XTOSKRNL_SOURCE_DIR}/rtl/widestr.c) - # Specify list of kernel source code files list(APPEND XTOSKRNL_SOURCE ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/archsup.S ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/boot.S - ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.c - ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/globals.c - ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/procsup.c - ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/traps.c - ${XTOSKRNL_SOURCE_DIR}/ex/rundown.c - ${XTOSKRNL_SOURCE_DIR}/hl/acpi.c - ${XTOSKRNL_SOURCE_DIR}/hl/cport.c - ${XTOSKRNL_SOURCE_DIR}/hl/fbdev.c - ${XTOSKRNL_SOURCE_DIR}/hl/globals.c - ${XTOSKRNL_SOURCE_DIR}/hl/init.c - ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/cpu.c - ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/pic.c - ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.c - ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/runlevel.c - ${XTOSKRNL_SOURCE_DIR}/kd/dbginit.c - ${XTOSKRNL_SOURCE_DIR}/kd/dbgio.c - ${XTOSKRNL_SOURCE_DIR}/kd/globals.c - ${XTOSKRNL_SOURCE_DIR}/ke/apc.c - ${XTOSKRNL_SOURCE_DIR}/ke/dpc.c - ${XTOSKRNL_SOURCE_DIR}/ke/event.c - ${XTOSKRNL_SOURCE_DIR}/ke/globals.c - ${XTOSKRNL_SOURCE_DIR}/ke/info.c - ${XTOSKRNL_SOURCE_DIR}/ke/kprocess.c - ${XTOSKRNL_SOURCE_DIR}/ke/krnlinit.c - ${XTOSKRNL_SOURCE_DIR}/ke/kthread.c - ${XTOSKRNL_SOURCE_DIR}/ke/kubsan.c - ${XTOSKRNL_SOURCE_DIR}/ke/panic.c - ${XTOSKRNL_SOURCE_DIR}/ke/runlevel.c - ${XTOSKRNL_SOURCE_DIR}/ke/semphore.c - ${XTOSKRNL_SOURCE_DIR}/ke/spinlock.c - ${XTOSKRNL_SOURCE_DIR}/ke/sysres.c - ${XTOSKRNL_SOURCE_DIR}/ke/timer.c - ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/irqs.c - ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/krnlinit.c - ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/kthread.c - ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/proc.c - ${XTOSKRNL_SOURCE_DIR}/mm/globals.c - ${XTOSKRNL_SOURCE_DIR}/mm/hlpool.c - ${XTOSKRNL_SOURCE_DIR}/mm/init.c - ${XTOSKRNL_SOURCE_DIR}/mm/kpools.c - ${XTOSKRNL_SOURCE_DIR}/mm/pages.c - ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/globals.c - ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/init.c - ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pages.c - ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pmap.c - ${XTOSKRNL_SOURCE_DIR}/po/idle.c - ${XTOSKRNL_SOURCE_DIR}/rtl/atomic.c - ${XTOSKRNL_SOURCE_DIR}/rtl/bitmap.c - ${XTOSKRNL_SOURCE_DIR}/rtl/byteswap.c - ${XTOSKRNL_SOURCE_DIR}/rtl/globals.c - ${XTOSKRNL_SOURCE_DIR}/rtl/guid.c - ${XTOSKRNL_SOURCE_DIR}/rtl/ioreg.c - ${XTOSKRNL_SOURCE_DIR}/rtl/math.c - ${XTOSKRNL_SOURCE_DIR}/rtl/memory.c - ${XTOSKRNL_SOURCE_DIR}/rtl/plist.c - ${XTOSKRNL_SOURCE_DIR}/rtl/string.c - ${XTOSKRNL_SOURCE_DIR}/rtl/widestr.c - ${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/dispatch.c - ${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/exsup.c) + ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.cc + ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/data.cc + ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/procsup.cc + ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/traps.cc + ${XTOSKRNL_SOURCE_DIR}/ex/exports.cc + ${XTOSKRNL_SOURCE_DIR}/ex/rundown.cc + ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/cpu.cc + ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/pic.cc + ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.cc + ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/runlevel.cc + ${XTOSKRNL_SOURCE_DIR}/hl/acpi.cc + ${XTOSKRNL_SOURCE_DIR}/hl/cport.cc + ${XTOSKRNL_SOURCE_DIR}/hl/data.cc + ${XTOSKRNL_SOURCE_DIR}/hl/exports.cc + ${XTOSKRNL_SOURCE_DIR}/hl/fbdev.cc + ${XTOSKRNL_SOURCE_DIR}/hl/init.cc + ${XTOSKRNL_SOURCE_DIR}/hl/ioreg.cc + ${XTOSKRNL_SOURCE_DIR}/kd/data.cc + ${XTOSKRNL_SOURCE_DIR}/kd/dbgio.cc + ${XTOSKRNL_SOURCE_DIR}/kd/exports.cc + ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/irq.cc + ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/krnlinit.cc + ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/kthread.cc + ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/proc.cc + ${XTOSKRNL_SOURCE_DIR}/ke/apc.cc + ${XTOSKRNL_SOURCE_DIR}/ke/bootinfo.cc + ${XTOSKRNL_SOURCE_DIR}/ke/crash.cc + ${XTOSKRNL_SOURCE_DIR}/ke/data.cc + ${XTOSKRNL_SOURCE_DIR}/ke/dpc.cc + ${XTOSKRNL_SOURCE_DIR}/ke/event.cc + ${XTOSKRNL_SOURCE_DIR}/ke/exports.cc + ${XTOSKRNL_SOURCE_DIR}/ke/kprocess.cc + ${XTOSKRNL_SOURCE_DIR}/ke/krnlinit.cc + ${XTOSKRNL_SOURCE_DIR}/ke/kthread.cc + ${XTOSKRNL_SOURCE_DIR}/ke/kubsan.cc + ${XTOSKRNL_SOURCE_DIR}/ke/runlevel.cc + ${XTOSKRNL_SOURCE_DIR}/ke/semphore.cc + ${XTOSKRNL_SOURCE_DIR}/ke/spinlock.cc + ${XTOSKRNL_SOURCE_DIR}/ke/sysres.cc + ${XTOSKRNL_SOURCE_DIR}/ke/timer.cc + ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/init.cc + ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pagemap.cc + ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/paging.cc + ${XTOSKRNL_SOURCE_DIR}/mm/data.cc + ${XTOSKRNL_SOURCE_DIR}/mm/hlpool.cc + ${XTOSKRNL_SOURCE_DIR}/mm/init.cc + ${XTOSKRNL_SOURCE_DIR}/mm/kpool.cc + ${XTOSKRNL_SOURCE_DIR}/mm/paging.cc + ${XTOSKRNL_SOURCE_DIR}/po/idle.cc + ${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/dispatch.cc + ${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/exsup.cc + ${XTOSKRNL_SOURCE_DIR}/rtl/atomic.cc + ${XTOSKRNL_SOURCE_DIR}/rtl/bitmap.cc + ${XTOSKRNL_SOURCE_DIR}/rtl/data.cc + ${XTOSKRNL_SOURCE_DIR}/rtl/endian.cc + ${XTOSKRNL_SOURCE_DIR}/rtl/exports.cc + ${XTOSKRNL_SOURCE_DIR}/rtl/guid.cc + ${XTOSKRNL_SOURCE_DIR}/rtl/llist.cc + ${XTOSKRNL_SOURCE_DIR}/rtl/math.cc + ${XTOSKRNL_SOURCE_DIR}/rtl/memory.cc + ${XTOSKRNL_SOURCE_DIR}/rtl/string.cc + ${XTOSKRNL_SOURCE_DIR}/rtl/widestr.cc) # Set module definition SPEC file set_specfile(xtoskrnl.spec xtoskrnl.exe) # Link static XTOS library -add_library(libxtos ${LIBXTOS_SOURCE}) +add_library(libxtos ${XTOSKRNL_SOURCE}) # Link kernel executable add_executable(xtoskrnl diff --git a/xtoskrnl/README.md b/xtoskrnl/README.md index 670fca5..9112f64 100644 --- a/xtoskrnl/README.md +++ b/xtoskrnl/README.md @@ -4,8 +4,8 @@ within the XTOS kernel space. It is responsible for various core services, such management, and process scheduling. The kernel contains the scheduler (sometimes referred to as the Dispatcher), the cache, object, and memory managers, the security manager, and other executive components described below. -All routines in the kernel are prefixed to indicate the subsystem they belong to, and their source code is organized -into corresponding directories. These subsystems include: +The source code of the kernel is organized into subsystem-specific directories. Each directory name also defines the +corresponding C++ namespace in which the subsystem's classes and routines reside. These subsystems include: * Ar - Architecture-specific Library * Ex - Kernel Executive @@ -56,13 +56,20 @@ routines, for use by other kernel components. ## Function Naming Convention All kernel functions adhere to a strict naming convention to enhance code readability and maintainability. The structure -of a function name is generally composed of three parts: <Prefix><Operation><Object> +of all public interfaces exposed by the kernel are generally composed of three parts: +<Prefix><Operation><Object> -The prefix identifies the component to which the function belongs. Additionally, the prefix indicates the function's -visibility. Private functions, which should not be called from outside their own module, have a 'p' appended to their -prefix. - -For example, consider the **KepInitializeStack()** routine: - * **Kep** - The prefix indicates a private (p) routine belonging to the Core Kernel Library (Ke). +The prefix identifies the component to which the function belongs. For example, consider the **KeInitializeThread()** +routine: + * **Ke** - The prefix indicates a routine belonging to the Core Kernel Library (Ke). * **Initialize** - The operation performed by the function. - * **Stack** - The object on which the operation is performed. + * **Thread** - The object on which the operation is performed. + +For all C++ code inside the kernel the naming model has evolved. Consider the **KE::KThread::InitializeThread()** +routine: + * **KE** - The namespace replaces the prefix and indicates the subsystem. Namespaces are written in uppercase and no + longer use the trailing p for private routines, because classes use C++ visibility to control access. + * **KThread** - Within each namespace, related functionality is grouped into classes, which encapsulate variables and + methods. + * **InitializeThread** - Method names follow the `` pattern. + \ No newline at end of file diff --git a/xtoskrnl/ar/amd64/archsup.S b/xtoskrnl/ar/amd64/archsup.S index 849df4f..d91f8ea 100644 --- a/xtoskrnl/ar/amd64/archsup.S +++ b/xtoskrnl/ar/amd64/archsup.S @@ -6,7 +6,7 @@ * DEVELOPERS: Rafal Kupiec */ -#include +#include .altmacro .text @@ -22,9 +22,9 @@ * * @since XT 1.0 */ -.macro ArpCreateTrapHandler Vector -.global ArpTrap\Vector -ArpTrap\Vector: +.macro ArCreateTrapHandler Vector +.global ArTrap\Vector +ArTrap\Vector: /* Push fake error code for non-error vectors */ .if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30 push $0 @@ -113,7 +113,7 @@ KernelMode$\Vector: /* Push Frame Pointer, clear direction flag and pass to trap dispatcher */ mov %rsp, %rcx cld - call ArpDispatchTrap + call ArDispatchTrap /* Test previous mode and swapgs if needed */ testb $1, TrapPreviousMode(%rbp) @@ -176,6 +176,6 @@ KernelModeReturn$\Vector: /* Populate common trap handlers */ .irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F .irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F - ArpCreateTrapHandler 0x\i\j + ArCreateTrapHandler 0x\i\j .endr .endr diff --git a/xtoskrnl/ar/amd64/boot.S b/xtoskrnl/ar/amd64/boot.S index d631845..a2f6dba 100644 --- a/xtoskrnl/ar/amd64/boot.S +++ b/xtoskrnl/ar/amd64/boot.S @@ -6,7 +6,7 @@ * DEVELOPERS: Aiken Harris */ -#include +#include .altmacro .text @@ -131,3 +131,17 @@ XpaTemporaryGdtDesc: .quad 0x0000000000000000, 0x00CF9A000000FFFF, 0x00AF9A00000 .global ArEnableExtendedPhysicalAddressingEnd ArEnableExtendedPhysicalAddressingEnd: + + +/** + * Starts an application processor (AP). This is just a stub. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +.global ArStartApplicationProcessor +ArStartApplicationProcessor: + +.global ArStartApplicationProcessorEnd +ArStartApplicationProcessorEnd: diff --git a/xtoskrnl/ar/amd64/cpufunc.c b/xtoskrnl/ar/amd64/cpufunc.cc similarity index 90% rename from xtoskrnl/ar/amd64/cpufunc.c rename to xtoskrnl/ar/amd64/cpufunc.cc index d129717..9a3db05 100644 --- a/xtoskrnl/ar/amd64/cpufunc.c +++ b/xtoskrnl/ar/amd64/cpufunc.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ar/amd64/cpufunc.c + * FILE: xtoskrnl/ar/amd64/cpufunc.cc * DESCRIPTION: Routines to provide access to special AMD64 CPU instructions * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -18,7 +18,7 @@ */ XTCDECL VOID -ArClearInterruptFlag(VOID) +AR::CpuFunc::ClearInterruptFlag(VOID) { __asm__ volatile("cli"); } @@ -35,7 +35,7 @@ ArClearInterruptFlag(VOID) */ XTCDECL BOOLEAN -ArCpuId(IN OUT PCPUID_REGISTERS Registers) +AR::CpuFunc::CpuId(IN OUT PCPUID_REGISTERS Registers) { UINT32 MaxLeaf; @@ -76,10 +76,10 @@ ArCpuId(IN OUT PCPUID_REGISTERS Registers) */ XTCDECL VOID -ArFlushTlb(VOID) +AR::CpuFunc::FlushTlb(VOID) { /* Flush the TLB by resetting the CR3 */ - ArWriteControlRegister(3, ArReadControlRegister(3)); + WriteControlRegister(3, ReadControlRegister(3)); } /** @@ -91,7 +91,7 @@ ArFlushTlb(VOID) */ XTCDECL ULONG -ArGetCpuFlags(VOID) +AR::CpuFunc::GetCpuFlags(VOID) { ULONG_PTR Flags; @@ -116,7 +116,7 @@ ArGetCpuFlags(VOID) XTASSEMBLY XTCDECL ULONG_PTR -ArGetStackPointer(VOID) +AR::CpuFunc::GetStackPointer(VOID) { /* Get current stack pointer */ __asm__ volatile("movq %%rsp, %%rax\n" @@ -135,7 +135,7 @@ ArGetStackPointer(VOID) */ XTCDECL VOID -ArHalt(VOID) +AR::CpuFunc::Halt(VOID) { __asm__ volatile("hlt"); } @@ -149,12 +149,12 @@ ArHalt(VOID) */ XTCDECL BOOLEAN -ArInterruptsEnabled(VOID) +AR::CpuFunc::InterruptsEnabled(VOID) { ULONG_PTR Flags; /* Get RFLAGS register */ - Flags = ArGetCpuFlags(); + Flags = GetCpuFlags(); /* Check if interrupts are enabled and return result */ return (Flags & X86_EFLAGS_IF_MASK) ? TRUE : FALSE; @@ -172,7 +172,7 @@ ArInterruptsEnabled(VOID) */ XTCDECL VOID -ArInvalidateTlbEntry(IN PVOID Address) +AR::CpuFunc::InvalidateTlbEntry(IN PVOID Address) { __asm__ volatile("invlpg (%0)" : @@ -192,7 +192,7 @@ ArInvalidateTlbEntry(IN PVOID Address) */ XTCDECL VOID -ArLoadGlobalDescriptorTable(IN PVOID Source) +AR::CpuFunc::LoadGlobalDescriptorTable(IN PVOID Source) { __asm__ volatile("lgdt %0" : @@ -212,7 +212,7 @@ ArLoadGlobalDescriptorTable(IN PVOID Source) */ XTCDECL VOID -ArLoadInterruptDescriptorTable(IN PVOID Source) +AR::CpuFunc::LoadInterruptDescriptorTable(IN PVOID Source) { __asm__ volatile("lidt %0" : @@ -232,7 +232,7 @@ ArLoadInterruptDescriptorTable(IN PVOID Source) */ XTCDECL VOID -ArLoadLocalDescriptorTable(IN USHORT Source) +AR::CpuFunc::LoadLocalDescriptorTable(IN USHORT Source) { __asm__ volatile("lldtw %0" : @@ -251,7 +251,7 @@ ArLoadLocalDescriptorTable(IN USHORT Source) */ XTCDECL VOID -ArLoadMxcsrRegister(IN ULONG Source) +AR::CpuFunc::LoadMxcsrRegister(IN ULONG Source) { __asm__ volatile("ldmxcsr %0" : @@ -273,8 +273,8 @@ ArLoadMxcsrRegister(IN ULONG Source) */ XTCDECL VOID -ArLoadSegment(IN USHORT Segment, - IN ULONG Source) +AR::CpuFunc::LoadSegment(IN USHORT Segment, + IN ULONG Source) { switch(Segment) { @@ -335,7 +335,7 @@ ArLoadSegment(IN USHORT Segment, */ XTCDECL VOID -ArLoadTaskRegister(USHORT Source) +AR::CpuFunc::LoadTaskRegister(USHORT Source) { __asm__ volatile("ltr %0" : @@ -351,7 +351,7 @@ ArLoadTaskRegister(USHORT Source) */ XTCDECL VOID -ArMemoryBarrier(VOID) +AR::CpuFunc::MemoryBarrier(VOID) { LONG Barrier; __asm__ volatile("lock; orl $0, %0;" @@ -371,7 +371,7 @@ ArMemoryBarrier(VOID) */ XTCDECL ULONG_PTR -ArReadControlRegister(IN USHORT ControlRegister) +AR::CpuFunc::ReadControlRegister(IN USHORT ControlRegister) { ULONG_PTR Value; @@ -435,7 +435,7 @@ ArReadControlRegister(IN USHORT ControlRegister) */ XTCDECL ULONG_PTR -ArReadDebugRegister(IN USHORT DebugRegister) +AR::CpuFunc::ReadDebugRegister(IN USHORT DebugRegister) { ULONG_PTR Value; @@ -504,7 +504,7 @@ ArReadDebugRegister(IN USHORT DebugRegister) */ XTCDECL ULONGLONG -ArReadGSQuadWord(ULONG Offset) +AR::CpuFunc::ReadGSQuadWord(ULONG Offset) { ULONGLONG Value; @@ -527,7 +527,7 @@ ArReadGSQuadWord(ULONG Offset) */ XTCDECL ULONGLONG -ArReadModelSpecificRegister(IN ULONG Register) +AR::CpuFunc::ReadModelSpecificRegister(IN ULONG Register) { ULONG Low, High; @@ -548,7 +548,7 @@ ArReadModelSpecificRegister(IN ULONG Register) */ XTCDECL UINT -ArReadMxCsrRegister(VOID) +AR::CpuFunc::ReadMxCsrRegister(VOID) { return __builtin_ia32_stmxcsr(); } @@ -562,7 +562,7 @@ ArReadMxCsrRegister(VOID) */ XTCDECL ULONGLONG -ArReadTimeStampCounter(VOID) +AR::CpuFunc::ReadTimeStampCounter(VOID) { ULONGLONG Low, High; @@ -582,7 +582,7 @@ ArReadTimeStampCounter(VOID) */ XTCDECL VOID -ArReadWriteBarrier(VOID) +AR::CpuFunc::ReadWriteBarrier(VOID) { __asm__ volatile("" : @@ -599,7 +599,7 @@ ArReadWriteBarrier(VOID) */ XTCDECL VOID -ArSetInterruptFlag(VOID) +AR::CpuFunc::SetInterruptFlag(VOID) { __asm__ volatile("sti"); } @@ -616,7 +616,7 @@ ArSetInterruptFlag(VOID) */ XTCDECL VOID -ArStoreGlobalDescriptorTable(OUT PVOID Destination) +AR::CpuFunc::StoreGlobalDescriptorTable(OUT PVOID Destination) { __asm__ volatile("sgdt %0" : "=m" (*(PSHORT)Destination) @@ -636,7 +636,7 @@ ArStoreGlobalDescriptorTable(OUT PVOID Destination) */ XTCDECL VOID -ArStoreInterruptDescriptorTable(OUT PVOID Destination) +AR::CpuFunc::StoreInterruptDescriptorTable(OUT PVOID Destination) { __asm__ volatile("sidt %0" : "=m" (*(PSHORT)Destination) @@ -656,7 +656,7 @@ ArStoreInterruptDescriptorTable(OUT PVOID Destination) */ XTCDECL VOID -ArStoreLocalDescriptorTable(OUT PVOID Destination) +AR::CpuFunc::StoreLocalDescriptorTable(OUT PVOID Destination) { __asm__ volatile("sldt %0" : "=m" (*(PSHORT)Destination) @@ -679,8 +679,8 @@ ArStoreLocalDescriptorTable(OUT PVOID Destination) */ XTCDECL VOID -ArStoreSegment(IN USHORT Segment, - OUT PVOID Destination) +AR::CpuFunc::StoreSegment(IN USHORT Segment, + OUT PVOID Destination) { switch(Segment) { @@ -709,7 +709,7 @@ ArStoreSegment(IN USHORT Segment, : "=r" (*(PUINT)Destination)); break; default: - Destination = NULL; + Destination = NULLPTR; break; } } @@ -726,7 +726,7 @@ ArStoreSegment(IN USHORT Segment, */ XTCDECL VOID -ArStoreTaskRegister(OUT PVOID Destination) +AR::CpuFunc::StoreTaskRegister(OUT PVOID Destination) { __asm__ volatile("str %0" : "=m" (*(PULONG)Destination) @@ -749,8 +749,8 @@ ArStoreTaskRegister(OUT PVOID Destination) */ XTCDECL VOID -ArWriteControlRegister(IN USHORT ControlRegister, - IN UINT_PTR Value) +AR::CpuFunc::WriteControlRegister(IN USHORT ControlRegister, + IN UINT_PTR Value) { /* Write a value into specified control register */ switch(ControlRegister) @@ -808,8 +808,8 @@ ArWriteControlRegister(IN USHORT ControlRegister, */ XTCDECL VOID -ArWriteDebugRegister(IN USHORT DebugRegister, - IN UINT_PTR Value) +AR::CpuFunc::WriteDebugRegister(IN USHORT DebugRegister, + IN UINT_PTR Value) { /* Write a value into specified debug register */ switch(DebugRegister) @@ -820,48 +820,56 @@ ArWriteDebugRegister(IN USHORT DebugRegister, : : "r" (Value) : "memory"); + break; case 1: /* Write value to DR1 */ __asm__ volatile("mov %0, %%dr1" : : "r" (Value) : "memory"); + break; case 2: /* Write value to DR2 */ __asm__ volatile("mov %0, %%dr2" : : "r" (Value) : "memory"); + break; case 3: /* Write value to DR3 */ __asm__ volatile("mov %0, %%dr3" : : "r" (Value) : "memory"); + break; case 4: /* Write value to DR4 */ __asm__ volatile("mov %0, %%dr4" : : "r" (Value) : "memory"); + break; case 5: /* Write value to DR5 */ __asm__ volatile("mov %0, %%dr5" : : "r" (Value) : "memory"); + break; case 6: /* Write value to DR6 */ __asm__ volatile("mov %0, %%dr6" : : "r" (Value) : "memory"); + break; case 7: /* Write value to DR7 */ __asm__ volatile("mov %0, %%dr7" : : "r" (Value) : "memory"); + break; } } @@ -877,7 +885,7 @@ ArWriteDebugRegister(IN USHORT DebugRegister, */ XTCDECL VOID -ArWriteEflagsRegister(IN UINT_PTR Value) +AR::CpuFunc::WriteEflagsRegister(IN UINT_PTR Value) { __asm__ volatile("push %0\n" "popf" @@ -900,8 +908,8 @@ ArWriteEflagsRegister(IN UINT_PTR Value) */ XTCDECL VOID -ArWriteModelSpecificRegister(IN ULONG Register, - IN ULONGLONG Value) +AR::CpuFunc::WriteModelSpecificRegister(IN ULONG Register, + IN ULONGLONG Value) { ULONG Low = Value & 0xFFFFFFFF; ULONG High = Value >> 32; @@ -922,7 +930,7 @@ ArWriteModelSpecificRegister(IN ULONG Register, */ XTCDECL VOID -ArYieldProcessor(VOID) +AR::CpuFunc::YieldProcessor(VOID) { __asm__ volatile("pause" : diff --git a/xtoskrnl/ar/amd64/data.cc b/xtoskrnl/ar/amd64/data.cc new file mode 100644 index 0000000..f8e124a --- /dev/null +++ b/xtoskrnl/ar/amd64/data.cc @@ -0,0 +1,28 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/ar/amd64/data.cc + * DESCRIPTION: AMD64 architecture-specific global and static data + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/* Initial kernel boot stack */ +UCHAR AR::ProcSup::BootStack[KERNEL_STACK_SIZE] = {}; + +/* Initial kernel fault stack */ +UCHAR AR::ProcSup::FaultStack[KERNEL_STACK_SIZE] = {}; + +/* Initial GDT */ +KGDTENTRY AR::ProcSup::InitialGdt[GDT_ENTRIES] = {}; + +/* Initial IDT */ +KIDTENTRY AR::ProcSup::InitialIdt[IDT_ENTRIES] = {}; + +/* Initial Processor Block */ +KPROCESSOR_BLOCK AR::ProcSup::InitialProcessorBlock; + +/* Initial TSS */ +KTSS AR::ProcSup::InitialTss; diff --git a/xtoskrnl/ar/amd64/globals.c b/xtoskrnl/ar/amd64/globals.c deleted file mode 100644 index 2221171..0000000 --- a/xtoskrnl/ar/amd64/globals.c +++ /dev/null @@ -1,28 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ar/amd64/globals.c - * DESCRIPTION: XT architecture library global variables - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/* Initial GDT */ -KGDTENTRY ArInitialGdt[GDT_ENTRIES] = {0}; - -/* Initial IDT */ -KIDTENTRY ArInitialIdt[IDT_ENTRIES] = {0}; - -/* Initial Processor Block */ -KPROCESSOR_BLOCK ArInitialProcessorBlock; - -/* Initial TSS */ -KTSS ArInitialTss; - -/* Initial kernel boot stack */ -UCHAR ArKernelBootStack[KERNEL_STACK_SIZE] = {0}; - -/* Initial kernel fault stack */ -UCHAR ArKernelFaultStack[KERNEL_STACK_SIZE] = {0}; diff --git a/xtoskrnl/ar/amd64/procsup.c b/xtoskrnl/ar/amd64/procsup.cc similarity index 54% rename from xtoskrnl/ar/amd64/procsup.c rename to xtoskrnl/ar/amd64/procsup.cc index d58a889..4656ab5 100644 --- a/xtoskrnl/ar/amd64/procsup.c +++ b/xtoskrnl/ar/amd64/procsup.cc @@ -1,121 +1,51 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ar/amd64/procsup.c + * FILE: xtoskrnl/ar/amd64/procsup.cc * DESCRIPTION: AMD64 processor functionality support * DEVELOPERS: Rafal Kupiec */ -#include +#include /** - * Initializes AMD64 processor specific structures. + * Gets the base address of the kernel boot stack. * - * @return This routine does not return any value. + * @return This routine returns a pointer to the kernel boot stack. * * @since XT 1.0 */ XTAPI -VOID -ArInitializeProcessor(IN PVOID ProcessorStructures) +PVOID +AR::ProcSup::GetBootStack(VOID) { - KDESCRIPTOR GdtDescriptor, IdtDescriptor; - PVOID KernelBootStack, KernelFaultStack; - PKPROCESSOR_BLOCK ProcessorBlock; - PKGDTENTRY Gdt; - PKIDTENTRY Idt; - PKTSS Tss; - - /* Check if processor structures buffer provided */ - if(ProcessorStructures) - { - /* Assign CPU structures from provided buffer */ - ArpInitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock, - &KernelBootStack, &KernelFaultStack); - - /* Use global IDT */ - Idt = ArInitialIdt; - } - else - { - /* Use initial structures */ - Gdt = ArInitialGdt; - Idt = ArInitialIdt; - Tss = &ArInitialTss; - KernelBootStack = &ArKernelBootStack; - KernelFaultStack = &ArKernelFaultStack; - ProcessorBlock = &ArInitialProcessorBlock; - } - - /* Initialize processor block */ - ArpInitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack); - - /* Initialize GDT, IDT and TSS */ - ArpInitializeGdt(ProcessorBlock); - ArpInitializeIdt(ProcessorBlock); - ArpInitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack); - - /* Set GDT and IDT descriptors */ - GdtDescriptor.Base = Gdt; - GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1; - IdtDescriptor.Base = Idt; - IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1; - - /* Load GDT, IDT and TSS */ - ArLoadGlobalDescriptorTable(&GdtDescriptor.Limit); - ArLoadInterruptDescriptorTable(&IdtDescriptor.Limit); - ArLoadTaskRegister((UINT)KGDT_SYS_TSS); - - /* Enter passive IRQ level */ - HlSetRunLevel(PASSIVE_LEVEL); - - /* Initialize segment registers */ - ArpInitializeSegments(); - - /* Set GS base */ - ArWriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock); - ArWriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock); - - /* Initialize processor registers */ - ArpInitializeProcessorRegisters(); - - /* Identify processor */ - ArpIdentifyProcessor(); + return (PVOID)BootStack; } -/** - * Updates an existing AMD64 GDT entry with new base address. - * - * @param Gdt - * Supplies a pointer to the GDT. - * - * @param Selector - * Specifies a segment selector of the GDT entry. - * - * @param Base - * Specifies a base address value of the descriptor. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ XTAPI VOID -ArSetGdtEntryBase(IN PKGDTENTRY Gdt, - IN USHORT Selector, - IN ULONG_PTR Base) +AR::ProcSup::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType, + OUT PVOID *TrampolineCode, + OUT PULONG_PTR TrampolineSize) { - PKGDTENTRY GdtEntry; - - /* Get GDT entry */ - GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK)); - - /* Set new GDT descriptor base */ - GdtEntry->BaseLow = (Base & 0xFFFF); - GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF); - GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF); - GdtEntry->BaseUpper = (Base >> 32); + switch(TrampolineType) + { + case TrampolineApStartup: + *TrampolineCode = (PVOID)ArStartApplicationProcessor; + *TrampolineSize = (ULONG_PTR)ArStartApplicationProcessorEnd - + (ULONG_PTR)ArStartApplicationProcessor; + break; + case TrampolineEnableXpa: + *TrampolineCode = (PVOID)ArEnableExtendedPhysicalAddressing; + *TrampolineSize = (ULONG_PTR)ArEnableExtendedPhysicalAddressingEnd - + (ULONG_PTR)ArEnableExtendedPhysicalAddressing; + break; + default: + *TrampolineCode = NULLPTR; + *TrampolineSize = 0; + break; + } } /** @@ -128,7 +58,7 @@ ArSetGdtEntryBase(IN PKGDTENTRY Gdt, */ XTAPI VOID -ArpIdentifyProcessor(VOID) +AR::ProcSup::IdentifyProcessor(VOID) { PKPROCESSOR_CONTROL_BLOCK Prcb; CPUID_REGISTERS CpuRegisters; @@ -138,15 +68,15 @@ ArpIdentifyProcessor(VOID) UNIMPLEMENTED; /* Get current processor control block */ - Prcb = KeGetCurrentProcessorControlBlock(); + Prcb = KE::Processor::GetCurrentProcessorControlBlock(); /* Get CPU vendor by issueing CPUID instruction */ RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING; - ArCpuId(&CpuRegisters); + CpuFunc::CpuId(&CpuRegisters); /* Store CPU vendor in processor control block */ - Prcb->CpuId.Vendor = CpuRegisters.Ebx; + Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx; *(PULONG)&Prcb->CpuId.VendorName[0] = CpuRegisters.Ebx; *(PULONG)&Prcb->CpuId.VendorName[4] = CpuRegisters.Edx; *(PULONG)&Prcb->CpuId.VendorName[8] = CpuRegisters.Ecx; @@ -155,7 +85,7 @@ ArpIdentifyProcessor(VOID) /* Get CPU standard features */ RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES; - ArCpuId(&CpuRegisters); + CpuFunc::CpuId(&CpuRegisters); /* Store CPU signature in processor control block */ CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax; @@ -195,6 +125,81 @@ ArpIdentifyProcessor(VOID) /* TODO: Store a list of CPU features in processor control block */ } +/** + * Initializes AMD64 processor specific structures. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures) +{ + KDESCRIPTOR GdtDescriptor, IdtDescriptor; + PVOID KernelBootStack, KernelFaultStack; + PKPROCESSOR_BLOCK ProcessorBlock; + PKGDTENTRY Gdt; + PKIDTENTRY Idt; + PKTSS Tss; + + /* Check if processor structures buffer provided */ + if(ProcessorStructures) + { + /* Assign CPU structures from provided buffer */ + InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock, + &KernelBootStack, &KernelFaultStack); + + /* Use global IDT */ + Idt = InitialIdt; + } + else + { + /* Use initial structures */ + Gdt = InitialGdt; + Idt = InitialIdt; + Tss = &InitialTss; + KernelBootStack = &BootStack; + KernelFaultStack = &FaultStack; + ProcessorBlock = &InitialProcessorBlock; + } + + /* Initialize processor block */ + InitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack); + + /* Initialize GDT, IDT and TSS */ + InitializeGdt(ProcessorBlock); + InitializeIdt(ProcessorBlock); + InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack); + + /* Set GDT and IDT descriptors */ + GdtDescriptor.Base = Gdt; + GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1; + IdtDescriptor.Base = Idt; + IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1; + + /* Load GDT, IDT and TSS */ + CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit); + CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit); + CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS); + + /* Enter passive IRQ level */ + HL::RunLevel::SetRunLevel(PASSIVE_LEVEL); + + /* Initialize segment registers */ + InitializeSegments(); + + /* Set GS base */ + CpuFunc::WriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock); + CpuFunc::WriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock); + + /* Initialize processor registers */ + InitializeProcessorRegisters(); + + /* Identify processor */ + IdentifyProcessor(); +} + /** * Initializes the kernel's Global Descriptor Table (GDT). * @@ -207,19 +212,21 @@ ArpIdentifyProcessor(VOID) */ XTAPI VOID -ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock) +AR::ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock) { /* Initialize GDT entries */ - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 1); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 1); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_DATA, 0x0, 0x0, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 1); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMCODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_USER, 1); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONG_PTR)ProcessorBlock->TssBase, sizeof(KTSS) - 1, AMD64_TSS, KGDT_DPL_SYSTEM, 0); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMTEB, 0x0, 0x0FFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_ALIAS, (ULONG_PTR)ProcessorBlock->GdtBase, (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 1); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 1); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_DATA, 0x0, 0x0, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 1); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMCODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_USER, 1); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONG_PTR)ProcessorBlock->TssBase, + sizeof(KTSS) - 1, AMD64_TSS, KGDT_DPL_SYSTEM, 0); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMTEB, 0x0, 0x0FFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_ALIAS, (ULONG_PTR)ProcessorBlock->GdtBase, + (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0); } /** @@ -234,7 +241,7 @@ ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock) */ XTAPI VOID -ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock) +AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock) { UINT Vector; @@ -242,34 +249,34 @@ ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock) for(Vector = 0; Vector < IDT_ENTRIES; Vector++) { /* Set the IDT to handle unexpected interrupts */ - ArpSetIdtGate(ProcessorBlock->IdtBase, Vector, ArpHandleTrapFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); } /* Setup IDT handlers for known interrupts and traps */ - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x00, ArpTrap0x00, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x01, ArpTrap0x01, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x02, ArpTrap0x02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x03, ArpTrap0x03, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x04, ArpTrap0x04, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x05, ArpTrap0x05, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x06, ArpTrap0x06, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x07, ArpTrap0x07, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x08, ArpTrap0x08, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x09, ArpTrap0x09, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0A, ArpTrap0x0A, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0B, ArpTrap0x0B, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0C, ArpTrap0x0C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0D, ArpTrap0x0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0E, ArpTrap0x0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x10, ArpTrap0x10, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x11, ArpTrap0x11, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x12, ArpTrap0x12, KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x13, ArpTrap0x13, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x1F, ArpTrap0x1F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2C, ArpTrap0x2C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2D, ArpTrap0x2D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2F, ArpTrap0x2F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0xE1, ArpTrap0xE1, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3); + SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3); + SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x1F, (PVOID)ArTrap0x1F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3); + SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3); + SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrap0x2F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArTrap0xE1, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); } /** @@ -293,18 +300,18 @@ ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock) */ XTAPI VOID -ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, - IN PKGDTENTRY Gdt, - IN PKIDTENTRY Idt, - IN PKTSS Tss, - IN PVOID DpcStack) +AR::ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, + IN PKGDTENTRY Gdt, + IN PKIDTENTRY Idt, + IN PKTSS Tss, + IN PVOID DpcStack) { /* Set processor block and processor control block */ ProcessorBlock->Self = ProcessorBlock; ProcessorBlock->CurrentPrcb = &ProcessorBlock->Prcb; /* Set GDT, IDT and TSS descriptors */ - ProcessorBlock->GdtBase = (PVOID)Gdt; + ProcessorBlock->GdtBase = (PKGDTENTRY)(PVOID)Gdt; ProcessorBlock->IdtBase = Idt; ProcessorBlock->TssBase = Tss; ProcessorBlock->Prcb.RspBase = Tss->Rsp0; @@ -322,10 +329,10 @@ ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr7 = 0; /* Set process and thread information */ - ProcessorBlock->Prcb.CurrentThread = &KeInitialThread.ThreadControlBlock; - ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &KeInitialProcess.ProcessControlBlock; - ProcessorBlock->Prcb.IdleThread = &KeInitialThread.ThreadControlBlock; - ProcessorBlock->Prcb.NextThread = NULL; + ProcessorBlock->Prcb.CurrentThread = &(KE::KThread::GetInitialThread())->ThreadControlBlock; + ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &(KE::KProcess::GetInitialProcess())->ProcessControlBlock; + ProcessorBlock->Prcb.IdleThread = &(KE::KThread::GetInitialThread())->ThreadControlBlock; + ProcessorBlock->Prcb.NextThread = NULLPTR; /* Set initial MXCSR register value */ ProcessorBlock->Prcb.MxCsr = INITIAL_MXCSR; @@ -343,56 +350,50 @@ ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, */ XTAPI VOID -ArpInitializeProcessorRegisters(VOID) +AR::ProcSup::InitializeProcessorRegisters(VOID) { ULONGLONG PatAttributes; /* Enable FXSAVE restore */ - ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_FXSR); + CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_FXSR); /* Enable XMMI exceptions */ - ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_XMMEXCPT); + CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_XMMEXCPT); /* Set debugger extension */ - ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_DE); + CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_DE); /* Enable large pages */ - ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_PSE); + CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_PSE); /* Enable write-protection */ - ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_WP); + CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_WP); /* Set alignment mask */ - ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_AM); + CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_AM); /* Disable FPU monitoring */ - ArWriteControlRegister(0, ArReadControlRegister(0) & ~CR0_MP); + CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) & ~CR0_MP); /* Disable x87 FPU exceptions */ - ArWriteControlRegister(0, ArReadControlRegister(0) & ~CR0_NE); + CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) & ~CR0_NE); /* Flush the TLB */ - ArFlushTlb(); - - /* Initialize system calls MSR */ - ArWriteModelSpecificRegister(X86_MSR_STAR, (((ULONG64)KGDT_R3_CMCODE | RPL_MASK) << 48) | ((ULONG64)KGDT_R0_CODE << 32)); - ArWriteModelSpecificRegister(X86_MSR_CSTAR, (ULONG64)&ArpHandleSystemCall32); - ArWriteModelSpecificRegister(X86_MSR_LSTAR, (ULONG64)&ArpHandleSystemCall64); - ArWriteModelSpecificRegister(X86_MSR_FMASK, X86_EFLAGS_IF_MASK | X86_EFLAGS_TF_MASK); - - /* Enable system call extensions (SCE) in EFER MSR */ - ArWriteModelSpecificRegister(X86_MSR_EFER, ArReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_SCE); + CpuFunc::FlushTlb(); + /* Initialize system call MSRs */ + Traps::InitializeSystemCallMsrs(); + /* Enable No-Execute (NXE) in EFER MSR */ - ArWriteModelSpecificRegister(X86_MSR_EFER, ArReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_NXE); + CpuFunc::WriteModelSpecificRegister(X86_MSR_EFER, CpuFunc::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_NXE); /* Initialize Page Attribute Table */ PatAttributes = (PAT_TYPE_WB << 0) | (PAT_TYPE_USWC << 8) | (PAT_TYPE_WEAK_UC << 16) | (PAT_TYPE_STRONG_UC << 24) | (PAT_TYPE_WB << 32) | (PAT_TYPE_USWC << 40) | (PAT_TYPE_WEAK_UC << 48) | (PAT_TYPE_STRONG_UC << 56); - ArWriteModelSpecificRegister(X86_MSR_PAT, PatAttributes); + CpuFunc::WriteModelSpecificRegister(X86_MSR_PAT, PatAttributes); /* Initialize MXCSR register */ - ArLoadMxcsrRegister(INITIAL_MXCSR); + CpuFunc::LoadMxcsrRegister(INITIAL_MXCSR); } /** @@ -422,12 +423,12 @@ ArpInitializeProcessorRegisters(VOID) */ XTAPI VOID -ArpInitializeProcessorStructures(IN PVOID ProcessorStructures, - OUT PKGDTENTRY *Gdt, - OUT PKTSS *Tss, - OUT PKPROCESSOR_BLOCK *ProcessorBlock, - OUT PVOID *KernelBootStack, - OUT PVOID *KernelFaultStack) +AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures, + OUT PKGDTENTRY *Gdt, + OUT PKTSS *Tss, + OUT PKPROCESSOR_BLOCK *ProcessorBlock, + OUT PVOID *KernelBootStack, + OUT PVOID *KernelFaultStack) { UINT_PTR Address; @@ -442,15 +443,15 @@ ArpInitializeProcessorStructures(IN PVOID ProcessorStructures, *KernelFaultStack = (PVOID)Address; /* Assign a space for GDT and advance */ - *Gdt = (PVOID)Address; - Address += sizeof(ArInitialGdt); + *Gdt = (PKGDTENTRY)(PVOID)Address; + Address += sizeof(InitialGdt); /* Assign a space for Processor Block and advance */ - *ProcessorBlock = (PVOID)Address; - Address += sizeof(ArInitialProcessorBlock); + *ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address; + Address += sizeof(InitialProcessorBlock); /* Assign a space for TSS */ - *Tss = (PVOID)Address; + *Tss = (PKTSS)(PVOID)Address; } /** @@ -462,15 +463,15 @@ ArpInitializeProcessorStructures(IN PVOID ProcessorStructures, */ XTAPI VOID -ArpInitializeSegments(VOID) +AR::ProcSup::InitializeSegments(VOID) { /* Initialize segments */ - ArLoadSegment(SEGMENT_CS, KGDT_R0_CODE); - ArLoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK); - ArLoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK); - ArLoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK); - ArLoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK); - ArLoadSegment(SEGMENT_SS, KGDT_R0_DATA); + CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE); + CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK); + CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK); + CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK); + CpuFunc::LoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK); + CpuFunc::LoadSegment(SEGMENT_SS, KGDT_R0_DATA); } /** @@ -488,9 +489,9 @@ ArpInitializeSegments(VOID) */ XTAPI VOID -ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, - IN PVOID KernelBootStack, - IN PVOID KernelFaultStack) +AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, + IN PVOID KernelBootStack, + IN PVOID KernelFaultStack) { /* Fill TSS with zeroes */ RtlZeroMemory(ProcessorBlock->TssBase, sizeof(KTSS)); @@ -532,13 +533,13 @@ ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, */ XTAPI VOID -ArpSetGdtEntry(IN PKGDTENTRY Gdt, - IN USHORT Selector, - IN ULONG_PTR Base, - IN ULONG Limit, - IN UCHAR Type, - IN UCHAR Dpl, - IN UCHAR SegmentMode) +AR::ProcSup::SetGdtEntry(IN PKGDTENTRY Gdt, + IN USHORT Selector, + IN ULONG_PTR Base, + IN ULONG Limit, + IN UCHAR Type, + IN UCHAR Dpl, + IN UCHAR SegmentMode) { PKGDTENTRY GdtEntry; UCHAR Granularity; @@ -580,6 +581,40 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt, GdtEntry->MustBeZero = 0; } +/** + * Updates an existing AMD64 GDT entry with new base address. + * + * @param Gdt + * Supplies a pointer to the GDT. + * + * @param Selector + * Specifies a segment selector of the GDT entry. + * + * @param Base + * Specifies a base address value of the descriptor. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt, + IN USHORT Selector, + IN ULONG_PTR Base) +{ + PKGDTENTRY GdtEntry; + + /* Get GDT entry */ + GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK)); + + /* Set new GDT descriptor base */ + GdtEntry->BaseLow = (Base & 0xFFFF); + GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF); + GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF); + GdtEntry->BaseUpper = (Base >> 32); +} + /** * Fills in a call, interrupt, task or trap gate entry. * @@ -607,12 +642,12 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt, */ XTAPI VOID -ArpSetIdtGate(IN PKIDTENTRY Idt, - IN USHORT Vector, - IN PVOID Handler, - IN USHORT Selector, - IN USHORT Ist, - IN USHORT Access) +AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt, + IN USHORT Vector, + IN PVOID Handler, + IN USHORT Selector, + IN USHORT Ist, + IN USHORT Access) { /* Setup the gate */ Idt[Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF); diff --git a/xtoskrnl/ar/amd64/traps.c b/xtoskrnl/ar/amd64/traps.cc similarity index 75% rename from xtoskrnl/ar/amd64/traps.c rename to xtoskrnl/ar/amd64/traps.cc index 66540f0..7c5a002 100644 --- a/xtoskrnl/ar/amd64/traps.c +++ b/xtoskrnl/ar/amd64/traps.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ar/amd64/traps.c + * FILE: xtoskrnl/ar/amd64/traps.cc * DESCRIPTION: AMD64 system traps * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -21,124 +21,138 @@ */ XTCDECL VOID -ArpDispatchTrap(IN PKTRAP_FRAME TrapFrame) +AR::Traps::DispatchTrap(IN PKTRAP_FRAME TrapFrame) { /* Check vector and call appropriate handler */ switch(TrapFrame->Vector) { case 0x00: /* Divide By Zero exception */ - ArpHandleTrap00(TrapFrame); + HandleTrap00(TrapFrame); break; case 0x01: /* Debug exception */ - ArpHandleTrap01(TrapFrame); + HandleTrap01(TrapFrame); break; case 0x02: /* Non-Maskable Interrupt (NMI) */ - ArpHandleTrap02(TrapFrame); + HandleTrap02(TrapFrame); break; case 0x03: /* INT3 instruction executed */ - ArpHandleTrap03(TrapFrame); + HandleTrap03(TrapFrame); break; case 0x04: /* Overflow exception */ - ArpHandleTrap04(TrapFrame); + HandleTrap04(TrapFrame); break; case 0x05: /* Bound Range Exceeded exception */ - ArpHandleTrap05(TrapFrame); + HandleTrap05(TrapFrame); break; case 0x06: /* Invalid Opcode exception */ - ArpHandleTrap06(TrapFrame); + HandleTrap06(TrapFrame); break; case 0x07: /* Device Not Available exception */ - ArpHandleTrap07(TrapFrame); + HandleTrap07(TrapFrame); break; case 0x08: /* Double Fault exception */ - ArpHandleTrap08(TrapFrame); + HandleTrap08(TrapFrame); break; case 0x09: /* Segment Overrun exception */ - ArpHandleTrap09(TrapFrame); + HandleTrap09(TrapFrame); break; case 0x0A: /* Invalid TSS exception */ - ArpHandleTrap0A(TrapFrame); + HandleTrap0A(TrapFrame); break; case 0x0B: /* Segment Not Present exception */ - ArpHandleTrap0B(TrapFrame); + HandleTrap0B(TrapFrame); break; case 0x0C: /* Stack Segment Fault exception */ - ArpHandleTrap0C(TrapFrame); + HandleTrap0C(TrapFrame); break; case 0x0D: /* General Protection Fault (GPF) exception*/ - ArpHandleTrap0D(TrapFrame); + HandleTrap0D(TrapFrame); break; case 0x0E: /* Page Fault exception */ - ArpHandleTrap0E(TrapFrame); + HandleTrap0E(TrapFrame); break; case 0x10: /* X87 Floating-Point exception */ - ArpHandleTrap10(TrapFrame); + HandleTrap10(TrapFrame); break; case 0x11: /* Alignment Check exception */ - ArpHandleTrap11(TrapFrame); + HandleTrap11(TrapFrame); break; case 0x12: /* Machine Check exception */ - ArpHandleTrap12(TrapFrame); + HandleTrap12(TrapFrame); break; case 0x13: /* SIMD Floating-Point exception */ - ArpHandleTrap13(TrapFrame); + HandleTrap13(TrapFrame); break; case 0x1F: /* Software Interrupt at APC level */ - ArpHandleTrap1F(TrapFrame); + HandleTrap1F(TrapFrame); break; case 0x2C: /* Assertion raised */ - ArpHandleTrap2C(TrapFrame); + HandleTrap2C(TrapFrame); break; case 0x2D: /* Debug-Service-Request raised */ - ArpHandleTrap2D(TrapFrame); + HandleTrap2D(TrapFrame); break; case 0x2F: /* Software Interrupt at DISPATCH level */ - ArpHandleTrap2F(TrapFrame); + HandleTrap2F(TrapFrame); break; case 0xE1: /* InterProcessor Interrupt (IPI) */ - ArpHandleTrapE1(TrapFrame); + HandleTrapE1(TrapFrame); break; default: /* Unknown/Unexpected trap */ - ArpHandleTrapFF(TrapFrame); + HandleTrapFF(TrapFrame); break; } } +/** + * Handles a 32-bit system call. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ XTCDECL VOID -ArpHandleSystemCall32(VOID) +AR::Traps::HandleSystemCall32(VOID) { DebugPrint(L"Handled 32-bit system call!\n"); } +/** + * Handles a 64-bit system call. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ XTCDECL VOID -ArpHandleSystemCall64(VOID) +AR::Traps::HandleSystemCall64(VOID) { DebugPrint(L"Handled 64-bit system call!\n"); } @@ -155,7 +169,7 @@ ArpHandleSystemCall64(VOID) */ XTCDECL VOID -ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap00(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Division-By-Zero Error (0x00)!\n"); for(;;); @@ -173,7 +187,7 @@ ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap01(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Debug exception (0x01)!\n"); for(;;); @@ -191,7 +205,7 @@ ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n"); for(;;); @@ -209,7 +223,7 @@ ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap03(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled INT3 (0x03)!\n"); for(;;); @@ -227,7 +241,7 @@ ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap04(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Overflow exception (0x04)!\n"); for(;;); @@ -245,7 +259,7 @@ ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap05(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Bound-Range-Exceeded exception (0x05)!\n"); for(;;); @@ -263,7 +277,7 @@ ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap06(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Invalid Opcode exception (0x06)!\n"); for(;;); @@ -281,7 +295,7 @@ ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap07(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Device Not Available exception (0x07)!\n"); for(;;); @@ -299,7 +313,7 @@ ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap08(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Double-Fault exception (0x08)!\n"); for(;;); @@ -317,7 +331,7 @@ ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap09(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Segment-Overrun exception (0x09)!\n"); for(;;); @@ -335,7 +349,7 @@ ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap0A(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Invalid-TSS exception (0x0A)!\n"); for(;;); @@ -353,7 +367,7 @@ ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap0B(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Segment-Not-Present exception (0x0B)!\n"); for(;;); @@ -371,7 +385,7 @@ ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap0C(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Stack-Segment-Fault exception (0x0C)!\n"); for(;;); @@ -389,7 +403,7 @@ ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap0D(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled General-Protection-Fault (0x0D)!\n"); for(;;); @@ -407,7 +421,7 @@ ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap0E(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Page-Fault exception (0x0E)!\n"); for(;;); @@ -425,7 +439,7 @@ ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap10(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled x87 Floating-Point exception (0x10)!\n"); for(;;); @@ -443,7 +457,7 @@ ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap11(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Alignment-Check exception (0x11)!\n"); for(;;); @@ -461,7 +475,7 @@ ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap12(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Machine-Check exception (0x12)!\n"); for(;;); @@ -479,7 +493,7 @@ ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap13(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled SIMD Floating-Point exception (0x13)!\n"); for(;;); @@ -497,7 +511,7 @@ ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap1F(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap1F(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Unhandled software interrupt at APC level (0x1F)!\n"); } @@ -514,7 +528,7 @@ ArpHandleTrap1F(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap2C(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Assertion (0x2C)!\n"); for(;;); @@ -532,7 +546,7 @@ ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap2D(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Debug-Service-Request (0x2D)!\n"); for(;;); @@ -550,7 +564,7 @@ ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap2F(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap2F(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Unhandled software interrupt at DISPATCH level (0x2F)!\n"); } @@ -567,7 +581,7 @@ ArpHandleTrap2F(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrapE1(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrapE1(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Unhandled IPI interrupt (0xE1)!\n"); } @@ -584,8 +598,47 @@ ArpHandleTrapE1(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrapFF(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrapFF(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Unexpected-Interrupt (0xFF)!\n"); for(;;); } + +/** + * Initializes system call MSRs. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +AR::Traps::InitializeSystemCallMsrs(VOID) +{ + /* Initialize system calls MSR */ + CpuFunc::WriteModelSpecificRegister(X86_MSR_STAR, (((ULONG64)KGDT_R3_CMCODE | RPL_MASK) << 48) | ((ULONG64)KGDT_R0_CODE << 32)); + CpuFunc::WriteModelSpecificRegister(X86_MSR_CSTAR, (ULONG64)&HandleSystemCall32); + CpuFunc::WriteModelSpecificRegister(X86_MSR_LSTAR, (ULONG64)&HandleSystemCall64); + CpuFunc::WriteModelSpecificRegister(X86_MSR_FMASK, X86_EFLAGS_IF_MASK | X86_EFLAGS_TF_MASK); + + /* Enable system call extensions (SCE) in EFER MSR */ + CpuFunc::WriteModelSpecificRegister(X86_MSR_EFER, CpuFunc::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_SCE); +} + +/** + * C-linkage wrapper for dispatching the trap provided by common trap handler. + * + * @param TrapFrame + * Supplies a kernel trap frame pushed by common trap handler on the stack. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTCDECL +VOID +ArDispatchTrap(IN PKTRAP_FRAME TrapFrame) +{ + AR::Traps::DispatchTrap(TrapFrame); +} diff --git a/xtoskrnl/ar/i686/archsup.S b/xtoskrnl/ar/i686/archsup.S index e80ac42..f1af307 100644 --- a/xtoskrnl/ar/i686/archsup.S +++ b/xtoskrnl/ar/i686/archsup.S @@ -6,7 +6,7 @@ * DEVELOPERS: Rafal Kupiec */ -#include +#include .altmacro .text @@ -22,9 +22,9 @@ * * @since XT 1.0 */ -.macro ArpCreateTrapHandler Vector -.global _ArpTrap\Vector -_ArpTrap\Vector: +.macro ArCreateTrapHandler Vector +.global _ArTrap\Vector +_ArTrap\Vector: /* Push fake error code for non-error vectors */ .if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30 push $0 @@ -84,7 +84,7 @@ KernelMode$\Vector: /* Push Frame Pointer, clear direction flag and pass to trap dispatcher */ push %esp cld - call _ArpDispatchTrap + call _ArDispatchTrap /* Clean up the stack */ add $4, %esp @@ -121,6 +121,6 @@ KernelModeReturn$\Vector: /* Populate common trap handlers */ .irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F .irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F - ArpCreateTrapHandler 0x\i\j + ArCreateTrapHandler 0x\i\j .endr .endr diff --git a/xtoskrnl/ar/i686/boot.S b/xtoskrnl/ar/i686/boot.S index edb4c05..7794b18 100644 --- a/xtoskrnl/ar/i686/boot.S +++ b/xtoskrnl/ar/i686/boot.S @@ -6,9 +6,21 @@ * DEVELOPERS: Aiken Harris */ -#include +#include .altmacro .text +/** + * Starts an application processor (AP). This is just a stub. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +.global _ArStartApplicationProcessor +_ArStartApplicationProcessor: + +.global _ArStartApplicationProcessorEnd +_ArStartApplicationProcessorEnd: diff --git a/xtoskrnl/ar/i686/cpufunc.c b/xtoskrnl/ar/i686/cpufunc.cc similarity index 91% rename from xtoskrnl/ar/i686/cpufunc.c rename to xtoskrnl/ar/i686/cpufunc.cc index 27b6676..bdbbe65 100644 --- a/xtoskrnl/ar/i686/cpufunc.c +++ b/xtoskrnl/ar/i686/cpufunc.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ar/i686/cpufunc.c + * FILE: xtoskrnl/ar/i686/cpufunc.cc * DESCRIPTION: Routines to provide access to special i686 CPU instructions * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -18,7 +18,7 @@ */ XTCDECL VOID -ArClearInterruptFlag(VOID) +AR::CpuFunc::ClearInterruptFlag(VOID) { __asm__ volatile("cli"); } @@ -35,7 +35,7 @@ ArClearInterruptFlag(VOID) */ XTCDECL BOOLEAN -ArCpuId(IN OUT PCPUID_REGISTERS Registers) +AR::CpuFunc::CpuId(IN OUT PCPUID_REGISTERS Registers) { UINT32 MaxLeaf; @@ -76,10 +76,10 @@ ArCpuId(IN OUT PCPUID_REGISTERS Registers) */ XTCDECL VOID -ArFlushTlb(VOID) +AR::CpuFunc::FlushTlb(VOID) { /* Flush the TLB by resetting the CR3 */ - ArWriteControlRegister(3, ArReadControlRegister(3)); + WriteControlRegister(3, ReadControlRegister(3)); } /** @@ -91,7 +91,7 @@ ArFlushTlb(VOID) */ XTCDECL ULONG -ArGetCpuFlags(VOID) +AR::CpuFunc::GetCpuFlags(VOID) { ULONG_PTR Flags; @@ -116,7 +116,7 @@ ArGetCpuFlags(VOID) XTASSEMBLY XTCDECL ULONG_PTR -ArGetStackPointer(VOID) +AR::CpuFunc::GetStackPointer(VOID) { /* Get current stack pointer */ __asm__ volatile("mov %%esp, %%eax\n" @@ -135,7 +135,7 @@ ArGetStackPointer(VOID) */ XTCDECL VOID -ArHalt(VOID) +AR::CpuFunc::Halt(VOID) { __asm__ volatile("hlt"); } @@ -149,12 +149,12 @@ ArHalt(VOID) */ XTCDECL BOOLEAN -ArInterruptsEnabled(VOID) +AR::CpuFunc::InterruptsEnabled(VOID) { ULONG_PTR Flags; /* Get RFLAGS register */ - Flags = ArGetCpuFlags(); + Flags = GetCpuFlags(); /* Check if interrupts are enabled and return result */ return (Flags & X86_EFLAGS_IF_MASK) ? TRUE : FALSE; @@ -172,7 +172,7 @@ ArInterruptsEnabled(VOID) */ XTCDECL VOID -ArInvalidateTlbEntry(PVOID Address) +AR::CpuFunc::InvalidateTlbEntry(PVOID Address) { __asm__ volatile("invlpg (%0)" : @@ -192,7 +192,7 @@ ArInvalidateTlbEntry(PVOID Address) */ XTCDECL VOID -ArLoadGlobalDescriptorTable(IN PVOID Source) +AR::CpuFunc::LoadGlobalDescriptorTable(IN PVOID Source) { __asm__ volatile("lgdt %0" : @@ -212,7 +212,7 @@ ArLoadGlobalDescriptorTable(IN PVOID Source) */ XTCDECL VOID -ArLoadInterruptDescriptorTable(IN PVOID Source) +AR::CpuFunc::LoadInterruptDescriptorTable(IN PVOID Source) { __asm__ volatile("lidt %0" : @@ -232,7 +232,7 @@ ArLoadInterruptDescriptorTable(IN PVOID Source) */ XTCDECL VOID -ArLoadLocalDescriptorTable(IN USHORT Source) +AR::CpuFunc::LoadLocalDescriptorTable(IN USHORT Source) { __asm__ volatile("lldtw %0" : @@ -254,8 +254,8 @@ ArLoadLocalDescriptorTable(IN USHORT Source) */ XTCDECL VOID -ArLoadSegment(IN USHORT Segment, - IN ULONG Source) +AR::CpuFunc::LoadSegment(IN USHORT Segment, + IN ULONG Source) { switch(Segment) { @@ -316,7 +316,7 @@ ArLoadSegment(IN USHORT Segment, */ XTCDECL VOID -ArLoadTaskRegister(USHORT Source) +AR::CpuFunc::LoadTaskRegister(USHORT Source) { __asm__ volatile("ltr %0" : @@ -332,7 +332,7 @@ ArLoadTaskRegister(USHORT Source) */ XTCDECL VOID -ArMemoryBarrier(VOID) +AR::CpuFunc::MemoryBarrier(VOID) { LONG Barrier; __asm__ volatile("xchg %%eax, %0" @@ -353,7 +353,7 @@ ArMemoryBarrier(VOID) */ XTCDECL ULONG_PTR -ArReadControlRegister(IN USHORT ControlRegister) +AR::CpuFunc::ReadControlRegister(IN USHORT ControlRegister) { ULONG_PTR Value; @@ -410,7 +410,7 @@ ArReadControlRegister(IN USHORT ControlRegister) */ XTCDECL ULONG_PTR -ArReadDebugRegister(IN USHORT DebugRegister) +AR::CpuFunc::ReadDebugRegister(IN USHORT DebugRegister) { ULONG_PTR Value; @@ -479,7 +479,7 @@ ArReadDebugRegister(IN USHORT DebugRegister) */ XTCDECL ULONG -ArReadFSDualWord(ULONG Offset) +AR::CpuFunc::ReadFSDualWord(ULONG Offset) { ULONG Value; __asm__ volatile("movl %%fs:%a[Offset], %k[Value]" @@ -500,7 +500,7 @@ ArReadFSDualWord(ULONG Offset) */ XTCDECL ULONGLONG -ArReadModelSpecificRegister(IN ULONG Register) +AR::CpuFunc::ReadModelSpecificRegister(IN ULONG Register) { ULONGLONG Value; @@ -519,7 +519,7 @@ ArReadModelSpecificRegister(IN ULONG Register) */ XTCDECL UINT -ArReadMxCsrRegister(VOID) +AR::CpuFunc::ReadMxCsrRegister(VOID) { return __builtin_ia32_stmxcsr(); } @@ -533,7 +533,7 @@ ArReadMxCsrRegister(VOID) */ XTCDECL ULONGLONG -ArReadTimeStampCounter(VOID) +AR::CpuFunc::ReadTimeStampCounter(VOID) { ULONGLONG Value; @@ -552,7 +552,7 @@ ArReadTimeStampCounter(VOID) */ XTCDECL VOID -ArReadWriteBarrier(VOID) +AR::CpuFunc::ReadWriteBarrier(VOID) { __asm__ volatile("" : @@ -569,7 +569,7 @@ ArReadWriteBarrier(VOID) */ XTCDECL VOID -ArSetInterruptFlag(VOID) +AR::CpuFunc::SetInterruptFlag(VOID) { __asm__ volatile("sti"); } @@ -586,7 +586,7 @@ ArSetInterruptFlag(VOID) */ XTCDECL VOID -ArStoreGlobalDescriptorTable(OUT PVOID Destination) +AR::CpuFunc::StoreGlobalDescriptorTable(OUT PVOID Destination) { __asm__ volatile("sgdt %0" : "=m" (*(PSHORT)Destination) @@ -606,7 +606,7 @@ ArStoreGlobalDescriptorTable(OUT PVOID Destination) */ XTCDECL VOID -ArStoreInterruptDescriptorTable(OUT PVOID Destination) +AR::CpuFunc::StoreInterruptDescriptorTable(OUT PVOID Destination) { __asm__ volatile("sidt %0" : "=m" (*(PSHORT)Destination) @@ -626,7 +626,7 @@ ArStoreInterruptDescriptorTable(OUT PVOID Destination) */ XTCDECL VOID -ArStoreLocalDescriptorTable(OUT PVOID Destination) +AR::CpuFunc::StoreLocalDescriptorTable(OUT PVOID Destination) { __asm__ volatile("sldt %0" : "=m" (*(PSHORT)Destination) @@ -649,8 +649,8 @@ ArStoreLocalDescriptorTable(OUT PVOID Destination) */ XTCDECL VOID -ArStoreSegment(IN USHORT Segment, - OUT PVOID Destination) +AR::CpuFunc::StoreSegment(IN USHORT Segment, + OUT PVOID Destination) { switch(Segment) { @@ -679,7 +679,7 @@ ArStoreSegment(IN USHORT Segment, : "=r" (*(PUINT)Destination)); break; default: - Destination = NULL; + Destination = NULLPTR; break; } } @@ -696,7 +696,7 @@ ArStoreSegment(IN USHORT Segment, */ XTCDECL VOID -ArStoreTaskRegister(OUT PVOID Destination) +AR::CpuFunc::StoreTaskRegister(OUT PVOID Destination) { __asm__ volatile("str %0" : "=m" (*(PULONG)Destination) @@ -719,8 +719,8 @@ ArStoreTaskRegister(OUT PVOID Destination) */ XTCDECL VOID -ArWriteControlRegister(IN USHORT ControlRegister, - IN UINT_PTR Value) +AR::CpuFunc::WriteControlRegister(IN USHORT ControlRegister, + IN UINT_PTR Value) { /* Write a value into specified control register */ switch(ControlRegister) @@ -771,8 +771,8 @@ ArWriteControlRegister(IN USHORT ControlRegister, */ XTCDECL VOID -ArWriteDebugRegister(IN USHORT DebugRegister, - IN UINT_PTR Value) +AR::CpuFunc::WriteDebugRegister(IN USHORT DebugRegister, + IN UINT_PTR Value) { /* Write a value into specified debug register */ switch(DebugRegister) @@ -840,7 +840,7 @@ ArWriteDebugRegister(IN USHORT DebugRegister, */ XTCDECL VOID -ArWriteEflagsRegister(IN UINT_PTR Value) +AR::CpuFunc::WriteEflagsRegister(IN UINT_PTR Value) { __asm__ volatile("push %0\n" "popf" @@ -863,8 +863,8 @@ ArWriteEflagsRegister(IN UINT_PTR Value) */ XTCDECL VOID -ArWriteModelSpecificRegister(IN ULONG Register, - IN ULONGLONG Value) +AR::CpuFunc::WriteModelSpecificRegister(IN ULONG Register, + IN ULONGLONG Value) { __asm__ volatile("wrmsr" : @@ -881,7 +881,7 @@ ArWriteModelSpecificRegister(IN ULONG Register, */ XTCDECL VOID -ArYieldProcessor(VOID) +AR::CpuFunc::YieldProcessor(VOID) { __asm__ volatile("pause" : diff --git a/xtoskrnl/ar/i686/data.cc b/xtoskrnl/ar/i686/data.cc new file mode 100644 index 0000000..fab40cc --- /dev/null +++ b/xtoskrnl/ar/i686/data.cc @@ -0,0 +1,34 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/ar/i686/data.cc + * DESCRIPTION: I686 architecture-specific global and static data + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/* Initial kernel boot stack */ +UCHAR AR::ProcSup::BootStack[KERNEL_STACK_SIZE] = {}; + +/* Double Fault gate */ +UCHAR AR::ProcSup::DoubleFaultTss[KTSS_IO_MAPS]; + +/* Initial kernel fault stack */ +UCHAR AR::ProcSup::FaultStack[KERNEL_STACK_SIZE] = {}; + +/* Initial GDT */ +KGDTENTRY AR::ProcSup::InitialGdt[GDT_ENTRIES] = {}; + +/* Initial IDT */ +KIDTENTRY AR::ProcSup::InitialIdt[IDT_ENTRIES] = {}; + +/* Initial Processor Block */ +KPROCESSOR_BLOCK AR::ProcSup::InitialProcessorBlock; + +/* Initial TSS */ +KTSS AR::ProcSup::InitialTss; + +/* NMI task gate */ +UCHAR AR::ProcSup::NonMaskableInterruptTss[KTSS_IO_MAPS]; diff --git a/xtoskrnl/ar/i686/globals.c b/xtoskrnl/ar/i686/globals.c deleted file mode 100644 index af4f87d..0000000 --- a/xtoskrnl/ar/i686/globals.c +++ /dev/null @@ -1,32 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ar/i686/globals.c - * DESCRIPTION: XT architecture library global variables - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/* Initial GDT */ -KGDTENTRY ArInitialGdt[GDT_ENTRIES] = {0}; - -/* Initial IDT */ -KIDTENTRY ArInitialIdt[IDT_ENTRIES] = {0}; - -/* Initial Processor Block */ -KPROCESSOR_BLOCK ArInitialProcessorBlock; - -/* Initial TSS */ -KTSS ArInitialTss; - -/* Double Fault and NMI task gates */ -UCHAR ArpDoubleFaultTss[KTSS_IO_MAPS]; -UCHAR ArpNonMaskableInterruptTss[KTSS_IO_MAPS]; - -/* Initial kernel boot stack */ -UCHAR ArKernelBootStack[KERNEL_STACK_SIZE] = {0}; - -/* Initial kernel fault stack */ -UCHAR ArKernelFaultStack[KERNEL_STACK_SIZE] = {0}; diff --git a/xtoskrnl/ar/i686/procsup.c b/xtoskrnl/ar/i686/procsup.cc similarity index 59% rename from xtoskrnl/ar/i686/procsup.c rename to xtoskrnl/ar/i686/procsup.cc index 161257b..5db6658 100644 --- a/xtoskrnl/ar/i686/procsup.c +++ b/xtoskrnl/ar/i686/procsup.cc @@ -1,116 +1,46 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ar/i686/procsup.c + * FILE: xtoskrnl/ar/i686/procsup.cc * DESCRIPTION: I686 processor functionality support * DEVELOPERS: Rafal Kupiec */ -#include +#include /** - * Initializes i686 processor specific structures. + * Gets the base address of the kernel boot stack. * - * @return This routine does not return any value. + * @return This routine returns a pointer to the kernel boot stack. * * @since XT 1.0 */ XTAPI -VOID -ArInitializeProcessor(IN PVOID ProcessorStructures) +PVOID +AR::ProcSup::GetBootStack(VOID) { - KDESCRIPTOR GdtDescriptor, IdtDescriptor; - PVOID KernelBootStack, KernelFaultStack; - PKPROCESSOR_BLOCK ProcessorBlock; - PKGDTENTRY Gdt; - PKIDTENTRY Idt; - PKTSS Tss; - - /* Check if processor structures buffer provided */ - if(ProcessorStructures) - { - /* Assign CPU structures from provided buffer */ - ArpInitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock, - &KernelBootStack, &KernelFaultStack); - - /* Use global IDT */ - Idt = ArInitialIdt; - } - else - { - /* Use initial structures */ - Gdt = ArInitialGdt; - Idt = ArInitialIdt; - Tss = &ArInitialTss; - KernelBootStack = &ArKernelBootStack; - KernelFaultStack = &ArKernelFaultStack; - ProcessorBlock = &ArInitialProcessorBlock; - } - - /* Initialize processor block */ - ArpInitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack); - - /* Initialize GDT, IDT and TSS */ - ArpInitializeGdt(ProcessorBlock); - ArpInitializeIdt(ProcessorBlock); - ArpInitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack); - - /* Set GDT and IDT descriptors */ - GdtDescriptor.Base = Gdt; - GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1; - IdtDescriptor.Base = Idt; - IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1; - - /* Load GDT, IDT and TSS */ - ArLoadGlobalDescriptorTable(&GdtDescriptor.Limit); - ArLoadInterruptDescriptorTable(&IdtDescriptor.Limit); - ArLoadTaskRegister((UINT)KGDT_SYS_TSS); - - /* Enter passive IRQ level */ - HlSetRunLevel(PASSIVE_LEVEL); - - /* Initialize segment registers */ - ArpInitializeSegments(); - - /* Initialize processor registers */ - ArpInitializeProcessorRegisters(); - - /* Identify processor */ - ArpIdentifyProcessor(); + return (PVOID)BootStack; } -/** - * Updates an existing i686 GDT entry with new base address. - * - * @param Gdt - * Supplies a pointer to the GDT. - * - * @param Selector - * Specifies a segment selector of the GDT entry. - * - * @param Base - * Specifies a base address value of the descriptor. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ XTAPI VOID -ArSetGdtEntryBase(IN PKGDTENTRY Gdt, - IN USHORT Selector, - IN ULONG_PTR Base) +AR::ProcSup::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType, + OUT PVOID *TrampolineCode, + OUT PULONG_PTR TrampolineSize) { - PKGDTENTRY GdtEntry; - - /* Get GDT entry */ - GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK)); - - /* Set new GDT descriptor base */ - GdtEntry->BaseLow = (Base & 0xFFFF); - GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF); - GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF); + switch(TrampolineType) + { + case TrampolineApStartup: + *TrampolineCode = (PVOID)ArStartApplicationProcessor; + *TrampolineSize = (ULONG_PTR)ArStartApplicationProcessorEnd - + (ULONG_PTR)ArStartApplicationProcessor; + break; + default: + *TrampolineCode = NULLPTR; + *TrampolineSize = 0; + break; + } } /** @@ -123,7 +53,7 @@ ArSetGdtEntryBase(IN PKGDTENTRY Gdt, */ XTAPI VOID -ArpIdentifyProcessor(VOID) +AR::ProcSup::IdentifyProcessor(VOID) { PKPROCESSOR_CONTROL_BLOCK Prcb; CPUID_REGISTERS CpuRegisters; @@ -133,15 +63,15 @@ ArpIdentifyProcessor(VOID) UNIMPLEMENTED; /* Get current processor control block */ - Prcb = KeGetCurrentProcessorControlBlock(); + Prcb = KE::Processor::GetCurrentProcessorControlBlock(); /* Get CPU vendor by issueing CPUID instruction */ RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING; - ArCpuId(&CpuRegisters); + CpuFunc::CpuId(&CpuRegisters); /* Store CPU vendor in processor control block */ - Prcb->CpuId.Vendor = CpuRegisters.Ebx; + Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx; *(PULONG)&Prcb->CpuId.VendorName[0] = CpuRegisters.Ebx; *(PULONG)&Prcb->CpuId.VendorName[4] = CpuRegisters.Edx; *(PULONG)&Prcb->CpuId.VendorName[8] = CpuRegisters.Ecx; @@ -150,7 +80,7 @@ ArpIdentifyProcessor(VOID) /* Get CPU standard features */ RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES; - ArCpuId(&CpuRegisters); + CpuFunc::CpuId(&CpuRegisters); /* Store CPU signature in processor control block */ CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax; @@ -190,6 +120,77 @@ ArpIdentifyProcessor(VOID) /* TODO: Store a list of CPU features in processor control block */ } +/** + * Initializes i686 processor specific structures. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures) +{ + KDESCRIPTOR GdtDescriptor, IdtDescriptor; + PVOID KernelBootStack, KernelFaultStack; + PKPROCESSOR_BLOCK ProcessorBlock; + PKGDTENTRY Gdt; + PKIDTENTRY Idt; + PKTSS Tss; + + /* Check if processor structures buffer provided */ + if(ProcessorStructures) + { + /* Assign CPU structures from provided buffer */ + InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock, + &KernelBootStack, &KernelFaultStack); + + /* Use global IDT */ + Idt = InitialIdt; + } + else + { + /* Use initial structures */ + Gdt = InitialGdt; + Idt = InitialIdt; + Tss = &InitialTss; + KernelBootStack = &BootStack; + KernelFaultStack = &FaultStack; + ProcessorBlock = &InitialProcessorBlock; + } + + /* Initialize processor block */ + InitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack); + + /* Initialize GDT, IDT and TSS */ + InitializeGdt(ProcessorBlock); + InitializeIdt(ProcessorBlock); + InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack); + + /* Set GDT and IDT descriptors */ + GdtDescriptor.Base = Gdt; + GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1; + IdtDescriptor.Base = Idt; + IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1; + + /* Load GDT, IDT and TSS */ + CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit); + CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit); + CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS); + + /* Enter passive IRQ level */ + HL::RunLevel::SetRunLevel(PASSIVE_LEVEL); + + /* Initialize segment registers */ + InitializeSegments(); + + /* Initialize processor registers */ + InitializeProcessorRegisters(); + + /* Identify processor */ + IdentifyProcessor(); +} + /** * Initializes the kernel's Global Descriptor Table (GDT). * @@ -202,23 +203,23 @@ ArpIdentifyProcessor(VOID) */ XTAPI VOID -ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock) +AR::ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock) { /* Initialize GDT entries */ - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 2); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONG_PTR)ProcessorBlock->TssBase, sizeof(KTSS) - 1, I686_TSS, KGDT_DPL_SYSTEM, 0); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_PB, (ULONG_PTR)ProcessorBlock, sizeof(KPROCESSOR_BLOCK), KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_TEB, 0x0, 0xFFF, KGDT_TYPE_DATA | KGDT_DESCRIPTOR_ACCESSED, KGDT_DPL_USER, 2); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDM_TILE, 0x0400, 0xFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 0); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_DF_TSS, 0x20000, 0xFFFF, I686_TSS, KGDT_DPL_SYSTEM, 0); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_NMI_TSS, 0x20000, 0xFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDBS, 0xB8000, 0x3FFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_ALIAS, (ULONG_PTR)ProcessorBlock->GdtBase, (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 2); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONG_PTR)ProcessorBlock->TssBase, sizeof(KTSS) - 1, I686_TSS, KGDT_DPL_SYSTEM, 0); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_PB, (ULONG_PTR)ProcessorBlock, sizeof(KPROCESSOR_BLOCK), KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_TEB, 0x0, 0xFFF, KGDT_TYPE_DATA | KGDT_DESCRIPTOR_ACCESSED, KGDT_DPL_USER, 2); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDM_TILE, 0x0400, 0xFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 0); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_DF_TSS, 0x20000, 0xFFFF, I686_TSS, KGDT_DPL_SYSTEM, 0); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NMI_TSS, 0x20000, 0xFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDBS, 0xB8000, 0x3FFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_ALIAS, (ULONG_PTR)ProcessorBlock->GdtBase, (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0); } /** @@ -233,7 +234,7 @@ ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock) */ XTAPI VOID -ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock) +AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock) { UINT Vector; @@ -241,34 +242,34 @@ ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock) for(Vector = 0; Vector < IDT_ENTRIES; Vector++) { /* Set the IDT to handle unexpected interrupts */ - ArpSetIdtGate(ProcessorBlock->IdtBase, Vector, ArpHandleTrapFF, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); } /* Setup IDT handlers for known interrupts and traps */ - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x00, ArpTrap0x00, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x01, ArpTrap0x01, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x02, ArpTrap0x02, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x03, ArpTrap0x03, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x04, ArpTrap0x04, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x05, ArpTrap0x05, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x06, ArpTrap0x06, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x07, ArpTrap0x07, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x08, ArpTrap0x08, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x09, ArpTrap0x09, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0A, ArpTrap0x0A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0B, ArpTrap0x0B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0C, ArpTrap0x0C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0D, ArpTrap0x0D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0E, ArpTrap0x0E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x10, ArpTrap0x10, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x11, ArpTrap0x11, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x12, ArpTrap0x12, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x13, ArpTrap0x13, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2A, ArpTrap0x2A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2B, ArpTrap0x2B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2C, ArpTrap0x2C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2D, ArpTrap0x2D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2E, ArpTrap0x2E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); + SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); + SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); + SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrap0x2A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); + SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrap0x2B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); + SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); + SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); + SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrap0x2E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); } /** @@ -292,18 +293,18 @@ ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock) */ XTAPI VOID -ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, - IN PKGDTENTRY Gdt, - IN PKIDTENTRY Idt, - IN PKTSS Tss, - IN PVOID DpcStack) +AR::ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, + IN PKGDTENTRY Gdt, + IN PKIDTENTRY Idt, + IN PKTSS Tss, + IN PVOID DpcStack) { /* Set processor block and processor control block */ ProcessorBlock->Self = ProcessorBlock; ProcessorBlock->CurrentPrcb = &ProcessorBlock->Prcb; /* Set GDT, IDT and TSS descriptors */ - ProcessorBlock->GdtBase = Gdt; + ProcessorBlock->GdtBase = (PKGDTENTRY)(PVOID)Gdt; ProcessorBlock->IdtBase = Idt; ProcessorBlock->TssBase = Tss; @@ -320,10 +321,10 @@ ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr7 = 0; /* Set process and thread information */ - ProcessorBlock->Prcb.CurrentThread = &KeInitialThread.ThreadControlBlock; - ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &KeInitialProcess.ProcessControlBlock; - ProcessorBlock->Prcb.IdleThread = &KeInitialThread.ThreadControlBlock; - ProcessorBlock->Prcb.NextThread = NULL; + ProcessorBlock->Prcb.CurrentThread = &(KE::KThread::GetInitialThread())->ThreadControlBlock; + ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &(KE::KProcess::GetInitialProcess())->ProcessControlBlock; + ProcessorBlock->Prcb.IdleThread = &(KE::KThread::GetInitialThread())->ThreadControlBlock; + ProcessorBlock->Prcb.NextThread = NULLPTR; /* Set initial runlevel */ ProcessorBlock->RunLevel = PASSIVE_LEVEL; @@ -338,13 +339,13 @@ ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, */ XTAPI VOID -ArpInitializeProcessorRegisters(VOID) +AR::ProcSup::InitializeProcessorRegisters(VOID) { /* Clear EFLAGS register */ - ArWriteEflagsRegister(0); + CpuFunc::WriteEflagsRegister(0); /* Enable write-protection */ - ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_WP); + CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_WP); } /** @@ -374,12 +375,12 @@ ArpInitializeProcessorRegisters(VOID) */ XTAPI VOID -ArpInitializeProcessorStructures(IN PVOID ProcessorStructures, - OUT PKGDTENTRY *Gdt, - OUT PKTSS *Tss, - OUT PKPROCESSOR_BLOCK *ProcessorBlock, - OUT PVOID *KernelBootStack, - OUT PVOID *KernelFaultStack) +AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures, + OUT PKGDTENTRY *Gdt, + OUT PKTSS *Tss, + OUT PKPROCESSOR_BLOCK *ProcessorBlock, + OUT PVOID *KernelBootStack, + OUT PVOID *KernelFaultStack) { UINT_PTR Address; @@ -394,15 +395,15 @@ ArpInitializeProcessorStructures(IN PVOID ProcessorStructures, *KernelFaultStack = (PVOID)Address; /* Assign a space for GDT and advance */ - *Gdt = (PVOID)Address; - Address += sizeof(ArInitialGdt); + *Gdt = (PKGDTENTRY)(PVOID)Address; + Address += sizeof(InitialGdt); /* Assign a space for Processor Block and advance */ - *ProcessorBlock = (PVOID)Address; - Address += sizeof(ArInitialProcessorBlock); + *ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address; + Address += sizeof(InitialProcessorBlock); /* Assign a space for TSS */ - *Tss = (PVOID)Address; + *Tss = (PKTSS)(PVOID)Address; } /** @@ -414,13 +415,13 @@ ArpInitializeProcessorStructures(IN PVOID ProcessorStructures, */ XTAPI VOID -ArpInitializeSegments(VOID) +AR::ProcSup::InitializeSegments(VOID) { /* Initialize segments */ - ArLoadSegment(SEGMENT_CS, KGDT_R0_CODE); - ArLoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK); - ArLoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK); - ArLoadSegment(SEGMENT_FS, KGDT_R0_PB); + CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE); + CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK); + CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK); + CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R0_PB); } /** @@ -435,9 +436,9 @@ ArpInitializeSegments(VOID) */ XTAPI VOID -ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, - IN PVOID KernelBootStack, - IN PVOID KernelFaultStack) +AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, + IN PVOID KernelBootStack, + IN PVOID KernelFaultStack) { /* Clear I/O map */ RtlSetMemory(ProcessorBlock->TssBase->IoMaps[0].IoMap, 0xFF, IOPM_FULL_SIZE); @@ -468,8 +469,8 @@ ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, ProcessorBlock->TssBase->Ss0 = KGDT_R0_DATA; /* Initialize task gates for DoubleFault and NMI traps */ - ArpSetDoubleFaultTssEntry(ProcessorBlock, KernelFaultStack); - ArpSetNonMaskableInterruptTssEntry(ProcessorBlock, KernelFaultStack); + SetDoubleFaultTssEntry(ProcessorBlock, KernelFaultStack); + SetNonMaskableInterruptTssEntry(ProcessorBlock, KernelFaultStack); } /** @@ -484,8 +485,8 @@ ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, */ XTAPI VOID -ArpSetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, - IN PVOID KernelFaultStack) +AR::ProcSup::SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, + IN PVOID KernelFaultStack) { PKGDTENTRY TaskGateEntry, TssEntry; PKTSS Tss; @@ -498,20 +499,20 @@ ArpSetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, ((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_DF_TSS; /* Initialize DoubleFault TSS and set initial state */ - Tss = (PKTSS)ArpDoubleFaultTss; + Tss = (PKTSS)DoubleFaultTss; Tss->IoMapBase = sizeof(KTSS); Tss->Flags = 0; Tss->LDT = KGDT_R0_LDT; - Tss->CR3 = ArReadControlRegister(3); + Tss->CR3 = CpuFunc::ReadControlRegister(3); Tss->Esp = (ULONG_PTR)KernelFaultStack; Tss->Esp0 = (ULONG_PTR)KernelFaultStack; - Tss->Eip = PtrToUlong(ArpHandleTrap08); + Tss->Eip = PtrToUlong(ArTrap0x08); Tss->Cs = KGDT_R0_CODE; Tss->Ds = KGDT_R3_DATA | RPL_MASK; Tss->Es = KGDT_R3_DATA | RPL_MASK; Tss->Fs = KGDT_R0_PB; Tss->Ss0 = KGDT_R0_DATA; - ArStoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss); + CpuFunc::StoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss); /* Setup DoubleFault TSS entry in Global Descriptor Table */ TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_DF_TSS / sizeof(KGDTENTRY)])); @@ -555,13 +556,13 @@ ArpSetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, */ XTAPI VOID -ArpSetGdtEntry(IN PKGDTENTRY Gdt, - IN USHORT Selector, - IN ULONG_PTR Base, - IN ULONG Limit, - IN UCHAR Type, - IN UCHAR Dpl, - IN UCHAR SegmentMode) +AR::ProcSup::SetGdtEntry(IN PKGDTENTRY Gdt, + IN USHORT Selector, + IN ULONG_PTR Base, + IN ULONG Limit, + IN UCHAR Type, + IN UCHAR Dpl, + IN UCHAR SegmentMode) { PKGDTENTRY GdtEntry; UCHAR Granularity; @@ -601,6 +602,39 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt, GdtEntry->Bits.Type = (Type & 0x1F); } +/** + * Updates an existing i686 GDT entry with new base address. + * + * @param Gdt + * Supplies a pointer to the GDT. + * + * @param Selector + * Specifies a segment selector of the GDT entry. + * + * @param Base + * Specifies a base address value of the descriptor. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt, + IN USHORT Selector, + IN ULONG_PTR Base) +{ + PKGDTENTRY GdtEntry; + + /* Get GDT entry */ + GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK)); + + /* Set new GDT descriptor base */ + GdtEntry->BaseLow = (Base & 0xFFFF); + GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF); + GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF); +} + /** * Fills in a call, interrupt, task or trap gate entry. * @@ -628,12 +662,12 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt, */ XTAPI VOID -ArpSetIdtGate(IN PKIDTENTRY Idt, - IN USHORT Vector, - IN PVOID Handler, - IN USHORT Selector, - IN USHORT Ist, - IN USHORT Access) +AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt, + IN USHORT Vector, + IN PVOID Handler, + IN USHORT Selector, + IN USHORT Ist, + IN USHORT Access) { /* Setup the gate */ Idt[Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF); @@ -654,8 +688,8 @@ ArpSetIdtGate(IN PKIDTENTRY Idt, */ XTAPI VOID -ArpSetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, - IN PVOID KernelFaultStack) +AR::ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, + IN PVOID KernelFaultStack) { PKGDTENTRY TaskGateEntry, TssEntry; PKTSS Tss; @@ -668,19 +702,19 @@ ArpSetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, ((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_NMI_TSS; /* Initialize NMI TSS and set initial state */ - Tss = (PKTSS)ArpNonMaskableInterruptTss; + Tss = (PKTSS)NonMaskableInterruptTss; Tss->IoMapBase = sizeof(KTSS); Tss->Flags = 0; Tss->LDT = KGDT_R0_LDT; - Tss->CR3 = ArReadControlRegister(3); + Tss->CR3 = CpuFunc::ReadControlRegister(3); Tss->Esp = (ULONG_PTR)KernelFaultStack; Tss->Esp0 = (ULONG_PTR)KernelFaultStack; - Tss->Eip = PtrToUlong(ArpHandleTrap02); + Tss->Eip = PtrToUlong(ArTrap0x02); Tss->Cs = KGDT_R0_CODE; Tss->Ds = KGDT_R3_DATA | RPL_MASK; Tss->Es = KGDT_R3_DATA | RPL_MASK; Tss->Fs = KGDT_R0_PB; - ArStoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss); + CpuFunc::StoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss); /* Setup NMI TSS entry in Global Descriptor Table */ TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_NMI_TSS / sizeof(KGDTENTRY)])); diff --git a/xtoskrnl/ar/i686/traps.c b/xtoskrnl/ar/i686/traps.cc similarity index 80% rename from xtoskrnl/ar/i686/traps.c rename to xtoskrnl/ar/i686/traps.cc index 031d9e2..eb5c1b6 100644 --- a/xtoskrnl/ar/i686/traps.c +++ b/xtoskrnl/ar/i686/traps.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ar/i686/traps.c + * FILE: xtoskrnl/ar/i686/traps.cc * DESCRIPTION: I686 system traps * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -21,110 +21,110 @@ */ XTCDECL VOID -ArpDispatchTrap(IN PKTRAP_FRAME TrapFrame) +AR::Traps::DispatchTrap(IN PKTRAP_FRAME TrapFrame) { /* Check vector and call appropriate handler */ switch(TrapFrame->Vector) { case 0x00: /* Divide By Zero exception */ - ArpHandleTrap00(TrapFrame); + HandleTrap00(TrapFrame); break; case 0x01: /* Debug exception */ - ArpHandleTrap01(TrapFrame); + HandleTrap01(TrapFrame); break; case 0x02: /* Non-Maskable Interrupt (NMI) */ - ArpHandleTrap02(TrapFrame); + HandleTrap02(TrapFrame); break; case 0x03: /* INT3 instruction executed */ - ArpHandleTrap03(TrapFrame); + HandleTrap03(TrapFrame); break; case 0x04: /* Overflow exception */ - ArpHandleTrap04(TrapFrame); + HandleTrap04(TrapFrame); break; case 0x05: /* Bound Range Exceeded exception */ - ArpHandleTrap05(TrapFrame); + HandleTrap05(TrapFrame); break; case 0x06: /* Invalid Opcode exception */ - ArpHandleTrap06(TrapFrame); + HandleTrap06(TrapFrame); break; case 0x07: /* Device Not Available exception */ - ArpHandleTrap07(TrapFrame); + HandleTrap07(TrapFrame); break; case 0x08: /* Double Fault exception */ - ArpHandleTrap08(TrapFrame); + HandleTrap08(TrapFrame); break; case 0x09: /* Segment Overrun exception */ - ArpHandleTrap09(TrapFrame); + HandleTrap09(TrapFrame); break; case 0x0A: /* Invalid TSS exception */ - ArpHandleTrap0A(TrapFrame); + HandleTrap0A(TrapFrame); break; case 0x0B: /* Segment Not Present exception */ - ArpHandleTrap0B(TrapFrame); + HandleTrap0B(TrapFrame); break; case 0x0C: /* Stack Segment Fault exception */ - ArpHandleTrap0C(TrapFrame); + HandleTrap0C(TrapFrame); break; case 0x0D: /* General Protection Fault (GPF) exception*/ - ArpHandleTrap0D(TrapFrame); + HandleTrap0D(TrapFrame); break; case 0x0E: /* Page Fault exception */ - ArpHandleTrap0E(TrapFrame); + HandleTrap0E(TrapFrame); break; case 0x10: /* X87 Floating-Point exception */ - ArpHandleTrap10(TrapFrame); + HandleTrap10(TrapFrame); break; case 0x11: /* Alignment Check exception */ - ArpHandleTrap11(TrapFrame); + HandleTrap11(TrapFrame); break; case 0x12: /* Machine Check exception */ - ArpHandleTrap12(TrapFrame); + HandleTrap12(TrapFrame); break; case 0x13: /* SIMD Floating-Point exception */ - ArpHandleTrap13(TrapFrame); + HandleTrap13(TrapFrame); break; case 0x2A: /* Tick Count service request */ - ArpHandleTrap2A(TrapFrame); + HandleTrap2A(TrapFrame); break; case 0x2B: /* User-mode callback return */ - ArpHandleTrap2B(TrapFrame); + HandleTrap2B(TrapFrame); break; case 0x2C: /* Assertion raised */ - ArpHandleTrap2C(TrapFrame); + HandleTrap2C(TrapFrame); break; case 0x2D: /* Debug-Service-Request raised */ - ArpHandleTrap2D(TrapFrame); + HandleTrap2D(TrapFrame); break; case 0x2E: /* System call service request */ - ArpHandleTrap2E(TrapFrame); + HandleTrap2E(TrapFrame); break; default: /* Unknown/Unexpected trap */ - ArpHandleTrapFF(TrapFrame); + HandleTrapFF(TrapFrame); break; } } @@ -141,7 +141,7 @@ ArpDispatchTrap(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap00(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Division-By-Zero Error (0x00)!\n"); for(;;); @@ -159,7 +159,7 @@ ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap01(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Debug exception (0x01)!\n"); for(;;); @@ -177,7 +177,7 @@ ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n"); for(;;); @@ -195,7 +195,7 @@ ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap03(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled INT3 (0x03)!\n"); for(;;); @@ -213,7 +213,7 @@ ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap04(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Overflow exception (0x04)!\n"); for(;;); @@ -231,7 +231,7 @@ ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap05(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Bound-Range-Exceeded exception (0x05)!\n"); for(;;); @@ -249,7 +249,7 @@ ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap06(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Invalid Opcode exception (0x06)!\n"); for(;;); @@ -267,7 +267,7 @@ ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap07(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Device Not Available exception (0x07)!\n"); for(;;); @@ -285,7 +285,7 @@ ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap08(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Double-Fault exception (0x08)!\n"); for(;;); @@ -303,7 +303,7 @@ ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap09(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Segment-Overrun exception (0x09)!\n"); for(;;); @@ -321,7 +321,7 @@ ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap0A(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Invalid-TSS exception (0x0A)!\n"); for(;;); @@ -339,7 +339,7 @@ ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap0B(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Segment-Not-Present exception (0x0B)!\n"); for(;;); @@ -357,7 +357,7 @@ ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap0C(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Stack-Segment-Fault exception (0x0C)!\n"); for(;;); @@ -375,7 +375,7 @@ ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap0D(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled General-Protection-Fault (0x0D)!\n"); for(;;); @@ -393,7 +393,7 @@ ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap0E(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Page-Fault exception (0x0E)!\n"); for(;;); @@ -411,7 +411,7 @@ ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap10(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled x87 Floating-Point exception (0x10)!\n"); for(;;); @@ -429,7 +429,7 @@ ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap11(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Alignment-Check exception (0x11)!\n"); for(;;); @@ -447,7 +447,7 @@ ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap12(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Machine-Check exception (0x12)!\n"); for(;;); @@ -465,7 +465,7 @@ ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap13(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled SIMD Floating-Point exception (0x13)!\n"); for(;;); @@ -483,7 +483,7 @@ ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap2A(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap2A(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Unhandled Tick Count service request (0x2A)!\n"); } @@ -500,7 +500,7 @@ ArpHandleTrap2A(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap2B(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap2B(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Unhandled Callback return service request (0x2B)!\n"); } @@ -517,7 +517,7 @@ ArpHandleTrap2B(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap2C(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Assertion (0x2C)!\n"); for(;;); @@ -535,7 +535,7 @@ ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap2D(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Debug-Service-Request (0x2D)!\n"); for(;;); @@ -553,7 +553,7 @@ ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap2E(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrap2E(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Unhandled system call (0x2E)!\n"); } @@ -570,8 +570,26 @@ ArpHandleTrap2E(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrapFF(IN PKTRAP_FRAME TrapFrame) +AR::Traps::HandleTrapFF(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Unexpected-Interrupt (0xFF)!\n"); for(;;); } + +/** + * C-linkage wrapper for dispatching the trap provided by common trap handler. + * + * @param TrapFrame + * Supplies a kernel trap frame pushed by common trap handler on the stack. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTCDECL +VOID +ArDispatchTrap(IN PKTRAP_FRAME TrapFrame) +{ + AR::Traps::DispatchTrap(TrapFrame); +} diff --git a/xtoskrnl/ex/exports.cc b/xtoskrnl/ex/exports.cc new file mode 100644 index 0000000..92dce80 --- /dev/null +++ b/xtoskrnl/ex/exports.cc @@ -0,0 +1,112 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/ex/exports.cc + * DESCRIPTION: C-compatible API wrappers for exported kernel functions + * DEVELOPERS: Aiken Harris + */ + +#include + + +/** + * Acquires the rundown protection for given descriptor. + * + * @param Descriptor + * Supplies a pointer to the rundown block descriptor. + * + * @return This routine returns TRUE if protection acquired successfully, or FALSE otherwise. + * + * @since NT 5.1 + */ +XTFASTCALL +BOOLEAN +ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) +{ + return EX::Rundown::AcquireProtection(Descriptor); +} + +/** + * Marks the rundown descriptor as completed. + * + * @param Descriptor + * Supplies a pointer to the descriptor to be completed. + * + * @return This routine does not return any value. + * + * @since NT 5.1 + */ +XTFASTCALL +VOID +ExCompleteRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) +{ + EX::Rundown::CompleteProtection(Descriptor); +} + +/** + * Initializes the rundown protection descriptor. + * + * @param Descriptor + * Supplies a pointer to the descriptor to be initialized. + * + * @return This routine does not return any value. + * + * @since NT 5.1 + */ +XTFASTCALL +VOID +ExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) +{ + EX::Rundown::InitializeProtection(Descriptor); +} + +/** + * Reinitializes the rundown protection structure after it has been completed. + * + * @param Descriptor + * Supplies a pointer to the descriptor to be reinitialized. + * + * @return This routine does not return any value. + * + * @since NT 5.1 + */ +XTFASTCALL +VOID +ExReInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) +{ + EX::Rundown::ReInitializeProtection(Descriptor); +} + +/** + * Releases the rundown protection for given descriptor. + * + * @param Descriptor + * Supplies a pointer to the descriptor to be initialized. + * + * @return This routine does not return any value. + * + * @since NT 5.1 + */ +XTFASTCALL +VOID +ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) +{ + EX::Rundown::ReleaseProtection(Descriptor); +} + +/** + * Waits until rundown protection calls are completed. + * + * @param Descriptor + * Supplies a pointer to the rundown block descriptor. + * + * @return This routine does not return any value. + * + * @since NT 5.1 + */ +XTFASTCALL +VOID +ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor) +{ + EX::Rundown::WaitForProtectionRelease(Descriptor); +} diff --git a/xtoskrnl/ex/rundown.c b/xtoskrnl/ex/rundown.cc similarity index 77% rename from xtoskrnl/ex/rundown.c rename to xtoskrnl/ex/rundown.cc index f5f5392..f522925 100644 --- a/xtoskrnl/ex/rundown.c +++ b/xtoskrnl/ex/rundown.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ex/rundown.c + * FILE: xtoskrnl/ex/rundown.cc * DESCRIPTION: Rundown protection mechanism * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -21,7 +21,7 @@ */ XTFASTCALL BOOLEAN -ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) +EX::Rundown::AcquireProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) { ULONG_PTR CurrentValue, NewValue; @@ -42,8 +42,8 @@ ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) NewValue = CurrentValue + 2; /* Exchange the value */ - NewValue = (ULONG_PTR)RtlAtomicCompareExchangePointer(&Descriptor->Ptr, (PVOID)NewValue, - (PVOID)CurrentValue); + NewValue = (ULONG_PTR)RTL::Atomic::CompareExchangePointer(&Descriptor->Ptr, (PVOID)NewValue, + (PVOID)CurrentValue); /* Make sure protection acquired */ if(NewValue == CurrentValue) @@ -69,9 +69,9 @@ ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) */ XTFASTCALL VOID -ExCompleteRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) +EX::Rundown::CompleteProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) { - RtlAtomicExchangePointer(&Descriptor->Ptr, (PVOID)EX_RUNDOWN_ACTIVE); + RTL::Atomic::ExchangePointer(&Descriptor->Ptr, (PVOID)EX_RUNDOWN_ACTIVE); } /** @@ -86,7 +86,7 @@ ExCompleteRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) */ XTFASTCALL VOID -ExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) +EX::Rundown::InitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) { /* Reset descriptor counter */ Descriptor->Count = 0; @@ -104,9 +104,9 @@ ExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) */ XTFASTCALL VOID -ExReInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) +EX::Rundown::ReInitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) { - RtlAtomicExchangePointer(&Descriptor->Ptr, NULL); + RTL::Atomic::ExchangePointer(&Descriptor->Ptr, NULLPTR); } /** @@ -121,7 +121,7 @@ ExReInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) */ XTFASTCALL VOID -ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) +EX::Rundown::ReleaseProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) { ULONG_PTR CurrentValue, NewValue; PEX_RUNDOWN_WAIT_BLOCK WaitBlock; @@ -134,9 +134,9 @@ ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) { WaitBlock = (PEX_RUNDOWN_WAIT_BLOCK)(CurrentValue & ~0x1); - if(!RtlAtomicDecrement64((PLONG_PTR)&WaitBlock->Count)) + if(!RTL::Atomic::Decrement64((PLONG_PTR)&WaitBlock->Count)) { - KeSetEvent(&WaitBlock->WakeEvent, 0, FALSE); + KE::Event::SetEvent(&WaitBlock->WakeEvent, 0, FALSE); } break; @@ -147,8 +147,8 @@ ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) NewValue = CurrentValue - 2; /* Exchange the value */ - NewValue = (ULONG_PTR)RtlAtomicCompareExchangePointer(&Descriptor->Ptr, (PVOID)NewValue, - (PVOID)CurrentValue); + NewValue = (ULONG_PTR)RTL::Atomic::CompareExchangePointer(&Descriptor->Ptr, (PVOID)NewValue, + (PVOID)CurrentValue); if(NewValue == CurrentValue) { @@ -172,7 +172,7 @@ ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) */ XTFASTCALL VOID -ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor) +EX::Rundown::WaitForProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor) { UNIMPLEMENTED; } diff --git a/xtoskrnl/hl/acpi.c b/xtoskrnl/hl/acpi.cc similarity index 79% rename from xtoskrnl/hl/acpi.c rename to xtoskrnl/hl/acpi.cc index 28d9ef7..2801f71 100644 --- a/xtoskrnl/hl/acpi.c +++ b/xtoskrnl/hl/acpi.cc @@ -1,14 +1,35 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/hl/x86/acpi.c + * FILE: xtoskrnl/hl/x86/acpi.cc * DESCRIPTION: Advanced Configuration and Power Interface (ACPI) support * DEVELOPERS: Rafal Kupiec */ -#include +#include +/** + * Stores given ACPI table in the kernel local cache. + * + * @param AcpiTable + * Supplies a pointer to ACPI table that will be stored in the cache. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +HL::Acpi::CacheAcpiTable(IN PACPI_DESCRIPTION_HEADER AcpiTable) +{ + PACPI_CACHE_LIST AcpiCache; + + /* Create new ACPI table cache entry */ + AcpiCache = CONTAIN_RECORD(AcpiTable, ACPI_CACHE_LIST, Header); + RTL::LinkedList::InsertTailList(&CacheList, &AcpiCache->ListEntry); +} + /** * Gets a pointer to the ACPI system description pointer (RSDP). * @@ -21,10 +42,10 @@ */ XTAPI XTSTATUS -HlGetAcpiSystemDescriptionPointer(OUT PACPI_RSDP *Rsdp) +HL::Acpi::GetAcpiSystemDescriptionPointer(OUT PACPI_RSDP *Rsdp) { /* Get RSDP and return success */ - *Rsdp = HlpAcpiRsdp; + *Rsdp = RsdpStructure; return STATUS_SUCCESS; } @@ -43,21 +64,21 @@ HlGetAcpiSystemDescriptionPointer(OUT PACPI_RSDP *Rsdp) */ XTAPI XTSTATUS -HlGetAcpiTable(IN ULONG Signature, - OUT PACPI_DESCRIPTION_HEADER *AcpiTable) +HL::Acpi::GetAcpiTable(IN ULONG Signature, + OUT PACPI_DESCRIPTION_HEADER *AcpiTable) { PACPI_DESCRIPTION_HEADER Table; XTSTATUS Status; /* Assume ACPI table not found */ - *AcpiTable = NULL; + *AcpiTable = NULLPTR; /* Attempt to get ACPI table from the cache */ - Status = HlpQueryAcpiCache(Signature, &Table); + Status = QueryAcpiCache(Signature, &Table); if(Status != STATUS_SUCCESS) { /* Table not found in the cache, query ACPI tables */ - Status = HlpQueryAcpiTables(Signature, &Table); + Status = QueryAcpiTables(Signature, &Table); if(Status != STATUS_SUCCESS) { /* ACPI table not found, return error */ @@ -70,27 +91,6 @@ HlGetAcpiTable(IN ULONG Signature, return STATUS_SUCCESS; } -/** - * Stores given ACPI table in the kernel local cache. - * - * @param AcpiTable - * Supplies a pointer to ACPI table that will be stored in the cache. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -HlpCacheAcpiTable(IN PACPI_DESCRIPTION_HEADER AcpiTable) -{ - PACPI_CACHE_LIST AcpiCache; - - /* Create new ACPI table cache entry */ - AcpiCache = CONTAIN_RECORD(AcpiTable, ACPI_CACHE_LIST, Header); - RtlInsertTailList(&HlpAcpiCacheList, &AcpiCache->ListEntry); -} - /** * Performs an initialization of the ACPI subsystem. * @@ -100,13 +100,13 @@ HlpCacheAcpiTable(IN PACPI_DESCRIPTION_HEADER AcpiTable) */ XTAPI XTSTATUS -HlpInitializeAcpi(VOID) +HL::Acpi::InitializeAcpi(VOID) { PACPI_FADT Fadt; XTSTATUS Status; /* Initialize ACPI cache */ - Status = HlpInitializeAcpiCache(); + Status = InitializeAcpiCache(); if(Status != STATUS_SUCCESS) { /* ACPI cache initialization failed, return error */ @@ -114,7 +114,7 @@ HlpInitializeAcpi(VOID) } /* Get Fixed ACPI Description Table (FADT) */ - Status = HlGetAcpiTable(ACPI_FADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Fadt); + Status = GetAcpiTable(ACPI_FADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Fadt); if(Status != STATUS_SUCCESS || !Fadt) { /* Failed to get FADT, return error */ @@ -122,7 +122,7 @@ HlpInitializeAcpi(VOID) } /* Initialize ACPI timer */ - HlpInitializeAcpiTimer(); + InitializeAcpiTimer(); /* Return success */ return STATUS_SUCCESS; @@ -137,16 +137,16 @@ HlpInitializeAcpi(VOID) */ XTAPI XTSTATUS -HlpInitializeAcpiCache(VOID) +HL::Acpi::InitializeAcpiCache(VOID) { PACPI_DESCRIPTION_HEADER Rsdt; XTSTATUS Status; /* Initialize ACPI cache list */ - RtlInitializeListHead(&HlpAcpiCacheList); + RTL::LinkedList::InitializeListHead(&CacheList); /* Get XSDT/RSDT */ - Status = HlpInitializeAcpiSystemDescriptionTable(&Rsdt); + Status = InitializeAcpiSystemDescriptionTable(&Rsdt); if(Status != STATUS_SUCCESS) { /* Failed to get XSDT/RSDT, return error */ @@ -154,7 +154,7 @@ HlpInitializeAcpiCache(VOID) } /* Cache XSDT/RSDT table */ - HlpCacheAcpiTable(Rsdt); + CacheAcpiTable(Rsdt); /* Return success */ return STATUS_SUCCESS; @@ -172,7 +172,7 @@ HlpInitializeAcpiCache(VOID) */ XTAPI XTSTATUS -HlpInitializeAcpiSystemDescriptionTable(OUT PACPI_DESCRIPTION_HEADER *AcpiTable) +HL::Acpi::InitializeAcpiSystemDescriptionTable(OUT PACPI_DESCRIPTION_HEADER *AcpiTable) { PHYSICAL_ADDRESS RsdpAddress, RsdtAddress; PSYSTEM_RESOURCE_HEADER ResourceHeader; @@ -182,7 +182,7 @@ HlpInitializeAcpiSystemDescriptionTable(OUT PACPI_DESCRIPTION_HEADER *AcpiTable) XTSTATUS Status; /* Assume ACPI table not found */ - *AcpiTable = NULL; + *AcpiTable = NULLPTR; /* Get ACPI system resource */ Status = KeGetSystemResource(SystemResourceAcpi, &ResourceHeader); @@ -197,31 +197,31 @@ HlpInitializeAcpiSystemDescriptionTable(OUT PACPI_DESCRIPTION_HEADER *AcpiTable) RsdpAddress.QuadPart = (LONGLONG)AcpiResource->Header.PhysicalAddress; /* Map RSDP and mark it as CD/WT to avoid delays in write-back cache */ - Status = MmMapHardwareMemory(RsdpAddress, 1, TRUE, (PVOID *)&HlpAcpiRsdp); - MmMarkHardwareMemoryWriteThrough(HlpAcpiRsdp, 1); + Status = MM::HardwarePool::MapHardwareMemory(RsdpAddress, 1, TRUE, (PVOID *)&RsdpStructure); + MM::HardwarePool::MarkHardwareMemoryWriteThrough(RsdpStructure, 1); /* Validate RSDP signature */ - if(Status != STATUS_SUCCESS || HlpAcpiRsdp->Signature != ACPI_RSDP_SIGNATURE) + if(Status != STATUS_SUCCESS || RsdpStructure->Signature != ACPI_RSDP_SIGNATURE) { /* Not mapped correctly or invalid RSDP signature, return error */ return STATUS_INVALID_PARAMETER; } /* Check RSDP revision to determine RSDT/XSDT address */ - if(HlpAcpiRsdp->Revision >= 2) + if(RsdpStructure->Revision >= 2) { /* Get XSDT address */ - RsdtAddress.QuadPart = (LONGLONG)HlpAcpiRsdp->XsdtAddress; + RsdtAddress.QuadPart = (LONGLONG)RsdpStructure->XsdtAddress; } else { /* Get RSDT address */ - RsdtAddress.QuadPart = (LONGLONG)HlpAcpiRsdp->RsdtAddress; + RsdtAddress.QuadPart = (LONGLONG)RsdpStructure->RsdtAddress; } /* Map RSDT/XSDT as CD/WT */ - Status = MmMapHardwareMemory(RsdtAddress, 2, TRUE, (PVOID *)&Rsdt); - MmMarkHardwareMemoryWriteThrough(Rsdt, 2); + Status = MM::HardwarePool::MapHardwareMemory(RsdtAddress, 2, TRUE, (PVOID *)&Rsdt); + MM::HardwarePool::MarkHardwareMemoryWriteThrough(Rsdt, 2); /* Validate RSDT/XSDT signature */ if((Status != STATUS_SUCCESS) || @@ -237,9 +237,9 @@ HlpInitializeAcpiSystemDescriptionTable(OUT PACPI_DESCRIPTION_HEADER *AcpiTable) if(RsdtPages != 2) { /* RSDT/XSDT needs less or more than 2 pages, remap it */ - MmUnmapHardwareMemory(Rsdt, 2, TRUE); - Status = MmMapHardwareMemory(RsdtAddress, RsdtPages, TRUE, (PVOID *)&Rsdt); - MmMarkHardwareMemoryWriteThrough(Rsdt, RsdtPages); + MM::HardwarePool::UnmapHardwareMemory(Rsdt, 2, TRUE); + Status = MM::HardwarePool::MapHardwareMemory(RsdtAddress, RsdtPages, TRUE, (PVOID *)&Rsdt); + MM::HardwarePool::MarkHardwareMemoryWriteThrough(Rsdt, RsdtPages); /* Make sure remapping was successful */ if(Status != STATUS_SUCCESS) @@ -263,7 +263,7 @@ HlpInitializeAcpiSystemDescriptionTable(OUT PACPI_DESCRIPTION_HEADER *AcpiTable) */ XTAPI XTSTATUS -HlpInitializeAcpiSystemInformation(VOID) +HL::Acpi::InitializeAcpiSystemInformation(VOID) { PACPI_MADT_LOCAL_X2APIC LocalX2Apic; PACPI_MADT_LOCAL_APIC LocalApic; @@ -273,7 +273,7 @@ HlpInitializeAcpiSystemInformation(VOID) USHORT CpuCount; /* Allocate memory for ACPI system information structure */ - Status = HlpInitializeAcpiSystemStructure(); + Status = InitializeAcpiSystemStructure(); if(Status != STATUS_SUCCESS) { /* Failed to allocate memory, return error */ @@ -281,7 +281,7 @@ HlpInitializeAcpiSystemInformation(VOID) } /* Get Multiple APIC Description Table (MADT) */ - Status = HlGetAcpiTable(ACPI_MADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Madt); + Status = GetAcpiTable(ACPI_MADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Madt); if(Status != STATUS_SUCCESS) { /* Failed to get MADT, return error */ @@ -306,9 +306,9 @@ HlpInitializeAcpiSystemInformation(VOID) if(LocalApic->Flags & ACPI_MADT_PLAOC_ENABLED) { /* Store CPU number, APIC ID and CPU ID */ - HlpSystemInfo.CpuInfo[CpuCount].AcpiId = LocalApic->AcpiId; - HlpSystemInfo.CpuInfo[CpuCount].ApicId = LocalApic->ApicId; - HlpSystemInfo.CpuInfo[CpuCount].CpuNumber = CpuCount; + SystemInfo.CpuInfo[CpuCount].AcpiId = LocalApic->AcpiId; + SystemInfo.CpuInfo[CpuCount].ApicId = LocalApic->ApicId; + SystemInfo.CpuInfo[CpuCount].CpuNumber = CpuCount; /* Increment number of CPUs */ CpuCount++; @@ -327,9 +327,9 @@ HlpInitializeAcpiSystemInformation(VOID) if(LocalX2Apic->Flags & ACPI_MADT_PLAOC_ENABLED) { /* Store CPU number, APIC ID and CPU ID */ - HlpSystemInfo.CpuInfo[CpuCount].AcpiId = LocalX2Apic->AcpiId; - HlpSystemInfo.CpuInfo[CpuCount].ApicId = LocalX2Apic->ApicId; - HlpSystemInfo.CpuInfo[CpuCount].CpuNumber = CpuCount; + SystemInfo.CpuInfo[CpuCount].AcpiId = LocalX2Apic->AcpiId; + SystemInfo.CpuInfo[CpuCount].ApicId = LocalX2Apic->ApicId; + SystemInfo.CpuInfo[CpuCount].CpuNumber = CpuCount; /* Increment number of CPUs */ CpuCount++; @@ -346,7 +346,7 @@ HlpInitializeAcpiSystemInformation(VOID) } /* Store number of CPUs */ - HlpSystemInfo.CpuCount = CpuCount; + SystemInfo.CpuCount = CpuCount; /* Return success */ return STATUS_SUCCESS; @@ -361,7 +361,7 @@ HlpInitializeAcpiSystemInformation(VOID) */ XTAPI XTSTATUS -HlpInitializeAcpiSystemStructure(VOID) +HL::Acpi::InitializeAcpiSystemStructure(VOID) { PHYSICAL_ADDRESS PhysicalAddress; PFN_NUMBER PageCount; @@ -371,7 +371,7 @@ HlpInitializeAcpiSystemStructure(VOID) ULONG CpuCount; /* Get Multiple APIC Description Table (MADT) */ - Status = HlGetAcpiTable(ACPI_MADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Madt); + Status = GetAcpiTable(ACPI_MADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Madt); if(Status != STATUS_SUCCESS) { /* Failed to get MADT, return error */ @@ -420,13 +420,13 @@ HlpInitializeAcpiSystemStructure(VOID) } /* Zero the ACPI system information structure */ - RtlZeroMemory(&HlpSystemInfo, sizeof(ACPI_SYSTEM_INFO)); + RTL::Memory::ZeroMemory(&SystemInfo, sizeof(ACPI_SYSTEM_INFO)); /* Calculate number of pages needed to store CPU information */ PageCount = SIZE_TO_PAGES(CpuCount * sizeof(PROCESSOR_IDENTITY)); /* Allocate memory for CPU information */ - Status = MmAllocateHardwareMemory(PageCount, TRUE, &PhysicalAddress); + Status = MM::HardwarePool::AllocateHardwareMemory(PageCount, TRUE, &PhysicalAddress); if(Status != STATUS_SUCCESS) { /* Failed to allocate memory, return error */ @@ -434,7 +434,7 @@ HlpInitializeAcpiSystemStructure(VOID) } /* Map physical address to the virtual memory area */ - Status = MmMapHardwareMemory(PhysicalAddress, PageCount, TRUE, (PVOID *)&HlpSystemInfo.CpuInfo); + Status = MM::HardwarePool::MapHardwareMemory(PhysicalAddress, PageCount, TRUE, (PVOID *)&SystemInfo.CpuInfo); if(Status != STATUS_SUCCESS) { /* Failed to map memory, return error */ @@ -442,7 +442,7 @@ HlpInitializeAcpiSystemStructure(VOID) } /* Zero the CPU information structure */ - RtlZeroMemory(HlpSystemInfo.CpuInfo, PAGES_TO_SIZE(PageCount)); + RTL::Memory::ZeroMemory(SystemInfo.CpuInfo, PAGES_TO_SIZE(PageCount)); /* Return success */ return STATUS_SUCCESS; @@ -457,13 +457,13 @@ HlpInitializeAcpiSystemStructure(VOID) */ XTAPI XTSTATUS -HlpInitializeAcpiTimer(VOID) +HL::Acpi::InitializeAcpiTimer(VOID) { PACPI_FADT Fadt; XTSTATUS Status; /* Get Fixed ACPI Description Table (FADT) */ - Status = HlGetAcpiTable(ACPI_FADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Fadt); + Status = GetAcpiTable(ACPI_FADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Fadt); if(Status != STATUS_SUCCESS || !Fadt) { /* Failed to get FADT, return error */ @@ -471,18 +471,18 @@ HlpInitializeAcpiTimer(VOID) } /* Set ACPI timer port address */ - HlpAcpiTimerInfo.TimerPort = Fadt->PmTmrBlkIoPort; + TimerInfo.TimerPort = Fadt->PmTmrBlkIoPort; /* Determine whether 32-bit or 24-bit timer is used */ if(Fadt->Flags & ACPI_FADT_32BIT_TIMER) { /* 32-bit timer */ - HlpAcpiTimerInfo.MsbMask = ACPI_FADT_TIMER_32BIT; + TimerInfo.MsbMask = ACPI_FADT_TIMER_32BIT; } else { /* 24-bit timer */ - HlpAcpiTimerInfo.MsbMask = ACPI_FADT_TIMER_24BIT; + TimerInfo.MsbMask = ACPI_FADT_TIMER_24BIT; } /* Return success */ @@ -504,19 +504,19 @@ HlpInitializeAcpiTimer(VOID) */ XTAPI XTSTATUS -HlpQueryAcpiCache(IN ULONG Signature, - OUT PACPI_DESCRIPTION_HEADER *AcpiTable) +HL::Acpi::QueryAcpiCache(IN ULONG Signature, + OUT PACPI_DESCRIPTION_HEADER *AcpiTable) { PACPI_DESCRIPTION_HEADER TableHeader; PACPI_CACHE_LIST AcpiCache; PLIST_ENTRY ListEntry; /* Initialize variables */ - TableHeader = NULL; + TableHeader = NULLPTR; /* Iterate through ACPI tables cache list */ - ListEntry = HlpAcpiCacheList.Flink; - while(ListEntry != &HlpAcpiCacheList) + ListEntry = CacheList.Flink; + while(ListEntry != &CacheList) { /* Get cached ACPI table header */ AcpiCache = CONTAIN_RECORD(ListEntry, ACPI_CACHE_LIST, ListEntry); @@ -534,7 +534,7 @@ HlpQueryAcpiCache(IN ULONG Signature, } /* Check if the requested ACPI table was found in the cache */ - if(TableHeader == NULL) + if(TableHeader == NULLPTR) { /* ACPI table not found in cache, return error */ return STATUS_NOT_FOUND; @@ -561,8 +561,8 @@ HlpQueryAcpiCache(IN ULONG Signature, */ XTAPI XTSTATUS -HlpQueryAcpiTables(IN ULONG Signature, - OUT PACPI_DESCRIPTION_HEADER *AcpiTable) +HL::Acpi::QueryAcpiTables(IN ULONG Signature, + OUT PACPI_DESCRIPTION_HEADER *AcpiTable) { ULONG TableCount, TableIndex, TablePages; PACPI_DESCRIPTION_HEADER TableHeader; @@ -580,13 +580,13 @@ HlpQueryAcpiTables(IN ULONG Signature, } /* Ensure that table header is not set before attempting to find ACPI table */ - TableHeader = NULL; + TableHeader = NULLPTR; /* Check if DSDT or FACS table requested */ if(Signature == ACPI_DSDT_SIGNATURE || Signature == ACPI_FACS_SIGNATURE) { /* Get FADT as it contains a pointer to DSDT and FACS */ - Status = HlGetAcpiTable(ACPI_FADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Fadt); + Status = GetAcpiTable(ACPI_FADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Fadt); if(Status != STATUS_SUCCESS) { /* Failed to get FADT, return error */ @@ -609,7 +609,7 @@ HlpQueryAcpiTables(IN ULONG Signature, TableAddress.HighPart = 0; /* Map table using hardware memory pool */ - Status = MmMapHardwareMemory(TableAddress, 2, TRUE, (PVOID*)&TableHeader); + Status = MM::HardwarePool::MapHardwareMemory(TableAddress, 2, TRUE, (PVOID*)&TableHeader); if(Status != STATUS_SUCCESS) { /* Failed to map table, return error */ @@ -619,11 +619,11 @@ HlpQueryAcpiTables(IN ULONG Signature, else { /* Query cache for XSDP table */ - Status = HlpQueryAcpiCache(ACPI_XSDT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Xsdt); + Status = QueryAcpiCache(ACPI_XSDT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Xsdt); if(Status != STATUS_SUCCESS) { /* XSDP not found, query cache for RSDP table */ - Status = HlpQueryAcpiCache(ACPI_RSDT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Rsdt); + Status = QueryAcpiCache(ACPI_RSDT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Rsdt); } /* Check if XSDT or RSDT table found */ @@ -634,7 +634,7 @@ HlpQueryAcpiTables(IN ULONG Signature, } /* Get table count depending on root table type */ - if(Xsdt != NULL) + if(Xsdt != NULLPTR) { /* Get table count from XSDT */ TableCount = (Xsdt->Header.Length - sizeof(ACPI_DESCRIPTION_HEADER)) / 8; @@ -649,7 +649,7 @@ HlpQueryAcpiTables(IN ULONG Signature, for(TableIndex = 0; TableIndex < TableCount; TableIndex++) { /* Check if XSDP or RSDT is used */ - if(Xsdt != NULL) + if(Xsdt != NULLPTR) { /* Get table header physical address from XSDT */ TableAddress.QuadPart = Xsdt->Tables[TableIndex]; @@ -662,14 +662,14 @@ HlpQueryAcpiTables(IN ULONG Signature, } /* Check whether some table is already mapped */ - if(TableHeader != NULL) + if(TableHeader != NULLPTR) { /* Unmap previous table */ - MmUnmapHardwareMemory(TableHeader, 2, TRUE); + MM::HardwarePool::UnmapHardwareMemory(TableHeader, 2, TRUE); } /* Map table using hardware memory pool */ - Status = MmMapHardwareMemory(TableAddress, 2, TRUE, (PVOID*)&TableHeader); + Status = MM::HardwarePool::MapHardwareMemory(TableAddress, 2, TRUE, (PVOID*)&TableHeader); if(Status != STATUS_SUCCESS) { /* Failed to map table, return error */ @@ -689,10 +689,10 @@ HlpQueryAcpiTables(IN ULONG Signature, if(TableHeader->Signature != Signature) { /* ACPI table not found, check if cleanup is needed */ - if(TableHeader != NULL) + if(TableHeader != NULLPTR) { /* Unmap non-matching ACPI table */ - MmUnmapHardwareMemory(TableHeader, 2, TRUE); + MM::HardwarePool::UnmapHardwareMemory(TableHeader, 2, TRUE); } /* Return error */ @@ -703,10 +703,10 @@ HlpQueryAcpiTables(IN ULONG Signature, if(TableHeader->Signature != ACPI_FADT_SIGNATURE || TableHeader->Revision > 2) { /* Validate table checksum */ - if(!HlpValidateAcpiTable(TableHeader, TableHeader->Length)) + if(!ValidateAcpiTable(TableHeader, TableHeader->Length)) { /* Checksum mismatch, unmap table and return error */ - MmUnmapHardwareMemory(TableHeader, 2, TRUE); + MM::HardwarePool::UnmapHardwareMemory(TableHeader, 2, TRUE); return STATUS_CRC_ERROR; } } @@ -716,8 +716,8 @@ HlpQueryAcpiTables(IN ULONG Signature, if(TablePages != 2) { /* ACPI table needs less or more than 2 pages, remap it */ - MmUnmapHardwareMemory(TableHeader, 2, FALSE); - Status = MmMapHardwareMemory(TableAddress, TablePages, TRUE, (PVOID*)&TableHeader); + MM::HardwarePool::UnmapHardwareMemory(TableHeader, 2, FALSE); + Status = MM::HardwarePool::MapHardwareMemory(TableAddress, TablePages, TRUE, (PVOID*)&TableHeader); /* Make sure remapping was successful */ if(Status != STATUS_SUCCESS) @@ -728,8 +728,8 @@ HlpQueryAcpiTables(IN ULONG Signature, } /* Mark table as write through and store it in local cache */ - MmMarkHardwareMemoryWriteThrough(TableHeader, TablePages); - HlpCacheAcpiTable(TableHeader); + MM::HardwarePool::MarkHardwareMemoryWriteThrough(TableHeader, TablePages); + CacheAcpiTable(TableHeader); /* Store ACPI table and return success */ *AcpiTable = TableHeader; @@ -751,15 +751,15 @@ HlpQueryAcpiTables(IN ULONG Signature, */ XTAPI BOOLEAN -HlpValidateAcpiTable(IN PVOID Buffer, - IN UINT_PTR Size) +HL::Acpi::ValidateAcpiTable(IN PVOID Buffer, + IN UINT_PTR Size) { PUCHAR Pointer; UCHAR Sum; /* Initialize variables */ Sum = 0; - Pointer = Buffer; + Pointer = (PUCHAR)Buffer; /* Calculate checksum of given table */ while(Size != 0) diff --git a/xtoskrnl/hl/amd64/cpu.c b/xtoskrnl/hl/amd64/cpu.cc similarity index 72% rename from xtoskrnl/hl/amd64/cpu.c rename to xtoskrnl/hl/amd64/cpu.cc index b136254..3a6b166 100644 --- a/xtoskrnl/hl/amd64/cpu.c +++ b/xtoskrnl/hl/amd64/cpu.cc @@ -1,13 +1,13 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/hl/amd64/cpu.c + * FILE: xtoskrnl/hl/amd64/cpu.cc * DESCRIPTION: HAL AMD64 processor support * DEVELOPERS: Rafal Kupiec */ -#include +#include /* Include common CPU interface */ -#include ARCH_COMMON(cpu.c) +#include ARCH_COMMON(cpu.cc) diff --git a/xtoskrnl/hl/amd64/ioport.c b/xtoskrnl/hl/amd64/ioport.cc similarity index 86% rename from xtoskrnl/hl/amd64/ioport.c rename to xtoskrnl/hl/amd64/ioport.cc index 1ec9adc..48e2085 100644 --- a/xtoskrnl/hl/amd64/ioport.c +++ b/xtoskrnl/hl/amd64/ioport.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/hl/amd64/ioport.c + * FILE: xtoskrnl/hl/amd64/ioport.cc * DESCRIPTION: I/O port access routines for AMD64 platform * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -21,7 +21,7 @@ */ XTCDECL UCHAR -HlIoPortInByte(IN USHORT Port) +HL::IoPort::ReadPort8(IN USHORT Port) { UCHAR Value; __asm__ volatile("inb %1, %0" @@ -30,27 +30,6 @@ HlIoPortInByte(IN USHORT Port) return Value; } -/** - * Reads the 32-bit data from the specified I/O port. - * - * @param Port - * Specifies the address to read from, in the range of 0-0xFFFF. - * - * @return The value read from the port. - * - * @since XT 1.0 - */ -XTCDECL -ULONG -HlIoPortInLong(IN USHORT Port) -{ - ULONG Value; - __asm__ volatile("inl %1, %0" - : "=a" (Value) - : "Nd" (Port)); - return Value; -} - /** * Reads the 16-bit data from the specified I/O port. * @@ -63,7 +42,7 @@ HlIoPortInLong(IN USHORT Port) */ XTCDECL USHORT -HlIoPortInShort(IN USHORT Port) +HL::IoPort::ReadPort16(IN USHORT Port) { USHORT Value; __asm__ volatile("inw %1, %0" @@ -72,6 +51,27 @@ HlIoPortInShort(IN USHORT Port) return Value; } +/** + * Reads the 32-bit data from the specified I/O port. + * + * @param Port + * Specifies the address to read from, in the range of 0-0xFFFF. + * + * @return The value read from the port. + * + * @since XT 1.0 + */ +XTCDECL +ULONG +HL::IoPort::ReadPort32(IN USHORT Port) +{ + ULONG Value; + __asm__ volatile("inl %1, %0" + : "=a" (Value) + : "Nd" (Port)); + return Value; +} + /** * Writes the 8-bit data to the specified I/O port. * @@ -87,8 +87,8 @@ HlIoPortInShort(IN USHORT Port) */ XTCDECL VOID -HlIoPortOutByte(IN USHORT Port, - IN UCHAR Value) +HL::IoPort::WritePort8(IN USHORT Port, + IN UCHAR Value) { __asm__ volatile("outb %0, %1" : @@ -96,30 +96,6 @@ HlIoPortOutByte(IN USHORT Port, "Nd" (Port)); } -/** - * Writes the 32-bit data to the specified I/O port. - * - * @param Port - * Specifies the address to write to, in the range of 0-0xFFFF. - * - * @param Value - * Supplies the value to write. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -HlIoPortOutLong(IN USHORT Port, - IN ULONG Value) -{ - __asm__ volatile("outl %0, %1" - : - : "a" (Value), - "Nd" (Port)); -} - /** * Writes the 16-bit data to the specified I/O port. * @@ -135,11 +111,35 @@ HlIoPortOutLong(IN USHORT Port, */ XTCDECL VOID -HlIoPortOutShort(IN USHORT Port, - IN USHORT Value) +HL::IoPort::WritePort16(IN USHORT Port, + IN USHORT Value) { __asm__ volatile("outw %0, %1" : : "a" (Value), "Nd" (Port)); } + +/** + * Writes the 32-bit data to the specified I/O port. + * + * @param Port + * Specifies the address to write to, in the range of 0-0xFFFF. + * + * @param Value + * Supplies the value to write. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +HL::IoPort::WritePort32(IN USHORT Port, + IN ULONG Value) +{ + __asm__ volatile("outl %0, %1" + : + : "a" (Value), + "Nd" (Port)); +} diff --git a/xtoskrnl/hl/amd64/pic.c b/xtoskrnl/hl/amd64/pic.cc similarity index 75% rename from xtoskrnl/hl/amd64/pic.c rename to xtoskrnl/hl/amd64/pic.cc index 60be3eb..076cdbb 100644 --- a/xtoskrnl/hl/amd64/pic.c +++ b/xtoskrnl/hl/amd64/pic.cc @@ -1,13 +1,13 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/hl/amd64/pic.c + * FILE: xtoskrnl/hl/amd64/pic.cc * DESCRIPTION: Programmable Interrupt Controller (PIC) for AMD64 support * DEVELOPERS: Rafal Kupiec */ -#include +#include /* Include common PIC interface */ -#include ARCH_COMMON(pic.c) +#include ARCH_COMMON(pic.cc) diff --git a/xtoskrnl/hl/amd64/runlevel.c b/xtoskrnl/hl/amd64/runlevel.cc similarity index 77% rename from xtoskrnl/hl/amd64/runlevel.c rename to xtoskrnl/hl/amd64/runlevel.cc index 5979a48..8408c39 100644 --- a/xtoskrnl/hl/amd64/runlevel.c +++ b/xtoskrnl/hl/amd64/runlevel.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/hl/amd64/runlevel.c + * FILE: xtoskrnl/hl/amd64/runlevel.cc * DESCRIPTION: Run Level management support for AMD64 architecture * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -18,9 +18,9 @@ */ XTFASTCALL KRUNLEVEL -HlGetRunLevel(VOID) +HL::RunLevel::GetRunLevel(VOID) { - return (KRUNLEVEL)ArReadControlRegister(8); + return (KRUNLEVEL)AR::CpuFunc::ReadControlRegister(8); } /** @@ -35,9 +35,9 @@ HlGetRunLevel(VOID) */ XTFASTCALL VOID -HlSetRunLevel(IN KRUNLEVEL RunLevel) +HL::RunLevel::SetRunLevel(IN KRUNLEVEL RunLevel) { - ArWriteControlRegister(8, RunLevel); + AR::CpuFunc::WriteControlRegister(8, RunLevel); } /** @@ -52,7 +52,7 @@ HlSetRunLevel(IN KRUNLEVEL RunLevel) */ XTFASTCALL KRUNLEVEL -HlpTransformApicTprToRunLevel(IN UCHAR Tpr) +HL::RunLevel::TransformApicTprToRunLevel(IN UCHAR Tpr) { return (KRUNLEVEL)(Tpr >> 4); } @@ -69,7 +69,7 @@ HlpTransformApicTprToRunLevel(IN UCHAR Tpr) */ XTFASTCALL UCHAR -HlpTransformRunLevelToApicTpr(IN KRUNLEVEL RunLevel) +HL::RunLevel::TransformRunLevelToApicTpr(IN KRUNLEVEL RunLevel) { return (RunLevel << 4); } diff --git a/xtoskrnl/hl/cport.c b/xtoskrnl/hl/cport.cc similarity index 66% rename from xtoskrnl/hl/cport.c rename to xtoskrnl/hl/cport.cc index 2a2071b..02c32df 100644 --- a/xtoskrnl/hl/cport.c +++ b/xtoskrnl/hl/cport.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/hl/cport.c + * FILE: xtoskrnl/hl/cport.cc * DESCRIPTION: Serial (COM) port support * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -30,10 +30,10 @@ */ XTCDECL XTSTATUS -HlComPortGetByte(IN PCPPORT Port, - OUT PUCHAR Byte, - IN BOOLEAN Wait, - IN BOOLEAN Poll) +HL::ComPort::ReadComPort(IN PCPPORT Port, + OUT PUCHAR Byte, + IN BOOLEAN Wait, + IN BOOLEAN Poll) { UCHAR Lsr; ULONG Retry; @@ -49,7 +49,7 @@ HlComPortGetByte(IN PCPPORT Port, while(Retry--) { /* Get LSR for data ready */ - Lsr = HlComPortReadLsr(Port, COMPORT_LSR_DR); + Lsr = ReadComPortLsr(Port, COMPORT_LSR_DR); if((Lsr & COMPORT_LSR_DR) == COMPORT_LSR_DR) { /* Check for errors */ @@ -68,13 +68,13 @@ HlComPortGetByte(IN PCPPORT Port, } /* Read the byte from serial port */ - *Byte = HlIoPortInByte(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_RBR)); + *Byte = HL::IoPort::ReadPort8(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_RBR)); /* Check if in modem control mode */ if(Port->Flags & COMPORT_FLAG_MC) { /* Handle Carrier Detected (CD) */ - if((HlIoPortInByte(PtrToShort(Port->Address + (ULONG)COMPORT_REG_MSR)) & COMPORT_MSR_DCD) == 0) + if((HL::IoPort::ReadPort8(PtrToShort(Port->Address + (ULONG)COMPORT_REG_MSR)) & COMPORT_MSR_DCD) == 0) { /* Skip byte if no CD present */ continue; @@ -85,67 +85,10 @@ HlComPortGetByte(IN PCPPORT Port, } /* Reset LSR and return that no data found */ - HlComPortReadLsr(Port, 0); + ReadComPortLsr(Port, 0); return STATUS_NOT_FOUND; } -/** - * This routine writes a byte to the serial port. - * - * @param Port - * Address of port object describing a port settings. - * - * @param Byte - * Data to be written. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -XTSTATUS -HlComPortPutByte(IN PCPPORT Port, - IN UCHAR Byte) -{ - UCHAR Lsr, Msr; - - /* Make sure the port has been initialized */ - if(Port->Address == 0) - { - return STATUS_DEVICE_NOT_READY; - } - - /* Check if port is in modem control */ - while(Port->Flags & COMPORT_FLAG_MC) - { - /* Get the Modem Status Register (MSR) */ - Msr = HlIoPortInByte(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_MSR)) & COMPORT_MSR_DSRCTSCD; - if(Msr != COMPORT_MSR_DSRCTSCD) - { - /* Take character, if CD is not set */ - Lsr = HlComPortReadLsr(Port, 0); - if((Msr & COMPORT_MSR_DCD) == 0 && (Lsr & COMPORT_LSR_DR) == COMPORT_LSR_DR) - { - /* Eat the character */ - HlIoPortInByte(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_RBR)); - } - } - else - { - /* CD, CTS and DSR are set, we can continue */ - break; - } - } - - /* Wait for busy port */ - while((HlComPortReadLsr(Port, COMPORT_LSR_THRE) & COMPORT_LSR_THRE) == 0); - - /* Send byte to the port */ - HlIoPortOutByte(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_THR), Byte); - - return STATUS_SUCCESS; -} - /** * Reads LSR from specified serial port. * @@ -161,19 +104,19 @@ HlComPortPutByte(IN PCPPORT Port, */ XTCDECL UCHAR -HlComPortReadLsr(IN PCPPORT Port, - IN UCHAR Byte) +HL::ComPort::ReadComPortLsr(IN PCPPORT Port, + IN UCHAR Byte) { UCHAR Lsr, Msr; /* Read the Line Status Register (LSR) */ - Lsr = HlIoPortInByte(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_LSR)); + Lsr = HL::IoPort::ReadPort8(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_LSR)); /* Check if expected byte is present */ if((Lsr & Byte) == 0) { /* Check Modem Status Register (MSR) for ring indicator */ - Msr = HlIoPortInByte(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_MSR)); + Msr = HL::IoPort::ReadPort8(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_MSR)); Port->Ring |= (Msr & COMPORT_MSR_RI) ? 1 : 2; if(Port->Ring == 3) { @@ -207,9 +150,9 @@ HlComPortReadLsr(IN PCPPORT Port, */ XTCDECL XTSTATUS -HlInitializeComPort(IN OUT PCPPORT Port, - IN PUCHAR PortAddress, - IN ULONG BaudRate) +HL::ComPort::InitializeComPort(IN OUT PCPPORT Port, + IN PUCHAR PortAddress, + IN ULONG BaudRate) { USHORT Flags; UCHAR Byte; @@ -237,8 +180,8 @@ HlInitializeComPort(IN OUT PCPPORT Port, do { /* Check whether the 16450/16550 scratch register exists */ - HlIoPortOutByte(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_SR), Byte); - if(HlIoPortInByte(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_SR)) != Byte) + HL::IoPort::WritePort8(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_SR), Byte); + if(HL::IoPort::ReadPort8(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_SR)) != Byte) { return STATUS_NOT_FOUND; } @@ -246,37 +189,37 @@ HlInitializeComPort(IN OUT PCPPORT Port, while(++Byte != 0); /* Disable interrupts */ - HlIoPortOutByte(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_LCR), COMPORT_LSR_DIS); - HlIoPortOutByte(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_IER), COMPORT_LSR_DIS); + HL::IoPort::WritePort8(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_LCR), COMPORT_LSR_DIS); + HL::IoPort::WritePort8(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_IER), COMPORT_LSR_DIS); /* Enable Divisor Latch Access Bit (DLAB) */ - HlIoPortOutByte(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_LCR), COMPORT_LCR_DLAB); + HL::IoPort::WritePort8(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_LCR), COMPORT_LCR_DLAB); /* Set baud rate */ Mode = COMPORT_CLOCK_RATE / BaudRate; - HlIoPortOutByte(PtrToUshort(PortAddress + (ULONG)COMPORT_DIV_DLL), (UCHAR)(Mode & 0xFF)); - HlIoPortOutByte(PtrToUshort(PortAddress + (ULONG)COMPORT_DIV_DLM), (UCHAR)((Mode >> 8) & 0xFF)); + HL::IoPort::WritePort8(PtrToUshort(PortAddress + (ULONG)COMPORT_DIV_DLL), (UCHAR)(Mode & 0xFF)); + HL::IoPort::WritePort8(PtrToUshort(PortAddress + (ULONG)COMPORT_DIV_DLM), (UCHAR)((Mode >> 8) & 0xFF)); /* Set 8 data bits, 1 stop bits, no parity (8n1) */ - HlIoPortOutByte(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_LCR), - COMPORT_LCR_8DATA | COMPORT_LCR_1STOP | COMPORT_LCR_PARN); + HL::IoPort::WritePort8(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_LCR), + COMPORT_LCR_8DATA | COMPORT_LCR_1STOP | COMPORT_LCR_PARN); /* Enable DTR, RTS and OUT2 */ - HlIoPortOutByte(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_MCR), - COMPORT_MCR_DTR | COMPORT_MCR_RTS | COMPORT_MCR_OUT2); + HL::IoPort::WritePort8(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_MCR), + COMPORT_MCR_DTR | COMPORT_MCR_RTS | COMPORT_MCR_OUT2); /* Enable FIFO */ - HlIoPortOutByte(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_FCR), - COMPORT_FCR_ENABLE | COMPORT_FCR_RCVR_RESET | COMPORT_FCR_TXMT_RESET); + HL::IoPort::WritePort8(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_FCR), + COMPORT_FCR_ENABLE | COMPORT_FCR_RCVR_RESET | COMPORT_FCR_TXMT_RESET); /* Mark port as fully initialized */ Flags |= COMPORT_FLAG_INIT; /* Make sure port works in Normal Operation Mode (NOM) */ - HlIoPortOutByte(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_MCR), COMPORT_MCR_NOM); + HL::IoPort::WritePort8(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_MCR), COMPORT_MCR_NOM); /* Read junk data out of the Receive Buffer Register (RBR) */ - HlIoPortInByte(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_RBR)); + HL::IoPort::ReadPort8(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_RBR)); /* Store port details */ Port->Address = PortAddress; @@ -287,3 +230,60 @@ HlInitializeComPort(IN OUT PCPPORT Port, /* Return success */ return STATUS_SUCCESS; } + +/** + * This routine writes a byte to the serial port. + * + * @param Port + * Address of port object describing a port settings. + * + * @param Byte + * Data to be written. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +XTSTATUS +HL::ComPort::WriteComPort(IN PCPPORT Port, + IN UCHAR Byte) +{ + UCHAR Lsr, Msr; + + /* Make sure the port has been initialized */ + if(Port->Address == 0) + { + return STATUS_DEVICE_NOT_READY; + } + + /* Check if port is in modem control */ + while(Port->Flags & COMPORT_FLAG_MC) + { + /* Get the Modem Status Register (MSR) */ + Msr = HL::IoPort::ReadPort8(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_MSR)) & COMPORT_MSR_DSRCTSCD; + if(Msr != COMPORT_MSR_DSRCTSCD) + { + /* Take character, if CD is not set */ + Lsr = ReadComPortLsr(Port, 0); + if((Msr & COMPORT_MSR_DCD) == 0 && (Lsr & COMPORT_LSR_DR) == COMPORT_LSR_DR) + { + /* Eat the character */ + HL::IoPort::ReadPort8(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_RBR)); + } + } + else + { + /* CD, CTS and DSR are set, we can continue */ + break; + } + } + + /* Wait for busy port */ + while((ReadComPortLsr(Port, COMPORT_LSR_THRE) & COMPORT_LSR_THRE) == 0); + + /* Send byte to the port */ + HL::IoPort::WritePort8(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_THR), Byte); + + return STATUS_SUCCESS; +} diff --git a/xtoskrnl/hl/data.cc b/xtoskrnl/hl/data.cc new file mode 100644 index 0000000..2ebed5e --- /dev/null +++ b/xtoskrnl/hl/data.cc @@ -0,0 +1,34 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/hl/data.cc + * DESCRIPTION: Hardware Layer global and static data + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/* ACPI tables cache list */ +LIST_ENTRY HL::Acpi::CacheList; + +/* ACPI Root System Description Pointer (RSDP) */ +PACPI_RSDP HL::Acpi::RsdpStructure; + +/* System information */ +ACPI_SYSTEM_INFO HL::Acpi::SystemInfo; + +/* ACPI timer information */ +ACPI_TIMER_INFO HL::Acpi::TimerInfo; + +/* Active processors count */ +KAFFINITY HL::Cpu::ActiveProcessors; + +/* FrameBuffer information */ +HL_FRAMEBUFFER_DATA HL::FrameBuffer::FrameBufferData; + +/* Scroll region information */ +HL_SCROLL_REGION_DATA HL::FrameBuffer::ScrollRegionData; + +/* APIC mode */ +APIC_MODE HL::Pic::ApicMode; diff --git a/xtoskrnl/hl/exports.cc b/xtoskrnl/hl/exports.cc new file mode 100644 index 0000000..0321cf1 --- /dev/null +++ b/xtoskrnl/hl/exports.cc @@ -0,0 +1,250 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/hl/exports.cc + * DESCRIPTION: C-compatible API wrappers for exported kernel functions + * DEVELOPERS: Aiken Harris + */ + +#include + + +/** + * Reads the 8-bit data from the specified I/O port. + * + * @param Port + * Specifies the address to read from, in the range of 0-0xFFFF. + * + * @return The value read from the port. + * + * @since XT 1.0 + */ +XTCLINK +XTCDECL +UCHAR +HlReadPort8(IN USHORT Port) +{ + return HL::IoPort::ReadPort8(Port); +} + +/** + * Reads the 16-bit data from the specified I/O port. + * + * @param Port + * Specifies the address to read from, in the range of 0-0xFFFF. + * + * @return The value read from the port. + * + * @since XT 1.0 + */ +XTCLINK +XTCDECL +USHORT +HlReadPort16(IN USHORT Port) +{ + return HL::IoPort::ReadPort16(Port); +} + +/** + * Reads the 32-bit data from the specified I/O port. + * + * @param Port + * Specifies the address to read from, in the range of 0-0xFFFF. + * + * @return The value read from the port. + * + * @since XT 1.0 + */ +XTCLINK +XTCDECL +ULONG +HlReadPort32(IN USHORT Port) +{ + return HL::IoPort::ReadPort32(Port); +} + +/** + * Reads an 8-bit data from a specified register address. + * + * @param Register + * Supplies a pointer to register address holding data to read. + * + * @return This routine returns a value at the specified register. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +UCHAR +HlReadRegister8(IN PVOID Register) +{ + return HL::IoRegister::ReadRegister8(Register); +} + +/** + * Reads a 16-bit data from a specified register address. + * + * @param Register + * Supplies a pointer to register address holding data to read. + * + * @return This routine returns a value at the specified register. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +USHORT +HlReadRegister16(IN PVOID Register) +{ + return HL::IoRegister::ReadRegister16(Register); +} + +/** + * Reads a 32-bit data from a specified register address. + * + * @param Register + * Supplies a pointer to register address holding data to read. + * + * @return This routine returns a value at the specified register. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +ULONG +HlReadRegister32(IN PVOID Register) +{ + return HL::IoRegister::ReadRegister32(Register); +} + +/** + * Writes the 8-bit data to the specified I/O port. + * + * @param Port + * Specifies the address to write to, in the range of 0-0xFFFF. + * + * @param Value + * Supplies the value to write. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTCDECL +VOID +HlWritePort8(IN USHORT Port, + IN UCHAR Value) +{ + HL::IoPort::WritePort8(Port, Value); +} + +/** + * Writes the 16-bit data to the specified I/O port. + * + * @param Port + * Specifies the address to write to, in the range of 0-0xFFFF. + * + * @param Value + * Supplies the value to write. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTCDECL +VOID +HlWritePort16(IN USHORT Port, + IN USHORT Value) +{ + HL::IoPort::WritePort16(Port, Value); +} + +/** + * Writes the 32-bit data to the specified I/O port. + * + * @param Port + * Specifies the address to write to, in the range of 0-0xFFFF. + * + * @param Value + * Supplies the value to write. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTCDECL +VOID +HlWritePort32(IN USHORT Port, + IN ULONG Value) +{ + HL::IoPort::WritePort32(Port, Value); +} + +/** + * Writes an 8-bit value into a specified register address. + * + * @param Register + * Supplies a pointer to register address where data will be written. + * + * @param Value + * Supplies a new value that will be stored into a register. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +VOID +HlWriteRegister8(IN PVOID Register, + IN UCHAR Value) +{ + HL::IoRegister::WriteRegister8(Register, Value); +} + +/** + * Writes a 16-bit value into a specified register address. + * + * @param Register + * Supplies a pointer to register address where data will be written. + * + * @param Value + * Supplies a new value that will be stored into a register. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +VOID +HlWriteRegister16(IN PVOID Register, + IN USHORT Value) +{ + HL::IoRegister::WriteRegister16(Register, Value); +} + +/** + * Writes a 32-bit value into a specified register address. + * + * @param Register + * Supplies a pointer to register address where data will be written. + * + * @param Value + * Supplies a new value that will be stored into a register. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +VOID +HlWriteRegister32(IN PVOID Register, + IN ULONG Value) +{ + HL::IoRegister::WriteRegister32(Register, Value); +} diff --git a/xtoskrnl/hl/fbdev.c b/xtoskrnl/hl/fbdev.cc similarity index 63% rename from xtoskrnl/hl/fbdev.c rename to xtoskrnl/hl/fbdev.cc index f5ed0d6..5b7d42d 100644 --- a/xtoskrnl/hl/fbdev.c +++ b/xtoskrnl/hl/fbdev.cc @@ -1,13 +1,13 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/hl/fbdev.c + * FILE: xtoskrnl/hl/fbdev.cc * DESCRIPTION: FrameBuffer support * DEVELOPERS: Rafal Kupiec * Aiken Harris */ -#include +#include #include @@ -23,7 +23,7 @@ */ XTAPI VOID -HlClearScreen(IN ULONG Color) +HL::FrameBuffer::ClearScreen(IN ULONG Color) { ULONG PositionX, PositionY; ULONG BackgroundColor; @@ -31,22 +31,22 @@ HlClearScreen(IN ULONG Color) PULONG Pixel; /* Make sure frame buffer is already initialized */ - if(HlpFrameBufferData.Initialized == FALSE) + if(FrameBufferData.Initialized == FALSE) { /* Unable to operate on non-initialized frame buffer */ return; } /* Convert background color and get pointer to frame buffer */ - BackgroundColor = HlpRGBColor(Color); - CurrentLine = HlpFrameBufferData.Address; + BackgroundColor = GetRGBColor(Color); + CurrentLine = (PCHAR)FrameBufferData.Address; /* Fill the screen with the specified color */ - for(PositionY = 0; PositionY < HlpFrameBufferData.Height; PositionY++, CurrentLine += HlpFrameBufferData.Pitch) + for(PositionY = 0; PositionY < FrameBufferData.Height; PositionY++, CurrentLine += FrameBufferData.Pitch) { /* Fill the current line with the specified color */ Pixel = (PULONG)CurrentLine; - for(PositionX = 0; PositionX < HlpFrameBufferData.Width; PositionX++) + for(PositionX = 0; PositionX < FrameBufferData.Width; PositionX++) { /* Set the color of the pixel */ Pixel[PositionX] = BackgroundColor; @@ -66,236 +66,65 @@ HlClearScreen(IN ULONG Color) */ XTCDECL XTSTATUS -HlDisplayCharacter(IN WCHAR Character) +HL::FrameBuffer::DisplayCharacter(IN WCHAR Character) { PSSFN_FONT_HEADER FbFont; /* Make sure frame buffer is already initialized */ - if(HlpFrameBufferData.Initialized == FALSE) + if(FrameBufferData.Initialized == FALSE) { /* Unable to operate on non-initialized frame buffer */ return STATUS_DEVICE_NOT_READY; } /* Get font information */ - FbFont = (PSSFN_FONT_HEADER)HlpFrameBufferData.Font; + FbFont = (PSSFN_FONT_HEADER)FrameBufferData.Font; /* Handle special characters */ switch(Character) { case L'\n': /* Move cursor to the beginning of the next line */ - HlpScrollRegionData.CursorX = HlpScrollRegionData.Left; - HlpScrollRegionData.CursorY += FbFont->Height; + ScrollRegionData.CursorX = ScrollRegionData.Left; + ScrollRegionData.CursorY += FbFont->Height; break; case L'\t': /* Move cursor to the next tab stop */ - HlpScrollRegionData.CursorX += (8 - (HlpScrollRegionData.CursorX - HlpScrollRegionData.Left) / FbFont->Width % 8) * FbFont->Width; - if (HlpScrollRegionData.CursorX >= HlpScrollRegionData.Right) + ScrollRegionData.CursorX += (8 - (ScrollRegionData.CursorX - ScrollRegionData.Left) / FbFont->Width % 8) * FbFont->Width; + if (ScrollRegionData.CursorX >= ScrollRegionData.Right) { - HlpScrollRegionData.CursorX = HlpScrollRegionData.Left; - HlpScrollRegionData.CursorY += FbFont->Height; + ScrollRegionData.CursorX = ScrollRegionData.Left; + ScrollRegionData.CursorY += FbFont->Height; } break; default: /* Draw the character */ - HlpDrawCharacter(HlpScrollRegionData.CursorX, HlpScrollRegionData.CursorY, HlpScrollRegionData.TextColor, Character); + DrawCharacter(ScrollRegionData.CursorX, ScrollRegionData.CursorY, ScrollRegionData.TextColor, Character); /* Advance cursor */ - HlpScrollRegionData.CursorX += FbFont->Width; + ScrollRegionData.CursorX += FbFont->Width; /* Check if cursor reached end of line */ - if(HlpScrollRegionData.CursorX >= HlpScrollRegionData.Right) + if(ScrollRegionData.CursorX >= ScrollRegionData.Right) { - HlpScrollRegionData.CursorX = HlpScrollRegionData.Left; - HlpScrollRegionData.CursorY += FbFont->Height; + ScrollRegionData.CursorX = ScrollRegionData.Left; + ScrollRegionData.CursorY += FbFont->Height; } break; } /* Check if cursor reached end of scroll region */ - if(HlpScrollRegionData.CursorY >= HlpScrollRegionData.Bottom) + if(ScrollRegionData.CursorY >= ScrollRegionData.Bottom) { /* Scroll one line up */ - HlpScrollRegion(); - HlpScrollRegionData.CursorY = HlpScrollRegionData.Bottom - FbFont->Height; + ScrollRegion(); + ScrollRegionData.CursorY = ScrollRegionData.Bottom - FbFont->Height; } /* Return success */ return STATUS_SUCCESS; } -/** - * Returns the current resolution of the frame buffer display. - * - * @param Width - * A pointer to memory area where the screen width will be stored. - * - * @param Height - * A pointer to memory area where the screen height will be stored. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -HlGetFrameBufferResolution(OUT PULONG Width, OUT PULONG Height) -{ - *Width = HlpFrameBufferData.Width; - *Height = HlpFrameBufferData.Height; -} - -/** - * Initializes frame buffer display. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTAPI -XTSTATUS -HlInitializeFrameBuffer(VOID) -{ - PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource; - PSYSTEM_RESOURCE_HEADER SystemResource; - XTSTATUS Status; - - /* Check if display already initialized */ - if(HlpFrameBufferData.Initialized) - { - /* Nothing to do */ - return STATUS_SUCCESS; - } - - /* Get FrameBuffer system resource */ - Status = KeGetSystemResource(SystemResourceFrameBuffer, &SystemResource); - if(Status != STATUS_SUCCESS) - { - /* Resource not found */ - return STATUS_NOT_FOUND; - } - - /* Cast system resource to FrameBuffer resource */ - FrameBufferResource = (PSYSTEM_RESOURCE_FRAMEBUFFER)SystemResource; - - /* Check if bootloader provided a framebuffer address */ - if(!FrameBufferResource->Header.VirtualAddress) - { - /* Display probably not initialized */ - return STATUS_DEVICE_NOT_READY; - } - - /* Check if bootloader provided a custom font */ - if(FrameBufferResource->Font) - { - /* Use custom font */ - HlpFrameBufferData.Font = FrameBufferResource->Font; - } - else - { - /* Use default font */ - HlpFrameBufferData.Font = (PVOID)&XtFbDefaultFont; - } - - /* Save framebuffer information and mark display as initialized */ - HlpFrameBufferData.Address = FrameBufferResource->Header.VirtualAddress; - HlpFrameBufferData.Width = FrameBufferResource->Width; - HlpFrameBufferData.Height = FrameBufferResource->Height; - HlpFrameBufferData.BytesPerPixel = FrameBufferResource->BitsPerPixel / 8; - HlpFrameBufferData.PixelsPerScanLine = FrameBufferResource->PixelsPerScanLine; - HlpFrameBufferData.Pitch = FrameBufferResource->Pitch; - HlpFrameBufferData.Pixels.BlueShift = FrameBufferResource->Pixels.BlueShift; - HlpFrameBufferData.Pixels.BlueSize = FrameBufferResource->Pixels.BlueSize; - HlpFrameBufferData.Pixels.GreenShift = FrameBufferResource->Pixels.GreenShift; - HlpFrameBufferData.Pixels.GreenSize = FrameBufferResource->Pixels.GreenSize; - HlpFrameBufferData.Pixels.RedShift = FrameBufferResource->Pixels.RedShift; - HlpFrameBufferData.Pixels.RedSize = FrameBufferResource->Pixels.RedSize; - HlpFrameBufferData.Pixels.ReservedShift = FrameBufferResource->Pixels.ReservedShift; - HlpFrameBufferData.Pixels.ReservedSize = FrameBufferResource->Pixels.ReservedSize; - HlpFrameBufferData.Initialized = TRUE; - - /* Clear screen */ - HlClearScreen(0x00000000); - - /* Return success */ - return STATUS_SUCCESS; -} - -/** - * Sets the scrollable region of the screen and calculates character dimensions. - * - * @param Left - * Supplies the left pixel coordinate of the scroll region. - * - * @param Top - * Supplies the top pixel coordinate of the scroll region. - * - * @param Right - * Supplies the right pixel coordinate of the scroll region. - * - * @param Bottom - * Supplies the bottom pixel coordinate of the scroll region. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -HlInitializeScrollRegion(IN ULONG Left, - IN ULONG Top, - IN ULONG Right, - IN ULONG Bottom, - IN ULONG FontColor) -{ - PSSFN_FONT_HEADER FbFont; - PCHAR PixelAddress; - - /* Make sure frame buffer is already initialized */ - if(HlpFrameBufferData.Initialized == FALSE) - { - /* Unable to operate on non-initialized frame buffer */ - return; - } - - /* Store pixel coordinates of the scroll region */ - HlpScrollRegionData.Left = Left; - HlpScrollRegionData.Top = Top; - HlpScrollRegionData.Right = Right; - HlpScrollRegionData.Bottom = Bottom; - - /* Get font information */ - FbFont = (PSSFN_FONT_HEADER)HlpFrameBufferData.Font; - - /* Validate font information */ - if(FbFont && FbFont->Width > 0 && FbFont->Height > 0) - { - /* Calculate character dimensions */ - HlpScrollRegionData.WidthInChars = (Right - Left) / FbFont->Width; - HlpScrollRegionData.HeightInChars = (Bottom - Top) / FbFont->Height; - - /* Ensure the bottom of the scroll region is an exact multiple of the font height */ - HlpScrollRegionData.Bottom = HlpScrollRegionData.Top + (HlpScrollRegionData.HeightInChars * FbFont->Height); - } - else - { - /* Fallback to 0 if font info is not available or invalid */ - HlpScrollRegionData.WidthInChars = 0; - HlpScrollRegionData.HeightInChars = 0; - } - - /* Initialize cursor position and font color */ - HlpScrollRegionData.CursorX = HlpScrollRegionData.Left; - HlpScrollRegionData.CursorY = HlpScrollRegionData.Top; - HlpScrollRegionData.TextColor = FontColor; - - /* Get the background color by reading the pixel at the top-left corner of the scroll region */ - PixelAddress = (PCHAR)HlpFrameBufferData.Address + (Top * HlpFrameBufferData.Pitch) + - (Left * HlpFrameBufferData.BytesPerPixel); - HlpScrollRegionData.BackgroundColor = *((PULONG)PixelAddress); -} - /** * Draws a character on the framebuffer at the given position and color using the SSFN font. * @@ -317,10 +146,10 @@ HlInitializeScrollRegion(IN ULONG Left, */ XTAPI VOID -HlpDrawCharacter(IN ULONG PositionX, - IN ULONG PositionY, - IN ULONG Color, - IN WCHAR WideCharacter) +HL::FrameBuffer::DrawCharacter(IN ULONG PositionX, + IN ULONG PositionY, + IN ULONG Color, + IN WCHAR WideCharacter) { UINT CurrentFragment, Glyph, GlyphLimit, Index, Line, Mapping; PUCHAR Character, CharacterMapping, Fragment; @@ -329,14 +158,14 @@ HlpDrawCharacter(IN ULONG PositionX, ULONG FontColor; /* Make sure frame buffer is already initialized */ - if(HlpFrameBufferData.Initialized == FALSE) + if(FrameBufferData.Initialized == FALSE) { /* Unable to operate on non-initialized frame buffer */ return; } /* Get pointers to font data */ - FbFont = (PSSFN_FONT_HEADER)HlpFrameBufferData.Font; + FbFont = (PSSFN_FONT_HEADER)FrameBufferData.Font; CharacterMapping = (PUCHAR)FbFont + FbFont->CharactersOffset; /* Find the character in the font's character table */ @@ -384,9 +213,9 @@ HlpDrawCharacter(IN ULONG PositionX, } /* Find the glyph position on the frame buffer and set font color */ - GlyphPixel = (UINT_PTR)HlpFrameBufferData.Address + PositionY * HlpFrameBufferData.Pitch + - PositionX * HlpFrameBufferData.BytesPerPixel; - FontColor = HlpRGBColor(Color); + GlyphPixel = (UINT_PTR)FrameBufferData.Address + PositionY * FrameBufferData.Pitch + + PositionX * FrameBufferData.BytesPerPixel; + FontColor = GetRGBColor(Color); /* Check all kerning fragments */ Mapping = 0; @@ -414,7 +243,7 @@ HlpDrawCharacter(IN ULONG PositionX, } /* Get initial glyph line */ - GlyphPixel += (CharacterMapping[1] - Mapping) * HlpFrameBufferData.Pitch; + GlyphPixel += (CharacterMapping[1] - Mapping) * FrameBufferData.Pitch; Mapping = CharacterMapping[1]; /* Extract glyph data from fragments table and advance */ @@ -445,12 +274,12 @@ HlpDrawCharacter(IN ULONG PositionX, } /* Advance pixel pointer */ - Pixel += HlpFrameBufferData.BytesPerPixel; + Pixel += FrameBufferData.BytesPerPixel; CurrentFragment <<= 1; } /* Advance to next line and increase mapping */ - GlyphPixel += HlpFrameBufferData.Pitch; + GlyphPixel += FrameBufferData.Pitch; Mapping++; } @@ -477,32 +306,54 @@ HlpDrawCharacter(IN ULONG PositionX, */ XTAPI VOID -HlpDrawPixel(IN ULONG PositionX, - IN ULONG PositionY, - IN ULONG Color) +HL::FrameBuffer::DrawPixel(IN ULONG PositionX, + IN ULONG PositionY, + IN ULONG Color) { PCHAR PixelAddress; /* Make sure frame buffer is already initialized */ - if(HlpFrameBufferData.Initialized == FALSE) + if(FrameBufferData.Initialized == FALSE) { /* Unable to operate on non-initialized frame buffer */ return; } /* Make sure point is not offscreen */ - if(PositionX >= HlpFrameBufferData.Width || PositionY >= HlpFrameBufferData.Height || Color > 0xFFFFFFFF) + if(PositionX >= FrameBufferData.Width || PositionY >= FrameBufferData.Height || Color > 0xFFFFFFFF) { /* Invalid pixel position or color given */ return; } /* Calculate the address of the pixel in the frame buffer memory */ - PixelAddress = (PCHAR)HlpFrameBufferData.Address + (PositionY * HlpFrameBufferData.Pitch) + - (PositionX * HlpFrameBufferData.BytesPerPixel); + PixelAddress = (PCHAR)FrameBufferData.Address + (PositionY * FrameBufferData.Pitch) + + (PositionX * FrameBufferData.BytesPerPixel); /* Set the color of the pixel by writing to the corresponding memory location */ - *((PULONG)PixelAddress) = HlpRGBColor(Color); + *((PULONG)PixelAddress) = GetRGBColor(Color); +} + +/** + * Returns the current resolution of the frame buffer display. + * + * @param Width + * A pointer to memory area where the screen width will be stored. + * + * @param Height + * A pointer to memory area where the screen height will be stored. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +HL::FrameBuffer::GetFrameBufferResolution(OUT PULONG Width, + OUT PULONG Height) +{ + *Width = FrameBufferData.Width; + *Height = FrameBufferData.Height; } /** @@ -517,7 +368,7 @@ HlpDrawPixel(IN ULONG PositionX, */ XTAPI ULONG -HlpRGBColor(IN ULONG Color) +HL::FrameBuffer::GetRGBColor(IN ULONG Color) { USHORT Blue, Green, Red, Reserved; @@ -528,8 +379,158 @@ HlpRGBColor(IN ULONG Color) Reserved = (USHORT)((Color >> 24) & 0xFF); /* Return color in FrameBuffer pixel format */ - return (ULONG)((Blue << HlpFrameBufferData.Pixels.BlueShift) | (Green << HlpFrameBufferData.Pixels.GreenShift) | - (Red << HlpFrameBufferData.Pixels.RedShift) | (Reserved << HlpFrameBufferData.Pixels.ReservedShift)); + return (ULONG)((Blue << FrameBufferData.Pixels.BlueShift) | (Green << FrameBufferData.Pixels.GreenShift) | + (Red << FrameBufferData.Pixels.RedShift) | (Reserved << FrameBufferData.Pixels.ReservedShift)); +} + +/** + * Initializes frame buffer display. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTAPI +XTSTATUS +HL::FrameBuffer::InitializeFrameBuffer(VOID) +{ + PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource; + PSYSTEM_RESOURCE_HEADER SystemResource; + XTSTATUS Status; + + /* Check if display already initialized */ + if(FrameBufferData.Initialized) + { + /* Nothing to do */ + return STATUS_SUCCESS; + } + + /* Get FrameBuffer system resource */ + Status = KeGetSystemResource(SystemResourceFrameBuffer, &SystemResource); + if(Status != STATUS_SUCCESS) + { + /* Resource not found */ + return STATUS_NOT_FOUND; + } + + /* Cast system resource to FrameBuffer resource */ + FrameBufferResource = (PSYSTEM_RESOURCE_FRAMEBUFFER)SystemResource; + + /* Check if bootloader provided a framebuffer address */ + if(!FrameBufferResource->Header.VirtualAddress) + { + /* Display probably not initialized */ + return STATUS_DEVICE_NOT_READY; + } + + /* Check if bootloader provided a custom font */ + if(FrameBufferResource->Font) + { + /* Use custom font */ + FrameBufferData.Font = FrameBufferResource->Font; + } + else + { + /* Use default font */ + FrameBufferData.Font = (PVOID)&XtFbDefaultFont; + } + + /* Save framebuffer information and mark display as initialized */ + FrameBufferData.Address = FrameBufferResource->Header.VirtualAddress; + FrameBufferData.Width = FrameBufferResource->Width; + FrameBufferData.Height = FrameBufferResource->Height; + FrameBufferData.BytesPerPixel = FrameBufferResource->BitsPerPixel / 8; + FrameBufferData.PixelsPerScanLine = FrameBufferResource->PixelsPerScanLine; + FrameBufferData.Pitch = FrameBufferResource->Pitch; + FrameBufferData.Pixels.BlueShift = FrameBufferResource->Pixels.BlueShift; + FrameBufferData.Pixels.BlueSize = FrameBufferResource->Pixels.BlueSize; + FrameBufferData.Pixels.GreenShift = FrameBufferResource->Pixels.GreenShift; + FrameBufferData.Pixels.GreenSize = FrameBufferResource->Pixels.GreenSize; + FrameBufferData.Pixels.RedShift = FrameBufferResource->Pixels.RedShift; + FrameBufferData.Pixels.RedSize = FrameBufferResource->Pixels.RedSize; + FrameBufferData.Pixels.ReservedShift = FrameBufferResource->Pixels.ReservedShift; + FrameBufferData.Pixels.ReservedSize = FrameBufferResource->Pixels.ReservedSize; + FrameBufferData.Initialized = TRUE; + + /* Clear screen */ + ClearScreen(0x00000000); + + /* Return success */ + return STATUS_SUCCESS; +} + +/** + * Sets the scrollable region of the screen and calculates character dimensions. + * + * @param Left + * Supplies the left pixel coordinate of the scroll region. + * + * @param Top + * Supplies the top pixel coordinate of the scroll region. + * + * @param Right + * Supplies the right pixel coordinate of the scroll region. + * + * @param Bottom + * Supplies the bottom pixel coordinate of the scroll region. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +HL::FrameBuffer::InitializeScrollRegion(IN ULONG Left, + IN ULONG Top, + IN ULONG Right, + IN ULONG Bottom, + IN ULONG FontColor) +{ + PSSFN_FONT_HEADER FbFont; + PCHAR PixelAddress; + + /* Make sure frame buffer is already initialized */ + if(FrameBufferData.Initialized == FALSE) + { + /* Unable to operate on non-initialized frame buffer */ + return; + } + + /* Store pixel coordinates of the scroll region */ + ScrollRegionData.Left = Left; + ScrollRegionData.Top = Top; + ScrollRegionData.Right = Right; + ScrollRegionData.Bottom = Bottom; + + /* Get font information */ + FbFont = (PSSFN_FONT_HEADER)FrameBufferData.Font; + + /* Validate font information */ + if(FbFont && FbFont->Width > 0 && FbFont->Height > 0) + { + /* Calculate character dimensions */ + ScrollRegionData.WidthInChars = (Right - Left) / FbFont->Width; + ScrollRegionData.HeightInChars = (Bottom - Top) / FbFont->Height; + + /* Ensure the bottom of the scroll region is an exact multiple of the font height */ + ScrollRegionData.Bottom = ScrollRegionData.Top + (ScrollRegionData.HeightInChars * FbFont->Height); + } + else + { + /* Fallback to 0 if font info is not available or invalid */ + ScrollRegionData.WidthInChars = 0; + ScrollRegionData.HeightInChars = 0; + } + + /* Initialize cursor position and font color */ + ScrollRegionData.CursorX = ScrollRegionData.Left; + ScrollRegionData.CursorY = ScrollRegionData.Top; + ScrollRegionData.TextColor = FontColor; + + /* Get the background color by reading the pixel at the top-left corner of the scroll region */ + PixelAddress = (PCHAR)FrameBufferData.Address + (Top * FrameBufferData.Pitch) + + (Left * FrameBufferData.BytesPerPixel); + ScrollRegionData.BackgroundColor = *((PULONG)PixelAddress); } /** @@ -541,7 +542,7 @@ HlpRGBColor(IN ULONG Color) */ XTAPI VOID -HlpScrollRegion(VOID) +HL::FrameBuffer::ScrollRegion(VOID) { PCHAR Destination, Source; PSSFN_FONT_HEADER FbFont; @@ -550,43 +551,43 @@ HlpScrollRegion(VOID) PULONG Pixel; /* Make sure frame buffer is already initialized */ - if(HlpFrameBufferData.Initialized == FALSE) + if(FrameBufferData.Initialized == FALSE) { /* Unable to operate on non-initialized frame buffer */ return; } /* Get font information */ - FbFont = (PSSFN_FONT_HEADER)HlpFrameBufferData.Font; + FbFont = (PSSFN_FONT_HEADER)FrameBufferData.Font; /* Calculate bytes per line in the scroll region */ - LineBytes = (HlpScrollRegionData.Right - HlpScrollRegionData.Left) * HlpFrameBufferData.BytesPerPixel; + LineBytes = (ScrollRegionData.Right - ScrollRegionData.Left) * FrameBufferData.BytesPerPixel; /* Scroll up each scan line in the scroll region */ - for(Line = HlpScrollRegionData.Top; Line < HlpScrollRegionData.Bottom - FbFont->Height; Line++) + for(Line = ScrollRegionData.Top; Line < ScrollRegionData.Bottom - FbFont->Height; Line++) { - Destination = (PCHAR)HlpFrameBufferData.Address + Line * HlpFrameBufferData.Pitch + - HlpScrollRegionData.Left * HlpFrameBufferData.BytesPerPixel; + Destination = (PCHAR)FrameBufferData.Address + Line * FrameBufferData.Pitch + + ScrollRegionData.Left * FrameBufferData.BytesPerPixel; /* The source is one full text line (FbFont->Height) below the destination */ - Source = (PCHAR)HlpFrameBufferData.Address + (Line + FbFont->Height) * HlpFrameBufferData.Pitch + - HlpScrollRegionData.Left * HlpFrameBufferData.BytesPerPixel; + Source = (PCHAR)FrameBufferData.Address + (Line + FbFont->Height) * FrameBufferData.Pitch + + ScrollRegionData.Left * FrameBufferData.BytesPerPixel; /* Move each scan line in the scroll region up */ - RtlMoveMemory(Destination, Source, LineBytes); + RTL::Memory::MoveMemory(Destination, Source, LineBytes); } /* Clear the last text line */ - for(Line = HlpScrollRegionData.Bottom - FbFont->Height; Line < HlpScrollRegionData.Bottom; Line++) + for(Line = ScrollRegionData.Bottom - FbFont->Height; Line < ScrollRegionData.Bottom; Line++) { /* Get pointer to the start of the scan line to clear */ - Pixel = (PULONG)((PCHAR)HlpFrameBufferData.Address + Line * HlpFrameBufferData.Pitch + - HlpScrollRegionData.Left * HlpFrameBufferData.BytesPerPixel); + Pixel = (PULONG)((PCHAR)FrameBufferData.Address + Line * FrameBufferData.Pitch + + ScrollRegionData.Left * FrameBufferData.BytesPerPixel); /* Clear each pixel in the scan line with the background color */ - for(PositionX = 0; PositionX < (HlpScrollRegionData.Right - HlpScrollRegionData.Left); PositionX++) + for(PositionX = 0; PositionX < (ScrollRegionData.Right - ScrollRegionData.Left); PositionX++) { - Pixel[PositionX] = HlpScrollRegionData.BackgroundColor; + Pixel[PositionX] = ScrollRegionData.BackgroundColor; } } } diff --git a/xtoskrnl/hl/globals.c b/xtoskrnl/hl/globals.c deleted file mode 100644 index c1094a4..0000000 --- a/xtoskrnl/hl/globals.c +++ /dev/null @@ -1,34 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/hl/globals.c - * DESCRIPTION: Architecture independent global variables related to HL subsystem - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/* ACPI tables cache list */ -LIST_ENTRY HlpAcpiCacheList; - -/* ACPI Root System Description Pointer (RSDP) */ -PACPI_RSDP HlpAcpiRsdp; - -/* ACPI timer information */ -ACPI_TIMER_INFO HlpAcpiTimerInfo; - -/* Active processors count */ -KAFFINITY HlpActiveProcessors; - -/* APIC mode */ -APIC_MODE HlpApicMode; - -/* FrameBuffer information */ -HL_FRAMEBUFFER_DATA HlpFrameBufferData; - -/* Scroll region information */ -HL_SCROLL_REGION_DATA HlpScrollRegionData; - -/* System information */ -ACPI_SYSTEM_INFO HlpSystemInfo; diff --git a/xtoskrnl/hl/i686/cpu.c b/xtoskrnl/hl/i686/cpu.cc similarity index 73% rename from xtoskrnl/hl/i686/cpu.c rename to xtoskrnl/hl/i686/cpu.cc index 2915cf4..1cd322d 100644 --- a/xtoskrnl/hl/i686/cpu.c +++ b/xtoskrnl/hl/i686/cpu.cc @@ -1,13 +1,13 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/hl/i686/cpu.c + * FILE: xtoskrnl/hl/i686/cpu.cc * DESCRIPTION: HAL i686 processor support * DEVELOPERS: Rafal Kupiec */ -#include +#include /* Include common CPU interface */ -#include ARCH_COMMON(cpu.c) +#include ARCH_COMMON(cpu.cc) diff --git a/xtoskrnl/hl/i686/ioport.c b/xtoskrnl/hl/i686/ioport.cc similarity index 86% rename from xtoskrnl/hl/i686/ioport.c rename to xtoskrnl/hl/i686/ioport.cc index fa6baf9..1f32ae6 100644 --- a/xtoskrnl/hl/i686/ioport.c +++ b/xtoskrnl/hl/i686/ioport.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/hl/i686/ioport.c + * FILE: xtoskrnl/hl/i686/ioport.cc * DESCRIPTION: I/O port access routines for i686 platform * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -21,7 +21,7 @@ */ XTCDECL UCHAR -HlIoPortInByte(IN USHORT Port) +HL::IoPort::ReadPort8(IN USHORT Port) { UCHAR Value; __asm__ volatile("inb %1, %0" @@ -30,27 +30,6 @@ HlIoPortInByte(IN USHORT Port) return Value; } -/** - * Reads the 32-bit data from the specified I/O port. - * - * @param Port - * Specifies the address to read from, in the range of 0-0xFFFF. - * - * @return The value read from the port. - * - * @since XT 1.0 - */ -XTCDECL -ULONG -HlIoPortInLong(IN USHORT Port) -{ - ULONG Value; - __asm__ volatile("inl %1, %0" - : "=a" (Value) - : "Nd" (Port)); - return Value; -} - /** * Reads the 16-bit data from the specified I/O port. * @@ -63,7 +42,7 @@ HlIoPortInLong(IN USHORT Port) */ XTCDECL USHORT -HlIoPortInShort(IN USHORT Port) +HL::IoPort::ReadPort16(IN USHORT Port) { USHORT Value; __asm__ volatile("inw %1, %0" @@ -72,6 +51,27 @@ HlIoPortInShort(IN USHORT Port) return Value; } +/** + * Reads the 32-bit data from the specified I/O port. + * + * @param Port + * Specifies the address to read from, in the range of 0-0xFFFF. + * + * @return The value read from the port. + * + * @since XT 1.0 + */ +XTCDECL +ULONG +HL::IoPort::ReadPort32(IN USHORT Port) +{ + ULONG Value; + __asm__ volatile("inl %1, %0" + : "=a" (Value) + : "Nd" (Port)); + return Value; +} + /** * Writes the 8-bit data to the specified I/O port. * @@ -87,8 +87,8 @@ HlIoPortInShort(IN USHORT Port) */ XTCDECL VOID -HlIoPortOutByte(IN USHORT Port, - IN UCHAR Value) +HL::IoPort::WritePort8(IN USHORT Port, + IN UCHAR Value) { __asm__ volatile("outb %0, %1" : @@ -96,30 +96,6 @@ HlIoPortOutByte(IN USHORT Port, "Nd" (Port)); } -/** - * Writes the 32-bit data to the specified I/O port. - * - * @param Port - * Specifies the address to write to, in the range of 0-0xFFFF. - * - * @param Value - * Supplies the value to write. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -HlIoPortOutLong(IN USHORT Port, - IN ULONG Value) -{ - __asm__ volatile("outl %0, %1" - : - : "a" (Value), - "Nd" (Port)); -} - /** * Writes the 16-bit data to the specified I/O port. * @@ -135,11 +111,35 @@ HlIoPortOutLong(IN USHORT Port, */ XTCDECL VOID -HlIoPortOutShort(IN USHORT Port, - IN USHORT Value) +HL::IoPort::WritePort16(IN USHORT Port, + IN USHORT Value) { __asm__ volatile("outw %0, %1" : : "a" (Value), "Nd" (Port)); } + +/** + * Writes the 32-bit data to the specified I/O port. + * + * @param Port + * Specifies the address to write to, in the range of 0-0xFFFF. + * + * @param Value + * Supplies the value to write. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +HL::IoPort::WritePort32(IN USHORT Port, + IN ULONG Value) +{ + __asm__ volatile("outl %0, %1" + : + : "a" (Value), + "Nd" (Port)); +} diff --git a/xtoskrnl/hl/i686/pic.c b/xtoskrnl/hl/i686/pic.cc similarity index 75% rename from xtoskrnl/hl/i686/pic.c rename to xtoskrnl/hl/i686/pic.cc index 120e588..cb0547f 100644 --- a/xtoskrnl/hl/i686/pic.c +++ b/xtoskrnl/hl/i686/pic.cc @@ -1,13 +1,13 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/hl/i686/pic.c + * FILE: xtoskrnl/hl/i686/pic.cc * DESCRIPTION: Programmable Interrupt Controller (PIC) for i686 support * DEVELOPERS: Rafal Kupiec */ -#include +#include /* Include common PIC interface */ -#include ARCH_COMMON(pic.c) +#include ARCH_COMMON(pic.cc) diff --git a/xtoskrnl/hl/i686/runlevel.c b/xtoskrnl/hl/i686/runlevel.cc similarity index 87% rename from xtoskrnl/hl/i686/runlevel.c rename to xtoskrnl/hl/i686/runlevel.cc index 1d56dff..da2f75e 100644 --- a/xtoskrnl/hl/i686/runlevel.c +++ b/xtoskrnl/hl/i686/runlevel.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/hl/i686/runlevel.c + * FILE: xtoskrnl/hl/i686/runlevel.cc * DESCRIPTION: Run Level management support for i686 architecture * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -18,9 +18,9 @@ */ XTFASTCALL KRUNLEVEL -HlGetRunLevel(VOID) +HL::RunLevel::GetRunLevel(VOID) { - return HlpTransformApicTprToRunLevel(HlReadApicRegister(APIC_TPR)); + return TransformApicTprToRunLevel(HL::Pic::ReadApicRegister(APIC_TPR)); } /** @@ -35,9 +35,9 @@ HlGetRunLevel(VOID) */ XTFASTCALL VOID -HlSetRunLevel(IN KRUNLEVEL RunLevel) +HL::RunLevel::SetRunLevel(IN KRUNLEVEL RunLevel) { - HlWriteApicRegister(APIC_TPR, HlpTransformRunLevelToApicTpr(RunLevel)); + HL::Pic::WriteApicRegister(APIC_TPR, TransformRunLevelToApicTpr(RunLevel)); } /** @@ -52,7 +52,7 @@ HlSetRunLevel(IN KRUNLEVEL RunLevel) */ XTFASTCALL KRUNLEVEL -HlpTransformApicTprToRunLevel(IN UCHAR Tpr) +HL::RunLevel::TransformApicTprToRunLevel(IN UCHAR Tpr) { STATIC KRUNLEVEL TransformationTable[16] = { @@ -90,7 +90,7 @@ HlpTransformApicTprToRunLevel(IN UCHAR Tpr) */ XTFASTCALL UCHAR -HlpTransformRunLevelToApicTpr(IN KRUNLEVEL RunLevel) +HL::RunLevel::TransformRunLevelToApicTpr(IN KRUNLEVEL RunLevel) { STATIC UCHAR TransformationTable[32] = { diff --git a/xtoskrnl/hl/init.c b/xtoskrnl/hl/init.cc similarity index 77% rename from xtoskrnl/hl/init.c rename to xtoskrnl/hl/init.cc index 6119f9a..10f8e40 100644 --- a/xtoskrnl/hl/init.c +++ b/xtoskrnl/hl/init.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/hl/init.c + * FILE: xtoskrnl/hl/init.cc * DESCRIPTION: Hardware layer initialization code * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -18,19 +18,19 @@ */ XTAPI XTSTATUS -HlInitializeSystem(VOID) +HL::Init::InitializeSystem(VOID) { XTSTATUS Status; /* Initialize ACPI */ - Status = HlpInitializeAcpi(); + Status = Acpi::InitializeAcpi(); if(Status != STATUS_SUCCESS) { return Status; } /* Get system information from ACPI */ - Status = HlpInitializeAcpiSystemInformation(); + Status = Acpi::InitializeAcpiSystemInformation(); if(Status != STATUS_SUCCESS) { return Status; diff --git a/xtoskrnl/rtl/ioreg.c b/xtoskrnl/hl/ioreg.cc similarity index 53% rename from xtoskrnl/rtl/ioreg.c rename to xtoskrnl/hl/ioreg.cc index 76dd0f5..f104019 100644 --- a/xtoskrnl/rtl/ioreg.c +++ b/xtoskrnl/hl/ioreg.cc @@ -1,73 +1,73 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/rtl/ioreg.c - * DESCRIPTION: I/O registers related routines + * FILE: xtoskrnl/hl/ioreg.cc + * DESCRIPTION: Basic I/O registers access functionality * DEVELOPERS: Rafal Kupiec */ -#include +#include /** - * Reads a byte from a specified register address. + * Reads an 8-bit data from a specified register address. * * @param Register * Supplies a pointer to register address holding data to read. * - * @return This routine returns UCHAR byte read from the register. + * @return This routine returns a value at the specified register. * * @since XT 1.0 */ XTAPI UCHAR -RtlReadRegisterByte(IN VOLATILE PVOID Register) +HL::IoRegister::ReadRegister8(IN PVOID Register) { return *((VOLATILE PUCHAR)Register); } /** - * Reads a byte from a specified register address. + * Reads a 16-bit data from a specified register address. * * @param Register * Supplies a pointer to register address holding data to read. * - * @return This routine returns ULONG byte read from the register. - * - * @since XT 1.0 - */ -XTAPI -ULONG -RtlReadRegisterLong(IN VOLATILE PVOID Register) -{ - return *((VOLATILE PULONG)Register); -} - -/** - * Reads a byte from a specified register address. - * - * @param Register - * Supplies a pointer to register address holding data to read. - * - * @return This routine returns USHORT byte read from the register. + * @return This routine returns a value at the specified register. * * @since XT 1.0 */ XTAPI USHORT -RtlReadRegisterShort(IN VOLATILE PVOID Register) +HL::IoRegister::ReadRegister16(IN PVOID Register) { return *((VOLATILE PUSHORT)Register); } /** - * Writes a byte into a specified register address. + * Reads a 32-bit data from a specified register address. + * + * @param Register + * Supplies a pointer to register address holding data to read. + * + * @return This routine returns a value at the specified register. + * + * @since XT 1.0 + */ +XTAPI +ULONG +HL::IoRegister::ReadRegister32(IN PVOID Register) +{ + return *((VOLATILE PULONG)Register); +} + +/** + * Writes an 8-bit value into a specified register address. * * @param Register * Supplies a pointer to register address where data will be written. * * @param Value - * Supplies a new UCHAR value that will be stored into a register. + * Supplies a new value that will be stored into a register. * * @return This routine does not return any value. * @@ -75,20 +75,20 @@ RtlReadRegisterShort(IN VOLATILE PVOID Register) */ XTAPI VOID -RtlWriteRegisterByte(IN VOLATILE PVOID Register, - IN UCHAR Value) +HL::IoRegister::WriteRegister8(IN PVOID Register, + IN UCHAR Value) { *((VOLATILE PUCHAR)Register) = Value; } /** - * Writes a byte into a specified register address. + * Writes a 16-bit value into a specified register address. * * @param Register * Supplies a pointer to register address where data will be written. * * @param Value - * Supplies a new ULONG value that will be stored into a register. + * Supplies a new value that will be stored into a register. * * @return This routine does not return any value. * @@ -96,29 +96,29 @@ RtlWriteRegisterByte(IN VOLATILE PVOID Register, */ XTAPI VOID -RtlWriteRegisterLong(IN VOLATILE PVOID Register, - IN ULONG Value) -{ - *((VOLATILE PULONG)Register) = Value; -} - -/** - * Writes a byte into a specified register address. - * - * @param Register - * Supplies a pointer to register address where data will be written. - * - * @param Value - * Supplies a new USHORT value that will be stored into a register. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -RtlWriteRegisterShort(IN VOLATILE PVOID Register, - IN USHORT Value) +HL::IoRegister::WriteRegister16(IN PVOID Register, + IN USHORT Value) { *((VOLATILE PUSHORT)Register) = Value; } + +/** + * Writes a 32-bit value into a specified register address. + * + * @param Register + * Supplies a pointer to register address where data will be written. + * + * @param Value + * Supplies a new value that will be stored into a register. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +HL::IoRegister::WriteRegister32(IN PVOID Register, + IN ULONG Value) +{ + *((VOLATILE PULONG)Register) = Value; +} diff --git a/xtoskrnl/hl/x86/cpu.c b/xtoskrnl/hl/x86/cpu.cc similarity index 75% rename from xtoskrnl/hl/x86/cpu.c rename to xtoskrnl/hl/x86/cpu.cc index 65f321f..a7c416d 100644 --- a/xtoskrnl/hl/x86/cpu.c +++ b/xtoskrnl/hl/x86/cpu.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/hl/x86/cpu.c + * FILE: xtoskrnl/hl/x86/cpu.cc * DESCRIPTION: HAL x86 (i686/AMD64) processor support * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -21,13 +21,13 @@ */ XTAPI VOID -HlInitializeProcessor(VOID) +HL::Cpu::InitializeProcessor(VOID) { PKPROCESSOR_BLOCK ProcessorBlock; KAFFINITY Affinity; /* Get current processor block */ - ProcessorBlock = KeGetCurrentProcessorBlock(); + ProcessorBlock = KE::Processor::GetCurrentProcessorBlock(); /* Set initial stall factor, CPU number and mask interrupts */ ProcessorBlock->StallScaleFactor = INITIAL_STALL_FACTOR; @@ -37,11 +37,11 @@ HlInitializeProcessor(VOID) Affinity = (KAFFINITY) 1 << ProcessorBlock->CpuNumber; /* Apply affinity to a set of processors */ - HlpActiveProcessors |= Affinity; + ActiveProcessors |= Affinity; /* Initialize APIC for this processor */ - HlpInitializePic(); + Pic::InitializePic(); /* Set the APIC running level */ - HlSetRunLevel(KeGetCurrentProcessorBlock()->RunLevel); + HL::RunLevel::SetRunLevel(KE::Processor::GetCurrentProcessorBlock()->RunLevel); } diff --git a/xtoskrnl/hl/x86/pic.c b/xtoskrnl/hl/x86/pic.cc similarity index 69% rename from xtoskrnl/hl/x86/pic.c rename to xtoskrnl/hl/x86/pic.cc index 513d7f5..2d31e2b 100644 --- a/xtoskrnl/hl/x86/pic.c +++ b/xtoskrnl/hl/x86/pic.cc @@ -1,14 +1,52 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/hl/x86/pic.c + * FILE: xtoskrnl/hl/x86/pic.cc * DESCRIPTION: Programmable Interrupt Controller (PIC) for x86 (i686/AMD64) support * DEVELOPERS: Rafal Kupiec */ -#include +#include +/** + * Checks whether the x2APIC extension is supported by the processor. + * + * @return This routine returns TRUE if x2APIC is supported, or FALSE otherwise. + * + * @since XT 1.0 + * + * @todo Check if bits 0 and 1 of DMAR ACPI table flags are set after implementing ACPI support. + * Intel VT-d spec says x2apic should not be enabled if they are. + */ +XTAPI +BOOLEAN +HL::Pic::CheckX2ApicSupport(VOID) +{ + CPUID_REGISTERS CpuRegisters; + + /* Prepare CPUID registers */ + CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES; + CpuRegisters.SubLeaf = 0; + CpuRegisters.Eax = 0; + CpuRegisters.Ebx = 0; + CpuRegisters.Ecx = 0; + CpuRegisters.Edx = 0; + + /* Get CPUID */ + AR::CpuFunc::CpuId(&CpuRegisters); + + /* Check x2APIC status from the CPUID results */ + if(!(CpuRegisters.Ecx & CPUID_FEATURES_ECX_X2APIC)) + { + /* x2APIC is not supported */ + return FALSE; + } + + /* x2APIC is supported */ + return TRUE; +} + /** * Clears all errors on the APIC. * @@ -18,10 +56,259 @@ */ XTAPI VOID -HlClearApicErrors(VOID) +HL::Pic::ClearApicErrors(VOID) { /* Clear APIC errors */ - HlWriteApicRegister(APIC_ESR, 0); + WriteApicRegister(APIC_ESR, 0); +} + +/** + * Gets the local APIC ID of the current processor. + * + * @return This routine returns the current processor's local APIC ID. + * + * @since XT 1.0 + */ +XTAPI +ULONG +HL::Pic::GetCpuApicId(VOID) +{ + ULONG ApicId; + + /* Read APIC ID register */ + ApicId = ReadApicRegister(APIC_ID); + + /* Return logical CPU ID depending on current APIC mode */ + return (ApicMode == APIC_MODE_COMPAT) ? ((ApicId & 0xFFFFFFFF) >> APIC_XAPIC_LDR_SHIFT) : ApicId; +} + +/** + * Allows an APIC spurious interrupts to end up. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +HL::Pic::HandleApicSpuriousService(VOID) +{ +} + +/** + * Allows a PIC spurious interrupts to end up. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +HL::Pic::HandlePicSpuriousService(VOID) +{ +} + +/** + * Initializes the APIC interrupt controller. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +HL::Pic::InitializeApic(VOID) +{ + APIC_SPURIOUS_REGISTER SpuriousRegister; + APIC_BASE_REGISTER BaseRegister; + APIC_LVT_REGISTER LvtRegister; + ULONG CpuNumber; + + /* Determine APIC mode (xAPIC compatibility or x2APIC) */ + if(CheckX2ApicSupport()) + { + /* Enable x2APIC mode */ + ApicMode = APIC_MODE_X2APIC; + } + else + { + /* Fall back to xAPIC compatibility mode */ + ApicMode = APIC_MODE_COMPAT; + } + + /* Get current processor number */ + CpuNumber = KE::Processor::GetCurrentProcessorNumber(); + + /* Enable the APIC */ + BaseRegister.LongLong = AR::CpuFunc::ReadModelSpecificRegister(APIC_LAPIC_MSR_BASE); + BaseRegister.Enable = 1; + BaseRegister.ExtendedMode = (ApicMode == APIC_MODE_X2APIC); + BaseRegister.BootStrapProcessor = (CpuNumber == 0) ? 1 : 0; + AR::CpuFunc::WriteModelSpecificRegister(APIC_LAPIC_MSR_BASE, BaseRegister.LongLong); + + /* Mask all interrupts by raising Task Priority Register (TPR) */ + WriteApicRegister(APIC_TPR, 0xFF); + + /* Perform initialization specific to xAPIC compatibility mode */ + if(ApicMode == APIC_MODE_COMPAT) + { + /* Use Flat Model for destination format (not supported in x2APIC) */ + WriteApicRegister(APIC_DFR, APIC_DF_FLAT); + + /* Set the logical APIC ID for this processor (read-only in x2APIC) */ + WriteApicRegister(APIC_LDR, (1UL << CpuNumber) << 24); + } + + /* Configure the spurious interrupt vector */ + SpuriousRegister.Long = ReadApicRegister(APIC_SIVR); + SpuriousRegister.Vector = APIC_VECTOR_SPURIOUS; + SpuriousRegister.SoftwareEnable = 1; + SpuriousRegister.CoreChecking = 0; + WriteApicRegister(APIC_SIVR, SpuriousRegister.Long); + + /* Setup the LVT Error entry to deliver APIC errors on a dedicated vector */ + WriteApicRegister(APIC_ERRLVTR, APIC_VECTOR_ERROR); + + /* Program the APIC timer for periodic mode */ + LvtRegister.Long = 0; + LvtRegister.Mask = 1; + LvtRegister.DeliveryMode = APIC_DM_FIXED; + LvtRegister.TimerMode = 1; + LvtRegister.TriggerMode = APIC_TGM_EDGE; + LvtRegister.Vector = APIC_VECTOR_PROFILE; + WriteApicRegister(APIC_TMRLVTR, LvtRegister.Long); + + /* Configure the performance counter overflow */ + LvtRegister.Long = 0; + LvtRegister.Mask = 0; + LvtRegister.DeliveryMode = APIC_DM_FIXED; + LvtRegister.TimerMode = 0; + LvtRegister.TriggerMode = APIC_TGM_EDGE; + LvtRegister.Vector = APIC_VECTOR_PERF; + WriteApicRegister(APIC_PCLVTR, LvtRegister.Long); + + /* Configure the LINT0 pin */ + LvtRegister.Long = 0; + LvtRegister.Mask = 1; + LvtRegister.DeliveryMode = APIC_DM_FIXED; + LvtRegister.TimerMode = 0; + LvtRegister.TriggerMode = APIC_TGM_EDGE; + LvtRegister.Vector = APIC_VECTOR_SPURIOUS; + WriteApicRegister(APIC_LINT0, LvtRegister.Long); + + /* Configure the LINT1 pin */ + LvtRegister.Long = 0; + LvtRegister.Mask = 0; + LvtRegister.DeliveryMode = APIC_DM_NMI; + LvtRegister.TimerMode = 0; + LvtRegister.TriggerMode = APIC_TGM_EDGE; + LvtRegister.Vector = APIC_VECTOR_NMI; + WriteApicRegister(APIC_LINT1, LvtRegister.Long); + + /* Register interrupt handlers */ + KE::Irq::SetInterruptHandler(APIC_VECTOR_SPURIOUS, (PVOID)HandleApicSpuriousService); + KE::Irq::SetInterruptHandler(PIC1_VECTOR_SPURIOUS, (PVOID)HandlePicSpuriousService); + + /* Clear any pre-existing errors */ + WriteApicRegister(APIC_ESR, 0); + + /* Re-enable all interrupts by lowering the Task Priority Register */ + WriteApicRegister(APIC_TPR, 0x00); +} + +/** + * Initializes the legacy PIC interrupt controller. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +HL::Pic::InitializeLegacyPic(VOID) +{ + PIC_I8259_ICW1 Icw1; + PIC_I8259_ICW2 Icw2; + PIC_I8259_ICW3 Icw3; + PIC_I8259_ICW4 Icw4; + + /* Initialize ICW1 for PIC1 port */ + Icw1.Init = TRUE; + Icw1.InterruptMode = EdgeTriggered; + Icw1.InterruptVectorAddress = 0; + Icw1.Interval = Interval8; + Icw1.NeedIcw4 = TRUE; + Icw1.OperatingMode = Cascade; + HL::IoPort::WritePort8(PIC1_CONTROL_PORT, Icw1.Bits); + + /* Initialize ICW2 for PIC1 port */ + Icw2.Bits = 0x00; + HL::IoPort::WritePort8(PIC1_DATA_PORT, Icw2.Bits); + + /* Initialize ICW3 for PIC1 port */ + Icw3.Bits = 0; + Icw3.SlaveIrq2 = TRUE; + HL::IoPort::WritePort8(PIC1_DATA_PORT, Icw3.Bits); + + /* Initialize ICW4 for PIC1 port */ + Icw4.BufferedMode = NonBuffered; + Icw4.EoiMode = NormalEoi; + Icw4.Reserved = 0; + Icw4.SpecialFullyNestedMode = FALSE; + Icw4.SystemMode = New8086Mode; + HL::IoPort::WritePort8(PIC1_DATA_PORT, Icw4.Bits); + + /* Mask all interrupts on PIC1 port */ + HL::IoPort::WritePort8(PIC1_DATA_PORT, 0xFF); + + /* Initialize ICW1 for PIC2 port */ + Icw1.Init = TRUE; + Icw1.InterruptMode = EdgeTriggered; + Icw1.InterruptVectorAddress = 0; + Icw1.Interval = Interval8; + Icw1.NeedIcw4 = TRUE; + Icw1.OperatingMode = Cascade; + HL::IoPort::WritePort8(PIC2_CONTROL_PORT, Icw1.Bits); + + /* Initialize ICW2 for PIC2 port */ + Icw2.Bits = 0x08; + HL::IoPort::WritePort8(PIC2_DATA_PORT, Icw2.Bits); + + /* Initialize ICW3 for PIC2 port */ + Icw3.Bits = 0; + Icw3.SlaveId = 2; + HL::IoPort::WritePort8(PIC2_DATA_PORT, Icw3.Bits); + + /* Initialize ICW4 for PIC2 port */ + Icw4.BufferedMode = NonBuffered; + Icw4.EoiMode = NormalEoi; + Icw4.Reserved = 0; + Icw4.SpecialFullyNestedMode = FALSE; + Icw4.SystemMode = New8086Mode; + HL::IoPort::WritePort8(PIC2_DATA_PORT, Icw4.Bits); + + /* Mask all interrupts on PIC2 port */ + HL::IoPort::WritePort8(PIC2_DATA_PORT, 0xFF); +} + +/** + * Initializes the (A)PIC interrupt controller. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + * + * @todo Initialize APIC only when supported, otherwise fall back to legacy PIC. + */ +XTAPI +VOID +HL::Pic::InitializePic(VOID) +{ + /* Initialize APIC */ + InitializeApic(); + + /* Initialize legacy PIC */ + InitializeLegacyPic(); } /** @@ -36,17 +323,17 @@ HlClearApicErrors(VOID) */ XTFASTCALL ULONGLONG -HlReadApicRegister(IN APIC_REGISTER Register) +HL::Pic::ReadApicRegister(IN APIC_REGISTER Register) { - if(HlpApicMode == APIC_MODE_X2APIC) + if(ApicMode == APIC_MODE_X2APIC) { /* Read from x2APIC MSR */ - return ArReadModelSpecificRegister((ULONG)(APIC_X2APIC_MSR_BASE + Register)); + return AR::CpuFunc::ReadModelSpecificRegister((ULONG)(APIC_X2APIC_MSR_BASE + Register)); } else { /* Read from xAPIC */ - return RtlReadRegisterLong((PULONG)(APIC_BASE + (Register << 4))); + return IoRegister::ReadRegister32((PULONG)(APIC_BASE + (Register << 4))); } } @@ -59,327 +346,10 @@ HlReadApicRegister(IN APIC_REGISTER Register) */ XTAPI VOID -HlSendEoi(VOID) +HL::Pic::SendEoi(VOID) { /* Send APIC EOI */ - HlWriteApicRegister(APIC_EOI, 0); -} - -/** - * Writes to the APIC register. - * - * @param Register - * Supplies the APIC register to write to. - * - * @param Value - * Supplies the value to write to the APIC register. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTFASTCALL -VOID -HlWriteApicRegister(IN APIC_REGISTER Register, - IN ULONGLONG Value) -{ - if(HlpApicMode == APIC_MODE_X2APIC) - { - /* Write to x2APIC MSR */ - ArWriteModelSpecificRegister((ULONG)(APIC_X2APIC_MSR_BASE + Register), Value); - } - else - { - /* Write to xAPIC */ - RtlWriteRegisterLong((PULONG)(APIC_BASE + (Register << 4)), Value); - } -} - -/** - * Checks whether the x2APIC extension is supported by the processor. - * - * @return This routine returns TRUE if x2APIC is supported, or FALSE otherwise. - * - * @since XT 1.0 - * - * @todo Check if bits 0 and 1 of DMAR ACPI table flags are set after implementing ACPI support. - * Intel VT-d spec says x2apic should not be enabled if they are. - */ -XTAPI -BOOLEAN -HlpCheckX2ApicSupport(VOID) -{ - CPUID_REGISTERS CpuRegisters; - - /* Prepare CPUID registers */ - CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES; - CpuRegisters.SubLeaf = 0; - CpuRegisters.Eax = 0; - CpuRegisters.Ebx = 0; - CpuRegisters.Ecx = 0; - CpuRegisters.Edx = 0; - - /* Get CPUID */ - ArCpuId(&CpuRegisters); - - /* Check x2APIC status from the CPUID results */ - if(!(CpuRegisters.Ecx & CPUID_FEATURES_ECX_X2APIC)) - { - /* x2APIC is not supported */ - return FALSE; - } - - /* x2APIC is supported */ - return TRUE; -} - -/** - * Gets the local APIC ID of the current processor. - * - * @return This routine returns the current processor's local APIC ID. - * - * @since XT 1.0 - */ -XTAPI -ULONG -HlpGetCpuApicId(VOID) -{ - ULONG ApicId; - - /* Read APIC ID register */ - ApicId = HlReadApicRegister(APIC_ID); - - /* Return logical CPU ID depending on current APIC mode */ - return (HlpApicMode == APIC_MODE_COMPAT) ? ((ApicId & 0xFFFFFFFF) >> APIC_XAPIC_LDR_SHIFT) : ApicId; -} - -/** - * Allows an APIC spurious interrupts to end up. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -HlpHandleApicSpuriousService(VOID) -{ -} - -/** - * Allows a PIC spurious interrupts to end up. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -HlpHandlePicSpuriousService(VOID) -{ -} - -/** - * Initializes the APIC interrupt controller. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -HlpInitializeApic(VOID) -{ - APIC_SPURIOUS_REGISTER SpuriousRegister; - APIC_BASE_REGISTER BaseRegister; - APIC_LVT_REGISTER LvtRegister; - ULONG CpuNumber; - - /* Determine APIC mode (xAPIC compatibility or x2APIC) */ - if(HlpCheckX2ApicSupport()) - { - /* Enable x2APIC mode */ - HlpApicMode = APIC_MODE_X2APIC; - } - else - { - /* Fall back to xAPIC compatibility mode */ - HlpApicMode = APIC_MODE_COMPAT; - } - - /* Get current processor number */ - CpuNumber = KeGetCurrentProcessorNumber(); - - /* Enable the APIC */ - BaseRegister.LongLong = ArReadModelSpecificRegister(APIC_LAPIC_MSR_BASE); - BaseRegister.Enable = 1; - BaseRegister.ExtendedMode = (HlpApicMode == APIC_MODE_X2APIC); - BaseRegister.BootStrapProcessor = (CpuNumber == 0) ? 1 : 0; - ArWriteModelSpecificRegister(APIC_LAPIC_MSR_BASE, BaseRegister.LongLong); - - /* Mask all interrupts by raising Task Priority Register (TPR) */ - HlWriteApicRegister(APIC_TPR, 0xFF); - - /* Perform initialization specific to xAPIC compatibility mode */ - if(HlpApicMode == APIC_MODE_COMPAT) - { - /* Use Flat Model for destination format (not supported in x2APIC) */ - HlWriteApicRegister(APIC_DFR, APIC_DF_FLAT); - - /* Set the logical APIC ID for this processor (read-only in x2APIC) */ - HlWriteApicRegister(APIC_LDR, (1UL << CpuNumber) << 24); - } - - /* Configure the spurious interrupt vector */ - SpuriousRegister.Long = HlReadApicRegister(APIC_SIVR); - SpuriousRegister.Vector = APIC_VECTOR_SPURIOUS; - SpuriousRegister.SoftwareEnable = 1; - SpuriousRegister.CoreChecking = 0; - HlWriteApicRegister(APIC_SIVR, SpuriousRegister.Long); - - /* Setup the LVT Error entry to deliver APIC errors on a dedicated vector */ - HlWriteApicRegister(APIC_ERRLVTR, APIC_VECTOR_ERROR); - - /* Program the APIC timer for periodic mode */ - LvtRegister.Long = 0; - LvtRegister.Mask = 1; - LvtRegister.DeliveryMode = APIC_DM_FIXED; - LvtRegister.TimerMode = 1; - LvtRegister.TriggerMode = APIC_TGM_EDGE; - LvtRegister.Vector = APIC_VECTOR_PROFILE; - HlWriteApicRegister(APIC_TMRLVTR, LvtRegister.Long); - - /* Configure the performance counter overflow */ - LvtRegister.Long = 0; - LvtRegister.Mask = 0; - LvtRegister.DeliveryMode = APIC_DM_FIXED; - LvtRegister.TimerMode = 0; - LvtRegister.TriggerMode = APIC_TGM_EDGE; - LvtRegister.Vector = APIC_VECTOR_PERF; - HlWriteApicRegister(APIC_PCLVTR, LvtRegister.Long); - - /* Configure the LINT0 pin */ - LvtRegister.Long = 0; - LvtRegister.Mask = 1; - LvtRegister.DeliveryMode = APIC_DM_FIXED; - LvtRegister.TimerMode = 0; - LvtRegister.TriggerMode = APIC_TGM_EDGE; - LvtRegister.Vector = APIC_VECTOR_SPURIOUS; - HlWriteApicRegister(APIC_LINT0, LvtRegister.Long); - - /* Configure the LINT1 pin */ - LvtRegister.Long = 0; - LvtRegister.Mask = 0; - LvtRegister.DeliveryMode = APIC_DM_NMI; - LvtRegister.TimerMode = 0; - LvtRegister.TriggerMode = APIC_TGM_EDGE; - LvtRegister.Vector = APIC_VECTOR_NMI; - HlWriteApicRegister(APIC_LINT1, LvtRegister.Long); - - /* Register interrupt handlers */ - KeSetInterruptHandler(APIC_VECTOR_SPURIOUS, HlpHandleApicSpuriousService); - KeSetInterruptHandler(PIC1_VECTOR_SPURIOUS, HlpHandlePicSpuriousService); - - /* Clear any pre-existing errors */ - HlWriteApicRegister(APIC_ESR, 0); - - /* Re-enable all interrupts by lowering the Task Priority Register */ - HlWriteApicRegister(APIC_TPR, 0x00); -} - -/** - * Initializes the legacy PIC interrupt controller. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -HlpInitializeLegacyPic(VOID) -{ - PIC_I8259_ICW1 Icw1; - PIC_I8259_ICW2 Icw2; - PIC_I8259_ICW3 Icw3; - PIC_I8259_ICW4 Icw4; - - /* Initialize ICW1 for PIC1 port */ - Icw1.Init = TRUE; - Icw1.InterruptMode = EdgeTriggered; - Icw1.InterruptVectorAddress = 0; - Icw1.Interval = Interval8; - Icw1.NeedIcw4 = TRUE; - Icw1.OperatingMode = Cascade; - HlIoPortOutByte(PIC1_CONTROL_PORT, Icw1.Bits); - - /* Initialize ICW2 for PIC1 port */ - Icw2.Bits = 0x00; - HlIoPortOutByte(PIC1_DATA_PORT, Icw2.Bits); - - /* Initialize ICW3 for PIC1 port */ - Icw3.Bits = 0; - Icw3.SlaveIrq2 = TRUE; - HlIoPortOutByte(PIC1_DATA_PORT, Icw3.Bits); - - /* Initialize ICW4 for PIC1 port */ - Icw4.BufferedMode = NonBuffered; - Icw4.EoiMode = NormalEoi; - Icw4.Reserved = 0; - Icw4.SpecialFullyNestedMode = FALSE; - Icw4.SystemMode = New8086Mode; - HlIoPortOutByte(PIC1_DATA_PORT, Icw4.Bits); - - /* Mask all interrupts on PIC1 port */ - HlIoPortOutByte(PIC1_DATA_PORT, 0xFF); - - /* Initialize ICW1 for PIC2 port */ - Icw1.Init = TRUE; - Icw1.InterruptMode = EdgeTriggered; - Icw1.InterruptVectorAddress = 0; - Icw1.Interval = Interval8; - Icw1.NeedIcw4 = TRUE; - Icw1.OperatingMode = Cascade; - HlIoPortOutByte(PIC2_CONTROL_PORT, Icw1.Bits); - - /* Initialize ICW2 for PIC2 port */ - Icw2.Bits = 0x08; - HlIoPortOutByte(PIC2_DATA_PORT, Icw2.Bits); - - /* Initialize ICW3 for PIC2 port */ - Icw3.Bits = 0; - Icw3.SlaveId = 2; - HlIoPortOutByte(PIC2_DATA_PORT, Icw3.Bits); - - /* Initialize ICW4 for PIC2 port */ - Icw4.BufferedMode = NonBuffered; - Icw4.EoiMode = NormalEoi; - Icw4.Reserved = 0; - Icw4.SpecialFullyNestedMode = FALSE; - Icw4.SystemMode = New8086Mode; - HlIoPortOutByte(PIC2_DATA_PORT, Icw4.Bits); - - /* Mask all interrupts on PIC2 port */ - HlIoPortOutByte(PIC2_DATA_PORT, 0xFF); -} - -/** - * Initializes the (A)PIC interrupt controller. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - * - * @todo Initialize APIC only when supported, otherwise fall back to legacy PIC. - */ -XTAPI -VOID -HlpInitializePic(VOID) -{ - /* Initialize APIC */ - HlpInitializeApic(); - - /* Initialize legacy PIC */ - HlpInitializeLegacyPic(); + WriteApicRegister(APIC_EOI, 0); } /** @@ -397,19 +367,49 @@ HlpInitializePic(VOID) */ XTAPI VOID -HlpSendIpi(ULONG ApicId, - ULONG Vector) +HL::Pic::SendIpi(ULONG ApicId, + ULONG Vector) { /* Check current APIC mode */ - if(HlpApicMode == APIC_MODE_X2APIC) + if(ApicMode == APIC_MODE_X2APIC) { /* Send IPI using x2APIC mode */ - HlWriteApicRegister(APIC_ICR0, ((ULONGLONG)ApicId << 32) | Vector); + WriteApicRegister(APIC_ICR0, ((ULONGLONG)ApicId << 32) | Vector); } else { /* Send IPI using xAPIC compatibility mode */ - HlWriteApicRegister(APIC_ICR1, ApicId << 24); - HlWriteApicRegister(APIC_ICR0, Vector); + WriteApicRegister(APIC_ICR1, ApicId << 24); + WriteApicRegister(APIC_ICR0, Vector); + } +} + +/** + * Writes to the APIC register. + * + * @param Register + * Supplies the APIC register to write to. + * + * @param Value + * Supplies the value to write to the APIC register. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTFASTCALL +VOID +HL::Pic::WriteApicRegister(IN APIC_REGISTER Register, + IN ULONGLONG Value) +{ + if(ApicMode == APIC_MODE_X2APIC) + { + /* Write to x2APIC MSR */ + AR::CpuFunc::WriteModelSpecificRegister((ULONG)(APIC_X2APIC_MSR_BASE + Register), Value); + } + else + { + /* Write to xAPIC */ + IoRegister::WriteRegister32((PULONG)(APIC_BASE + (Register << 4)), Value); } } diff --git a/xtoskrnl/includes/amd64/ari.h b/xtoskrnl/includes/amd64/ari.h deleted file mode 100644 index 1b63daa..0000000 --- a/xtoskrnl/includes/amd64/ari.h +++ /dev/null @@ -1,434 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/includes/amd64/ari.h - * DESCRIPTION: AMD64 architecture library routines - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTOSKRNL_AMD64_ARI_H -#define __XTOSKRNL_AMD64_ARI_H - -#include - - -/* AMD64 architecture library routines forward references */ -XTCDECL -VOID -ArClearInterruptFlag(VOID); - -XTCDECL -BOOLEAN -ArCpuId(IN OUT PCPUID_REGISTERS Registers); - -XTCDECL -VOID -ArFlushTlb(VOID); - -XTCDECL -ULONG -ArGetCpuFlags(VOID); - -XTASSEMBLY -XTCDECL -ULONG_PTR -ArGetStackPointer(VOID); - -XTCDECL -VOID -ArHalt(VOID); - -XTAPI -VOID -ArInitializeProcessor(IN PVOID ProcessorStructures); - -XTCDECL -BOOLEAN -ArInterruptsEnabled(VOID); - -XTCDECL -VOID -ArInvalidateTlbEntry(IN PVOID Address); - -XTCDECL -VOID -ArLoadGlobalDescriptorTable(IN PVOID Source); - -XTCDECL -VOID -ArLoadInterruptDescriptorTable(IN PVOID Source); - -XTCDECL -VOID -ArLoadLocalDescriptorTable(IN USHORT Source); - -XTCDECL -VOID -ArLoadMxcsrRegister(IN ULONG Source); - -XTCDECL -VOID -ArLoadSegment(IN USHORT Segment, - IN ULONG Source); - -XTCDECL -VOID -ArLoadTaskRegister(IN USHORT Source); - -XTCDECL -VOID -ArMemoryBarrier(VOID); - -XTCDECL -ULONG_PTR -ArReadControlRegister(IN USHORT ControlRegister); - -XTCDECL -ULONG_PTR -ArReadDebugRegister(IN USHORT DebugRegister); - -XTCDECL -ULONGLONG -ArReadGSQuadWord(IN ULONG Offset); - -XTCDECL -ULONGLONG -ArReadModelSpecificRegister(IN ULONG Register); - -XTCDECL -UINT -ArReadMxCsrRegister(VOID); - -XTCDECL -ULONGLONG -ArReadTimeStampCounter(VOID); - -XTCDECL -VOID -ArReadWriteBarrier(VOID); - -XTAPI -VOID -ArSetGdtEntryBase(IN PKGDTENTRY Gdt, - IN USHORT Selector, - IN ULONG_PTR Base); - -XTCDECL -VOID -ArSetInterruptFlag(VOID); - -XTCDECL -VOID -ArStoreGlobalDescriptorTable(OUT PVOID Destination); - -XTCDECL -VOID -ArStoreInterruptDescriptorTable(OUT PVOID Destination); - -XTCDECL -VOID -ArStoreLocalDescriptorTable(OUT PVOID Destination); - -XTCDECL -VOID -ArStoreSegment(IN USHORT Segment, - OUT PVOID Destination); - -XTCDECL -VOID -ArStoreTaskRegister(OUT PVOID Destination); - -XTCDECL -VOID -ArWriteControlRegister(IN USHORT ControlRegister, - IN UINT_PTR Value); - -XTCDECL -VOID -ArWriteDebugRegister(IN USHORT DebugRegister, - IN UINT_PTR Value); - -XTCDECL -VOID -ArWriteEflagsRegister(IN UINT_PTR Value); - -XTCDECL -VOID -ArWriteModelSpecificRegister(IN ULONG Register, - IN ULONGLONG Value); - -XTCDECL -VOID -ArYieldProcessor(VOID); - -XTCDECL -VOID -ArpDispatchTrap(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleSystemCall32(VOID); - -XTCDECL -VOID -ArpHandleSystemCall64(VOID); - -XTCDECL -VOID -ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap1F(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap2F(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrapE1(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrapFF(IN PKTRAP_FRAME TrapFrame); - -XTAPI -VOID -ArpIdentifyProcessor(VOID); - -XTAPI -VOID -ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock); - -XTAPI -VOID -ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock); - -XTAPI -VOID -ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, - IN PKGDTENTRY Gdt, - IN PKIDTENTRY Idt, - IN PKTSS Tss, - IN PVOID DpcStack); - -XTAPI -VOID -ArpInitializeProcessorRegisters(VOID); - -XTAPI -VOID -ArpInitializeProcessorStructures(IN PVOID ProcessorStructures, - OUT PKGDTENTRY *Gdt, - OUT PKTSS *Tss, - OUT PKPROCESSOR_BLOCK *ProcessorBlock, - OUT PVOID *KernelBootStack, - OUT PVOID *KernelFaultStack); - -XTAPI -VOID -ArpInitializeSegments(VOID); - -XTAPI -VOID -ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, - IN PVOID KernelBootStack, - IN PVOID KernelFaultStack); - -XTAPI -VOID -ArpSetGdtEntry(IN PKGDTENTRY Gdt, - IN USHORT Selector, - IN ULONG_PTR Base, - IN ULONG Limit, - IN UCHAR Type, - IN UCHAR Dpl, - IN UCHAR SegmentMode); - -XTAPI -VOID -ArpSetIdtGate(IN PKIDTENTRY Idt, - IN USHORT Vector, - IN PVOID Handler, - IN USHORT Selector, - IN USHORT Ist, - IN USHORT Access); - -XTCDECL -VOID -ArpTrap0x00(VOID); - -XTCDECL -VOID -ArpTrap0x01(VOID); - -XTCDECL -VOID -ArpTrap0x02(VOID); - -XTCDECL -VOID -ArpTrap0x03(VOID); - -XTCDECL -VOID -ArpTrap0x04(VOID); - -XTCDECL -VOID -ArpTrap0x05(VOID); - -XTCDECL -VOID -ArpTrap0x06(VOID); - -XTCDECL -VOID -ArpTrap0x07(VOID); - -XTCDECL -VOID -ArpTrap0x08(VOID); - -XTCDECL -VOID -ArpTrap0x09(VOID); - -XTCDECL -VOID -ArpTrap0x0A(VOID); - -XTCDECL -VOID -ArpTrap0x0B(VOID); - -XTCDECL -VOID -ArpTrap0x0C(VOID); - -XTCDECL -VOID -ArpTrap0x0D(VOID); - -XTCDECL -VOID -ArpTrap0x0E(VOID); - -XTCDECL -VOID -ArpTrap0x10(VOID); - -XTCDECL -VOID -ArpTrap0x11(VOID); - -XTCDECL -VOID -ArpTrap0x12(VOID); - -XTCDECL -VOID -ArpTrap0x13(VOID); - -XTCDECL -VOID -ArpTrap0x1F(VOID); - -XTCDECL -VOID -ArpTrap0x2C(VOID); - -XTCDECL -VOID -ArpTrap0x2D(VOID); - -XTCDECL -VOID -ArpTrap0x2F(VOID); - -XTCDECL -VOID -ArpTrap0xE1(VOID); - -#endif /* __XTOSKRNL_AMD64_ARI_H */ diff --git a/xtoskrnl/includes/amd64/globals.h b/xtoskrnl/includes/amd64/globals.h deleted file mode 100644 index 234379a..0000000 --- a/xtoskrnl/includes/amd64/globals.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/includes/amd64/globals.h - * DESCRIPTION: XT kernel global variables related to AMD64 architecture - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTOSKRNL_AMD64_GLOBALS_H -#define __XTOSKRNL_AMD64_GLOBALS_H - -#include - - -/* Initial GDT */ -EXTERN KGDTENTRY ArInitialGdt[GDT_ENTRIES]; - -/* Initial IDT */ -EXTERN KIDTENTRY ArInitialIdt[IDT_ENTRIES]; - -/* Initial Processor Block */ -EXTERN KPROCESSOR_BLOCK ArInitialProcessorBlock; - -/* Initial TSS */ -EXTERN KTSS ArInitialTss; - -/* Kernel own boot stack */ -EXTERN UCHAR ArKernelBootStack[KERNEL_STACK_SIZE]; - -/* Kernel own fault stack */ -EXTERN UCHAR ArKernelFaultStack[KERNEL_STACK_SIZE]; - -/* Page mapping routines for systems using 4-level paging (PML4) */ -EXTERN CMMPAGEMAP_ROUTINES MmpPml4Routines; - -/* Page mapping routines for systems using 5-level paging (PML5) */ -EXTERN CMMPAGEMAP_ROUTINES MmpPml5Routines; - -#endif /* __XTOSKRNL_AMD64_GLOBALS_H */ diff --git a/xtoskrnl/includes/amd64/hli.h b/xtoskrnl/includes/amd64/hli.h deleted file mode 100644 index bc4a268..0000000 --- a/xtoskrnl/includes/amd64/hli.h +++ /dev/null @@ -1,74 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/includes/amd64/hli.h - * DESCRIPTION: XT hardware abstraction layer routines specific to AMD64 architecture - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTOSKRNL_AMD64_HLI_H -#define __XTOSKRNL_AMD64_HLI_H - -#include - - -/* HAL library routines forward references */ -XTAPI -VOID -HlClearApicErrors(VOID); - -XTFASTCALL -ULONGLONG -HlReadApicRegister(IN APIC_REGISTER Register); - -XTAPI -VOID -HlSendEoi(VOID); - -XTFASTCALL -VOID -HlWriteApicRegister(IN APIC_REGISTER Register, - IN ULONGLONG Value); - -XTAPI -BOOLEAN -HlpCheckX2ApicSupport(VOID); - -XTAPI -ULONG -HlpGetCpuApicId(VOID); - -XTCDECL -VOID -HlpHandleApicSpuriousService(VOID); - -XTCDECL -VOID -HlpHandlePicSpuriousService(VOID); - -XTAPI -VOID -HlpInitializeApic(); - -XTAPI -VOID -HlpInitializeLegacyPic(VOID); - -XTAPI -VOID -HlpInitializePic(); - -XTAPI -VOID -HlpSendIpi(ULONG ApicId, - ULONG Vector); - -XTFASTCALL -KRUNLEVEL -HlpTransformApicTprToRunLevel(IN UCHAR Tpr); - -XTFASTCALL -UCHAR -HlpTransformRunLevelToApicTpr(IN KRUNLEVEL RunLevel); - -#endif /* __XTOSKRNL_AMD64_HLI_H */ diff --git a/xtoskrnl/includes/amd64/kei.h b/xtoskrnl/includes/amd64/kei.h deleted file mode 100644 index de0da65..0000000 --- a/xtoskrnl/includes/amd64/kei.h +++ /dev/null @@ -1,60 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/includes/amd64/kei.h - * DESCRIPTION: XTOS kernel services routine definitions specific to AMD64 architecture - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTOSKRNL_AMD64_KEI_H -#define __XTOSKRNL_AMD64_KEI_H - -#include - - -/* AMD64 specific Kernel services routines forward references */ -XTAPI -PKPROCESSOR_BLOCK -KeGetCurrentProcessorBlock(VOID); - -XTAPI -PKPROCESSOR_CONTROL_BLOCK -KeGetCurrentProcessorControlBlock(VOID); - -XTAPI -ULONG -KeGetCurrentProcessorNumber(VOID); - -XTAPI -PKTHREAD -KeGetCurrentThread(VOID); - -XTAPI -VOID -KepInitializeKernel(VOID); - -XTAPI -VOID -KepInitializeMachine(VOID); - -XTAPI -VOID -KepInitializeThreadContext(IN PKTHREAD Thread, - IN PKSYSTEM_ROUTINE SystemRoutine, - IN PKSTART_ROUTINE StartRoutine, - IN PVOID StartContext, - IN PCONTEXT ContextRecord); - -XTAPI -VOID -KepSaveProcessorState(OUT PKPROCESSOR_STATE CpuState); - -XTAPI -VOID -KepStartKernel(VOID); - -XTAPI -VOID -KepSwitchBootStack(IN ULONG_PTR Stack); - -#endif /* __XTOSKRNL_AMD64_KEI_H */ diff --git a/xtoskrnl/includes/amd64/mmi.h b/xtoskrnl/includes/amd64/mmi.h deleted file mode 100644 index dbbcba0..0000000 --- a/xtoskrnl/includes/amd64/mmi.h +++ /dev/null @@ -1,73 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/includes/amd64/mmi.h - * DESCRIPTION: XT memory manager routines specific to AMD64 architecture - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTOSKRNL_AMD64_MMI_H -#define __XTOSKRNL_AMD64_MMI_H - -#include - - -/* AMD64 Memory Manager routines forward references */ -XTAPI -VOID -MmInitializePageMapSupport(VOID); - -XTFASTCALL -VOID -MmZeroPages(IN PVOID Address, - IN ULONG Size); - -XTAPI -VOID -MmpClearPte(PHARDWARE_PTE PtePointer); - -XTAPI -BOOLEAN -MmpGetExtendedPhysicalAddressingStatus(VOID); - -XTAPI -PMMP5E -MmpGetP5eAddress(PVOID Address); - -XTAPI -PMMPDE -MmpGetPdeAddress(PVOID Address); - -XTAPI -PMMPPE -MmpGetPpeAddress(PVOID Address); - -XTAPI -PMMPTE -MmpGetPteAddress(PVOID Address); - -XTAPI -PMMPXE -MmpGetPxeAddress(PVOID Address); - -XTAPI -VOID -MmpInitializeArchitecture(VOID); - -XTAPI -BOOLEAN -MmpPteValid(PHARDWARE_PTE PtePointer); - -XTAPI -VOID -MmpSetPte(PHARDWARE_PTE PtePointer, - PFN_NUMBER PageFrameNumber, - BOOLEAN Writable); - -XTAPI -VOID -MmpSetPteCaching(PHARDWARE_PTE PtePointer, - BOOLEAN CacheDisable, - BOOLEAN WriteThrough); - -#endif /* __XTOSKRNL_AMD64_MMI_H */ diff --git a/xtoskrnl/includes/amd64/rtli.h b/xtoskrnl/includes/amd64/rtli.h deleted file mode 100644 index d9d187d..0000000 --- a/xtoskrnl/includes/amd64/rtli.h +++ /dev/null @@ -1,21 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/includes/amd64/rtli.h - * DESCRIPTION: XT runtime library routines specific to AMD64 architecture - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTOSKRNL_AMD64_RTLI_H -#define __XTOSKRNL_AMD64_RTLI_H - -#include - - -/* Runtime Library routines specific to AMD64 forward references */ -XTAPI -VOID -RtlGetStackLimits(OUT PULONG_PTR StackBase, - OUT PULONG_PTR StackLimit); - -#endif /* __XTOSKRNL_AMD64_RTLI_H */ diff --git a/xtoskrnl/includes/ar.hh b/xtoskrnl/includes/ar.hh new file mode 100644 index 0000000..437761f --- /dev/null +++ b/xtoskrnl/includes/ar.hh @@ -0,0 +1,19 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ar.hh + * DESCRIPTION: Architecture Library + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_AR_HH +#define __XTOSKRNL_AR_HH + +#include + +#include XTOS_ARCH_HEADER(ar, assembly.hh) +#include XTOS_ARCH_HEADER(ar, cpufunc.hh) +#include XTOS_ARCH_HEADER(ar, procsup.hh) +#include XTOS_ARCH_HEADER(ar, traps.hh) + +#endif /* __XTOSKRNL_AR_HH */ diff --git a/xtoskrnl/includes/amd64/asmsup.h b/xtoskrnl/includes/ar/amd64/asmsup.h similarity index 100% rename from xtoskrnl/includes/amd64/asmsup.h rename to xtoskrnl/includes/ar/amd64/asmsup.h diff --git a/xtoskrnl/includes/ar/amd64/assembly.hh b/xtoskrnl/includes/ar/amd64/assembly.hh new file mode 100644 index 0000000..f9f7274 --- /dev/null +++ b/xtoskrnl/includes/ar/amd64/assembly.hh @@ -0,0 +1,158 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ar/amd64/assembly.hh + * DESCRIPTION: Architecture-specific assembler prototypes + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_AR_ASSEMBLY_HH +#define __XTOSKRNL_AR_ASSEMBLY_HH + +#include + + +/* TrampolineEnableXpa end address to calculate trampoline size */ +XTCLINK PVOID ArEnableExtendedPhysicalAddressingEnd[]; + +/* TrampolineApStartup end address to calculate trampoline size */ +XTCLINK PVOID ArStartApplicationProcessorEnd[]; + + +/* Forward reference for assembler code */ +XTCLINK +XTCDECL +VOID +ArEnableExtendedPhysicalAddressing(IN ULONG_PTR PageMap); + +XTCLINK +XTCDECL +VOID +ArStartApplicationProcessor(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x00(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x01(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x02(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x03(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x04(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x05(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x06(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x07(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x08(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x09(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x0A(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x0B(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x0C(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x0D(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x0E(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x10(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x11(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x12(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x13(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x1F(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x2C(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x2D(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x2F(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0xE1(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0xFF(VOID); + +#endif /* __XTOSKRNL_AR_ASSEMBLY_HH */ diff --git a/xtoskrnl/includes/ar/amd64/cpufunc.hh b/xtoskrnl/includes/ar/amd64/cpufunc.hh new file mode 100644 index 0000000..856d3d2 --- /dev/null +++ b/xtoskrnl/includes/ar/amd64/cpufunc.hh @@ -0,0 +1,62 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ar/amd64/cpufunc.hh + * DESCRIPTION: Architecture-specific CPU control and utility functions for low-level system operations + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_AR_CPUFUNC_HH +#define __XTOSKRNL_AR_CPUFUNC_HH + +#include + + +/* Architecture-specific Library */ +namespace AR +{ + class CpuFunc + { + public: + STATIC XTCDECL VOID ClearInterruptFlag(VOID); + STATIC XTCDECL BOOLEAN CpuId(IN OUT PCPUID_REGISTERS Registers); + STATIC XTCDECL VOID FlushTlb(VOID); + STATIC XTCDECL ULONG GetCpuFlags(VOID); + STATIC XTASSEMBLY XTCDECL ULONG_PTR GetStackPointer(VOID); + STATIC XTCDECL VOID Halt(VOID); + STATIC XTCDECL BOOLEAN InterruptsEnabled(VOID); + STATIC XTCDECL VOID InvalidateTlbEntry(IN PVOID Address); + STATIC XTCDECL VOID LoadGlobalDescriptorTable(IN PVOID Source); + STATIC XTCDECL VOID LoadInterruptDescriptorTable(IN PVOID Source); + STATIC XTCDECL VOID LoadLocalDescriptorTable(IN USHORT Source); + STATIC XTCDECL VOID LoadMxcsrRegister(IN ULONG Source); + STATIC XTCDECL VOID LoadSegment(IN USHORT Segment, + IN ULONG Source); + STATIC XTCDECL VOID LoadTaskRegister(USHORT Source); + STATIC XTCDECL VOID MemoryBarrier(VOID); + STATIC XTCDECL ULONG_PTR ReadControlRegister(IN USHORT ControlRegister); + STATIC XTCDECL ULONG_PTR ReadDebugRegister(IN USHORT DebugRegister); + STATIC XTCDECL ULONGLONG ReadGSQuadWord(ULONG Offset); + STATIC XTCDECL ULONGLONG ReadModelSpecificRegister(IN ULONG Register); + STATIC XTCDECL UINT ReadMxCsrRegister(VOID); + STATIC XTCDECL ULONGLONG ReadTimeStampCounter(VOID); + STATIC XTCDECL VOID ReadWriteBarrier(VOID); + STATIC XTCDECL VOID SetInterruptFlag(VOID); + STATIC XTCDECL VOID StoreGlobalDescriptorTable(OUT PVOID Destination); + STATIC XTCDECL VOID StoreInterruptDescriptorTable(OUT PVOID Destination); + STATIC XTCDECL VOID StoreLocalDescriptorTable(OUT PVOID Destination); + STATIC XTCDECL VOID StoreSegment(IN USHORT Segment, + OUT PVOID Destination); + STATIC XTCDECL VOID StoreTaskRegister(OUT PVOID Destination); + STATIC XTCDECL VOID WriteControlRegister(IN USHORT ControlRegister, + IN UINT_PTR Value); + STATIC XTCDECL VOID WriteDebugRegister(IN USHORT DebugRegister, + IN UINT_PTR Value); + STATIC XTCDECL VOID WriteEflagsRegister(IN UINT_PTR Value); + STATIC XTCDECL VOID WriteModelSpecificRegister(IN ULONG Register, + IN ULONGLONG Value); + STATIC XTCDECL VOID YieldProcessor(VOID); + }; +} + +#endif /* __XTOSKRNL_AR_CPUFUNC_HH */ diff --git a/xtoskrnl/includes/ar/amd64/procsup.hh b/xtoskrnl/includes/ar/amd64/procsup.hh new file mode 100644 index 0000000..f9d8094 --- /dev/null +++ b/xtoskrnl/includes/ar/amd64/procsup.hh @@ -0,0 +1,74 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ar/amd64/procsup.hh + * DESCRIPTION: Architecture-specific routines for AMD64 processor initialization and system structure setup + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_AR_PROCSUP_HH +#define __XTOSKRNL_AR_PROCSUP_HH + +#include + + +/* Architecture-specific Library */ +namespace AR +{ + class ProcSup + { + private: + STATIC UCHAR BootStack[KERNEL_STACK_SIZE]; + STATIC UCHAR FaultStack[KERNEL_STACK_SIZE]; + STATIC KGDTENTRY InitialGdt[GDT_ENTRIES]; + STATIC KIDTENTRY InitialIdt[IDT_ENTRIES]; + STATIC KPROCESSOR_BLOCK InitialProcessorBlock; + STATIC KTSS InitialTss; + + public: + STATIC XTAPI PVOID GetBootStack(VOID); + STATIC XTAPI VOID GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType, + OUT PVOID *TrampolineCode, + OUT PULONG_PTR TrampolineSize); + STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures); + + private: + STATIC XTAPI VOID IdentifyProcessor(VOID); + STATIC XTAPI VOID InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock); + STATIC XTAPI VOID InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock); + STATIC XTAPI VOID InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, + IN PKGDTENTRY Gdt, + IN PKIDTENTRY Idt, + IN PKTSS Tss, + IN PVOID DpcStack); + STATIC XTAPI VOID InitializeProcessorRegisters(VOID); + STATIC XTAPI VOID InitializeProcessorStructures(IN PVOID ProcessorStructures, + OUT PKGDTENTRY *Gdt, + OUT PKTSS *Tss, + OUT PKPROCESSOR_BLOCK *ProcessorBlock, + OUT PVOID *KernelBootStack, + OUT PVOID *KernelFaultStack); + STATIC XTAPI VOID InitializeSegments(VOID); + STATIC XTAPI VOID InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, + IN PVOID KernelBootStack, + IN PVOID KernelFaultStack); + STATIC XTAPI VOID SetGdtEntry(IN PKGDTENTRY Gdt, + IN USHORT Selector, + IN ULONG_PTR Base, + IN ULONG Limit, + IN UCHAR Type, + IN UCHAR Dpl, + IN UCHAR SegmentMode); + STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt, + IN USHORT Selector, + IN ULONG_PTR Base); + STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt, + IN USHORT Vector, + IN PVOID Handler, + IN USHORT Selector, + IN USHORT Ist, + IN USHORT Access); + }; +} + +#endif /* __XTOSKRNL_AR_PROCSUP_HH */ diff --git a/xtoskrnl/includes/ar/amd64/traps.hh b/xtoskrnl/includes/ar/amd64/traps.hh new file mode 100644 index 0000000..2d14e6a --- /dev/null +++ b/xtoskrnl/includes/ar/amd64/traps.hh @@ -0,0 +1,55 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ar/amd64/traps.hh + * DESCRIPTION: Trap handling routines and the dispatcher for processor exceptions + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_AR_TRAPS_HH +#define __XTOSKRNL_AR_TRAPS_HH + +#include + + +/* Architecture-specific Library */ +namespace AR +{ + class Traps + { + public: + STATIC XTCDECL VOID DispatchTrap(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID InitializeSystemCallMsrs(VOID); + + private: + STATIC XTCDECL VOID HandleSystemCall32(VOID); + STATIC XTCDECL VOID HandleSystemCall64(VOID); + STATIC XTCDECL VOID HandleTrap00(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap01(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap02(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap03(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap04(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap05(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap06(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap07(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap08(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap09(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap0A(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap0B(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap0C(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap0D(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap0E(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap10(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap11(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap12(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap13(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap1F(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap2C(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap2D(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap2F(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrapE1(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrapFF(IN PKTRAP_FRAME TrapFrame); + }; +} + +#endif /* __XTOSKRNL_AR_TRAPS_HH */ diff --git a/xtoskrnl/includes/i686/asmsup.h b/xtoskrnl/includes/ar/i686/asmsup.h similarity index 100% rename from xtoskrnl/includes/i686/asmsup.h rename to xtoskrnl/includes/ar/i686/asmsup.h diff --git a/xtoskrnl/includes/ar/i686/assembly.hh b/xtoskrnl/includes/ar/i686/assembly.hh new file mode 100644 index 0000000..f2a7a2e --- /dev/null +++ b/xtoskrnl/includes/ar/i686/assembly.hh @@ -0,0 +1,151 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ar/i686/assembly.hh + * DESCRIPTION: Architecture-specific assembler prototypes + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_AR_ASSEMBLY_HH +#define __XTOSKRNL_AR_ASSEMBLY_HH + +#include + + +/* TrampolineApStartup end address to calculate trampoline size */ +XTCLINK PVOID ArStartApplicationProcessorEnd[]; + + +/* Forward reference for assembler code */ +XTCLINK +XTCDECL +VOID +ArStartApplicationProcessor(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x00(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x01(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x02(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x03(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x04(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x05(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x06(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x07(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x08(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x09(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x0A(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x0B(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x0C(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x0D(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x0E(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x10(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x11(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x12(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x13(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x2A(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x2B(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x2C(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x2D(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0x2E(VOID); + +XTCLINK +XTCDECL +VOID +ArTrap0xFF(VOID); + + +#endif /* __XTOSKRNL_AR_ASSEMBLY_HH */ diff --git a/xtoskrnl/includes/ar/i686/cpufunc.hh b/xtoskrnl/includes/ar/i686/cpufunc.hh new file mode 100644 index 0000000..b05c696 --- /dev/null +++ b/xtoskrnl/includes/ar/i686/cpufunc.hh @@ -0,0 +1,61 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ar/i686/cpufunc.hh + * DESCRIPTION: Architecture-specific CPU control and utility functions for low-level system operations + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_AR_CPUFUNC_HH +#define __XTOSKRNL_AR_CPUFUNC_HH + +#include + + +/* Architecture-specific Library */ +namespace AR +{ + class CpuFunc + { + public: + STATIC XTCDECL VOID ClearInterruptFlag(VOID); + STATIC XTCDECL BOOLEAN CpuId(IN OUT PCPUID_REGISTERS Registers); + STATIC XTCDECL VOID FlushTlb(VOID); + STATIC XTCDECL ULONG GetCpuFlags(VOID); + STATIC XTASSEMBLY XTCDECL ULONG_PTR GetStackPointer(VOID); + STATIC XTCDECL VOID Halt(VOID); + STATIC XTCDECL BOOLEAN InterruptsEnabled(VOID); + STATIC XTCDECL VOID InvalidateTlbEntry(IN PVOID Address); + STATIC XTCDECL VOID LoadGlobalDescriptorTable(IN PVOID Source); + STATIC XTCDECL VOID LoadInterruptDescriptorTable(IN PVOID Source); + STATIC XTCDECL VOID LoadLocalDescriptorTable(IN USHORT Source); + STATIC XTCDECL VOID LoadSegment(IN USHORT Segment, + IN ULONG Source); + STATIC XTCDECL VOID LoadTaskRegister(USHORT Source); + STATIC XTCDECL VOID MemoryBarrier(VOID); + STATIC XTCDECL ULONG_PTR ReadControlRegister(IN USHORT ControlRegister); + STATIC XTCDECL ULONG_PTR ReadDebugRegister(IN USHORT DebugRegister); + STATIC XTCDECL ULONG ReadFSDualWord(ULONG Offset); + STATIC XTCDECL ULONGLONG ReadModelSpecificRegister(IN ULONG Register); + STATIC XTCDECL UINT ReadMxCsrRegister(VOID); + STATIC XTCDECL ULONGLONG ReadTimeStampCounter(VOID); + STATIC XTCDECL VOID ReadWriteBarrier(VOID); + STATIC XTCDECL VOID SetInterruptFlag(VOID); + STATIC XTCDECL VOID StoreGlobalDescriptorTable(OUT PVOID Destination); + STATIC XTCDECL VOID StoreInterruptDescriptorTable(OUT PVOID Destination); + STATIC XTCDECL VOID StoreLocalDescriptorTable(OUT PVOID Destination); + STATIC XTCDECL VOID StoreSegment(IN USHORT Segment, + OUT PVOID Destination); + STATIC XTCDECL VOID StoreTaskRegister(OUT PVOID Destination); + STATIC XTCDECL VOID WriteControlRegister(IN USHORT ControlRegister, + IN UINT_PTR Value); + STATIC XTCDECL VOID WriteDebugRegister(IN USHORT DebugRegister, + IN UINT_PTR Value); + STATIC XTCDECL VOID WriteEflagsRegister(IN UINT_PTR Value); + STATIC XTCDECL VOID WriteModelSpecificRegister(IN ULONG Register, + IN ULONGLONG Value); + STATIC XTCDECL VOID YieldProcessor(VOID); + }; +} + +#endif /* __XTOSKRNL_AR_CPUFUNC_HH */ diff --git a/xtoskrnl/includes/ar/i686/procsup.hh b/xtoskrnl/includes/ar/i686/procsup.hh new file mode 100644 index 0000000..dffc056 --- /dev/null +++ b/xtoskrnl/includes/ar/i686/procsup.hh @@ -0,0 +1,82 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ar/i686/procsup.hh + * DESCRIPTION: Architecture-specific routines for i686 processor initialization and system structure setup + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_AR_PROCSUP_HH +#define __XTOSKRNL_AR_PROCSUP_HH + +#include + + +/* Architecture-specific Library */ +namespace AR +{ + class ProcSup + { + private: + STATIC UCHAR BootStack[KERNEL_STACK_SIZE]; + STATIC UCHAR DoubleFaultTss[KTSS_IO_MAPS]; + STATIC UCHAR FaultStack[KERNEL_STACK_SIZE]; + STATIC KGDTENTRY InitialGdt[GDT_ENTRIES]; + STATIC KIDTENTRY InitialIdt[IDT_ENTRIES]; + STATIC KPROCESSOR_BLOCK InitialProcessorBlock; + STATIC KTSS InitialTss; + STATIC UCHAR NonMaskableInterruptTss[KTSS_IO_MAPS]; + + + public: + STATIC XTAPI PVOID GetBootStack(VOID); + STATIC XTAPI VOID GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType, + OUT PVOID *TrampolineCode, + OUT PULONG_PTR TrampolineSize); + STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures); + + private: + STATIC XTAPI VOID IdentifyProcessor(VOID); + STATIC XTAPI VOID InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock); + STATIC XTAPI VOID InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock); + STATIC XTAPI VOID InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, + IN PKGDTENTRY Gdt, + IN PKIDTENTRY Idt, + IN PKTSS Tss, + IN PVOID DpcStack); + STATIC XTAPI VOID InitializeProcessorRegisters(VOID); + STATIC XTAPI VOID InitializeProcessorStructures(IN PVOID ProcessorStructures, + OUT PKGDTENTRY *Gdt, + OUT PKTSS *Tss, + OUT PKPROCESSOR_BLOCK *ProcessorBlock, + OUT PVOID *KernelBootStack, + OUT PVOID *KernelFaultStack); + STATIC XTAPI VOID InitializeSegments(VOID); + STATIC XTAPI VOID InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, + IN PVOID KernelBootStack, + IN PVOID KernelFaultStack); + STATIC XTAPI VOID SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, + IN PVOID KernelFaultStack); + STATIC XTAPI VOID SetGdtEntry(IN PKGDTENTRY Gdt, + IN USHORT Selector, + IN ULONG_PTR Base, + IN ULONG Limit, + IN UCHAR Type, + IN UCHAR Dpl, + IN UCHAR SegmentMode); + STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt, + IN USHORT Selector, + IN ULONG_PTR Base); + STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt, + IN USHORT Vector, + IN PVOID Handler, + IN USHORT Selector, + IN USHORT Ist, + IN USHORT Access); + STATIC XTAPI VOID SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, + IN PVOID KernelFaultStack); + + }; +} + +#endif /* __XTOSKRNL_AR_PROCSUP_HH */ diff --git a/xtoskrnl/includes/ar/i686/traps.hh b/xtoskrnl/includes/ar/i686/traps.hh new file mode 100644 index 0000000..a256257 --- /dev/null +++ b/xtoskrnl/includes/ar/i686/traps.hh @@ -0,0 +1,52 @@ +/**@s + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ar/i686/traps.hh + * DESCRIPTION: Trap handling routines and the dispatcher for processor exceptions + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_AR_TRAPS_HH +#define __XTOSKRNL_AR_TRAPS_HH + +#include + + +/* Architecture-specific Library */ +namespace AR +{ + class Traps + { + public: + STATIC XTCDECL VOID DispatchTrap(IN PKTRAP_FRAME TrapFrame); + + private: + STATIC XTCDECL VOID HandleTrap00(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap01(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap02(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap03(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap04(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap05(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap06(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap07(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap08(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap09(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap0A(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap0B(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap0C(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap0D(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap0E(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap10(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap11(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap12(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap13(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap2A(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap2B(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap2C(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap2D(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrap2E(IN PKTRAP_FRAME TrapFrame); + STATIC XTCDECL VOID HandleTrapFF(IN PKTRAP_FRAME TrapFrame); + }; +} + +#endif /* __XTOSKRNL_AR_TRAPS_HH */ diff --git a/xtoskrnl/includes/ex.hh b/xtoskrnl/includes/ex.hh new file mode 100644 index 0000000..747bd2f --- /dev/null +++ b/xtoskrnl/includes/ex.hh @@ -0,0 +1,16 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ex.hh + * DESCRIPTION: Kernel Executive + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_EX_HH +#define __XTOSKRNL_EX_HH + +#include + +#include + +#endif /* __XTOSKRNL_EX_HH */ diff --git a/xtoskrnl/includes/ex/rundown.hh b/xtoskrnl/includes/ex/rundown.hh new file mode 100644 index 0000000..b7d617f --- /dev/null +++ b/xtoskrnl/includes/ex/rundown.hh @@ -0,0 +1,30 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ex/rundown.hh + * DESCRIPTION: Rundown protection mechanism + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_EX_RUNDOWN_HH +#define __XTOSKRNL_EX_RUNDOWN_HH + +#include + + +/* Architecture-specific Library */ +namespace EX +{ + class Rundown + { + public: + STATIC XTFASTCALL BOOLEAN AcquireProtection(IN PEX_RUNDOWN_REFERENCE Descriptor); + STATIC XTFASTCALL VOID CompleteProtection(IN PEX_RUNDOWN_REFERENCE Descriptor); + STATIC XTFASTCALL VOID InitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor); + STATIC XTFASTCALL VOID ReInitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor); + STATIC XTFASTCALL VOID ReleaseProtection(IN PEX_RUNDOWN_REFERENCE Descriptor); + STATIC XTFASTCALL VOID WaitForProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor); + }; +} + +#endif /* __XTOSKRNL_EX_RUNDOWN_HH */ diff --git a/xtoskrnl/includes/globals.h b/xtoskrnl/includes/globals.h deleted file mode 100644 index 0c45bfe..0000000 --- a/xtoskrnl/includes/globals.h +++ /dev/null @@ -1,115 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/includes/globals.h - * DESCRIPTION: XT kernel global variables - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTOSKRNL_GLOBALS_H -#define __XTOSKRNL_GLOBALS_H - -#include - - -/* ACPI tables cache list */ -EXTERN LIST_ENTRY HlpAcpiCacheList; - -/* ACPI Root System Description Pointer (RSDP) */ -EXTERN PACPI_RSDP HlpAcpiRsdp; - -/* ACPI timer information */ -EXTERN ACPI_TIMER_INFO HlpAcpiTimerInfo; - -/* Active processors count */ -EXTERN KAFFINITY HlpActiveProcessors; - -/* APIC mode */ -EXTERN APIC_MODE HlpApicMode; - -/* FrameBuffer information */ -EXTERN HL_FRAMEBUFFER_DATA HlpFrameBufferData; - -/* Scroll region information */ -EXTERN HL_SCROLL_REGION_DATA HlpScrollRegionData; - -/* System information */ -EXTERN ACPI_SYSTEM_INFO HlpSystemInfo; - -/* Pointer to DbgPrint() routine */ -EXTERN PKD_PRINT_ROUTINE KdPrint; - -/* Kernel Debugger mode */ -EXTERN KD_DEBUG_MODE KdpDebugMode; - -/* Debugger I/O providers initialization routines */ -EXTERN PKD_INIT_ROUTINE KdpIoProvidersInitRoutines[KDBG_PROVIDERS_COUNT]; - -/* List of active I/O providers */ -EXTERN LIST_ENTRY KdpProviders; - -/* Debugger's serial port handle */ -EXTERN CPPORT KdpSerialPort; - -/* Pre-defined serial port addresses */ -EXTERN ULONG KdpSerialPortList[COMPORT_COUNT]; - - -/* Kernel initialization block passed by boot loader */ -EXTERN PKERNEL_INITIALIZATION_BLOCK KeInitializationBlock; - -/* Kernel initial process */ -EXTERN EPROCESS KeInitialProcess; - -/* Kernel initial thread */ -EXTERN ETHREAD KeInitialThread; - -/* Kernel service descriptor table */ -EXTERN KSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable[KSERVICE_TABLES_COUNT]; - -/* Kernel process list */ -EXTERN LIST_ENTRY KepProcessListHead; - -/* Kernel system resources list */ -EXTERN LIST_ENTRY KepSystemResourcesListHead; - -/* Kernel system resources lock */ -EXTERN KSPIN_LOCK KepSystemResourcesLock; - -/* Kernel UBSAN active frame flag */ -EXTERN BOOLEAN KepUbsanActiveFrame; - -/* Biggest free memory descriptor */ -EXTERN PLOADER_MEMORY_DESCRIPTOR MmFreeDescriptor; - -/* Highest physical page number */ -EXTERN ULONG_PTR MmHighestPhysicalPage; - -/* Lowest physical page number */ -EXTERN ULONG_PTR MmLowestPhysicalPage; - -/* Number of physical pages */ -EXTERN ULONG MmNumberOfPhysicalPages; - -/* Old biggest free memory descriptor */ -EXTERN LOADER_MEMORY_DESCRIPTOR MmOldFreeDescriptor; - -/* Processor structures data (THIS IS A TEMPORARY HACK) */ -EXTERN UCHAR MmProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE]; - -/* Allocation descriptors dedicated for hardware layer */ -EXTERN LOADER_MEMORY_DESCRIPTOR MmpHardwareAllocationDescriptors[MM_HARDWARE_ALLOCATION_DESCRIPTORS]; - -/* Live address of kernel's hardware heap */ -EXTERN PVOID MmpHardwareHeapStart; - -/* Information about the current page map */ -EXTERN MMPAGEMAP_INFO MmpPageMapInfo; - -/* Pointers to page map routines for the current paging mode */ -EXTERN PCMMPAGEMAP_ROUTINES MmpPageMapRoutines; - -/* Number of used hardware allocation descriptors */ -EXTERN ULONG MmpUsedHardwareAllocationDescriptors; - -#endif /* __XTOSKRNL_GLOBALS_H */ diff --git a/xtoskrnl/includes/hl.hh b/xtoskrnl/includes/hl.hh new file mode 100644 index 0000000..fd76ffc --- /dev/null +++ b/xtoskrnl/includes/hl.hh @@ -0,0 +1,25 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/hl.hh + * DESCRIPTION: Hardware Layer + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_HL_HH +#define __XTOSKRNL_HL_HH + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#endif /* __XTOSKRNL_HL_HH */ diff --git a/xtoskrnl/includes/hl/acpi.hh b/xtoskrnl/includes/hl/acpi.hh new file mode 100644 index 0000000..227cf0f --- /dev/null +++ b/xtoskrnl/includes/hl/acpi.hh @@ -0,0 +1,48 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/hl/acpi.hh + * DESCRIPTION: Advanced Configuration and Power Interface (ACPI) support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_HL_ACPI_HH +#define __XTOSKRNL_HL_ACPI_HH + +#include + + +/* Hardware Layer */ +namespace HL +{ + class Acpi + { + private: + STATIC LIST_ENTRY CacheList; + STATIC PACPI_RSDP RsdpStructure; + STATIC ACPI_SYSTEM_INFO SystemInfo; + STATIC ACPI_TIMER_INFO TimerInfo; + + public: + STATIC XTAPI XTSTATUS GetAcpiSystemDescriptionPointer(OUT PACPI_RSDP *Rsdp); + STATIC XTAPI XTSTATUS GetAcpiTable(IN ULONG Signature, + OUT PACPI_DESCRIPTION_HEADER *AcpiTable); + STATIC XTAPI XTSTATUS InitializeAcpi(VOID); + STATIC XTAPI XTSTATUS InitializeAcpiSystemInformation(VOID); + + private: + STATIC XTAPI VOID CacheAcpiTable(IN PACPI_DESCRIPTION_HEADER AcpiTable); + STATIC XTAPI XTSTATUS InitializeAcpiCache(VOID); + STATIC XTAPI XTSTATUS InitializeAcpiSystemDescriptionTable(OUT PACPI_DESCRIPTION_HEADER *AcpiTable); + STATIC XTAPI XTSTATUS InitializeAcpiSystemStructure(VOID); + STATIC XTAPI XTSTATUS InitializeAcpiTimer(VOID); + STATIC XTAPI XTSTATUS QueryAcpiCache(IN ULONG Signature, + OUT PACPI_DESCRIPTION_HEADER *AcpiTable); + STATIC XTAPI XTSTATUS QueryAcpiTables(IN ULONG Signature, + OUT PACPI_DESCRIPTION_HEADER *AcpiTable); + STATIC XTAPI BOOLEAN ValidateAcpiTable(IN PVOID Buffer, + IN UINT_PTR Size); + }; +} + +#endif /* __XTOSKRNL_HL_ACPI_HH */ diff --git a/xtoskrnl/includes/hl/cport.hh b/xtoskrnl/includes/hl/cport.hh new file mode 100644 index 0000000..0d7280c --- /dev/null +++ b/xtoskrnl/includes/hl/cport.hh @@ -0,0 +1,35 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/hl/cpu.hh + * DESCRIPTION: Serial (COM) port support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_HL_CPORT_HH +#define __XTOSKRNL_HL_CPORT_HH + +#include + + +/* Hardware Layer */ +namespace HL +{ + class ComPort + { + public: + STATIC XTCDECL XTSTATUS ReadComPort(IN PCPPORT Port, + OUT PUCHAR Byte, + IN BOOLEAN Wait, + IN BOOLEAN Poll); + STATIC XTCDECL UCHAR ReadComPortLsr(IN PCPPORT Port, + IN UCHAR Byte); + STATIC XTCDECL XTSTATUS InitializeComPort(IN OUT PCPPORT Port, + IN PUCHAR PortAddress, + IN ULONG BaudRate); + STATIC XTCDECL XTSTATUS WriteComPort(IN PCPPORT Port, + IN UCHAR Byte); + }; +} + +#endif /* __XTOSKRNL_HL_CPORT_HH */ diff --git a/xtoskrnl/includes/hl/cpu.hh b/xtoskrnl/includes/hl/cpu.hh new file mode 100644 index 0000000..bb9201a --- /dev/null +++ b/xtoskrnl/includes/hl/cpu.hh @@ -0,0 +1,27 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/hl/cpu.hh + * DESCRIPTION: HAL processor support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_HL_CPU_HH +#define __XTOSKRNL_HL_CPU_HH + +#include + + +/* Hardware Layer */ +namespace HL +{ + class Cpu + { + private: + STATIC KAFFINITY ActiveProcessors; + public: + STATIC XTAPI VOID InitializeProcessor(VOID); + }; +} + +#endif /* __XTOSKRNL_HL_CPU_HH */ diff --git a/xtoskrnl/includes/hl/fbdev.hh b/xtoskrnl/includes/hl/fbdev.hh new file mode 100644 index 0000000..f6b7c7a --- /dev/null +++ b/xtoskrnl/includes/hl/fbdev.hh @@ -0,0 +1,50 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/hl/fbdev.hh + * DESCRIPTION: FrameBuffer support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_HL_FBDEV_HH +#define __XTOSKRNL_HL_FBDEV_HH + +#include + + +/* Hardware Layer */ +namespace HL +{ + class FrameBuffer + { + private: + STATIC HL_FRAMEBUFFER_DATA FrameBufferData; + STATIC HL_SCROLL_REGION_DATA ScrollRegionData; + + public: + STATIC XTAPI VOID ClearScreen(IN ULONG Color); + STATIC XTCDECL XTSTATUS DisplayCharacter(IN WCHAR Character); + STATIC XTAPI VOID GetFrameBufferResolution(OUT PULONG Width, + OUT PULONG Height); + STATIC XTAPI XTSTATUS InitializeFrameBuffer(VOID); + STATIC XTAPI VOID InitializeScrollRegion(IN ULONG Left, + IN ULONG Top, + IN ULONG Right, + IN ULONG Bottom, + IN ULONG FontColor); + + + private: + STATIC XTAPI VOID DrawCharacter(IN ULONG PositionX, + IN ULONG PositionY, + IN ULONG Color, + IN WCHAR WideCharacter); + STATIC XTAPI VOID DrawPixel(IN ULONG PositionX, + IN ULONG PositionY, + IN ULONG Color); + STATIC XTAPI ULONG GetRGBColor(IN ULONG Color); + STATIC XTAPI VOID ScrollRegion(VOID); + }; +} + +#endif /* __XTOSKRNL_HL_FBDEV_HH */ diff --git a/xtoskrnl/includes/hl/init.hh b/xtoskrnl/includes/hl/init.hh new file mode 100644 index 0000000..8185616 --- /dev/null +++ b/xtoskrnl/includes/hl/init.hh @@ -0,0 +1,25 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/hl/init.hh + * DESCRIPTION: Hardware layer initialization + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_HL_INIT_HH +#define __XTOSKRNL_HL_INIT_HH + +#include + + +/* Hardware Layer */ +namespace HL +{ + class Init + { + public: + STATIC XTAPI XTSTATUS InitializeSystem(VOID); + }; +} + +#endif /* __XTOSKRNL_HL_INIT_HH */ diff --git a/xtoskrnl/includes/hl/ioport.hh b/xtoskrnl/includes/hl/ioport.hh new file mode 100644 index 0000000..0eb1d97 --- /dev/null +++ b/xtoskrnl/includes/hl/ioport.hh @@ -0,0 +1,33 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/hl/ioport.hh + * DESCRIPTION: I/O port access routines + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_HL_IOPORT_HH +#define __XTOSKRNL_HL_IOPORT_HH + +#include + + +/* Hardware Layer */ +namespace HL +{ + 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); + }; +} + +#endif /* __XTOSKRNL_HL_IOPORT_HH */ diff --git a/xtoskrnl/includes/hl/ioreg.hh b/xtoskrnl/includes/hl/ioreg.hh new file mode 100644 index 0000000..b1b98ee --- /dev/null +++ b/xtoskrnl/includes/hl/ioreg.hh @@ -0,0 +1,33 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/hl/ioreg.hh + * DESCRIPTION: Basic I/O registers access functionality + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_HL_IOREG_HH +#define __XTOSKRNL_HL_IOREG_HH + +#include + + +/* Hardware Layer */ +namespace HL +{ + class IoRegister + { + public: + STATIC XTAPI UCHAR ReadRegister8(IN PVOID Register); + STATIC XTAPI USHORT ReadRegister16(IN PVOID Register); + STATIC XTAPI ULONG ReadRegister32(IN PVOID Register); + STATIC XTAPI VOID WriteRegister8(IN PVOID Register, + IN UCHAR Value); + STATIC XTAPI VOID WriteRegister16(IN PVOID Register, + IN USHORT Value); + STATIC XTAPI VOID WriteRegister32(IN PVOID Register, + IN ULONG Value); + }; +} + +#endif /* __XTOSKRNL_HL_IOREG_HH */ diff --git a/xtoskrnl/includes/hl/pic.hh b/xtoskrnl/includes/hl/pic.hh new file mode 100644 index 0000000..85b8fca --- /dev/null +++ b/xtoskrnl/includes/hl/pic.hh @@ -0,0 +1,43 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/hl/pic.hh + * DESCRIPTION: HAL processor support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_HL_PIC_HH +#define __XTOSKRNL_HL_PIC_HH + +#include + + +/* Hardware Layer */ +namespace HL +{ + class Pic + { + private: + STATIC APIC_MODE ApicMode; + + public: + STATIC XTAPI VOID ClearApicErrors(VOID); + STATIC XTAPI ULONG GetCpuApicId(VOID); + STATIC XTAPI VOID InitializePic(VOID); + STATIC XTFASTCALL ULONGLONG ReadApicRegister(IN APIC_REGISTER Register); + STATIC XTAPI VOID SendEoi(VOID); + STATIC XTAPI VOID SendIpi(ULONG ApicId, + ULONG Vector); + STATIC XTFASTCALL VOID WriteApicRegister(IN APIC_REGISTER Register, + IN ULONGLONG Value); + + private: + STATIC XTAPI BOOLEAN CheckX2ApicSupport(VOID); + STATIC XTCDECL VOID HandleApicSpuriousService(VOID); + STATIC XTCDECL VOID HandlePicSpuriousService(VOID); + STATIC XTAPI VOID InitializeApic(VOID); + STATIC XTAPI VOID InitializeLegacyPic(VOID); + }; +} + +#endif /* __XTOSKRNL_HL_PIC_HH */ diff --git a/xtoskrnl/includes/hl/runlevel.hh b/xtoskrnl/includes/hl/runlevel.hh new file mode 100644 index 0000000..5283378 --- /dev/null +++ b/xtoskrnl/includes/hl/runlevel.hh @@ -0,0 +1,30 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/hl/runlevel.hh + * DESCRIPTION: Run Level management support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_HL_RUNLEVEL_HH +#define __XTOSKRNL_HL_RUNLEVEL_HH + +#include + + +/* Hardware Layer */ +namespace HL +{ + class RunLevel + { + public: + STATIC XTFASTCALL KRUNLEVEL GetRunLevel(VOID); + STATIC XTFASTCALL VOID SetRunLevel(IN KRUNLEVEL RunLevel); + + private: + STATIC XTFASTCALL KRUNLEVEL TransformApicTprToRunLevel(IN UCHAR Tpr); + STATIC XTFASTCALL UCHAR TransformRunLevelToApicTpr(IN KRUNLEVEL RunLevel); + }; +} + +#endif /* __XTOSKRNL_HL_RUNLEVEL_HH */ diff --git a/xtoskrnl/includes/hli.h b/xtoskrnl/includes/hli.h deleted file mode 100644 index effb6ba..0000000 --- a/xtoskrnl/includes/hli.h +++ /dev/null @@ -1,152 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/includes/hli.h - * DESCRIPTION: XT hardware abstraction layer routines - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTOSKRNL_HLI_H -#define __XTOSKRNL_HLI_H - -#include - - -/* HAL library routines forward references */ -XTAPI -VOID -HlClearScreen(IN ULONG Color); - -XTCDECL -XTSTATUS -HlComPortGetByte(IN PCPPORT Port, - OUT PUCHAR Byte, - IN BOOLEAN Wait, - IN BOOLEAN Poll); - -XTCDECL -XTSTATUS -HlComPortPutByte(IN PCPPORT Port, - IN UCHAR Byte); - -XTCDECL -UCHAR -HlComPortReadLsr(IN PCPPORT Port, - IN UCHAR Byte); - -XTCDECL -XTSTATUS -HlDisplayCharacter(IN WCHAR Character); - -XTAPI -XTSTATUS -HlGetAcpiSystemDescriptionPointer(OUT PACPI_RSDP *Rsdp); - -XTAPI -XTSTATUS -HlGetAcpiTable(IN ULONG Signature, - OUT PACPI_DESCRIPTION_HEADER *AcpiTable); - -XTAPI -VOID -HlGetFrameBufferResolution(OUT PULONG Width, OUT PULONG Height); - -XTFASTCALL -KRUNLEVEL -HlGetRunLevel(VOID); - -XTCDECL -XTSTATUS -HlInitializeComPort(IN OUT PCPPORT Port, - IN PUCHAR PortAddress, - IN ULONG BaudRate); - -XTAPI -XTSTATUS -HlInitializeFrameBuffer(VOID); - -XTAPI -VOID -HlInitializeProcessor(VOID); - -XTAPI -VOID -HlInitializeScrollRegion(IN ULONG Left, - IN ULONG Top, - IN ULONG Right, - IN ULONG Bottom, - IN ULONG FontColor); - -XTAPI -XTSTATUS -HlInitializeSystem(VOID); - -XTFASTCALL -VOID -HlSetRunLevel(IN KRUNLEVEL RunLevel); - -XTAPI -VOID -HlpCacheAcpiTable(IN PACPI_DESCRIPTION_HEADER AcpiTable); - -XTAPI -VOID -HlpDrawCharacter(IN ULONG PositionX, - IN ULONG PositionY, - IN ULONG Color, - IN WCHAR WideCharacter); - -XTAPI -VOID -HlpDrawPixel(IN ULONG PosX, - IN ULONG PosY, - IN ULONG Color); - -XTAPI -XTSTATUS -HlpInitializeAcpi(VOID); - -XTAPI -XTSTATUS -HlpInitializeAcpiCache(VOID); - -XTAPI -XTSTATUS -HlpInitializeAcpiSystemDescriptionTable(OUT PACPI_DESCRIPTION_HEADER *AcpiTable); - -XTAPI -XTSTATUS -HlpInitializeAcpiSystemInformation(VOID); - -XTAPI -XTSTATUS -HlpInitializeAcpiSystemStructure(VOID); - -XTAPI -XTSTATUS -HlpInitializeAcpiTimer(VOID); - -XTAPI -XTSTATUS -HlpQueryAcpiCache(IN ULONG Signature, - OUT PACPI_DESCRIPTION_HEADER *AcpiTable); - -XTAPI -XTSTATUS -HlpQueryAcpiTables(IN ULONG Signature, - OUT PACPI_DESCRIPTION_HEADER *AcpiTable); - -XTAPI -ULONG -HlpRGBColor(IN ULONG Color); - -XTAPI -VOID -HlpScrollRegion(VOID); - -XTAPI -BOOLEAN -HlpValidateAcpiTable(IN PVOID Buffer, - IN UINT_PTR Size); - -#endif /* __XTOSKRNL_HLI_H */ diff --git a/xtoskrnl/includes/i686/ari.h b/xtoskrnl/includes/i686/ari.h deleted file mode 100644 index 377e7f3..0000000 --- a/xtoskrnl/includes/i686/ari.h +++ /dev/null @@ -1,432 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/includes/i686/ari.h - * DESCRIPTION: I686 architecture library routines - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTOSKRNL_I686_ARI_H -#define __XTOSKRNL_I686_ARI_H - -#include - - -/* I686 architecture library routines forward references */ -XTCDECL -VOID -ArClearInterruptFlag(VOID); - -XTCDECL -BOOLEAN -ArCpuId(IN OUT PCPUID_REGISTERS Registers); - -XTCDECL -VOID -ArFlushTlb(VOID); - -XTCDECL -ULONG -ArGetCpuFlags(VOID); - -XTASSEMBLY -XTCDECL -ULONG_PTR -ArGetStackPointer(VOID); - -XTCDECL -VOID -ArHalt(VOID); - -XTAPI -VOID -ArInitializeProcessor(IN PVOID ProcessorStructures); - -XTCDECL -BOOLEAN -ArInterruptsEnabled(VOID); - -XTCDECL -VOID -ArInvalidateTlbEntry(IN PVOID Address); - -XTCDECL -VOID -ArLoadGlobalDescriptorTable(IN PVOID Source); - -XTCDECL -VOID -ArLoadInterruptDescriptorTable(IN PVOID Source); - -XTCDECL -VOID -ArLoadLocalDescriptorTable(IN USHORT Source); - -XTCDECL -VOID -ArLoadSegment(IN USHORT Segment, - IN ULONG Source); - -XTCDECL -VOID -ArLoadTaskRegister(IN USHORT Source); - -XTCDECL -VOID -ArMemoryBarrier(VOID); - -XTCDECL -ULONG_PTR -ArReadControlRegister(IN USHORT ControlRegister); - -XTCDECL -ULONG_PTR -ArReadDebugRegister(IN USHORT DebugRegister); - -XTCDECL -ULONG -ArReadFSDualWord(IN ULONG Offset); - -XTCDECL -ULONGLONG -ArReadModelSpecificRegister(IN ULONG Register); - -XTCDECL -UINT -ArReadMxCsrRegister(VOID); - -XTCDECL -ULONGLONG -ArReadTimeStampCounter(VOID); - -XTCDECL -VOID -ArReadWriteBarrier(VOID); - -XTAPI -VOID -ArSetGdtEntryBase(IN PKGDTENTRY Gdt, - IN USHORT Selector, - IN ULONG_PTR Base); - -XTCDECL -VOID -ArSetInterruptFlag(VOID); - -XTCDECL -VOID -ArStoreGlobalDescriptorTable(OUT PVOID Destination); - -XTCDECL -VOID -ArStoreInterruptDescriptorTable(OUT PVOID Destination); - -XTCDECL -VOID -ArStoreLocalDescriptorTable(OUT PVOID Destination); - -XTCDECL -VOID -ArStoreSegment(IN USHORT Segment, - OUT PVOID Destination); - -XTCDECL -VOID -ArStoreTaskRegister(OUT PVOID Destination); - -XTCDECL -VOID -ArWriteControlRegister(IN USHORT ControlRegister, - IN UINT_PTR Value); - -XTCDECL -VOID -ArWriteDebugRegister(IN USHORT DebugRegister, - IN UINT_PTR Value); - -XTCDECL -VOID -ArWriteEflagsRegister(IN UINT_PTR Value); - -XTCDECL -VOID -ArWriteModelSpecificRegister(IN ULONG Register, - IN ULONGLONG Value); - -XTCDECL -VOID -ArYieldProcessor(VOID); - -XTCDECL -VOID -ArpDispatchTrap(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap2A(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap2B(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrap2E(IN PKTRAP_FRAME TrapFrame); - -XTCDECL -VOID -ArpHandleTrapFF(IN PKTRAP_FRAME TrapFrame); - -XTAPI -VOID -ArpIdentifyProcessor(VOID); - -XTAPI -VOID -ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock); - -XTAPI -VOID -ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock); - -XTAPI -VOID -ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, - IN PKGDTENTRY Gdt, - IN PKIDTENTRY Idt, - IN PKTSS Tss, - IN PVOID DpcStack); - -XTAPI -VOID -ArpInitializeProcessorRegisters(VOID); - -XTAPI -VOID -ArpInitializeProcessorStructures(IN PVOID ProcessorStructures, - OUT PKGDTENTRY *Gdt, - OUT PKTSS *Tss, - OUT PKPROCESSOR_BLOCK *ProcessorBlock, - OUT PVOID *KernelBootStack, - OUT PVOID *KernelFaultStack); - -XTAPI -VOID -ArpInitializeSegments(VOID); - -XTAPI -VOID -ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, - IN PVOID KernelBootStack, - IN PVOID KernelFaultStack); - -XTAPI -VOID -ArpSetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, - IN PVOID KernelFaultStack); - -XTAPI -VOID -ArpSetGdtEntry(IN PKGDTENTRY Gdt, - IN USHORT Selector, - IN ULONG_PTR Base, - IN ULONG Limit, - IN UCHAR Type, - IN UCHAR Dpl, - IN UCHAR SegmentMode); - -XTAPI -VOID -ArpSetIdtGate(IN PKIDTENTRY Idt, - IN USHORT Vector, - IN PVOID Handler, - IN USHORT Selector, - IN USHORT Ist, - IN USHORT Access); - -XTAPI -VOID -ArpSetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, - IN PVOID KernelFaultStack); - -XTCDECL -VOID -ArpTrap0x00(VOID); - -XTCDECL -VOID -ArpTrap0x01(VOID); - -XTCDECL -VOID -ArpTrap0x02(VOID); - -XTCDECL -VOID -ArpTrap0x03(VOID); - -XTCDECL -VOID -ArpTrap0x04(VOID); - -XTCDECL -VOID -ArpTrap0x05(VOID); - -XTCDECL -VOID -ArpTrap0x06(VOID); - -XTCDECL -VOID -ArpTrap0x07(VOID); - -XTCDECL -VOID -ArpTrap0x08(VOID); - -XTCDECL -VOID -ArpTrap0x09(VOID); - -XTCDECL -VOID -ArpTrap0x0A(VOID); - -XTCDECL -VOID -ArpTrap0x0B(VOID); - -XTCDECL -VOID -ArpTrap0x0C(VOID); - -XTCDECL -VOID -ArpTrap0x0D(VOID); - -XTCDECL -VOID -ArpTrap0x0E(VOID); - -XTCDECL -VOID -ArpTrap0x10(VOID); - -XTCDECL -VOID -ArpTrap0x11(VOID); - -XTCDECL -VOID -ArpTrap0x12(VOID); - -XTCDECL -VOID -ArpTrap0x13(VOID); - -XTCDECL -VOID -ArpTrap0x2A(VOID); - -XTCDECL -VOID -ArpTrap0x2B(VOID); - -XTCDECL -VOID -ArpTrap0x2C(VOID); - -XTCDECL -VOID -ArpTrap0x2D(VOID); - -XTCDECL -VOID -ArpTrap0x2E(VOID); - -#endif /* __XTOSKRNL_I686_ARI_H */ diff --git a/xtoskrnl/includes/i686/globals.h b/xtoskrnl/includes/i686/globals.h deleted file mode 100644 index e5bf03e..0000000 --- a/xtoskrnl/includes/i686/globals.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/includes/i686/globals.h - * DESCRIPTION: XT kernel global variables related to i686 architecture - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTOSKRNL_I686_GLOBALS_H -#define __XTOSKRNL_I686_GLOBALS_H - -#include - - -/* Initial GDT */ -EXTERN KGDTENTRY ArInitialGdt[GDT_ENTRIES]; - -/* Initial IDT */ -EXTERN KIDTENTRY ArInitialIdt[IDT_ENTRIES]; - -/* Initial Processor Block */ -EXTERN KPROCESSOR_BLOCK ArInitialProcessorBlock; - -/* Initial TSS */ -EXTERN KTSS ArInitialTss; - -/* Double Fault and NMI task gates */ -EXTERN UCHAR ArpDoubleFaultTss[KTSS_IO_MAPS]; -EXTERN UCHAR ArpNonMaskableInterruptTss[KTSS_IO_MAPS]; - -/* Kernel own boot stack */ -EXTERN UCHAR ArKernelBootStack[KERNEL_STACK_SIZE]; - -/* Kernel own fault stack */ -EXTERN UCHAR ArKernelFaultStack[KERNEL_STACK_SIZE]; - -/* Page mapping routines for systems using 2-level paging (PML2) */ -EXTERN CMMPAGEMAP_ROUTINES MmpPml2Routines; - -/* Page mapping routines for systems using 3-level paging (PML3) */ -EXTERN CMMPAGEMAP_ROUTINES MmpPml3Routines; - -#endif /* __XTOSKRNL_I686_GLOBALS_H */ diff --git a/xtoskrnl/includes/i686/hli.h b/xtoskrnl/includes/i686/hli.h deleted file mode 100644 index 3ce4df4..0000000 --- a/xtoskrnl/includes/i686/hli.h +++ /dev/null @@ -1,74 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/includes/i686/hli.h - * DESCRIPTION: XT hardware abstraction layer routines specific to i686 architecture - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTOSKRNL_I686_HLI_H -#define __XTOSKRNL_I686_HLI_H - -#include - - -/* HAL library routines forward references */ -XTAPI -VOID -HlClearApicErrors(VOID); - -XTFASTCALL -ULONGLONG -HlReadApicRegister(IN APIC_REGISTER Register); - -XTAPI -VOID -HlSendEoi(VOID); - -XTFASTCALL -VOID -HlWriteApicRegister(IN APIC_REGISTER Register, - IN ULONGLONG Value); - -XTAPI -BOOLEAN -HlpCheckX2ApicSupport(VOID); - -XTAPI -ULONG -HlpGetCpuApicId(VOID); - -XTCDECL -VOID -HlpHandleApicSpuriousService(VOID); - -XTCDECL -VOID -HlpHandlePicSpuriousService(VOID); - -XTAPI -VOID -HlpInitializeApic(VOID); - -XTAPI -VOID -HlpInitializeLegacyPic(VOID); - -XTAPI -VOID -HlpInitializePic(VOID); - -XTAPI -VOID -HlpSendIpi(ULONG ApicId, - ULONG Vector); - -XTFASTCALL -KRUNLEVEL -HlpTransformApicTprToRunLevel(IN UCHAR Tpr); - -XTFASTCALL -UCHAR -HlpTransformRunLevelToApicTpr(IN KRUNLEVEL RunLevel); - -#endif /* __XTOSKRNL_I686_HLI_H */ diff --git a/xtoskrnl/includes/i686/kei.h b/xtoskrnl/includes/i686/kei.h deleted file mode 100644 index 5d37e6f..0000000 --- a/xtoskrnl/includes/i686/kei.h +++ /dev/null @@ -1,60 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/includes/i686/kei.h - * DESCRIPTION: XTOS kernel services routine definitions specific to i686 architecture - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTOSKRNL_I686_KEI_H -#define __XTOSKRNL_I686_KEI_H - -#include - - -/* I686 specific Kernel services routines forward references */ -XTAPI -PKPROCESSOR_BLOCK -KeGetCurrentProcessorBlock(VOID); - -XTAPI -PKPROCESSOR_CONTROL_BLOCK -KeGetCurrentProcessorControlBlock(VOID); - -XTAPI -ULONG -KeGetCurrentProcessorNumber(VOID); - -XTAPI -PKTHREAD -KeGetCurrentThread(VOID); - -XTAPI -VOID -KepInitializeKernel(VOID); - -XTAPI -VOID -KepInitializeMachine(VOID); - -XTAPI -VOID -KepInitializeThreadContext(IN PKTHREAD Thread, - IN PKSYSTEM_ROUTINE SystemRoutine, - IN PKSTART_ROUTINE StartRoutine, - IN PVOID StartContext, - IN PCONTEXT ContextRecord); - -XTAPI -VOID -KepSaveProcessorState(OUT PKPROCESSOR_STATE CpuState); - -XTAPI -VOID -KepStartKernel(VOID); - -XTAPI -VOID -KepSwitchBootStack(IN ULONG_PTR Stack); - -#endif /* __XTOSKRNL_I686_KEI_H */ diff --git a/xtoskrnl/includes/i686/mmi.h b/xtoskrnl/includes/i686/mmi.h deleted file mode 100644 index cc36a58..0000000 --- a/xtoskrnl/includes/i686/mmi.h +++ /dev/null @@ -1,81 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/includes/i686/mmi.h - * DESCRIPTION: XT memory manager routines specific to i686 architecture - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTOSKRNL_I686_MMI_H -#define __XTOSKRNL_I686_MMI_H - -#include - - -/* i686 Memory Manager routines forward references */ -XTAPI -VOID -MmInitializePageMapSupport(VOID); - -XTFASTCALL -VOID -MmZeroPages(IN PVOID Address, - IN ULONG Size); - -XTAPI -VOID -MmpClearPte(PHARDWARE_PTE PtePointer); - -XTAPI -BOOLEAN -MmpGetExtendedPhysicalAddressingStatus(VOID); - -XTAPI -PMMPDE -MmpGetPdeAddress(PVOID Address); - -XTAPI -PMMPPE -MmpGetPpeAddress(PVOID Address); - -XTAPI -PMMPTE -MmpGetPteAddress(PVOID Address); - -XTAPI -VOID -MmpInitializeArchitecture(VOID); - -XTAPI -BOOLEAN -MmpPml2PteValid(PHARDWARE_PTE PtePointer); - -XTAPI -VOID -MmpSetPml2Pte(PHARDWARE_PTE PtePointer, - PFN_NUMBER PageFrameNumber, - BOOLEAN Writable); - -XTAPI -VOID -MmpSetPml2PteCaching(PHARDWARE_PTE PtePointer, - BOOLEAN CacheDisable, - BOOLEAN WriteThrough); - -XTAPI -BOOLEAN -MmpPml3PteValid(PHARDWARE_PTE PtePointer); - -XTAPI -VOID -MmpSetPml3Pte(PHARDWARE_PTE PtePointer, - PFN_NUMBER PageFrameNumber, - BOOLEAN Writable); - -XTAPI -VOID -MmpSetPml3PteCaching(PHARDWARE_PTE PtePointer, - BOOLEAN CacheDisable, - BOOLEAN WriteThrough); - -#endif /* __XTOSKRNL_I686_MMI_H */ diff --git a/xtoskrnl/includes/i686/rtli.h b/xtoskrnl/includes/i686/rtli.h deleted file mode 100644 index d7fd287..0000000 --- a/xtoskrnl/includes/i686/rtli.h +++ /dev/null @@ -1,21 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/includes/i686/rtli.h - * DESCRIPTION: XT runtime library routines specific to i686 architecture - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTOSKRNL_I686_RTLI_H -#define __XTOSKRNL_I686_RTLI_H - -#include - - -/* Runtime Library routines specific to I686 forward references */ -XTAPI -VOID -RtlGetStackLimits(OUT PULONG_PTR StackBase, - OUT PULONG_PTR StackLimit); - -#endif /* __XTOSKRNL_I686_RTLI_H */ diff --git a/xtoskrnl/includes/kd.hh b/xtoskrnl/includes/kd.hh new file mode 100644 index 0000000..859cfc7 --- /dev/null +++ b/xtoskrnl/includes/kd.hh @@ -0,0 +1,17 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/kd.hh + * DESCRIPTION: Kernel Debugger + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KD_HH +#define __XTOSKRNL_KD_HH + +#include + +#include +#include + +#endif /* __XTOSKRNL_KD_HH */ diff --git a/xtoskrnl/includes/kd/dbg.hh b/xtoskrnl/includes/kd/dbg.hh new file mode 100644 index 0000000..3fae6c8 --- /dev/null +++ b/xtoskrnl/includes/kd/dbg.hh @@ -0,0 +1,23 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/kd/dbg.hh + * DESCRIPTION: Kernel debugging support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KD_DBG_HH +#define __XTOSKRNL_KD_DBG_HH + +#include + + +/* Redefine DebugPrint macro for the kernel to enable early debugging */ +#undef DebugPrint +#ifdef DBG + #define DebugPrint(Format, ...) if(KD::DebugIo::KdPrint) KD::DebugIo::KdPrint(Format, __VA_ARGS__); +#else + #define DebugPrint(Format, ...) ((VOID)NULLPTR) +#endif + +#endif /* __XTOSKRNL_KD_DBG_HH */ diff --git a/xtoskrnl/includes/kd/dbgio.hh b/xtoskrnl/includes/kd/dbgio.hh new file mode 100644 index 0000000..86aeaf8 --- /dev/null +++ b/xtoskrnl/includes/kd/dbgio.hh @@ -0,0 +1,46 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/kd/dbgio.hh + * DESCRIPTION: Kernel Debugger I/O support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KD_DBGIO_HH +#define __XTOSKRNL_KD_DBGIO_HH + +#include + + +/* Kernel Debugger */ +namespace KD +{ + class DebugIo + { + public: + STATIC PKD_PRINT_ROUTINE KdPrint; + + private: + STATIC KD_DEBUG_MODE DebugMode; + STATIC PKD_INIT_ROUTINE IoProvidersInitRoutines[KDBG_PROVIDERS_COUNT]; + STATIC LIST_ENTRY Providers; + STATIC CPPORT SerialPort; + STATIC ULONG SerialPortList[COMPORT_COUNT]; + + public: + STATIC XTCDECL VOID DbgPrint(PCWSTR Format, + ...); + STATIC XTCDECL VOID DbgPrintEx(PCWSTR Format, + VA_LIST Arguments); + STATIC XTAPI XTSTATUS InitializeDebugIoProviders(VOID); + STATIC XTAPI VOID SetPrintRoutine(PKD_PRINT_ROUTINE DebugPrintRoutine); + + private: + STATIC XTAPI XTSTATUS DetectDebugPorts(VOID); + STATIC XTAPI XTSTATUS InitializeFrameBufferProvider(VOID); + STATIC XTAPI XTSTATUS InitializeSerialPortProvider(VOID); + STATIC XTCDECL XTSTATUS SerialWriteCharacter(WCHAR Character); + }; +} + +#endif /* __XTOSKRNL_KD_DBGIO_HH */ diff --git a/xtoskrnl/includes/kdi.h b/xtoskrnl/includes/kdi.h deleted file mode 100644 index 6515273..0000000 --- a/xtoskrnl/includes/kdi.h +++ /dev/null @@ -1,44 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/includes/kdi.h - * DESCRIPTION: Kernel Debugger routines - * DEVELOPERS: Aiken Harris - */ - -#ifndef __XTOSKRNL_KDI_H -#define __XTOSKRNL_KDI_H - -#include - - -/* Kernel Debugger routines forward references */ -XTAPI -XTSTATUS -KdInitializeDebugIoProviders(VOID); - -XTAPI -VOID -KdSetPrintRoutine(PVOID DebugPrintRoutine); - -XTCDECL -VOID -KdpDebugPrint(PCWSTR Format, ...); - -XTAPI -XTSTATUS -KdpDetectDebugPorts(VOID); - -XTAPI -XTSTATUS -KdpInitializeFrameBufferProvider(VOID); - -XTAPI -XTSTATUS -KdpInitializeSerialPortProvider(VOID); - -XTCDECL -XTSTATUS -KdpSerialWriteCharacter(WCHAR Character); - -#endif /* __XTOSKRNL_KDI_H */ diff --git a/xtoskrnl/includes/ke.hh b/xtoskrnl/includes/ke.hh new file mode 100644 index 0000000..063a367 --- /dev/null +++ b/xtoskrnl/includes/ke.hh @@ -0,0 +1,31 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke.hh + * DESCRIPTION: Kernel Library + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_HH +#define __XTOSKRNL_KE_HH + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif /* __XTOSKRNL_KE_HH */ diff --git a/xtoskrnl/includes/ke/apc.hh b/xtoskrnl/includes/ke/apc.hh new file mode 100644 index 0000000..fc6c0cc --- /dev/null +++ b/xtoskrnl/includes/ke/apc.hh @@ -0,0 +1,32 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/apc.hh + * DESCRIPTION: Kernel APC objects support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_APC_HH +#define __XTOSKRNL_KE_APC_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class Apc + { + public: + STATIC XTAPI VOID InitializeApc(IN PKAPC Apc, + IN PKTHREAD Thread, + IN KAPC_ENVIRONMENT Environment, + IN PKKERNEL_ROUTINE KernelRoutine, + IN PKRUNDOWN_ROUTINE RundownRoutine, + IN PKNORMAL_ROUTINE NormalRoutine, + IN KPROCESSOR_MODE ApcMode, + IN PVOID Context); + }; +} + +#endif /* __XTOSKRNL_KE_APC_HH */ diff --git a/xtoskrnl/includes/ke/bootinfo.hh b/xtoskrnl/includes/ke/bootinfo.hh new file mode 100644 index 0000000..ff74497 --- /dev/null +++ b/xtoskrnl/includes/ke/bootinfo.hh @@ -0,0 +1,40 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/bootinfo.hh + * DESCRIPTION: Bootloader-provided system information handling support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_BOOTINFO_HH +#define __XTOSKRNL_KE_BOOTINFO_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class BootInformation + { + private: + STATIC PKERNEL_INITIALIZATION_BLOCK InitializationBlock; + + public: + STATIC XTAPI PKD_PRINT_ROUTINE GetDebugPrint(VOID); + STATIC XTAPI SYSTEM_FIRMWARE_TYPE GetFirmwareType(VOID); + STATIC XTAPI XTSTATUS GetKernelParameter(IN PCWSTR ParameterName, + OUT PCWSTR *Parameter); + STATIC XTAPI PLIST_ENTRY GetMemoryDescriptors(VOID); + STATIC XTAPI PLIST_ENTRY GetSystemResources(VOID); + STATIC XTAPI VOID InitializeInitializationBlock(IN PKERNEL_INITIALIZATION_BLOCK Block); + + /* TEMPORARY FOR COMPATIBILITY WITH C CODE */ + STATIC XTAPI PKERNEL_INITIALIZATION_BLOCK GetInitializationBlock(VOID) + { + return InitializationBlock; + } + }; +} + +#endif /* __XTOSKRNL_KE_BOOTINFO_HH */ diff --git a/xtoskrnl/includes/ke/crash.hh b/xtoskrnl/includes/ke/crash.hh new file mode 100644 index 0000000..88356ad --- /dev/null +++ b/xtoskrnl/includes/ke/crash.hh @@ -0,0 +1,31 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/crash.hh + * DESCRIPTION: System shutdown and kernel panic mechanism + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_CRASH_HH +#define __XTOSKRNL_KE_CRASH_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class Crash + { + public: + STATIC XTAPI VOID HaltSystem(VOID); + STATIC XTAPI VOID Panic(IN ULONG Code); + STATIC XTAPI VOID PanicEx(IN ULONG Code, + IN ULONG_PTR Parameter1, + IN ULONG_PTR Parameter2, + IN ULONG_PTR Parameter3, + IN ULONG_PTR Parameter4); + }; +} + +#endif /* __XTOSKRNL_KE_CRASH_HH */ diff --git a/xtoskrnl/includes/ke/dpc.hh b/xtoskrnl/includes/ke/dpc.hh new file mode 100644 index 0000000..e3266b6 --- /dev/null +++ b/xtoskrnl/includes/ke/dpc.hh @@ -0,0 +1,37 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/dpc.hh + * DESCRIPTION: Deferred Procedure Call (DPC) support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_DPC_HH +#define __XTOSKRNL_KE_DPC_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class Dpc + { + public: + STATIC XTAPI VOID InitializeDpc(IN PKDPC Dpc, + IN PKDEFERRED_ROUTINE DpcRoutine, + IN PVOID DpcContext); + STATIC XTAPI VOID InitializeThreadedDpc(IN PKDPC Dpc, + IN PKDEFERRED_ROUTINE DpcRoutine, + IN PVOID DpcContext); + STATIC XTAPI VOID SetTargetProcessor(IN PKDPC Dpc, + IN CCHAR Number); + STATIC XTAPI VOID SignalCallDone(IN PVOID SystemArgument); + STATIC XTAPI BOOLEAN SignalCallSynchronize(IN PVOID SystemArgument); + + private: + STATIC XTFASTCALL VOID RetireList(IN PKPROCESSOR_CONTROL_BLOCK Prcb); + }; +} + +#endif /* __XTOSKRNL_KE_DPC_HH */ diff --git a/xtoskrnl/includes/ke/event.hh b/xtoskrnl/includes/ke/event.hh new file mode 100644 index 0000000..74cdd4c --- /dev/null +++ b/xtoskrnl/includes/ke/event.hh @@ -0,0 +1,31 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/event.hh + * DESCRIPTION: Kernel events support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_EVENT_HH +#define __XTOSKRNL_KE_EVENT_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class Event + { + public: + STATIC XTAPI VOID ClearEvent(IN PKEVENT Event); + STATIC XTAPI VOID InitializeEvent(OUT PKEVENT Event, + IN KEVENT_TYPE EventType, + IN BOOLEAN InitialState); + STATIC XTAPI LONG SetEvent(IN PKEVENT Event, + IN KPRIORITY Increment, + IN BOOLEAN Wait); + }; +} + +#endif /* __XTOSKRNL_KE_EVENT_HH */ diff --git a/xtoskrnl/includes/ke/info.hh b/xtoskrnl/includes/ke/info.hh new file mode 100644 index 0000000..4ff789e --- /dev/null +++ b/xtoskrnl/includes/ke/info.hh @@ -0,0 +1,27 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/info.hh + * DESCRIPTION: Generic kernel information support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_INFO_HH +#define __XTOSKRNL_KE_INFO_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class Info + { + public: + STATIC XTAPI SYSTEM_FIRMWARE_TYPE GetFirmwareType(VOID); + STATIC XTAPI XTSTATUS GetKernelParameter(IN PCWSTR ParameterName, + OUT PCWSTR *Parameter); + }; +} + +#endif /* __XTOSKRNL_KE_INFO_HH */ diff --git a/xtoskrnl/includes/ke/irq.hh b/xtoskrnl/includes/ke/irq.hh new file mode 100644 index 0000000..8817fe2 --- /dev/null +++ b/xtoskrnl/includes/ke/irq.hh @@ -0,0 +1,26 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/irq.hh + * DESCRIPTION: Kernel interrupts support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_IRQ_HH +#define __XTOSKRNL_KE_IRQ_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class Irq + { + public: + STATIC XTAPI VOID SetInterruptHandler(IN ULONG Vector, + IN PVOID Handler); + }; +} + +#endif /* __XTOSKRNL_KE_IRQ_HH */ diff --git a/xtoskrnl/includes/ke/kprocess.hh b/xtoskrnl/includes/ke/kprocess.hh new file mode 100644 index 0000000..ae7c370 --- /dev/null +++ b/xtoskrnl/includes/ke/kprocess.hh @@ -0,0 +1,33 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/kprocess.hh + * DESCRIPTION: XT kernel process manipulation support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_KPROCESS_HH +#define __XTOSKRNL_KE_KPROCESS_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class KProcess + { + private: + STATIC EPROCESS InitialProcess; + + public: + STATIC XTAPI PEPROCESS GetInitialProcess(VOID); + STATIC XTAPI VOID InitializeProcess(IN OUT PKPROCESS Process, + IN KPRIORITY Priority, + IN KAFFINITY Affinity, + IN PULONG_PTR DirectoryTable, + IN BOOLEAN Alignment); + }; +} + +#endif /* __XTOSKRNL_KE_KPROCESS_HH */ diff --git a/xtoskrnl/includes/ke/krnlinit.hh b/xtoskrnl/includes/ke/krnlinit.hh new file mode 100644 index 0000000..e92ccee --- /dev/null +++ b/xtoskrnl/includes/ke/krnlinit.hh @@ -0,0 +1,30 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/krnlinit.hh + * DESCRIPTION: XTOS Kernel initialization + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_KRNLINIT_HH +#define __XTOSKRNL_KE_KRNLINIT_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class KernelInit + { + public: + STATIC XTAPI VOID InitializeMachine(VOID); + STATIC XTAPI VOID SwitchBootStack(VOID); + + private: + STATIC XTAPI VOID InitializeKernel(VOID); + STATIC XTAPI VOID StartKernel(VOID); + }; +} + +#endif /* __XTOSKRNL_KE_KRNLINIT_HH */ diff --git a/xtoskrnl/includes/ke/kthread.hh b/xtoskrnl/includes/ke/kthread.hh new file mode 100644 index 0000000..f924e71 --- /dev/null +++ b/xtoskrnl/includes/ke/kthread.hh @@ -0,0 +1,55 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/kthread.hh + * DESCRIPTION: XT kernel thread manipulation support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_KTHREAD_HH +#define __XTOSKRNL_KE_KTHREAD_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class KThread + { + private: + STATIC ETHREAD InitialThread; + + public: + STATIC XTFASTCALL VOID ExitDispatcher(IN KRUNLEVEL OldRunLevel); + STATIC XTAPI PETHREAD GetInitialThread(VOID); + STATIC XTAPI XTSTATUS InitializeThread(IN PKPROCESS Process, + IN OUT PKTHREAD Thread, + IN PKSYSTEM_ROUTINE SystemRoutine, + IN PKSTART_ROUTINE StartRoutine, + IN PVOID StartContext, + IN PCONTEXT Context, + IN PVOID EnvironmentBlock, + IN PVOID Stack, + IN BOOLEAN StartThread); + STATIC XTAPI VOID StartThread(IN PKTHREAD Thread); + + private: + STATIC XTAPI VOID InitializeThreadContext(IN PKTHREAD Thread, + IN PKSYSTEM_ROUTINE SystemRoutine, + IN PKSTART_ROUTINE StartRoutine, + IN PVOID StartContext, + IN PCONTEXT ContextRecord); + STATIC XTAPI VOID SuspendNop(IN PKAPC Apc, + IN OUT PKNORMAL_ROUTINE *NormalRoutine, + IN OUT PVOID *NormalContext, + IN OUT PVOID *SystemArgument1, + IN OUT PVOID *SystemArgument2); + STATIC XTAPI VOID SuspendRundown(IN PKAPC Apc); + STATIC XTAPI VOID SuspendThread(IN PVOID NormalContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2); + }; +} + +#endif /* __XTOSKRNL_KE_KTHREAD_HH */ diff --git a/xtoskrnl/includes/ke/kubsan.hh b/xtoskrnl/includes/ke/kubsan.hh new file mode 100644 index 0000000..34bd2a8 --- /dev/null +++ b/xtoskrnl/includes/ke/kubsan.hh @@ -0,0 +1,67 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/kubsan.hh + * DESCRIPTION: Kernel Undefined Behaviour Sanitizer (UBSAN) error reporting handler + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_KUBSAN_HH +#define __XTOSKRNL_KE_KUBSAN_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class KUbsan + { + private: + STATIC BOOLEAN ActiveFrame; + + public: + STATIC XTCDECL VOID HandleDivisionOverflow(PKUBSAN_OVERFLOW_DATA Data, + PVOID Lhs, + PVOID Rhs); + STATIC XTCDECL VOID HandleFloatCastOverflow(PKUBSAN_FLOAT_CAST_OVERFLOW_DATA Data, + ULONG_PTR Lhs, + ULONG_PTR Rhs); + STATIC XTCDECL VOID HandleFunctionTypeMismatch(PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA Data, + ULONG_PTR Pointer); + STATIC XTCDECL VOID HandleIntegerOverflow(PKUBSAN_OVERFLOW_DATA Data, + ULONG_PTR Lhs, + ULONG_PTR Rhs); + STATIC XTCDECL VOID HandleInvalidBuiltin(PKUBSAN_INVALID_BUILTIN_DATA Data); + STATIC XTCDECL VOID HandleMisalignedAccess(PKUBSAN_TYPE_MISMATCH_DATA Data, + ULONG_PTR Pointer); + STATIC XTCDECL VOID HandleNegateOverflow(PKUBSAN_OVERFLOW_DATA Data, + ULONG_PTR OldValue); + STATIC XTCDECL VOID HandleNullPointerDereference(PKUBSAN_TYPE_MISMATCH_DATA Data); + STATIC XTCDECL VOID HandleObjectSizeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data, + ULONG_PTR Pointer); + STATIC XTCDECL VOID HandleOutOfBounds(PKUBSAN_OUT_OF_BOUNDS_DATA Data, + ULONG_PTR Index); + STATIC XTCDECL VOID HandlePointerOverflow(PKUBSAN_OVERFLOW_DATA Data, + ULONG_PTR Lhs, + ULONG_PTR Rhs); + STATIC XTCDECL VOID HandleShiftOutOfBounds(PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA Data, + ULONG_PTR Lhs, + ULONG_PTR Rhs); + STATIC XTCDECL VOID HandleTypeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data, + ULONG_PTR Pointer); + + private: + STATIC XTCDECL BOOLEAN CheckReport(PKUBSAN_SOURCE_LOCATION Location); + STATIC XTCDECL VOID EnterFrame(PKUBSAN_SOURCE_LOCATION Location, + PCCHAR Reason); + STATIC XTCDECL LONGLONG GetSignedValue(PKUBSAN_TYPE_DESCRIPTOR Type, + PVOID Value); + STATIC XTCDECL PCCHAR GetTypeKind(UCHAR TypeCheckKind); + STATIC XTCDECL ULONGLONG GetUnsignedValue(PKUBSAN_TYPE_DESCRIPTOR Type, + PVOID Value); + STATIC XTCDECL VOID LeaveFrame(); + }; +} + +#endif /* __XTOSKRNL_KE_KUBSAN_HH */ diff --git a/xtoskrnl/includes/ke/proc.hh b/xtoskrnl/includes/ke/proc.hh new file mode 100644 index 0000000..08ee47a --- /dev/null +++ b/xtoskrnl/includes/ke/proc.hh @@ -0,0 +1,29 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/proc.hh + * DESCRIPTION: Processor-related functionality for the kernel + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_PROC_HH +#define __XTOSKRNL_KE_PROC_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class Processor + { + public: + STATIC XTAPI PKPROCESSOR_BLOCK GetCurrentProcessorBlock(VOID); + STATIC XTAPI PKPROCESSOR_CONTROL_BLOCK GetCurrentProcessorControlBlock(VOID); + STATIC XTAPI ULONG GetCurrentProcessorNumber(VOID); + STATIC XTAPI PKTHREAD GetCurrentThread(VOID); + STATIC XTAPI VOID SaveProcessorState(OUT PKPROCESSOR_STATE CpuState); + }; +} + +#endif /* __XTOSKRNL_KE_PROC_HH */ diff --git a/xtoskrnl/includes/ke/runlevel.hh b/xtoskrnl/includes/ke/runlevel.hh new file mode 100644 index 0000000..d3fca05 --- /dev/null +++ b/xtoskrnl/includes/ke/runlevel.hh @@ -0,0 +1,27 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/runlevel.hh + * DESCRIPTION: Running Level management support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_RUNLEVEL_HH +#define __XTOSKRNL_KE_RUNLEVEL_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class RunLevel + { + public: + STATIC XTFASTCALL KRUNLEVEL GetCurrentRunLevel(VOID); + STATIC XTFASTCALL VOID LowerRunLevel(IN KRUNLEVEL RunLevel); + STATIC XTFASTCALL KRUNLEVEL RaiseRunLevel(IN KRUNLEVEL RunLevel); + }; +} + +#endif /* __XTOSKRNL_KE_RUNLEVEL_HH */ diff --git a/xtoskrnl/includes/ke/semphore.hh b/xtoskrnl/includes/ke/semphore.hh new file mode 100644 index 0000000..50c7dfd --- /dev/null +++ b/xtoskrnl/includes/ke/semphore.hh @@ -0,0 +1,32 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/semphore.hh + * DESCRIPTION: Semaphores support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_SEMPHORE_HH +#define __XTOSKRNL_KE_SEMPHORE_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class Semaphore + { + public: + STATIC XTAPI VOID InitializeSemaphore(IN PKSEMAPHORE Semaphore, + IN LONG Count, + IN LONG Limit); + STATIC XTAPI LONG ReadState(IN PKSEMAPHORE Semaphore); + STATIC XTAPI LONG ReleaseSemaphore(IN PKSEMAPHORE Semaphore, + IN KPRIORITY Increment, + IN LONG Adjustment, + IN BOOLEAN Wait); + }; +} + +#endif /* __XTOSKRNL_KE_SEMPHORE_HH */ diff --git a/xtoskrnl/includes/ke/spinlock.hh b/xtoskrnl/includes/ke/spinlock.hh new file mode 100644 index 0000000..7efcbe2 --- /dev/null +++ b/xtoskrnl/includes/ke/spinlock.hh @@ -0,0 +1,29 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/spinlock.hh + * DESCRIPTION: Spinlocks support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_SPINLOCK_HH +#define __XTOSKRNL_KE_SPINLOCK_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class SpinLock + { + public: + STATIC XTFASTCALL VOID AcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel); + STATIC XTFASTCALL VOID AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock); + STATIC XTAPI VOID InitializeSpinLock(IN PKSPIN_LOCK SpinLock); + STATIC XTFASTCALL VOID ReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel); + STATIC XTFASTCALL VOID ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock); + }; +} + +#endif /* __XTOSKRNL_KE_SPINLOCK_HH */ diff --git a/xtoskrnl/includes/ke/sysres.hh b/xtoskrnl/includes/ke/sysres.hh new file mode 100644 index 0000000..b97603d --- /dev/null +++ b/xtoskrnl/includes/ke/sysres.hh @@ -0,0 +1,40 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/sysres.hh + * DESCRIPTION: System boot resources management + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_SYSRES_HH +#define __XTOSKRNL_KE_SYSRES_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class SystemResources + { + private: + STATIC LIST_ENTRY ResourcesListHead; + STATIC KSPIN_LOCK ResourcesLock; + + public: + STATIC XTAPI XTSTATUS AcquireResource(IN SYSTEM_RESOURCE_TYPE ResourceType, + OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader); + STATIC XTAPI XTSTATUS GetResource(IN SYSTEM_RESOURCE_TYPE ResourceType, + OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader); + STATIC XTAPI VOID InitializeResources(VOID); + STATIC XTAPI VOID ReleaseResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader); + + private: + STATIC XTAPI XTSTATUS GetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, + IN BOOLEAN ResourceLock, + OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader); + + }; +} + +#endif /* __XTOSKRNL_KE_SYSRES_HH */ diff --git a/xtoskrnl/includes/ke/timer.hh b/xtoskrnl/includes/ke/timer.hh new file mode 100644 index 0000000..55a5b6f --- /dev/null +++ b/xtoskrnl/includes/ke/timer.hh @@ -0,0 +1,37 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/timer.hh + * DESCRIPTION: Kernel timer object support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_TIMER_HH +#define __XTOSKRNL_KE_TIMER_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class Timer + { + public: + STATIC XTAPI BOOLEAN CancelTimer(IN PKTIMER Timer); + STATIC XTAPI VOID ClearTimer(IN PKTIMER Timer); + STATIC XTAPI BOOLEAN GetState(IN PKTIMER Timer); + STATIC XTAPI VOID InitializeTimer(OUT PKTIMER Timer, + IN KTIMER_TYPE Type); + STATIC XTAPI ULONGLONG QueryTimer(IN PKTIMER Timer); + STATIC XTAPI VOID SetTimer(IN PKTIMER Timer, + IN LARGE_INTEGER DueTime, + IN LONG Period, + IN PKDPC Dpc); + + private: + STATIC XTAPI VOID RemoveTimer(IN OUT PKTIMER Timer); + }; +} + +#endif /* __XTOSKRNL_KE_TIMER_HH */ diff --git a/xtoskrnl/includes/kei.h b/xtoskrnl/includes/kei.h deleted file mode 100644 index 76c0795..0000000 --- a/xtoskrnl/includes/kei.h +++ /dev/null @@ -1,233 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/includes/kei.h - * DESCRIPTION: XTOS kernel services routine definitions - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTOSKRNL_KEI_H -#define __XTOSKRNL_KEI_H - -#include - - -/* Kernel services routines forward references */ -XTAPI -VOID -KeClearEvent(IN PKEVENT Event); - -XTAPI -VOID -KeClearTimer(IN PKTIMER Timer); - -XTAPI -SYSTEM_FIRMWARE_TYPE -KeGetFirmwareType(VOID); - -XTAPI -XTSTATUS -KeGetKernelParameter(IN PCWSTR ParameterName, - OUT PCWSTR *Parameter); - -XTAPI -VOID -KeHaltSystem(VOID); - -XTAPI -VOID -KeInitializeEvent(OUT PKEVENT Event, - IN KEVENT_TYPE EventType, - IN BOOLEAN InitialState); - -XTAPI -VOID -KeInitializeProcess(IN OUT PKPROCESS Process, - IN KPRIORITY Priority, - IN KAFFINITY Affinity, - IN PULONG_PTR DirectoryTable, - IN BOOLEAN Alignment); - -XTAPI -XTSTATUS -KeInitializeThread(IN PKPROCESS Process, - IN OUT PKTHREAD Thread, - IN PKSYSTEM_ROUTINE SystemRoutine, - IN PKSTART_ROUTINE StartRoutine, - IN PVOID StartContext, - IN PCONTEXT Context, - IN PVOID EnvironmentBlock, - IN PVOID Stack, - IN BOOLEAN StartThread); - -XTAPI -VOID -KePanic(IN ULONG Code); - -XTAPI -VOID -KePanicEx(IN ULONG Code, - IN ULONG_PTR Parameter1, - IN ULONG_PTR Parameter2, - IN ULONG_PTR Parameter3, - IN ULONG_PTR Parameter4); - -XTAPI -ULONGLONG -KeQueryTimer(IN PKTIMER Timer); - -XTAPI -LONG -KeSetEvent(IN PKEVENT Event, - IN KPRIORITY Increment, - IN BOOLEAN Wait); - -XTAPI -VOID -KeSetInterruptHandler(IN ULONG Vector, - IN PVOID Handler); - -XTAPI -VOID -KeStartThread(IN PKTHREAD Thread); - -XTAPI -VOID -KeStartXtSystem(IN PKERNEL_INITIALIZATION_BLOCK Parameters); - -XTCDECL -BOOLEAN -KepCheckUbsanReport(PKUBSAN_SOURCE_LOCATION Location); - -XTCDECL -VOID -KepEnterUbsanFrame(PKUBSAN_SOURCE_LOCATION Location, - PCCHAR Reason); - -XTFASTCALL -VOID -KepExitDispatcher(IN KRUNLEVEL OldRunLevel); - -XTCDECL -LONGLONG -KepGetSignedUbsanValue(PKUBSAN_TYPE_DESCRIPTOR Type, - PVOID Value); - -XTAPI -XTSTATUS -KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, - IN BOOLEAN Acquire, - OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader); - -XTCDECL -PCCHAR -KepGetUbsanTypeKind(UCHAR TypeCheckKind); - -XTCDECL -ULONGLONG -KepGetUnsignedUbsanValue(PKUBSAN_TYPE_DESCRIPTOR Type, - PVOID Value); - -XTCDECL -VOID -KepHandleUbsanDivisionOverflow(PKUBSAN_OVERFLOW_DATA Data, - PVOID Lhs, - PVOID Rhs); - -XTCDECL -VOID -KepHandleUbsanFloatCastOverflow(PKUBSAN_FLOAT_CAST_OVERFLOW_DATA Data, - ULONG_PTR Lhs, - ULONG_PTR Rhs); - -XTCDECL -VOID -KepHandleUbsanFunctionTypeMismatch(PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA Data, - ULONG_PTR Pointer); - -XTCDECL -VOID -KepHandleUbsanIntegerOverflow(PKUBSAN_OVERFLOW_DATA Data, - ULONG_PTR Lhs, - ULONG_PTR Rhs); - -XTCDECL -VOID -KepHandleUbsanInvalidBuiltin(PKUBSAN_INVALID_BUILTIN_DATA Data); - -XTCDECL -VOID -KepHandleUbsanMisalignedAccess(PKUBSAN_TYPE_MISMATCH_DATA Data, - ULONG_PTR Pointer); - -XTCDECL -VOID -KepHandleUbsanNegateOverflow(PKUBSAN_OVERFLOW_DATA Data, - ULONG_PTR OldValue); - -XTCDECL -VOID -KepHandleUbsanNullPointerDereference(PKUBSAN_TYPE_MISMATCH_DATA Data); - -XTCDECL -VOID -KepHandleUbsanObjectSizeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data, - ULONG_PTR Pointer); - -XTCDECL -VOID -KepHandleUbsanOutOfBounds(PKUBSAN_OUT_OF_BOUNDS_DATA Data, - ULONG_PTR Index); - -XTCDECL -VOID -KepHandleUbsanPointerOverflow(PKUBSAN_OVERFLOW_DATA Data, - ULONG_PTR Lhs, - ULONG_PTR Rhs); - -XTCDECL -VOID -KepHandleUbsanShiftOutOfBounds(PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA Data, - ULONG_PTR Lhs, - ULONG_PTR Rhs); - -XTCDECL -VOID -KepHandleUbsanTypeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data, - ULONG_PTR Pointer); - -XTAPI -VOID -KepInitializeSystemResources(VOID); - -XTCDECL -VOID -KepLeaveUbsanFrame(); - -XTAPI -VOID -KepRemoveTimer(IN OUT PKTIMER Timer); - -XTFASTCALL -VOID -KepRetireDpcList(IN PKPROCESSOR_CONTROL_BLOCK Prcb); - -XTAPI -VOID -KepSuspendNop(IN PKAPC Apc, - IN OUT PKNORMAL_ROUTINE *NormalRoutine, - IN OUT PVOID *NormalContext, - IN OUT PVOID *SystemArgument1, - IN OUT PVOID *SystemArgument2); - -XTAPI -VOID -KepSuspendRundown(IN PKAPC Apc); - -XTAPI -VOID -KepSuspendThread(IN PVOID NormalContext, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2); - -#endif /* __XTOSKRNL_KEI_H */ diff --git a/xtoskrnl/includes/mm.hh b/xtoskrnl/includes/mm.hh new file mode 100644 index 0000000..8dbdfb5 --- /dev/null +++ b/xtoskrnl/includes/mm.hh @@ -0,0 +1,21 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/mm.hh + * DESCRIPTION: Memory Manager + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_MM_HH +#define __XTOSKRNL_MM_HH + +#include + +#include XTOS_ARCH_HEADER(mm, pagemap.hh) + +#include +#include +#include +#include + +#endif /* __XTOSKRNL_MM_HH */ diff --git a/xtoskrnl/includes/mm/amd64/pagemap.hh b/xtoskrnl/includes/mm/amd64/pagemap.hh new file mode 100644 index 0000000..79a4418 --- /dev/null +++ b/xtoskrnl/includes/mm/amd64/pagemap.hh @@ -0,0 +1,53 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/mm/pagemap.hh + * DESCRIPTION: Low-level support for page map manipulation + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_MM_PAGEMAP_HH +#define __XTOSKRNL_MM_PAGEMAP_HH + +#include + + +/* Memory Manager */ +namespace MM +{ + typedef class PageMap + { + protected: + MMPAGEMAP_INFO PageMapInfo; + + public: + XTAPI VOID ClearPte(PHARDWARE_PTE PtePointer); + XTAPI PMMP5E GetP5eAddress(PVOID Address); + XTAPI PMMPDE GetPdeAddress(PVOID Address); + XTAPI PMMPPE GetPpeAddress(PVOID Address); + XTAPI PMMPTE GetPteAddress(PVOID Address); + XTAPI PMMPXE GetPxeAddress(PVOID Address); + virtual XTAPI VOID InitializePageMapInfo(VOID) = 0; + XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer); + XTAPI VOID SetPte(PHARDWARE_PTE PtePointer, + PFN_NUMBER PageFrameNumber, + BOOLEAN Writable); + XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer, + BOOLEAN CacheDisable, + BOOLEAN WriteThrough); + } PAGEMAP, *PPAGEMAP; + + class PageMapBasic final : public PageMap + { + public: + XTAPI VOID InitializePageMapInfo(VOID); + }; + + class PageMapXpa final : public PageMap + { + public: + XTAPI VOID InitializePageMapInfo(VOID); + }; +} + +#endif /* __XTOSKRNL_MM_PAGEMAP_HH */ diff --git a/xtoskrnl/includes/mm/hlpool.hh b/xtoskrnl/includes/mm/hlpool.hh new file mode 100644 index 0000000..007605c --- /dev/null +++ b/xtoskrnl/includes/mm/hlpool.hh @@ -0,0 +1,44 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/mm/hlpool.hh + * DESCRIPTION: Hardware layer pool memory management + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_MM_HLPOOL_HH +#define __XTOSKRNL_MM_HLPOOL_HH + +#include + + +/* Memory Manager */ +namespace MM +{ + class HardwarePool + { + private: + STATIC LOADER_MEMORY_DESCRIPTOR HardwareAllocationDescriptors[MM_HARDWARE_ALLOCATION_DESCRIPTORS]; + STATIC PVOID HardwareHeapStart; + STATIC ULONG UsedHardwareAllocationDescriptors; + + public: + STATIC XTAPI XTSTATUS AllocateHardwareMemory(IN PFN_NUMBER PageCount, + IN BOOLEAN Aligned, + OUT PPHYSICAL_ADDRESS Buffer); + STATIC XTAPI XTSTATUS MapHardwareMemory(IN PHYSICAL_ADDRESS PhysicalAddress, + IN PFN_NUMBER PageCount, + IN BOOLEAN FlushTlb, + OUT PVOID *VirtualAddress); + STATIC XTAPI VOID MarkHardwareMemoryWriteThrough(IN PVOID VirtualAddress, + IN PFN_NUMBER PageCount); + STATIC XTAPI VOID RemapHardwareMemory(IN PVOID VirtualAddress, + IN PHYSICAL_ADDRESS PhysicalAddress, + IN BOOLEAN FlushTlb); + STATIC XTAPI XTSTATUS UnmapHardwareMemory(IN PVOID VirtualAddress, + IN PFN_NUMBER PageCount, + IN BOOLEAN FlushTlb); + }; +} + +#endif /* __XTOSKRNL_MM_HLPOOL_HH */ diff --git a/xtoskrnl/includes/mm/i686/pagemap.hh b/xtoskrnl/includes/mm/i686/pagemap.hh new file mode 100644 index 0000000..0ca1616 --- /dev/null +++ b/xtoskrnl/includes/mm/i686/pagemap.hh @@ -0,0 +1,65 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/mm/pagemap.hh + * DESCRIPTION: Low-level support for page map manipulation + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_MM_PAGEMAP_HH +#define __XTOSKRNL_MM_PAGEMAP_HH + +#include + + +/* Memory Manager */ +namespace MM +{ + typedef class PageMap + { + protected: + MMPAGEMAP_INFO PageMapInfo; + + public: + XTAPI VOID ClearPte(PHARDWARE_PTE PtePointer); + XTAPI PMMPDE GetPdeAddress(PVOID Address); + XTAPI PMMPPE GetPpeAddress(PVOID Address); + XTAPI PMMPTE GetPteAddress(PVOID Address); + virtual XTAPI VOID InitializePageMapInfo(VOID) = 0; + virtual XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer) = 0; + virtual XTAPI VOID SetPte(PHARDWARE_PTE PtePointer, + PFN_NUMBER PageFrameNumber, + BOOLEAN Writable) = 0; + virtual XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer, + BOOLEAN CacheDisable, + BOOLEAN WriteThrough) = 0; + } PAGEMAP, *PPAGEMAP; + + class PageMapBasic final : public PageMap + { + public: + XTAPI VOID InitializePageMapInfo(VOID); + XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer); + XTAPI VOID SetPte(PHARDWARE_PTE PtePointer, + PFN_NUMBER PageFrameNumber, + BOOLEAN Writable); + XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer, + BOOLEAN CacheDisable, + BOOLEAN WriteThrough); + }; + + class PageMapXpa final : public PageMap + { + public: + XTAPI VOID InitializePageMapInfo(VOID); + XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer); + XTAPI VOID SetPte(PHARDWARE_PTE PtePointer, + PFN_NUMBER PageFrameNumber, + BOOLEAN Writable); + XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer, + BOOLEAN CacheDisable, + BOOLEAN WriteThrough); + }; +} + +#endif /* __XTOSKRNL_MM_PAGEMAP_HH */ diff --git a/xtoskrnl/includes/mm/init.hh b/xtoskrnl/includes/mm/init.hh new file mode 100644 index 0000000..e606876 --- /dev/null +++ b/xtoskrnl/includes/mm/init.hh @@ -0,0 +1,39 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/mm/init.hh + * DESCRIPTION: Memory Manager initialization + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_MM_INIT_HH +#define __XTOSKRNL_MM_INIT_HH + +#include + + +/* Memory Manager */ +namespace MM +{ + class Init + { + private: + STATIC PLOADER_MEMORY_DESCRIPTOR FreeDescriptor; + STATIC ULONG_PTR HighestPhysicalPage; + STATIC ULONG_PTR LowestPhysicalPage; + STATIC ULONG NumberOfPhysicalPages; + STATIC LOADER_MEMORY_DESCRIPTOR OldFreeDescriptor; + + public: + STATIC XTAPI VOID InitializeMemoryManager(VOID); + STATIC XTAPI VOID InitializePageMapSupport(VOID); + STATIC XTAPI VOID ScanMemoryDescriptors(VOID); + + private: + STATIC XTAPI VOID InitializeArchitecture(VOID); + STATIC XTAPI BOOLEAN VerifyMemoryTypeFree(LOADER_MEMORY_TYPE MemoryType); + STATIC XTAPI BOOLEAN VerifyMemoryTypeInvisible(LOADER_MEMORY_TYPE MemoryType); + }; +} + +#endif /* __XTOSKRNL_MM_INIT_HH */ diff --git a/xtoskrnl/includes/mm/kpool.hh b/xtoskrnl/includes/mm/kpool.hh new file mode 100644 index 0000000..2e94881 --- /dev/null +++ b/xtoskrnl/includes/mm/kpool.hh @@ -0,0 +1,35 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/mm/hlpool.hh + * DESCRIPTION: Kernel pool memory management + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_MM_KPOOL_HH +#define __XTOSKRNL_MM_KPOOL_HH + +#include + + +/* Memory Manager */ +namespace MM +{ + class KernelPool + { + private: + STATIC UCHAR ProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE]; + + public: + STATIC XTAPI XTSTATUS AllocateKernelStack(IN PVOID *Stack, + IN BOOLEAN LargeStack, + IN UCHAR SystemNode); + STATIC XTAPI XTSTATUS AllocateProcessorStructures(IN ULONG CpuNumber, + OUT PVOID *StructuresData); + STATIC XTAPI VOID FreeKernelStack(IN PVOID Stack, + IN BOOLEAN LargeStack); + STATIC XTAPI VOID FreeProcessorStructures(IN PVOID StructuresData); + }; +} + +#endif /* __XTOSKRNL_MM_KPOOL_HH */ diff --git a/xtoskrnl/includes/mm/paging.hh b/xtoskrnl/includes/mm/paging.hh new file mode 100644 index 0000000..2f261f3 --- /dev/null +++ b/xtoskrnl/includes/mm/paging.hh @@ -0,0 +1,47 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/mm/paging.hh + * DESCRIPTION: Low level page management support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_MM_PAGING_HH +#define __XTOSKRNL_MM_PAGING_HH + +#include + + +/* Memory Manager */ +namespace MM +{ + class Paging + { + private: + STATIC PPAGEMAP PmlRoutines; + + public: + STATIC XTAPI VOID ClearPte(PHARDWARE_PTE PtePointer); + STATIC XTAPI VOID FlushTlb(VOID); + STATIC XTAPI PMMPDE GetPdeAddress(PVOID Address); + STATIC XTAPI PMMPPE GetPpeAddress(PVOID Address); + STATIC XTAPI PMMPTE GetPteAddress(PVOID Address); + STATIC XTAPI VOID InitializePageMapSupport(VOID); + STATIC XTAPI BOOLEAN PteValid(PHARDWARE_PTE PtePointer); + STATIC XTAPI VOID SetPte(PHARDWARE_PTE PtePointer, + PFN_NUMBER PageFrameNumber, + BOOLEAN Writable); + STATIC XTAPI VOID SetPteCaching(PHARDWARE_PTE PtePointer, + BOOLEAN CacheDisable, + BOOLEAN WriteThrough); + STATIC XTFASTCALL VOID ZeroPages(IN PVOID Address, + IN ULONG Size); + + private: + STATIC XTAPI BOOLEAN GetExtendedPhysicalAddressingStatus(VOID); + STATIC XTAPI PPAGEMAP GetPageMapBasicRoutines(VOID); + STATIC XTAPI PPAGEMAP GetPageMapXpaRoutines(VOID); + }; +} + +#endif /* __XTOSKRNL_MM_PAGING_HH */ diff --git a/xtoskrnl/includes/mmi.h b/xtoskrnl/includes/mmi.h deleted file mode 100644 index 7118b07..0000000 --- a/xtoskrnl/includes/mmi.h +++ /dev/null @@ -1,86 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/includes/mmi.h - * DESCRIPTION: Memory manager routines - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTOSKRNL_MMI_H -#define __XTOSKRNL_MMI_H - -#include - - -/* Memory Manager routines forward references */ -XTAPI -XTSTATUS -MmAllocateHardwareMemory(IN PFN_NUMBER PageCount, - IN BOOLEAN Aligned, - OUT PPHYSICAL_ADDRESS Buffer); - -XTAPI -XTSTATUS -MmAllocateKernelStack(IN PVOID *Stack, - IN BOOLEAN LargeStack, - IN UCHAR SystemNode); - -XTAPI -XTSTATUS -MmAllocateProcessorStructures(IN ULONG CpuNumber, - OUT PVOID *StructuresData); - -XTAPI -VOID -MmFlushTlb(VOID); - -XTAPI -VOID -MmFreeKernelStack(IN PVOID Stack, - IN BOOLEAN LargeStack); - -XTAPI -VOID -MmFreeProcessorStructures(IN PVOID StructuresData); - -XTAPI -VOID -MmInitializeMemoryManager(VOID); - -XTAPI -XTSTATUS -MmMapHardwareMemory(IN PHYSICAL_ADDRESS PhysicalAddress, - IN PFN_NUMBER PageCount, - IN BOOLEAN FlushTlb, - OUT PVOID *VirtualAddress); - -XTAPI -VOID -MmMarkHardwareMemoryWriteThrough(IN PVOID VirtualAddress, - IN PFN_NUMBER PageCount); - -XTAPI -VOID -MmRemapHardwareMemory(IN PVOID VirtualAddress, - IN PHYSICAL_ADDRESS PhysicalAddress, - IN BOOLEAN FlushTlb); - -XTAPI -XTSTATUS -MmUnmapHardwareMemory(IN PVOID VirtualAddress, - IN PFN_NUMBER PageCount, - IN BOOLEAN FlushTlb); - -XTAPI -VOID -MmpScanMemoryDescriptors(VOID); - -XTAPI -BOOLEAN -MmpVerifyMemoryTypeFree(LOADER_MEMORY_TYPE MemoryType); - -XTAPI -BOOLEAN -MmpVerifyMemoryTypeInvisible(LOADER_MEMORY_TYPE MemoryType); - -#endif /* __XTOSKRNL_MMI_H */ diff --git a/xtoskrnl/includes/po.hh b/xtoskrnl/includes/po.hh new file mode 100644 index 0000000..c6c9c34 --- /dev/null +++ b/xtoskrnl/includes/po.hh @@ -0,0 +1,17 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/po.hh + * DESCRIPTION: Power Management + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_PO_HH +#define __XTOSKRNL_PO_HH + +#include + +#include + + +#endif /* __XTOSKRNL_PO_HH */ diff --git a/xtoskrnl/includes/po/idle.hh b/xtoskrnl/includes/po/idle.hh new file mode 100644 index 0000000..0452063 --- /dev/null +++ b/xtoskrnl/includes/po/idle.hh @@ -0,0 +1,33 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/po/idle.hh + * DESCRIPTION: Processor idle functionality support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_PO_IDLE_HH +#define __XTOSKRNL_PO_IDLE_HH + +#include + + +/* Runtime Library */ +namespace PO +{ + class Idle + { + public: + STATIC XTAPI VOID InitializeProcessorIdleState(IN OUT PKPROCESSOR_CONTROL_BLOCK Prcb); + + private: + STATIC XTFASTCALL VOID Idle0Function(IN PPROCESSOR_POWER_STATE PowerState); + STATIC XTAPI VOID PerfIdle(IN PPROCESSOR_POWER_STATE PowerState); + STATIC XTAPI VOID PerfIdleDpc(IN PKDPC Dpc, + IN PVOID DeferredContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2); + }; +} + +#endif /* __XTOSKRNL_PO_IDLE_HH */ diff --git a/xtoskrnl/includes/poi.h b/xtoskrnl/includes/poi.h deleted file mode 100644 index a53e03b..0000000 --- a/xtoskrnl/includes/poi.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/includes/poi.h - * DESCRIPTION: Power manager subsystem routines - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTOSKRNL_POI_H -#define __XTOSKRNL_POI_H - -#include - - -/* Power Manager routines forward references */ -XTAPI -VOID -PoInitializeProcessorControlBlock(IN OUT PKPROCESSOR_CONTROL_BLOCK Prcb); - -XTFASTCALL -VOID -PopIdle0Function(IN PPROCESSOR_POWER_STATE PowerState); - -XTAPI -VOID -PopPerfIdle(PPROCESSOR_POWER_STATE PowerState); - -XTAPI -VOID -PopPerfIdleDpc(IN PKDPC Dpc, - IN PVOID DeferredContext, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2); - -#endif /* __XTOSKRNL_POI_H */ diff --git a/xtoskrnl/includes/rtl.hh b/xtoskrnl/includes/rtl.hh new file mode 100644 index 0000000..a35ca99 --- /dev/null +++ b/xtoskrnl/includes/rtl.hh @@ -0,0 +1,25 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/rtl.hh + * DESCRIPTION: Runtime Library + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_RTL_HH +#define __XTOSKRNL_RTL_HH + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif /* __XTOSKRNL_RTL_HH */ diff --git a/xtoskrnl/includes/rtl/atomic.hh b/xtoskrnl/includes/rtl/atomic.hh new file mode 100644 index 0000000..f3b9150 --- /dev/null +++ b/xtoskrnl/includes/rtl/atomic.hh @@ -0,0 +1,97 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/rtl/atomic.hh + * DESCRIPTION: Atomic operations support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_RTL_ATOMIC_HH +#define __XTOSKRNL_RTL_ATOMIC_HH + +#include + + +/* Runtime Library */ +namespace RTL +{ + class Atomic + { + public: + STATIC XTFASTCALL CHAR And8(IN PCHAR Address, + IN CHAR Mask); + STATIC XTFASTCALL SHORT And16(IN PSHORT Address, + IN SHORT Mask); + STATIC XTFASTCALL LONG And32(IN PLONG Address, + IN LONG Mask); + STATIC XTFASTCALL LONG_PTR And64(IN PLONG_PTR Address, + IN LONG_PTR Mask); + STATIC XTFASTCALL UCHAR BitTestAndSet(IN PLONG Base, + IN LONG Offset); + STATIC XTFASTCALL UCHAR BitTestAndSet64(IN PLONGLONG Base, + IN LONGLONG Offset); + STATIC XTFASTCALL CHAR CompareExchange8(IN PCHAR Address, + IN CHAR Comperand, + IN CHAR Exchange); + STATIC XTFASTCALL SHORT CompareExchange16(IN PSHORT Address, + IN SHORT Comperand, + IN SHORT Exchange); + STATIC XTFASTCALL LONG CompareExchange32(IN PLONG Address, + IN LONG Comperand, + IN LONG Exchange); + STATIC XTFASTCALL LONG_PTR CompareExchange64(IN PLONG_PTR Address, + IN LONG_PTR Comperand, + IN LONG_PTR Exchange); + STATIC XTFASTCALL PVOID CompareExchangePointer(IN PVOID *Address, + IN PVOID Comperand, + IN PVOID Exchange); + STATIC XTFASTCALL CHAR Decrement8(IN PCHAR Address); + STATIC XTFASTCALL SHORT Decrement16(IN PSHORT Address); + STATIC XTFASTCALL LONG Decrement32(IN PLONG Address); + STATIC XTFASTCALL LONG_PTR Decrement64(IN PLONG_PTR Address); + STATIC XTFASTCALL CHAR Exchange8(IN PCHAR Address, + IN CHAR Exchange); + STATIC XTFASTCALL SHORT Exchange16(IN PSHORT Address, + IN SHORT Exchange); + STATIC XTFASTCALL LONG Exchange32(IN PLONG Address, + IN LONG Exchange); + STATIC XTFASTCALL LONG_PTR Exchange64(IN PLONG_PTR Address, + IN LONG_PTR Exchange); + STATIC XTFASTCALL CHAR ExchangeAdd8(IN PCHAR Address, + IN CHAR Value); + STATIC XTFASTCALL SHORT ExchangeAdd16(IN PSHORT Address, + IN SHORT Value); + STATIC XTFASTCALL LONG ExchangeAdd32(IN PLONG Address, + IN LONG Value); + STATIC XTFASTCALL LONG_PTR ExchangeAdd64(IN PLONG_PTR Address, + IN LONG_PTR Value); + STATIC XTFASTCALL PVOID ExchangePointer(IN PVOID *Address, + IN PVOID Exchange); + STATIC XTFASTCALL PSINGLE_LIST_ENTRY FlushSingleList(IN PSINGLE_LIST_HEADER Header); + STATIC XTFASTCALL CHAR Increment8(IN PCHAR Address); + STATIC XTFASTCALL SHORT Increment16(IN PSHORT Address); + STATIC XTFASTCALL LONG Increment32(IN PLONG Address); + STATIC XTFASTCALL LONG_PTR Increment64(IN PLONG_PTR Address); + STATIC XTFASTCALL CHAR Or8(IN PCHAR Address, + IN CHAR Mask); + STATIC XTFASTCALL SHORT Or16(IN PSHORT Address, + IN SHORT Mask); + STATIC XTFASTCALL LONG Or32(IN PLONG Address, + IN LONG Mask); + STATIC XTFASTCALL LONG_PTR Or64(IN PLONG_PTR Address, + IN LONG_PTR Mask); + STATIC XTFASTCALL XTFASTCALL PSINGLE_LIST_ENTRY PopEntrySingleList(IN PSINGLE_LIST_HEADER Header); + STATIC XTFASTCALL PSINGLE_LIST_ENTRY PushEntrySingleList(IN PSINGLE_LIST_HEADER Header, + IN PSINGLE_LIST_ENTRY Entry); + STATIC XTFASTCALL CHAR Xor8(IN PCHAR Address, + IN CHAR Mask); + STATIC XTFASTCALL SHORT Xor16(IN PSHORT Address, + IN SHORT Mask); + STATIC XTFASTCALL LONG Xor32(IN PLONG Address, + IN LONG Mask); + STATIC XTFASTCALL LONG_PTR Xor64(IN PLONG_PTR Address, + IN LONG_PTR Mask); + }; +} + +#endif /* __XTOSKRNL_RTL_ATOMIC_HH */ diff --git a/xtoskrnl/includes/rtl/bitmap.hh b/xtoskrnl/includes/rtl/bitmap.hh new file mode 100644 index 0000000..933cce1 --- /dev/null +++ b/xtoskrnl/includes/rtl/bitmap.hh @@ -0,0 +1,64 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/rtl/bitmap.hh + * DESCRIPTION: Bit maps support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_RTL_BITMAP_HH +#define __XTOSKRNL_RTL_BITMAP_HH + +#include + + +/* Runtime Library */ +namespace RTL +{ + class BitMap + { + public: + STATIC XTAPI VOID ClearAllBits(IN PRTL_BITMAP BitMap); + STATIC XTAPI VOID ClearBit(IN PRTL_BITMAP BitMap, + IN ULONG_PTR Bit); + STATIC XTAPI VOID ClearBits(IN PRTL_BITMAP BitMap, + IN ULONG_PTR StartingIndex, + IN ULONG_PTR Length); + STATIC XTAPI ULONG ClearSetBits(IN PRTL_BITMAP BitMap, + IN ULONG_PTR Length, + IN ULONG_PTR Index); + STATIC XTAPI VOID DumpBitMap(IN PRTL_BITMAP BitMap); + STATIC XTAPI ULONG_PTR FindClearBits(IN PRTL_BITMAP BitMap, + IN ULONG_PTR Length, + IN ULONG_PTR Index); + STATIC XTAPI ULONG_PTR FindSetBits(IN PRTL_BITMAP BitMap, + IN ULONG_PTR Length, + IN ULONG_PTR Index); + STATIC XTAPI VOID InitializeBitMap(IN PRTL_BITMAP BitMap, + IN PULONG_PTR Buffer, + IN ULONG Size); + STATIC XTAPI VOID SetAllBits(IN PRTL_BITMAP BitMap); + STATIC XTAPI VOID SetBit(IN PRTL_BITMAP BitMap, + IN ULONG_PTR Bit); + STATIC XTAPI VOID SetBits(IN PRTL_BITMAP BitMap, + IN ULONG_PTR StartingIndex, + IN ULONG_PTR Length); + STATIC XTAPI ULONG SetClearBits(IN PRTL_BITMAP BitMap, + IN ULONG_PTR Length, + IN ULONG_PTR Index); + STATIC XTAPI BOOLEAN TestBit(IN PRTL_BITMAP BitMap, + IN ULONG_PTR Bit); + + private: + STATIC XTAPI ULONG_PTR CountBits(IN PRTL_BITMAP BitMap, + IN ULONG_PTR Length, + IN ULONG_PTR StartingIndex, + IN BOOLEAN SetBits); + STATIC XTAPI ULONG_PTR FindBits(IN PRTL_BITMAP BitMap, + IN ULONG_PTR Length, + IN ULONG_PTR StartingIndex, + IN BOOLEAN SetBits); + }; +} + +#endif /* __XTOSKRNL_RTL_BITMAP_HH */ diff --git a/xtoskrnl/includes/rtl/dispatch.hh b/xtoskrnl/includes/rtl/dispatch.hh new file mode 100644 index 0000000..171306d --- /dev/null +++ b/xtoskrnl/includes/rtl/dispatch.hh @@ -0,0 +1,26 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/rtl/dispatch.hh + * DESCRIPTION: Dispatching support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_RTL_DISPATCH_HH +#define __XTOSKRNL_RTL_DISPATCH_HH + +#include + + +/* Runtime Library */ +namespace RTL +{ + class Dispatcher + { + public: + STATIC XTAPI VOID GetStackLimits(OUT PULONG_PTR StackBase, + OUT PULONG_PTR StackLimit); + }; +} + +#endif /* __XTOSKRNL_RTL_DISPATCH_HH */ diff --git a/xtoskrnl/includes/rtl/endian.hh b/xtoskrnl/includes/rtl/endian.hh new file mode 100644 index 0000000..d8afcd7 --- /dev/null +++ b/xtoskrnl/includes/rtl/endian.hh @@ -0,0 +1,27 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/rtl/endian.hh + * DESCRIPTION: Endian conversion routines + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_RTL_ENDIAN_HH +#define __XTOSKRNL_RTL_ENDIAN_HH + +#include + + +/* Runtime Library */ +namespace RTL +{ + class Endianness + { + public: + STATIC XTFASTCALL USHORT SwapByte16(IN USHORT Source); + STATIC XTFASTCALL ULONG SwapByte32(IN ULONG Source); + STATIC XTFASTCALL ULONGLONG SwapByte64(IN ULONGLONG Source); + }; +} + +#endif /* __XTOSKRNL_RTL_ENDIAN_HH */ diff --git a/xtoskrnl/includes/rtl/guid.hh b/xtoskrnl/includes/rtl/guid.hh new file mode 100644 index 0000000..f27f287 --- /dev/null +++ b/xtoskrnl/includes/rtl/guid.hh @@ -0,0 +1,26 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/rtl/gui.hh + * DESCRIPTION: Endian conversion routines + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_RTL_GUID_HH +#define __XTOSKRNL_RTL_GUID_HH + +#include + + +/* Runtime Library */ +namespace RTL +{ + class Guid + { + public: + STATIC XTAPI BOOLEAN CompareGuids(IN PGUID Guid1, + IN PGUID Guid2); + }; +} + +#endif /* __XTOSKRNL_RTL_GUID_HH */ diff --git a/xtoskrnl/includes/rtl/llist.hh b/xtoskrnl/includes/rtl/llist.hh new file mode 100644 index 0000000..dc0e6ab --- /dev/null +++ b/xtoskrnl/includes/rtl/llist.hh @@ -0,0 +1,33 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/rtl/llist.hh + * DESCRIPTION: Linked list manipulation routines + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_RTL_LLIST_HH +#define __XTOSKRNL_RTL_LLIST_HH + +#include + + +/* Runtime Library */ +namespace RTL +{ + class LinkedList + { + public: + STATIC XTCDECL VOID InitializeListHead(IN PLIST_ENTRY ListHead); + STATIC XTCDECL VOID InitializeListHead32(IN PLIST_ENTRY32 ListHead); + STATIC XTCDECL VOID InsertHeadList(IN OUT PLIST_ENTRY ListHead, + IN PLIST_ENTRY Entry); + STATIC XTCDECL VOID InsertTailList(IN OUT PLIST_ENTRY ListHead, + IN PLIST_ENTRY Entry); + STATIC XTCDECL BOOLEAN ListEmpty(IN PLIST_ENTRY ListHead); + STATIC XTCDECL BOOLEAN ListLoop(IN PLIST_ENTRY ListHead); + STATIC XTCDECL VOID RemoveEntryList(IN PLIST_ENTRY Entry); + }; +} + +#endif /* __XTOSKRNL_RTL_LLIST_HH */ diff --git a/xtoskrnl/includes/rtl/math.hh b/xtoskrnl/includes/rtl/math.hh new file mode 100644 index 0000000..78e773c --- /dev/null +++ b/xtoskrnl/includes/rtl/math.hh @@ -0,0 +1,51 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/rtl/math.hh + * DESCRIPTION: Kernel math support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_RTL_MATH_HH +#define __XTOSKRNL_RTL_MATH_HH + +#include + + +/* Runtime Library */ +namespace RTL +{ + class Math + { + public: + STATIC XTAPI LARGE_INTEGER ConvertToLargeInteger32(IN LONG Value); + STATIC XTAPI LARGE_INTEGER ConvertToLargeIntegerUnsigned32(IN ULONG Value); + STATIC XTAPI INT CountLeadingZeroes32(IN ULONG Value); + STATIC XTAPI INT CountLeadingZeroes64(IN ULONGLONG Value); + STATIC XTAPI INT CountTrailingZeroes32(IN ULONG Value); + STATIC XTAPI INT CountTrailingZeroes64(IN ULONGLONG Value); + STATIC XTAPI LONGLONG Divide32(IN LONG Dividend, + IN LONG Divisor, + OUT PLONG Remainder); + STATIC XTAPI LONGLONG Divide64(IN LONGLONG Dividend, + IN LONGLONG Divisor, + OUT PLONGLONG Remainder); + STATIC XTAPI ULONGLONG DivideUnsigned32(IN ULONG Dividend, + IN ULONG Divisor, + OUT PULONG Remainder); + STATIC XTAPI ULONGLONG DivideUnsigned64(IN ULONGLONG Dividend, + IN ULONGLONG Divisor, + OUT PULONGLONG Remainder); + STATIC XTAPI LARGE_INTEGER DivideLargeInteger(IN LARGE_INTEGER Dividend, + IN ULONG Divisor, + OUT PULONG Remainder); + STATIC XTAPI LONG GetBaseExponent(IN DOUBLE Value, + OUT PDOUBLE PowerOfTen); + STATIC XTAPI BOOLEAN InfiniteDouble(IN DOUBLE Value); + STATIC XTAPI LARGE_INTEGER MultiplyLargeInteger(IN LARGE_INTEGER Multiplicand, + IN LONG Multiplier); + STATIC XTAPI BOOLEAN NanDouble(IN DOUBLE Value); + }; +} + +#endif /* __XTOSKRNL_RTL_MATH_HH */ diff --git a/xtoskrnl/includes/rtl/memory.hh b/xtoskrnl/includes/rtl/memory.hh new file mode 100644 index 0000000..77a2c62 --- /dev/null +++ b/xtoskrnl/includes/rtl/memory.hh @@ -0,0 +1,41 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/rtl/memory.hh + * DESCRIPTION: Memory related routines + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_RTL_MEMORY_HH +#define __XTOSKRNL_RTL_MEMORY_HH + +#include + + +/* Runtime Library */ +namespace RTL +{ + 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 BOOLEAN SameMemory(IN PCVOID LeftBuffer, + IN PCVOID RightBuffer, + 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); + }; +} + +#endif /* __XTOSKRNL_RTL_MEMORY_HH */ diff --git a/xtoskrnl/includes/rtl/string.hh b/xtoskrnl/includes/rtl/string.hh new file mode 100644 index 0000000..8d1ca18 --- /dev/null +++ b/xtoskrnl/includes/rtl/string.hh @@ -0,0 +1,55 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/rtl/string.hh + * DESCRIPTION: String support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_RTL_STRING_HH +#define __XTOSKRNL_RTL_STRING_HH + +#include + + +/* Runtime Library */ +namespace RTL +{ + class String + { + public: + STATIC XTAPI SIZE_T CompareString(IN PCSTR String1, + IN PCSTR String2, + IN SIZE_T Length); + STATIC XTAPI SIZE_T CompareStringInsensitive(IN PCSTR String1, + IN PCSTR String2, + IN SIZE_T Length); + STATIC XTAPI PCHAR ConcatenateString(OUT PCHAR Destination, + IN PCHAR Source, + IN SIZE_T Count); + STATIC XTAPI VOID CopyString(IN PCHAR Destination, + IN PCSTR Source, + IN ULONG Length); + STATIC XTAPI PCSTR FindString(IN PCSTR Source, + IN PCSTR Search); + STATIC XTAPI PCSTR FindStringInsensitive(IN PCSTR Source, + IN PCSTR Search); + STATIC XTAPI VOID ReverseString(IN OUT PCHAR String, + IN ULONG 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 TokenizeString(IN PCHAR String, + IN PCSTR Delimiter, + IN OUT PCHAR *SavePtr); + STATIC XTAPI CHAR ToLowerCharacter(IN CHAR Character); + STATIC XTAPI CHAR ToUpperCharacter(IN CHAR Character); + STATIC XTAPI PCHAR TrimLeftString(IN PCHAR String); + STATIC XTAPI PCHAR TrimRightString(IN PCHAR String); + STATIC XTAPI PCHAR TrimString(IN PCHAR String); + }; +} + +#endif /* __XTOSKRNL_RTL_STRING_HH */ diff --git a/xtoskrnl/includes/rtl/widestr.hh b/xtoskrnl/includes/rtl/widestr.hh new file mode 100644 index 0000000..66175fe --- /dev/null +++ b/xtoskrnl/includes/rtl/widestr.hh @@ -0,0 +1,87 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/rtl/widestr.hh + * DESCRIPTION: Wide string support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_RTL_WIDESTR_HH +#define __XTOSKRNL_RTL_WIDESTR_HH + +#include + + +/* Runtime Library */ +namespace RTL +{ + 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 VOID CopyWideString(IN PWCHAR Destination, + IN PCWSTR Source, + IN ULONG Length); + STATIC XTAPI PCWSTR FindWideString(IN PCWSTR Source, + IN PCWSTR Search); + STATIC XTAPI PCWSTR FindWideStringInsensitive(IN PCWSTR Source, + IN PCWSTR Search); + STATIC XTAPI XTSTATUS FormatWideString(IN PRTL_PRINT_CONTEXT Context, + IN PCWSTR Format, + IN VA_LIST ArgumentList); + STATIC XTAPI VOID ReverseWideString(IN OUT PWCHAR String, + IN ULONG Length); + STATIC XTAPI PWCHAR TokenizeWideString(IN PWCHAR String, + IN PCWSTR Delimiter, + IN OUT PWCHAR *SavePtr); + STATIC XTAPI WCHAR ToLowerWideCharacter(IN WCHAR Character); + STATIC XTAPI WCHAR ToUpperWideCharacter(IN WCHAR Character); + STATIC XTAPI PWCHAR TrimLeftWideString(IN PWCHAR String); + STATIC XTAPI PWCHAR TrimRightWideString(IN PWCHAR String); + STATIC XTAPI PWCHAR TrimWideString(IN PWCHAR String); + STATIC XTAPI SIZE_T WideStringLength(IN PCWSTR String, + IN SIZE_T MaxLength); + + private: + STATIC XTAPI XTSTATUS FormatArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context, + IN PCWSTR Format, + IN PVA_LIST ArgumentList, + IN OUT PULONG Index); + STATIC XTAPI ULONGLONG GetArgument(IN PVA_LIST ArgumentList, + IN ULONG ArgumentNumber, + IN LONG ArgumentSize); + STATIC XTAPI ULONGLONG GetSpecifierValue(IN PWCHAR *Format); + STATIC XTAPI XTSTATUS WriteWideCharacter(IN PRTL_PRINT_CONTEXT Context, + IN WCHAR Character); + STATIC XTCDECL XTSTATUS WriteCustomValue(IN PRTL_PRINT_CONTEXT Context, + IN PCWSTR Format, + IN ...); + STATIC XTAPI XTSTATUS WriteDoubleValue(IN PRTL_PRINT_CONTEXT Context, + IN PRTL_PRINT_FORMAT_PROPERTIES FormatProperties, + IN DOUBLE Value); + STATIC XTAPI XTSTATUS WriteHexDoubleValue(IN PRTL_PRINT_CONTEXT Context, + IN PRTL_PRINT_FORMAT_PROPERTIES FormatProperties, + IN DOUBLE Double); + STATIC XTAPI XTSTATUS WriteIntegerValue(IN PRTL_PRINT_CONTEXT Context, + IN PRTL_PRINT_FORMAT_PROPERTIES FormatProperties, + IN ULONGLONG Integer); + STATIC XTAPI XTSTATUS WriteStringValue(PRTL_PRINT_CONTEXT Context, + PRTL_PRINT_FORMAT_PROPERTIES FormatProperties, + PCSTR String, + SIZE_T StringLength); + STATIC XTAPI XTSTATUS WriteValue(PRTL_PRINT_CONTEXT Context, + PRTL_PRINT_FORMAT_PROPERTIES FormatProperties, + PCWSTR String, + SIZE_T StringLength); + }; +} + +#endif /* __XTOSKRNL_RTL_WIDESTR_HH */ diff --git a/xtoskrnl/includes/rtli.h b/xtoskrnl/includes/rtli.h deleted file mode 100644 index 616806d..0000000 --- a/xtoskrnl/includes/rtli.h +++ /dev/null @@ -1,379 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/includes/rtli.h - * DESCRIPTION: XT runtime library routines - * DEVELOPERS: Rafal Kupiec - */ - -#ifndef __XTOSKRNL_RTLI_H -#define __XTOSKRNL_RTLI_H - -#include - - -/* Runtime Library routines forward references */ -XTFASTCALL -CHAR -RtlAtomicAnd8(IN VOLATILE PCHAR Address, - IN CHAR Mask); - -XTFASTCALL -SHORT -RtlAtomicAnd16(IN VOLATILE PSHORT Address, - IN SHORT Mask); - -XTFASTCALL -LONG -RtlAtomicAnd32(IN VOLATILE PLONG Address, - IN LONG Mask); - -XTFASTCALL -LONG_PTR -RtlAtomicAnd64(IN VOLATILE PLONG_PTR Address, - IN LONG_PTR Mask); - -XTFASTCALL -UCHAR -RtlAtomicBitTestAndSet(IN VOLATILE PLONG Base, - IN LONG Offset); - -XTFASTCALL -UCHAR -RtlAtomicBitTestAndSet64(IN VOLATILE PLONGLONG Base, - IN LONGLONG Offset); - -XTFASTCALL -CHAR -RtlAtomicCompareExchange8(IN VOLATILE PCHAR Address, - IN CHAR Comperand, - IN CHAR Exchange); - -XTFASTCALL -SHORT -RtlAtomicCompareExchange16(IN VOLATILE PSHORT Address, - IN SHORT Comperand, - IN SHORT Exchange); - -XTFASTCALL -LONG -RtlAtomicCompareExchange32(IN VOLATILE PLONG Address, - IN LONG Comperand, - IN LONG Exchange); - -XTFASTCALL -LONG_PTR -RtlAtomicCompareExchange64(IN VOLATILE PLONG_PTR Address, - IN LONG_PTR Comperand, - IN LONG_PTR Exchange); - -XTFASTCALL -PVOID -RtlAtomicCompareExchangePointer(IN VOLATILE PVOID *Address, - IN PVOID Comperand, - IN PVOID Exchange); - -XTFASTCALL -CHAR -RtlAtomicDecrement8(IN VOLATILE PCHAR Address); - -XTFASTCALL -SHORT -RtlAtomicDecrement16(IN VOLATILE PSHORT Address); - -XTFASTCALL -LONG -RtlAtomicDecrement32(IN VOLATILE PLONG Address); - -XTFASTCALL -LONG_PTR -RtlAtomicDecrement64(IN VOLATILE PLONG_PTR Address); - -XTFASTCALL -CHAR -RtlAtomicExchange8(IN VOLATILE PCHAR Address, - IN CHAR Exchange); - -XTFASTCALL -SHORT -RtlAtomicExchange16(IN VOLATILE PSHORT Address, - IN SHORT Exchange); - -XTFASTCALL -LONG -RtlAtomicExchange32(IN VOLATILE PLONG Address, - IN LONG Exchange); - -XTFASTCALL -LONG_PTR -RtlAtomicExchange64(IN VOLATILE PLONG_PTR Address, - IN LONG_PTR Exchange); - -XTFASTCALL -CHAR -RtlAtomicExchangeAdd8(IN VOLATILE PCHAR Address, - IN CHAR Value); - -XTFASTCALL -SHORT -RtlAtomicExchangeAdd16(IN VOLATILE PSHORT Address, - IN SHORT Value); - -XTFASTCALL -LONG -RtlAtomicExchangeAdd32(IN VOLATILE PLONG Address, - IN LONG Value); - -XTFASTCALL -LONG_PTR -RtlAtomicExchangeAdd64(IN VOLATILE PLONG_PTR Address, - IN LONG_PTR Value); - -XTFASTCALL -PVOID -RtlAtomicExchangePointer(IN VOLATILE PVOID *Address, - IN PVOID Exchange); - -XTFASTCALL -PSINGLE_LIST_ENTRY -RtlAtomicFlushSingleList(IN PSINGLE_LIST_HEADER Header); - -XTFASTCALL -CHAR -RtlAtomicIncrement8(IN VOLATILE PCHAR Address); - -XTFASTCALL -SHORT -RtlAtomicIncrement16(IN VOLATILE PSHORT Address); - -XTFASTCALL -LONG -RtlAtomicIncrement32(IN VOLATILE PLONG Address); - -XTFASTCALL -LONG_PTR -RtlAtomicIncrement64(IN VOLATILE PLONG_PTR Address); - -XTFASTCALL -CHAR -RtlAtomicOr8(IN VOLATILE PCHAR Address, - IN CHAR Mask); - -XTFASTCALL -SHORT -RtlAtomicOr16(IN VOLATILE PSHORT Address, - IN SHORT Mask); - -XTFASTCALL -LONG -RtlAtomicOr32(IN VOLATILE PLONG Address, - IN LONG Mask); - -XTFASTCALL -LONG_PTR -RtlAtomicOr64(IN VOLATILE PLONG_PTR Address, - IN LONG_PTR Mask); - -XTFASTCALL -PSINGLE_LIST_ENTRY -RtlAtomicPopEntrySingleList(IN PSINGLE_LIST_HEADER Header); - -XTFASTCALL -PSINGLE_LIST_ENTRY -RtlAtomicPushEntrySingleList(IN PSINGLE_LIST_HEADER Header, - IN PSINGLE_LIST_ENTRY Entry); - -XTFASTCALL -CHAR -RtlAtomicXor8(IN VOLATILE PCHAR Address, - IN CHAR Mask); - -XTFASTCALL -SHORT -RtlAtomicXor16(IN VOLATILE PSHORT Address, - IN SHORT Mask); - -XTFASTCALL -LONG -RtlAtomicXor32(IN VOLATILE PLONG Address, - IN LONG Mask); - -XTFASTCALL -LONG_PTR -RtlAtomicXor64(IN VOLATILE PLONG_PTR Address, - IN LONG_PTR Mask); - -XTFASTCALL -USHORT -RtlByteSwap16(IN USHORT Source); - -XTFASTCALL -ULONG -RtlByteSwap32(IN ULONG Source); - -XTFASTCALL -ULONGLONG -RtlByteSwap64(IN ULONGLONG Source); - -XTAPI -INT -RtlCountLeadingZeroes32(IN ULONG Value); - -XTAPI -INT -RtlCountLeadingZeroes64(IN ULONGLONG Value); - -XTAPI -INT -RtlCountTrailingZeroes32(IN ULONG Value); - -XTAPI -INT -RtlCountTrailingZeroes64(IN ULONGLONG Value); - -XTAPI -LONGLONG -RtlDivide32(IN LONG Dividend, - IN LONG Divisor, - OUT PLONG Remainder); - -XTAPI -LONGLONG -RtlDivide64(IN LONGLONG Dividend, - IN LONGLONG Divisor, - OUT PLONGLONG Remainder); - -XTAPI -ULONGLONG -RtlDivideUnsigned32(IN ULONG Dividend, - IN ULONG Divisor, - OUT PULONG Remainder); - -XTAPI -ULONGLONG -RtlDivideUnsigned64(IN ULONGLONG Dividend, - IN ULONGLONG Divisor, - OUT PULONGLONG Remainder); - -XTAPI -VOID -RtlDumpBitMap(IN PRTL_BITMAP BitMap); - -XTAPI -LONG -RtlGetBaseExponent(IN DOUBLE Value, - OUT PDOUBLE PowerOfTen); - -XTCDECL -BOOLEAN -RtlInfiniteDouble(IN DOUBLE Value); - -XTCDECL -VOID -RtlInitializeListHead(IN PLIST_ENTRY ListHead); - -XTCDECL -VOID -RtlInitializeListHead32(IN PLIST_ENTRY32 ListHead); - -XTCDECL -VOID -RtlInsertHeadList(IN OUT PLIST_ENTRY ListHead, - IN PLIST_ENTRY Entry); - -XTCDECL -VOID -RtlInsertTailList(IN OUT PLIST_ENTRY ListHead, - IN PLIST_ENTRY Entry); - -XTCDECL -BOOLEAN -RtlListEmpty(PLIST_ENTRY ListHead); - -XTCDECL -BOOLEAN -RtlListLoop(IN PLIST_ENTRY ListHead); - -XTCDECL -BOOLEAN -RtlNanDouble(IN DOUBLE Value); - -XTCDECL -VOID -RtlRemoveEntryList(IN PLIST_ENTRY Entry); - -XTAPI -ULONG_PTR -RtlpCountBits(IN PRTL_BITMAP BitMap, - IN ULONG_PTR Length, - IN ULONG_PTR StartingIndex, - IN BOOLEAN SetBits); - -XTAPI -ULONG_PTR -RtlpFindBits(IN PRTL_BITMAP BitMap, - IN ULONG_PTR Length, - IN ULONG_PTR StartingIndex, - IN BOOLEAN SetBits); - -XTAPI -XTSTATUS -RtlpFormatWideStringArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context, - IN PCWSTR Format, - IN PVA_LIST ArgumentList, - IN OUT PULONG Index); - -XTAPI -ULONGLONG -RtlpGetWideStringArgument(IN PVA_LIST ArgumentList, - IN ULONG ArgumentNumber, - IN LONG ArgumentSize); - -XTAPI -ULONGLONG -RtlpGetWideStringSpecifierValue(IN PWCHAR *Format); - -XTAPI -XTSTATUS -RtlpWriteWideCharacter(IN PRTL_PRINT_CONTEXT Context, - IN WCHAR Character); - -XTCDECL -XTSTATUS -RtlpWriteWideStringCustomValue(IN PRTL_PRINT_CONTEXT Context, - IN PCWSTR Format, - IN ...); - -XTAPI -XTSTATUS -RtlpWriteWideStringDoubleValue(IN PRTL_PRINT_CONTEXT Context, - IN PRTL_PRINT_FORMAT_PROPERTIES FormatProperties, - IN DOUBLE Value); - -XTAPI -XTSTATUS -RtlpWriteWideStringHexDoubleValue(IN PRTL_PRINT_CONTEXT Context, - IN PRTL_PRINT_FORMAT_PROPERTIES FormatProperties, - IN DOUBLE Value); - -XTAPI -XTSTATUS -RtlpWriteWideStringIntegerValue(IN PRTL_PRINT_CONTEXT Context, - IN PRTL_PRINT_FORMAT_PROPERTIES FormatProperties, - IN ULONGLONG Integer); - -XTAPI -XTSTATUS -RtlpWriteWideStringStringValue(PRTL_PRINT_CONTEXT Context, - PRTL_PRINT_FORMAT_PROPERTIES FormatProperties, - PCHAR String, - SIZE_T StringLength); - -XTAPI -XTSTATUS -RtlpWriteWideStringValue(PRTL_PRINT_CONTEXT Context, - PRTL_PRINT_FORMAT_PROPERTIES FormatProperties, - PWCHAR String, - SIZE_T StringLength); - -#endif /* __XTOSKRNL_RTLI_H */ diff --git a/xtoskrnl/includes/xtos.h b/xtoskrnl/includes/xtos.h deleted file mode 100644 index 4dd1f24..0000000 --- a/xtoskrnl/includes/xtos.h +++ /dev/null @@ -1,29 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/includes/xtos.h - * DESCRIPTION: Top level header for the XT kernel - * DEVELOPERS: Rafal Kupiec - */ - -/* XT Development Kit */ -#include - -/* XT OS version */ -#include - -/* Kernel specific headers */ -#include "globals.h" -#include "hli.h" -#include "kdi.h" -#include "kei.h" -#include "mmi.h" -#include "poi.h" -#include "rtli.h" - -#include ARCH_HEADER(globals.h) -#include ARCH_HEADER(ari.h) -#include ARCH_HEADER(hli.h) -#include ARCH_HEADER(kei.h) -#include ARCH_HEADER(mmi.h) -#include ARCH_HEADER(rtli.h) diff --git a/xtoskrnl/includes/xtos.hh b/xtoskrnl/includes/xtos.hh new file mode 100644 index 0000000..3363583 --- /dev/null +++ b/xtoskrnl/includes/xtos.hh @@ -0,0 +1,27 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/xtos.hh + * DESCRIPTION: Top level header for the XT kernel + * DEVELOPERS: Aiken Harris + */ + + +/* Preprocessor macro for including arch-specific headers */ +#define XTOS_ARCH_HEADER(subsystem, header) STRINGIFY(subsystem/_ARCH/header) + +/* XT Kernel Mode Development Kit */ +#include + +/* XT OS version */ +#include + +/* Kernel specific headers */ +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/xtoskrnl/kd/data.cc b/xtoskrnl/kd/data.cc new file mode 100644 index 0000000..acaaa9c --- /dev/null +++ b/xtoskrnl/kd/data.cc @@ -0,0 +1,31 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/kd/globals.cc + * DESCRIPTION: Kernel Debugger global and static data + * DEVELOPERS: Aiken Harris + */ + +#include + + +/* Kernel Debugger mode */ +KD_DEBUG_MODE KD::DebugIo::DebugMode; + +/* Debugger I/O providers initialization routines */ +PKD_INIT_ROUTINE KD::DebugIo::IoProvidersInitRoutines[KDBG_PROVIDERS_COUNT] = { + InitializeFrameBufferProvider, + InitializeSerialPortProvider +}; + +/* Pointer to DbgPrint() routine */ +PKD_PRINT_ROUTINE KD::DebugIo::KdPrint = NULLPTR; + +/* List of active I/O providers */ +LIST_ENTRY KD::DebugIo::Providers; + +/* Debugger's serial port handle */ +CPPORT KD::DebugIo::SerialPort; + +/* Pre-defined serial port addresses */ +ULONG KD::DebugIo::SerialPortList[COMPORT_COUNT] = COMPORT_ADDRESS; diff --git a/xtoskrnl/kd/dbginit.c b/xtoskrnl/kd/dbginit.c deleted file mode 100644 index a1b598b..0000000 --- a/xtoskrnl/kd/dbginit.c +++ /dev/null @@ -1,192 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/kd/dbginit.c - * DESCRIPTION: Kernel Debugger initialization - * DEVELOPERS: Aiken Harris - */ - -#include - - -/** - * Initializes the kernel's debugger I/O providers. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTAPI -XTSTATUS -KdInitializeDebugIoProviders(VOID) -{ - ULONG Index; - XTSTATUS ProviderStatus, Status; - - /* Initialize debug providers list */ - RtlInitializeListHead(&KdpProviders); - - RtlZeroMemory(&KdpDebugMode, sizeof(KD_DEBUG_MODE)); - KdpDetectDebugPorts(); - - /* Iterate over providers initialization routines */ - for(Index = 0; Index < KDBG_PROVIDERS_COUNT; Index++) - { - /* Initialize provider */ - ProviderStatus = KdpIoProvidersInitRoutines[Index](); - Status = (Status || ProviderStatus); - } - - /* Initialize debug print routine */ - KdSetPrintRoutine(KdpDebugPrint); - - /* Return status code */ - return Status; -} - -/** - * Configures the kernel's debug print routine by setting a new output handler. - * - * @param DebugPrintRoutine - * Supplies a pointer to the new debug print routine. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -KdSetPrintRoutine(PVOID DebugPrintRoutine) -{ - /* Set debug print routine */ - KdPrint = DebugPrintRoutine; -} - -/** - * Detects and enables the kernel's debug ports based on the 'DEBUG' parameter passed to the kernel. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTAPI -XTSTATUS -KdpDetectDebugPorts(VOID) -{ - PCWSTR DebugOption; - XTSTATUS Status; - - /* Get debug parameter */ - Status = KeGetKernelParameter(L"DEBUG", &DebugOption); - if(Status != STATUS_SUCCESS) - { - /* Debug parameter not found, disable debugging */ - KdpDebugMode.Enabled = FALSE; - return Status; - } - - /* Skip parameter name and check if it is set */ - DebugOption += 5; - if(*DebugOption != L'=') - { - /* Debug parameter not set, disable debugging */ - KdpDebugMode.Enabled = FALSE; - return STATUS_INVALID_PARAMETER; - } - - /* Skip '=' symbol */ - DebugOption++; - - /* Iterate over all debug ports */ - while(*DebugOption != L'\0' && *DebugOption != L' ') - { - /* Check what port is set for debugging */ - if(RtlCompareWideStringInsensitive(DebugOption, L"COM", 3) == 0) - { - /* Enable serial port debugging mode */ - KdpDebugMode.Mode |= DEBUG_PROVIDER_COMPORT; - - /* Read COM port number */ - DebugOption += 3; - while(*DebugOption >= '0' && *DebugOption <= '9') - { - /* Get port number */ - KdpDebugMode.ComPortNumber *= 10; - KdpDebugMode.ComPortNumber += *DebugOption - '0'; - DebugOption++; - } - - /* Check if custom COM port address supplied */ - if(KdpDebugMode.ComPortNumber == 0 && RtlCompareWideStringInsensitive(DebugOption, L":0x", 3) == 0) - { - /* COM port address provided */ - DebugOption += 3; - while((*DebugOption >= '0' && *DebugOption <= '9') || - (*DebugOption >= 'A' && *DebugOption <= 'F') || - (*DebugOption >= 'a' && *DebugOption <= 'f')) - { - /* Get port address */ - KdpDebugMode.ComPortAddress *= 16; - if(*DebugOption >= '0' && *DebugOption <= '9') - { - KdpDebugMode.ComPortAddress += *DebugOption - '0'; - } - else if(*DebugOption >= 'A' && *DebugOption <= 'F') - { - KdpDebugMode.ComPortAddress += *DebugOption - 'A' + 10; - } - else if(*DebugOption >= 'a' && *DebugOption <= 'f') - { - KdpDebugMode.ComPortAddress += *DebugOption - 'a' + 10; - } - DebugOption++; - } - } - - /* Look for additional COM port parameters */ - if(*DebugOption == ',') - { - /* Baud rate provided */ - DebugOption++; - while(*DebugOption >= '0' && *DebugOption <= '9') - { - /* Get baud rate */ - KdpDebugMode.ComPortBaudRate *= 10; - KdpDebugMode.ComPortBaudRate += *DebugOption - '0'; - DebugOption++; - } - } - } - else if(RtlCompareWideStringInsensitive(DebugOption, L"SCREEN", 6) == 0) - { - /* Enable framebuffer debugging mode */ - KdpDebugMode.Mode |= DEBUG_PROVIDER_FRAMEBUFFER; - DebugOption += 6; - } - else if(*DebugOption == L';') - { - /* Skip separator */ - DebugOption++; - } - else - { - /* Invalid debug option, skip it */ - while(*DebugOption != L'\0' && *DebugOption != L' ' && *DebugOption != L';') - { - /* Advance debug option */ - DebugOption++; - } - - } - } - - /* Ensure at least one debug port is enabled */ - if(KdpDebugMode.Mode != 0) - { - /* Enable debugging */ - KdpDebugMode.Enabled = TRUE; - } - - /* Return success */ - return STATUS_SUCCESS; -} diff --git a/xtoskrnl/kd/dbgio.c b/xtoskrnl/kd/dbgio.c deleted file mode 100644 index 301e460..0000000 --- a/xtoskrnl/kd/dbgio.c +++ /dev/null @@ -1,175 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/kd/dbgio.c - * DESCRIPTION: Kernel Debugger I/O routines - * DEVELOPERS: Aiken Harris - */ - -#include - - -/** - * Prints a formatted string using the configured debug output providers. - * - * @param Format - * Supplies the format string. - * - * @param ... - * Supplies the variable argument list. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -KdpDebugPrint(PCWSTR Format, ...) -{ - VA_LIST Arguments; - PLIST_ENTRY DispatchTableEntry; - PKD_DISPATCH_TABLE DispatchTable; - - /* Initialise the va_list */ - VA_START(Arguments, Format); - - DispatchTableEntry = KdpProviders.Flink; - while(DispatchTableEntry != &KdpProviders) - { - DispatchTable = CONTAIN_RECORD(DispatchTableEntry, KD_DISPATCH_TABLE, ListEntry); - - RtlFormatWideString(&DispatchTable->PrintContext, (PWCHAR)Format, Arguments); - - DispatchTableEntry = DispatchTableEntry->Flink; - } - - /* Clean up the va_list */ - VA_END(Arguments); -} - -/** - * Initializes the framebuffer device provider for the kernel debugger. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTAPI -XTSTATUS -KdpInitializeFrameBufferProvider(VOID) -{ - STATIC KD_DISPATCH_TABLE DispatchTable; - ULONG Height, Width; - - /* Check if framebuffer provider is enabled */ - if(KdpDebugMode.Enabled && (KdpDebugMode.Mode & DEBUG_PROVIDER_FRAMEBUFFER) == 0) - { - /* Screen is not enabled, no need to initialize provider */ - return STATUS_PORT_DISCONNECTED; - } - - /* Ensure frame buffer is initialized and get FB resolution */ - HlInitializeFrameBuffer(); - HlGetFrameBufferResolution(&Width, &Height); - - /* Print debug message */ - DebugPrint(L"Initializing debug console at framebuffer device (%lu x %lu)\n", Width, Height); - - /* Initialize scroll region to full screen and white font color */ - HlInitializeScrollRegion(0, 0, Width - 1, Height - 1, 0xFFFFFFFF); - - /* Initialize screen dispatch table */ - DispatchTable.PrintContext.WriteWideCharacter = HlDisplayCharacter; - RtlInsertHeadList(&KdpProviders, &DispatchTable.ListEntry); - - /* Return success */ - return STATUS_SUCCESS; -} - -/** - * Initializes the serial port device provider for the kernel debugger. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTAPI -XTSTATUS -KdpInitializeSerialPortProvider(VOID) -{ - STATIC KD_DISPATCH_TABLE DispatchTable; - XTSTATUS Status; - - /* Check if serial port provider is enabled */ - if(KdpDebugMode.Enabled && (KdpDebugMode.Mode & DEBUG_PROVIDER_COMPORT) == 0) - { - /* Serial port is not enabled, no need to initialize provider */ - return STATUS_PORT_DISCONNECTED; - } - - /* Check if custom COM port address supplied */ - if(!KdpDebugMode.ComPortAddress) - { - /* We support only a pre-defined number of ports */ - if(KdpDebugMode.ComPortNumber > COMPORT_COUNT) - { - /* Fail if wrong/unsupported port used */ - return STATUS_INVALID_PARAMETER; - } - - /* Check if serial port is set */ - if(KdpDebugMode.ComPortNumber == 0) - { - /* Use COM1 by default */ - KdpDebugMode.ComPortNumber = 1; - } - - /* Set custom port address based on the port number and print debug message */ - KdpDebugMode.ComPortAddress = KdpSerialPortList[KdpDebugMode.ComPortNumber - 1]; - DebugPrint(L"Initializing debug console at serial port (COM%lu, BaudRate: %lu)\n", - KdpDebugMode.ComPortNumber, KdpDebugMode.ComPortBaudRate); - } - else - { - /* Custom port address supplied, print debug message */ - DebugPrint(L"Initializing debug console at serial port (0x%lX, BaudRate: %lu)\n", - KdpDebugMode.ComPortAddress, KdpDebugMode.ComPortBaudRate); - } - - /* Initialize COM port */ - Status = HlInitializeComPort(&KdpSerialPort, UlongToPtr(KdpDebugMode.ComPortAddress), KdpDebugMode.ComPortBaudRate); - if(Status != STATUS_SUCCESS) - { - /* Serial port initialization failed */ - return Status; - } - - /* Initialize serial port dispatch table */ - DispatchTable.PrintContext.WriteWideCharacter = KdpSerialWriteCharacter; - RtlInsertHeadList(&KdpProviders, &DispatchTable.ListEntry); - - /* Return success */ - return STATUS_SUCCESS; -} - -/** - * 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 -KdpSerialWriteCharacter(WCHAR Character) -{ - WCHAR Buffer[2]; - - /* Write character to the serial console */ - Buffer[0] = Character; - Buffer[1] = 0; - return HlComPortPutByte(&KdpSerialPort, Buffer[0]); -} diff --git a/xtoskrnl/kd/dbgio.cc b/xtoskrnl/kd/dbgio.cc new file mode 100644 index 0000000..febf449 --- /dev/null +++ b/xtoskrnl/kd/dbgio.cc @@ -0,0 +1,386 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/kd/dbgio.cc + * DESCRIPTION: Kernel Debugger I/O routines + * DEVELOPERS: Aiken Harris + */ + +#include + + +/** + * Prints a formatted string using the configured debug output providers. + * + * @param Format + * Supplies the format string. + * + * @param ... + * Supplies the variable argument list. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +KD::DebugIo::DbgPrint(PCWSTR Format, + ...) +{ + VA_LIST Arguments; + + /* Initialise the va_list */ + VA_START(Arguments, Format); + + /* Call the actual debug print routine */ + DbgPrintEx(Format, Arguments); + + /* Clean up the va_list */ + VA_END(Arguments); +} + +/** + * Prints a formatted string using the configured debug output providers (va_list variant). + * + * @param Format + * Supplies the format string. + * + * @param ... + * Supplies the variable argument list. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +KD::DebugIo::DbgPrintEx(PCWSTR Format, + VA_LIST Arguments) +{ + PLIST_ENTRY DispatchTableEntry; + PKD_DISPATCH_TABLE DispatchTable; + + /* Iterate over all registered debug providers */ + DispatchTableEntry = Providers.Flink; + while(DispatchTableEntry != &Providers) + { + /* Get dispatch table */ + DispatchTable = CONTAIN_RECORD(DispatchTableEntry, KD_DISPATCH_TABLE, ListEntry); + + /* Print formatted string using the provider's print context */ + RTL::WideString::FormatWideString(&DispatchTable->PrintContext, (PWCHAR)Format, Arguments); + + /* Move to the next provider */ + DispatchTableEntry = DispatchTableEntry->Flink; + } +} + +/** + * Detects and enables the kernel's debug ports based on the 'DEBUG' parameter passed to the kernel. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTAPI +XTSTATUS +KD::DebugIo::DetectDebugPorts(VOID) +{ + PCWSTR DebugOption; + XTSTATUS Status; + + /* Get debug parameter */ + Status = KE::BootInformation::GetKernelParameter(L"DEBUG", &DebugOption); + if(Status != STATUS_SUCCESS) + { + /* Debug parameter not found, disable debugging */ + DebugMode.Enabled = FALSE; + return Status; + } + + /* Skip parameter name and check if it is set */ + DebugOption += 5; + if(*DebugOption != L'=') + { + /* Debug parameter not set, disable debugging */ + DebugMode.Enabled = FALSE; + return STATUS_INVALID_PARAMETER; + } + + /* Skip '=' symbol */ + DebugOption++; + + /* Iterate over all debug ports */ + while(*DebugOption != L'\0' && *DebugOption != L' ') + { + /* Check what port is set for debugging */ + if(RTL::WideString::CompareWideStringInsensitive(DebugOption, L"COM", 3) == 0) + { + /* Enable serial port debugging mode */ + DebugMode.Mode |= DEBUG_PROVIDER_COMPORT; + + /* Read COM port number */ + DebugOption += 3; + while(*DebugOption >= '0' && *DebugOption <= '9') + { + /* Get port number */ + DebugMode.ComPortNumber *= 10; + DebugMode.ComPortNumber += *DebugOption - '0'; + DebugOption++; + } + + /* Check if custom COM port address supplied */ + if(DebugMode.ComPortNumber == 0 && RTL::WideString::CompareWideStringInsensitive(DebugOption, L":0x", 3) == 0) + { + /* COM port address provided */ + DebugOption += 3; + while((*DebugOption >= '0' && *DebugOption <= '9') || + (*DebugOption >= 'A' && *DebugOption <= 'F') || + (*DebugOption >= 'a' && *DebugOption <= 'f')) + { + /* Get port address */ + DebugMode.ComPortAddress *= 16; + if(*DebugOption >= '0' && *DebugOption <= '9') + { + DebugMode.ComPortAddress += *DebugOption - '0'; + } + else if(*DebugOption >= 'A' && *DebugOption <= 'F') + { + DebugMode.ComPortAddress += *DebugOption - 'A' + 10; + } + else if(*DebugOption >= 'a' && *DebugOption <= 'f') + { + DebugMode.ComPortAddress += *DebugOption - 'a' + 10; + } + DebugOption++; + } + } + + /* Look for additional COM port parameters */ + if(*DebugOption == ',') + { + /* Baud rate provided */ + DebugOption++; + while(*DebugOption >= '0' && *DebugOption <= '9') + { + /* Get baud rate */ + DebugMode.ComPortBaudRate *= 10; + DebugMode.ComPortBaudRate += *DebugOption - '0'; + DebugOption++; + } + } + } + else if(RTL::WideString::CompareWideStringInsensitive(DebugOption, L"SCREEN", 6) == 0) + { + /* Enable framebuffer debugging mode */ + DebugMode.Mode |= DEBUG_PROVIDER_FRAMEBUFFER; + DebugOption += 6; + } + else if(*DebugOption == L';') + { + /* Skip separator */ + DebugOption++; + } + else + { + /* Invalid debug option, skip it */ + while(*DebugOption != L'\0' && *DebugOption != L' ' && *DebugOption != L';') + { + /* Advance debug option */ + DebugOption++; + } + + } + } + + /* Ensure at least one debug port is enabled */ + if(DebugMode.Mode != 0) + { + /* Enable debugging */ + DebugMode.Enabled = TRUE; + } + + /* Return success */ + return STATUS_SUCCESS; +} + +/** + * Initializes the kernel's debugger I/O providers. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTAPI +XTSTATUS +KD::DebugIo::InitializeDebugIoProviders(VOID) +{ + ULONG Index; + XTSTATUS ProviderStatus, Status; + + /* Initialize debug providers list */ + RTL::LinkedList::InitializeListHead(&Providers); + + RTL::Memory::ZeroMemory(&DebugMode, sizeof(KD_DEBUG_MODE)); + DetectDebugPorts(); + + /* Iterate over providers initialization routines */ + for(Index = 0; Index < KDBG_PROVIDERS_COUNT; Index++) + { + /* Initialize provider */ + ProviderStatus = IoProvidersInitRoutines[Index](); + Status = (Status || ProviderStatus); + } + + /* Initialize debug print routine */ + SetPrintRoutine((PKD_PRINT_ROUTINE)DbgPrint); + + /* Return status code */ + return Status; +} + +/** + * Initializes the framebuffer device provider for the kernel debugger. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTAPI +XTSTATUS +KD::DebugIo::InitializeFrameBufferProvider(VOID) +{ + STATIC KD_DISPATCH_TABLE DispatchTable; + ULONG Height, Width; + + /* Check if framebuffer provider is enabled */ + if(DebugMode.Enabled && (DebugMode.Mode & DEBUG_PROVIDER_FRAMEBUFFER) == 0) + { + /* Screen is not enabled, no need to initialize provider */ + return STATUS_PORT_DISCONNECTED; + } + + /* Ensure frame buffer is initialized and get FB resolution */ + HL::FrameBuffer::InitializeFrameBuffer(); + HL::FrameBuffer::GetFrameBufferResolution(&Width, &Height); + + /* Print debug message */ + DebugPrint(L"Initializing debug console at framebuffer device (%lu x %lu)\n", Width, Height); + + /* Initialize scroll region to full screen and white font color */ + HL::FrameBuffer::InitializeScrollRegion(0, 0, Width - 1, Height - 1, 0xFFFFFFFF); + + /* Initialize screen dispatch table */ + DispatchTable.PrintContext.WriteWideCharacter = HL::FrameBuffer::DisplayCharacter; + RTL::LinkedList::InsertHeadList(&Providers, &DispatchTable.ListEntry); + + /* Return success */ + return STATUS_SUCCESS; +} + +/** + * Initializes the serial port device provider for the kernel debugger. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTAPI +XTSTATUS +KD::DebugIo::InitializeSerialPortProvider(VOID) +{ + STATIC KD_DISPATCH_TABLE DispatchTable; + XTSTATUS Status; + + /* Check if serial port provider is enabled */ + if(DebugMode.Enabled && (DebugMode.Mode & DEBUG_PROVIDER_COMPORT) == 0) + { + /* Serial port is not enabled, no need to initialize provider */ + return STATUS_PORT_DISCONNECTED; + } + + /* Check if custom COM port address supplied */ + if(!DebugMode.ComPortAddress) + { + /* We support only a pre-defined number of ports */ + if(DebugMode.ComPortNumber > COMPORT_COUNT) + { + /* Fail if wrong/unsupported port used */ + return STATUS_INVALID_PARAMETER; + } + + /* Check if serial port is set */ + if(DebugMode.ComPortNumber == 0) + { + /* Use COM1 by default */ + DebugMode.ComPortNumber = 1; + } + + /* Set custom port address based on the port number and print debug message */ + DebugMode.ComPortAddress = SerialPortList[DebugMode.ComPortNumber - 1]; + DebugPrint(L"Initializing debug console at serial port (COM%lu, BaudRate: %lu)\n", + DebugMode.ComPortNumber, DebugMode.ComPortBaudRate); + } + else + { + /* Custom port address supplied, print debug message */ + DebugPrint(L"Initializing debug console at serial port (0x%lX, BaudRate: %lu)\n", + DebugMode.ComPortAddress, DebugMode.ComPortBaudRate); + } + + /* Initialize COM port */ + Status = HL::ComPort::InitializeComPort(&SerialPort, (PUCHAR)UlongToPtr(DebugMode.ComPortAddress), DebugMode.ComPortBaudRate); + if(Status != STATUS_SUCCESS) + { + /* Serial port initialization failed */ + return Status; + } + + /* Initialize serial port dispatch table */ + DispatchTable.PrintContext.WriteWideCharacter = SerialWriteCharacter; + RTL::LinkedList::InsertHeadList(&Providers, &DispatchTable.ListEntry); + + /* Return success */ + return STATUS_SUCCESS; +} + +/** + * Configures the kernel's debug print routine by setting a new output handler. + * + * @param DebugPrintRoutine + * Supplies a pointer to the new debug print routine. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +KD::DebugIo::SetPrintRoutine(PKD_PRINT_ROUTINE DebugPrintRoutine) +{ + /* Set debug print routine */ + KdPrint = DebugPrintRoutine; +} + + +/** + * 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 +KD::DebugIo::SerialWriteCharacter(WCHAR Character) +{ + WCHAR Buffer[2]; + + /* Write character to the serial console */ + Buffer[0] = Character; + Buffer[1] = 0; + return HL::ComPort::WriteComPort(&SerialPort, Buffer[0]); +} diff --git a/xtoskrnl/kd/exports.cc b/xtoskrnl/kd/exports.cc new file mode 100644 index 0000000..622fade --- /dev/null +++ b/xtoskrnl/kd/exports.cc @@ -0,0 +1,40 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/kd/exports.cc + * DESCRIPTION: C-compatible API wrappers for exported kernel functions + * DEVELOPERS: Aiken Harris + */ + +#include + + +/** + * Prints a formatted string using the configured debug output providers. + * + * @param Format + * Supplies the format string. + * + * @param ... + * Supplies the variable argument list. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTCDECL +VOID +DbgPrint(PCWSTR Format, + ...) +{ + VA_LIST Arguments; + + /* Initialise the va_list */ + VA_START(Arguments, Format); + + KD::DebugIo::DbgPrintEx(Format, Arguments); + + /* Clean up the va_list */ + VA_END(Arguments); +} diff --git a/xtoskrnl/kd/globals.c b/xtoskrnl/kd/globals.c deleted file mode 100644 index cbc86aa..0000000 --- a/xtoskrnl/kd/globals.c +++ /dev/null @@ -1,31 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/kd/globals.c - * DESCRIPTION: Architecture independent global variables related to KD subsystem - * DEVELOPERS: Aiken Harris - */ - -#include - - -/* Pointer to DbgPrint() routine */ -PKD_PRINT_ROUTINE KdPrint = NULL; - -/* Kernel Debugger mode */ -KD_DEBUG_MODE KdpDebugMode; - -/* Debugger I/O providers initialization routines */ -PKD_INIT_ROUTINE KdpIoProvidersInitRoutines[KDBG_PROVIDERS_COUNT] = { - KdpInitializeFrameBufferProvider, - KdpInitializeSerialPortProvider -}; - -/* List of active I/O providers */ -LIST_ENTRY KdpProviders; - -/* Debugger's serial port handle */ -CPPORT KdpSerialPort; - -/* Pre-defined serial port addresses */ -ULONG KdpSerialPortList[COMPORT_COUNT] = COMPORT_ADDRESS; diff --git a/xtoskrnl/ke/amd64/irqs.c b/xtoskrnl/ke/amd64/irq.cc similarity index 80% rename from xtoskrnl/ke/amd64/irqs.c rename to xtoskrnl/ke/amd64/irq.cc index 8fbf992..0d39623 100644 --- a/xtoskrnl/ke/amd64/irqs.c +++ b/xtoskrnl/ke/amd64/irq.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/amd64/irqs.c + * FILE: xtoskrnl/ke/amd64/irq.cc * DESCRIPTION: Kernel interrupts support for amd64 architecture * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -24,13 +24,13 @@ */ XTAPI VOID -KeSetInterruptHandler(IN ULONG Vector, - IN PVOID Handler) +KE::Irq::SetInterruptHandler(IN ULONG Vector, + IN PVOID Handler) { PKPROCESSOR_BLOCK ProcessorBlock; /* Get current processor block */ - ProcessorBlock = KeGetCurrentProcessorBlock(); + ProcessorBlock = KE::Processor::GetCurrentProcessorBlock(); /* Update interrupt handler */ ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF); diff --git a/xtoskrnl/ke/amd64/krnlinit.c b/xtoskrnl/ke/amd64/krnlinit.cc similarity index 56% rename from xtoskrnl/ke/amd64/krnlinit.c rename to xtoskrnl/ke/amd64/krnlinit.cc index 610e4ef..985d7d1 100644 --- a/xtoskrnl/ke/amd64/krnlinit.c +++ b/xtoskrnl/ke/amd64/krnlinit.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/amd64/krnlinit.c + * FILE: xtoskrnl/ke/amd64/krnlinit.cc * DESCRIPTION: CPU architecture specific kernel initialization * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -18,17 +18,17 @@ */ XTAPI VOID -KepInitializeKernel(VOID) +KE::KernelInit::InitializeKernel(VOID) { XTSTATUS Status; /* Initialize hardware layer subsystem */ - Status = HlInitializeSystem(); + Status = HL::Init::InitializeSystem(); if(Status != STATUS_SUCCESS) { /* Hardware layer initialization failed, kernel panic */ DebugPrint(L"Failed to initialize hardware layer subsystem!\n"); - KePanic(0); + Crash::Panic(0); } } @@ -41,20 +41,20 @@ KepInitializeKernel(VOID) */ XTAPI VOID -KepInitializeMachine(VOID) +KE::KernelInit::InitializeMachine(VOID) { /* Re-enable IDE interrupts */ - HlIoPortOutByte(0x376, 0); - HlIoPortOutByte(0x3F6, 0); + HL::IoPort::WritePort8(0x376, 0); + HL::IoPort::WritePort8(0x3F6, 0); /* Initialize frame buffer */ - HlInitializeFrameBuffer(); + HL::FrameBuffer::InitializeFrameBuffer(); /* Initialize processor */ - HlInitializeProcessor(); + HL::Cpu::InitializeProcessor(); /* Initialize page map support */ - MmInitializePageMapSupport(); + MM::Paging::InitializePageMapSupport(); } /** @@ -66,7 +66,7 @@ KepInitializeMachine(VOID) */ XTAPI VOID -KepStartKernel(VOID) +KE::KernelInit::StartKernel(VOID) { PKPROCESSOR_CONTROL_BLOCK Prcb; ULONG_PTR PageDirectory[2]; @@ -74,33 +74,33 @@ KepStartKernel(VOID) PKTHREAD CurrentThread; /* Get processor control block and current thread */ - Prcb = KeGetCurrentProcessorControlBlock(); - CurrentThread = KeGetCurrentThread(); + Prcb = Processor::GetCurrentProcessorControlBlock(); + CurrentThread = Processor::GetCurrentThread(); /* Get current process */ CurrentProcess = CurrentThread->ApcState.Process; /* Initialize CPU power state structures */ - PoInitializeProcessorControlBlock(Prcb); + PO::Idle::InitializeProcessorIdleState(Prcb); /* Save processor state */ - KepSaveProcessorState(&Prcb->ProcessorState); + Processor::SaveProcessorState(&Prcb->ProcessorState); /* Lower to APC runlevel */ - KeLowerRunLevel(APC_LEVEL); + RunLevel::LowerRunLevel(APC_LEVEL); /* Initialize XTOS kernel */ - KepInitializeKernel(); + InitializeKernel(); /* Initialize Idle process */ - RtlInitializeListHead(&KepProcessListHead); PageDirectory[0] = 0; PageDirectory[1] = 0; - KeInitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE); + KProcess::InitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE); CurrentProcess->Quantum = MAXCHAR; /* Initialize Idle thread */ - KeInitializeThread(CurrentProcess, CurrentThread, NULL, NULL, NULL, NULL, NULL, ArKernelBootStack, TRUE); + KThread::InitializeThread(CurrentProcess, CurrentThread, NULLPTR, NULLPTR, NULLPTR, + NULLPTR, NULLPTR, AR::ProcSup::GetBootStack(), TRUE); CurrentThread->NextProcessor = Prcb->CpuNumber; CurrentThread->Priority = THREAD_HIGH_PRIORITY; CurrentThread->State = Running; @@ -109,29 +109,39 @@ KepStartKernel(VOID) CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber; /* Enter infinite loop */ - DebugPrint(L"KepStartKernel() finished. Entering infinite loop.\n"); - for(;;); + DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n"); + Crash::HaltSystem(); } /** - * Switches to a new kernel boot stack. + * Switches execution to a new boot stack and transfers control to the KernelInit::StartKernel() routine. * - * @return This routine does not return any value + * @return This routine does not return any value. * * @since XT 1.0 */ XTAPI VOID -KepSwitchBootStack(IN ULONG_PTR Stack) +KE::KernelInit::SwitchBootStack(VOID) { - /* Discard old stack frame, switch stack and jump to KepStartKernel() */ + ULONG_PTR Stack; + PVOID StartKernel; + + /* Calculate the stack pointer at the top of the buffer, ensuring it is properly aligned as required by the ABI */ + Stack = ((ULONG_PTR)AR::ProcSup::GetBootStack() + KERNEL_STACK_SIZE) & ~(STACK_ALIGNMENT - 1); + + /* Get address of KernelInit::StartKernel() */ + StartKernel = (PVOID)KernelInit::StartKernel; + + /* Discard old stack frame, switch stack and jump to KernelInit::StartKernel() */ __asm__ volatile("mov %0, %%rdx\n" "xor %%rbp, %%rbp\n" "mov %%rdx, %%rsp\n" "sub %1, %%rsp\n" - "jmp KepStartKernel\n" + "jmp *%2\n" : : "m" (Stack), "i" (FLOATING_SAVE_AREA_SIZE | KEXCEPTION_FRAME_SIZE | KSWITCH_FRAME_SIZE | KRETURN_ADDRESS_SIZE), - "p" (KepStartKernel)); + "r" (StartKernel) + : "rdx", "rbp", "rsp", "memory"); } diff --git a/xtoskrnl/ke/amd64/kthread.c b/xtoskrnl/ke/amd64/kthread.cc similarity index 83% rename from xtoskrnl/ke/amd64/kthread.c rename to xtoskrnl/ke/amd64/kthread.cc index 096d7d6..83820e7 100644 --- a/xtoskrnl/ke/amd64/kthread.c +++ b/xtoskrnl/ke/amd64/kthread.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/amd64/kthread.c + * FILE: xtoskrnl/ke/amd64/kthread.cc * DESCRIPTION: AMD64 thread manipulation support * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -33,11 +33,11 @@ */ XTAPI VOID -KepInitializeThreadContext(IN PKTHREAD Thread, - IN PKSYSTEM_ROUTINE SystemRoutine, - IN PKSTART_ROUTINE StartRoutine, - IN PVOID StartContext, - IN PCONTEXT ContextRecord) +KE::KThread::InitializeThreadContext(IN PKTHREAD Thread, + IN PKSYSTEM_ROUTINE SystemRoutine, + IN PKSTART_ROUTINE StartRoutine, + IN PVOID StartContext, + IN PCONTEXT ContextRecord) { PKTHREAD_INIT_FRAME ThreadFrame; @@ -45,7 +45,7 @@ KepInitializeThreadContext(IN PKTHREAD Thread, ThreadFrame = ((PKTHREAD_INIT_FRAME)Thread->InitialStack) - 1; /* Fill floating point save area with zeroes */ - RtlZeroMemory(&ThreadFrame->NpxFrame, sizeof(FLOATING_SAVE_AREA)); + RTL::Memory::ZeroMemory(&ThreadFrame->NpxFrame, sizeof(FLOATING_SAVE_AREA)); /* Check if context provided for this thread */ if(ContextRecord) @@ -54,8 +54,8 @@ KepInitializeThreadContext(IN PKTHREAD Thread, UNIMPLEMENTED; /* Fill exception and trap frames with zeroes */ - RtlZeroMemory(&ThreadFrame->ExceptionFrame, sizeof(KEXCEPTION_FRAME)); - RtlZeroMemory(&ThreadFrame->TrapFrame, sizeof(KTRAP_FRAME)); + RTL::Memory::ZeroMemory(&ThreadFrame->ExceptionFrame, sizeof(KEXCEPTION_FRAME)); + RTL::Memory::ZeroMemory(&ThreadFrame->TrapFrame, sizeof(KTRAP_FRAME)); /* Disable debug registers and enable context registers */ ContextRecord->ContextFlags &= ~CONTEXT_DEBUG_REGISTERS | CONTEXT_CONTROL; @@ -99,7 +99,7 @@ KepInitializeThreadContext(IN PKTHREAD Thread, Thread->NpxState = NPX_STATE_UNUSED; /* Set thread start address */ - ThreadFrame->StartFrame.Return = (ULONG64)NULL; + ThreadFrame->StartFrame.Return = (ULONG64)NULLPTR; } /* Initialize thread startup information */ diff --git a/xtoskrnl/ke/amd64/proc.c b/xtoskrnl/ke/amd64/proc.c deleted file mode 100644 index 04b7ca6..0000000 --- a/xtoskrnl/ke/amd64/proc.c +++ /dev/null @@ -1,114 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/amd64/proc.c - * DESCRIPTION: AMD64 processor-related functionality for the kernel - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/** - * Gets the processor block for the currently executing processor. - * - * @return This routine returns the current processor block read from the GS register. - * - * @since XT 1.0 - */ -XTAPI -PKPROCESSOR_BLOCK -KeGetCurrentProcessorBlock(VOID) -{ - /* Get processor block from GS register */ - return (PKPROCESSOR_BLOCK)ArReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Self)); -} - -/** - * Gets the processor control block for the currently executing processor. - * - * @return This routine returns the current processor control block read from the GS register. - * - * @since XT 1.0 - */ -XTAPI -PKPROCESSOR_CONTROL_BLOCK -KeGetCurrentProcessorControlBlock(VOID) -{ - return (PKPROCESSOR_CONTROL_BLOCK)ArReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CurrentPrcb)); -} - -/** - * Gets the number of the currently executing processor. - * - * @return This routine returns the zero-indexed processor number. - * - * @since XT 1.0 - */ -XTAPI -ULONG -KeGetCurrentProcessorNumber(VOID) -{ - return (ULONG)ArReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CpuNumber)); -} - -/** - * Gets the current thread running on the currently executing processor. - * - * @return This routine returns the address of the current thread object. - * - * @since NT 3.5 - */ -XTAPI -PKTHREAD -KeGetCurrentThread(VOID) -{ - return (PKTHREAD)ArReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Prcb.CurrentThread)); -} - -/** - * Saves the current processor state. - * - * @param State - * Supplies a pointer to the processor state structure. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -KepSaveProcessorState(OUT PKPROCESSOR_STATE CpuState) -{ - /* Save CR registers */ - CpuState->SpecialRegisters.Cr0 = ArReadControlRegister(0); - CpuState->SpecialRegisters.Cr2 = ArReadControlRegister(2); - CpuState->SpecialRegisters.Cr3 = ArReadControlRegister(3); - CpuState->SpecialRegisters.Cr4 = ArReadControlRegister(4); - CpuState->SpecialRegisters.Cr8 = ArReadControlRegister(8); - - /* Save DR registers */ - CpuState->SpecialRegisters.KernelDr0 = ArReadDebugRegister(0); - CpuState->SpecialRegisters.KernelDr1 = ArReadDebugRegister(1); - CpuState->SpecialRegisters.KernelDr2 = ArReadDebugRegister(2); - CpuState->SpecialRegisters.KernelDr3 = ArReadDebugRegister(3); - CpuState->SpecialRegisters.KernelDr6 = ArReadDebugRegister(6); - CpuState->SpecialRegisters.KernelDr7 = ArReadDebugRegister(7); - - /* Save MSR registers */ - CpuState->SpecialRegisters.MsrGsBase = ArReadModelSpecificRegister(X86_MSR_GSBASE); - CpuState->SpecialRegisters.MsrGsSwap = ArReadModelSpecificRegister(X86_MSR_KERNEL_GSBASE); - CpuState->SpecialRegisters.MsrCStar = ArReadModelSpecificRegister(X86_MSR_CSTAR); - CpuState->SpecialRegisters.MsrLStar = ArReadModelSpecificRegister(X86_MSR_LSTAR); - CpuState->SpecialRegisters.MsrStar = ArReadModelSpecificRegister(X86_MSR_STAR); - CpuState->SpecialRegisters.MsrSyscallMask = ArReadModelSpecificRegister(X86_MSR_FMASK); - - /* Save XMM control/status register */ - CpuState->SpecialRegisters.MxCsr = ArReadMxCsrRegister(); - - /* Save GDT, IDT, LDT and TaskRegister */ - ArStoreGlobalDescriptorTable(&CpuState->SpecialRegisters.Gdtr.Limit); - ArStoreInterruptDescriptorTable(&CpuState->SpecialRegisters.Idtr.Limit); - ArStoreLocalDescriptorTable(&CpuState->SpecialRegisters.Ldtr); - ArStoreTaskRegister(&CpuState->SpecialRegisters.Tr); -} diff --git a/xtoskrnl/ke/amd64/proc.cc b/xtoskrnl/ke/amd64/proc.cc new file mode 100644 index 0000000..3666888 --- /dev/null +++ b/xtoskrnl/ke/amd64/proc.cc @@ -0,0 +1,114 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/ke/amd64/proc.cc + * DESCRIPTION: AMD64 processor-related functionality for the kernel + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * Gets the processor block for the currently executing processor. + * + * @return This routine returns the current processor block read from the GS register. + * + * @since XT 1.0 + */ +XTAPI +PKPROCESSOR_BLOCK +KE::Processor::GetCurrentProcessorBlock(VOID) +{ + /* Get processor block from GS register */ + return (PKPROCESSOR_BLOCK)AR::CpuFunc::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Self)); +} + +/** + * Gets the processor control block for the currently executing processor. + * + * @return This routine returns the current processor control block read from the GS register. + * + * @since XT 1.0 + */ +XTAPI +PKPROCESSOR_CONTROL_BLOCK +KE::Processor::GetCurrentProcessorControlBlock(VOID) +{ + return (PKPROCESSOR_CONTROL_BLOCK)AR::CpuFunc::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CurrentPrcb)); +} + +/** + * Gets the number of the currently executing processor. + * + * @return This routine returns the zero-indexed processor number. + * + * @since XT 1.0 + */ +XTAPI +ULONG +KE::Processor::GetCurrentProcessorNumber(VOID) +{ + return (ULONG)AR::CpuFunc::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CpuNumber)); +} + +/** + * Gets the current thread running on the currently executing processor. + * + * @return This routine returns the address of the current thread object. + * + * @since NT 3.5 + */ +XTAPI +PKTHREAD +KE::Processor::GetCurrentThread(VOID) +{ + return (PKTHREAD)AR::CpuFunc::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Prcb.CurrentThread)); +} + +/** + * Saves the current processor state. + * + * @param State + * Supplies a pointer to the processor state structure. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +KE::Processor::SaveProcessorState(OUT PKPROCESSOR_STATE CpuState) +{ + /* Save CR registers */ + CpuState->SpecialRegisters.Cr0 = AR::CpuFunc::ReadControlRegister(0); + CpuState->SpecialRegisters.Cr2 = AR::CpuFunc::ReadControlRegister(2); + CpuState->SpecialRegisters.Cr3 = AR::CpuFunc::ReadControlRegister(3); + CpuState->SpecialRegisters.Cr4 = AR::CpuFunc::ReadControlRegister(4); + CpuState->SpecialRegisters.Cr8 = AR::CpuFunc::ReadControlRegister(8); + + /* Save DR registers */ + CpuState->SpecialRegisters.KernelDr0 = AR::CpuFunc::ReadDebugRegister(0); + CpuState->SpecialRegisters.KernelDr1 = AR::CpuFunc::ReadDebugRegister(1); + CpuState->SpecialRegisters.KernelDr2 = AR::CpuFunc::ReadDebugRegister(2); + CpuState->SpecialRegisters.KernelDr3 = AR::CpuFunc::ReadDebugRegister(3); + CpuState->SpecialRegisters.KernelDr6 = AR::CpuFunc::ReadDebugRegister(6); + CpuState->SpecialRegisters.KernelDr7 = AR::CpuFunc::ReadDebugRegister(7); + + /* Save MSR registers */ + CpuState->SpecialRegisters.MsrGsBase = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_GSBASE); + CpuState->SpecialRegisters.MsrGsSwap = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_KERNEL_GSBASE); + CpuState->SpecialRegisters.MsrCStar = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_CSTAR); + CpuState->SpecialRegisters.MsrLStar = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_LSTAR); + CpuState->SpecialRegisters.MsrStar = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_STAR); + CpuState->SpecialRegisters.MsrSyscallMask = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_FMASK); + + /* Save XMM control/status register */ + CpuState->SpecialRegisters.MxCsr = AR::CpuFunc::ReadMxCsrRegister(); + + /* Save GDT, IDT, LDT and TaskRegister */ + AR::CpuFunc::StoreGlobalDescriptorTable(&CpuState->SpecialRegisters.Gdtr.Limit); + AR::CpuFunc::StoreInterruptDescriptorTable(&CpuState->SpecialRegisters.Idtr.Limit); + AR::CpuFunc::StoreLocalDescriptorTable(&CpuState->SpecialRegisters.Ldtr); + AR::CpuFunc::StoreTaskRegister(&CpuState->SpecialRegisters.Tr); +} diff --git a/xtoskrnl/ke/apc.c b/xtoskrnl/ke/apc.cc similarity index 79% rename from xtoskrnl/ke/apc.c rename to xtoskrnl/ke/apc.cc index 2d65a9b..9147aa3 100644 --- a/xtoskrnl/ke/apc.c +++ b/xtoskrnl/ke/apc.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/apc.c + * FILE: xtoskrnl/ke/apc.cc * DESCRIPTION: Kernel APC objects support * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -42,14 +42,14 @@ */ XTAPI VOID -KeInitializeApc(IN PKAPC Apc, - IN PKTHREAD Thread, - IN KAPC_ENVIRONMENT Environment, - IN PKKERNEL_ROUTINE KernelRoutine, - IN PKRUNDOWN_ROUTINE RundownRoutine, - IN PKNORMAL_ROUTINE NormalRoutine, - IN KPROCESSOR_MODE ApcMode, - IN PVOID Context) +KE::Apc::InitializeApc(IN PKAPC Apc, + IN PKTHREAD Thread, + IN KAPC_ENVIRONMENT Environment, + IN PKKERNEL_ROUTINE KernelRoutine, + IN PKRUNDOWN_ROUTINE RundownRoutine, + IN PKNORMAL_ROUTINE NormalRoutine, + IN KPROCESSOR_MODE ApcMode, + IN PVOID Context) { /* Set APC type and thread */ Apc->Type = ApcObject; @@ -83,7 +83,7 @@ KeInitializeApc(IN PKAPC Apc, { /* Set context and mode for special APC */ Apc->ApcMode = KernelMode; - Apc->NormalContext = NULL; + Apc->NormalContext = NULLPTR; } /* Mark APC as not inserted yet */ diff --git a/xtoskrnl/ke/bootinfo.cc b/xtoskrnl/ke/bootinfo.cc new file mode 100644 index 0000000..241f91e --- /dev/null +++ b/xtoskrnl/ke/bootinfo.cc @@ -0,0 +1,155 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/ke/bootinfo.cc + * DESCRIPTION: Bootloader-provided system information handling support + * DEVELOPERS: Aiken Harris + */ + +#include + + +/** + * Retrieves a pointer to the DebugPrint routine provided by the bootloader. + * + * @return This routine returns a pointer to the DebugPrint routine. + * + * @since XT 1.0 + */ +XTAPI +PKD_PRINT_ROUTINE +KE::BootInformation::GetDebugPrint(VOID) +{ + return (PKD_PRINT_ROUTINE)InitializationBlock->LoaderInformation.DbgPrint; +} + +/** + * Retrieves the system firmware type (BIOS or UEFI). + * + * @return This routine returns the type of the system firmware. + * + * @since XT 1.0 + */ +XTAPI +SYSTEM_FIRMWARE_TYPE +KE::BootInformation::GetFirmwareType(VOID) +{ + return InitializationBlock->FirmwareInformation.FirmwareType; +} + +/** + * Retrieves a pointer to the specified kernel parameter within the kernel parameters list. + * + * @param ParameterName + * Supplies a pointer to a null-terminated wide string specifying the name of the parameter to search for. + * + * @param Parameter + * Supplies a pointer to a variable that receives a pointer to the matching parameter, or NULLPTR if not found. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTAPI +XTSTATUS +KE::BootInformation::GetKernelParameter(IN PCWSTR ParameterName, + OUT PCWSTR *Parameter) +{ + PCWSTR Match, SearchStart; + SIZE_T ParameterNameLength; + + /* Validate input parameters */ + if(!ParameterName || !Parameter) + { + /* Invalid input parameters, return error */ + return STATUS_INVALID_PARAMETER; + } + + /* Get the length of the parameter name we are looking for */ + ParameterNameLength = RTL::WideString::WideStringLength(ParameterName, 0); + if(ParameterNameLength == 0) + { + /* Do not allow empty parameter names */ + return STATUS_INVALID_PARAMETER; + } + + /* Assume the requested parameter is not present in the kernel parameters */ + *Parameter = NULLPTR; + + /* Start searching from the beginning of the list */ + SearchStart = InitializationBlock->KernelParameters; + + /* Search for the parameter name */ + while((Match = RTL::WideString::FindWideStringInsensitive(SearchStart, ParameterName))) + { + /* Check if the match is at the start of the string or preceded by a space */ + if(Match == InitializationBlock->KernelParameters || *(Match - 1) == L' ') + { + /* Check the character after the match to avoid matching prefixes */ + if(Match[ParameterNameLength] == L'\0' || + Match[ParameterNameLength] == L' ' || + Match[ParameterNameLength] == L'=') + { + /* A valid parameter was found, return a pointer to it */ + *Parameter = Match; + return STATUS_SUCCESS; + } + } + + /* The match was a substring of a larger token, continue searching */ + SearchStart = Match + 1; + } + + /* Parameter not found */ + return STATUS_NOT_FOUND; +} + +/** + * Retrieves a pointer to the list of memory descriptors. + * + * @return This routine returns a pointer to the list of memory descriptors. + * + * @since XT 1.0 + */ +XTAPI +PLIST_ENTRY +KE::BootInformation::GetMemoryDescriptors(VOID) +{ + return &InitializationBlock->MemoryDescriptorListHead; +} + +/** + * Retrieves a pointer to the list of system resources. + * + * @return This routine returns a pointer to the list of system resources. + * + * @since XT 1.0 + */ +XTAPI +PLIST_ENTRY +KE::BootInformation::GetSystemResources(VOID) +{ + return &InitializationBlock->SystemResourcesListHead; +} + +/** + * Initializes the bootloader-provided system information. + * + * @param Block + * Supplies a pointer to the kernel initialization block. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +KE::BootInformation::InitializeInitializationBlock(IN PKERNEL_INITIALIZATION_BLOCK Block) +{ + /* Check if the initialization block is already initialized */ + if(!InitializationBlock) + { + /* Save the kernel initialization block */ + InitializationBlock = Block; + } +} diff --git a/xtoskrnl/ke/panic.c b/xtoskrnl/ke/crash.cc similarity index 72% rename from xtoskrnl/ke/panic.c rename to xtoskrnl/ke/crash.cc index aa27ca3..50172b4 100644 --- a/xtoskrnl/ke/panic.c +++ b/xtoskrnl/ke/crash.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/panic.c + * FILE: xtoskrnl/ke/panic.cc * DESCRIPTION: System shutdown and kernel panic mechanism * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -18,14 +18,14 @@ */ XTAPI VOID -KeHaltSystem(VOID) +KE::Crash::HaltSystem(VOID) { /* Enter infinite loop */ for(;;) { /* Halt system */ - ArClearInterruptFlag(); - ArHalt(); + AR::CpuFunc::ClearInterruptFlag(); + AR::CpuFunc::Halt(); } } @@ -41,9 +41,9 @@ KeHaltSystem(VOID) */ XTAPI VOID -KePanic(IN ULONG Code) +KE::Crash::Panic(IN ULONG Code) { - KePanicEx(Code, 0, 0, 0, 0); + PanicEx(Code, 0, 0, 0, 0); } /** @@ -70,12 +70,12 @@ KePanic(IN ULONG Code) */ XTAPI VOID -KePanicEx(IN ULONG Code, - IN ULONG_PTR Parameter1, - IN ULONG_PTR Parameter2, - IN ULONG_PTR Parameter3, - IN ULONG_PTR Parameter4) +KE::Crash::PanicEx(IN ULONG Code, + IN ULONG_PTR Parameter1, + IN ULONG_PTR Parameter2, + IN ULONG_PTR Parameter3, + IN ULONG_PTR Parameter4) { - KdPrint(L"Fatal System Error: 0x%08lx\nKernel Panic!\n\n", Code); - KeHaltSystem(); + KD::DebugIo::KdPrint(L"Fatal System Error: 0x%08lx\nKernel Panic!\n\n", Code); + HaltSystem(); } diff --git a/xtoskrnl/ke/data.cc b/xtoskrnl/ke/data.cc new file mode 100644 index 0000000..60722bf --- /dev/null +++ b/xtoskrnl/ke/data.cc @@ -0,0 +1,28 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/ke/data.cc + * DESCRIPTION: Kernel Library global and static data + * DEVELOPERS: Aiken Harris + */ + +#include + + +/* Kernel initialization block passed by boot loader */ +PKERNEL_INITIALIZATION_BLOCK KE::BootInformation::InitializationBlock = {}; + +/* Kernel boot resources list */ +LIST_ENTRY KE::SystemResources::ResourcesListHead; + +/* Kernel boot resources lock */ +KSPIN_LOCK KE::SystemResources::ResourcesLock; + +/* Kernel initial process */ +EPROCESS KE::KProcess::InitialProcess; + +/* Kernel initial thread */ +ETHREAD KE::KThread::InitialThread = {}; + +/* Kernel UBSAN active frame flag */ +BOOLEAN KE::KUbsan::ActiveFrame = FALSE; diff --git a/xtoskrnl/ke/dpc.c b/xtoskrnl/ke/dpc.cc similarity index 79% rename from xtoskrnl/ke/dpc.c rename to xtoskrnl/ke/dpc.cc index 3b7f9af..f0f707d 100644 --- a/xtoskrnl/ke/dpc.c +++ b/xtoskrnl/ke/dpc.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/dpc.c + * FILE: xtoskrnl/ke/dpc.cc * DESCRIPTION: Deferred Procedure Call (DPC) support * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -27,9 +27,9 @@ */ XTAPI VOID -KeInitializeDpc(IN PKDPC Dpc, - IN PKDEFERRED_ROUTINE DpcRoutine, - IN PVOID DpcContext) +KE::Dpc::InitializeDpc(IN PKDPC Dpc, + IN PKDEFERRED_ROUTINE DpcRoutine, + IN PVOID DpcContext) { /* Initialize DPC */ Dpc->Type = DpcObject; @@ -39,7 +39,7 @@ KeInitializeDpc(IN PKDPC Dpc, /* Initialize DPC routine and context data */ Dpc->DeferredContext = DpcContext; Dpc->DeferredRoutine = DpcRoutine; - Dpc->DpcData = NULL; + Dpc->DpcData = NULLPTR; } /** @@ -60,9 +60,9 @@ KeInitializeDpc(IN PKDPC Dpc, */ XTAPI VOID -KeInitializeThreadedDpc(IN PKDPC Dpc, - IN PKDEFERRED_ROUTINE DpcRoutine, - IN PVOID DpcContext) +KE::Dpc::InitializeThreadedDpc(IN PKDPC Dpc, + IN PKDEFERRED_ROUTINE DpcRoutine, + IN PVOID DpcContext) { /* Initialize threaded DPC */ Dpc->Type = ThreadedDpcObject; @@ -72,7 +72,7 @@ KeInitializeThreadedDpc(IN PKDPC Dpc, /* Initialize DPC routine and context data */ Dpc->DeferredContext = DpcContext; Dpc->DeferredRoutine = DpcRoutine; - Dpc->DpcData = NULL; + Dpc->DpcData = NULLPTR; } /** @@ -90,8 +90,8 @@ KeInitializeThreadedDpc(IN PKDPC Dpc, */ XTAPI VOID -KeSetTargetProcessorDpc(IN PKDPC Dpc, - IN CCHAR Number) +KE::Dpc::SetTargetProcessor(IN PKDPC Dpc, + IN CCHAR Number) { Dpc->Number = MAXIMUM_PROCESSORS + Number; } @@ -108,9 +108,9 @@ KeSetTargetProcessorDpc(IN PKDPC Dpc, */ XTAPI VOID -KeSignalCallDpcDone(IN PVOID SystemArgument) +KE::Dpc::SignalCallDone(IN PVOID SystemArgument) { - RtlAtomicDecrement32(SystemArgument); + RTL::Atomic::Decrement32((PLONG)SystemArgument); } /** @@ -125,7 +125,7 @@ KeSignalCallDpcDone(IN PVOID SystemArgument) */ XTAPI BOOLEAN -KeSignalCallDpcSynchronize(IN PVOID SystemArgument) +KE::Dpc::SignalCallSynchronize(IN PVOID SystemArgument) { UNIMPLEMENTED; @@ -145,7 +145,7 @@ KeSignalCallDpcSynchronize(IN PVOID SystemArgument) */ XTFASTCALL VOID -KepRetireDpcList(IN PKPROCESSOR_CONTROL_BLOCK Prcb) +KE::Dpc::RetireList(IN PKPROCESSOR_CONTROL_BLOCK Prcb) { UNIMPLEMENTED; } diff --git a/xtoskrnl/ke/event.c b/xtoskrnl/ke/event.cc similarity index 80% rename from xtoskrnl/ke/event.c rename to xtoskrnl/ke/event.cc index 2cffd3e..df7085c 100644 --- a/xtoskrnl/ke/event.c +++ b/xtoskrnl/ke/event.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/event.c + * FILE: xtoskrnl/ke/event.cc * DESCRIPTION: Kernel events support * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -21,7 +21,7 @@ */ XTAPI VOID -KeClearEvent(IN PKEVENT Event) +KE::Event::ClearEvent(IN PKEVENT Event) { /* Clear event's signal state */ Event->Header.SignalState = FALSE; @@ -45,9 +45,9 @@ KeClearEvent(IN PKEVENT Event) */ XTAPI VOID -KeInitializeEvent(OUT PKEVENT Event, - IN KEVENT_TYPE EventType, - IN BOOLEAN InitialState) +KE::Event::InitializeEvent(OUT PKEVENT Event, + IN KEVENT_TYPE EventType, + IN BOOLEAN InitialState) { /* Initialize event dispatcher header */ Event->Header.Type = EventType; @@ -75,9 +75,9 @@ KeInitializeEvent(OUT PKEVENT Event, */ XTAPI LONG -KeSetEvent(IN PKEVENT Event, - IN KPRIORITY Increment, - IN BOOLEAN Wait) +KE::Event::SetEvent(IN PKEVENT Event, + IN KPRIORITY Increment, + IN BOOLEAN Wait) { UNIMPLEMENTED; diff --git a/xtoskrnl/ke/exports.cc b/xtoskrnl/ke/exports.cc new file mode 100644 index 0000000..040b2be --- /dev/null +++ b/xtoskrnl/ke/exports.cc @@ -0,0 +1,533 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/ke/exports.cc + * DESCRIPTION: C-compatible API wrappers for exported kernel functions + * DEVELOPERS: Aiken Harris + */ + +#include + + +/** + * Acquires a specified queued spinlock. + * + * @param LockLevel + * Supplies the queued spinlock level. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTFASTCALL +VOID +KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel) +{ + KE::SpinLock::AcquireQueuedSpinLock(LockLevel); +} + +/** + * Acquires a kernel spin lock. + * + * @param SpinLock + * Supplies a pointer to the kernel spin lock. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTFASTCALL +VOID +KeAcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock) +{ + KE::SpinLock::AcquireSpinLock(SpinLock); +} + +/** + * Looks for an unacquired system resource of the specified type and acquires it. + * + * @param ResourceType + * Supplies system resource type. + * + * @param ResourceHeader + * Specifies a memory area where a pointer to the system resource header will be stored. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +XTSTATUS +KeAcquireSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, + OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader) +{ + return KE::SystemResources::AcquireResource(ResourceType, ResourceHeader); +} + +/** + * Cancels the timer. + * + * @param Timer + * Supplies a pointer to a timer object. + * + * @return This routine returns TRUE if the cancelled timer was set, or FALSE otherwise. + * + * @since NT 3.5 + */ +XTCLINK +XTAPI +BOOLEAN +KeCancelTimer(IN PKTIMER Timer) +{ + return KE::Timer::CancelTimer(Timer); +} + +/** + * Gets the current running level of the current processor. + * + * @return This routine returns the current running level. + * + * @since XT 1.0 + */ +XTCLINK +XTFASTCALL +KRUNLEVEL +KeGetCurrentRunLevel(VOID) +{ + return KE::RunLevel::GetCurrentRunLevel(); +} + +/** + * Looks for an unacquired system resource of the specified type and returns it without acquiring an ownership. + * + * @param ResourceType + * Supplies system resource type. + * + * @param ResourceHeader + * Specifies a memory area where a pointer to the system resource header will be stored. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +XTSTATUS +KeGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, + OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader) +{ + return KE::SystemResources::GetResource(ResourceType, ResourceHeader); +} + +/** + * Reads the current signal state of the given timer. + * + * @param Timer + * Supplies a pointer to a timer object. + * + * @return This routine returns TRUE if the timer is set, or FALSE otherwise. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +BOOLEAN +KeGetTimerState(IN PKTIMER Timer) +{ + return KE::Timer::GetState(Timer); +} + +/** + * Initializes an APC object. + * + * @param Apc + * Supplies a pointer to the APC object. + * + * @param Thread + * Supplies a pointer to the thread object. + * + * @param Environment + * Specifies an environment in which the APC will run. + * + * @param KernelRoutine + * Supplies a pointer to routine called at APC_LEVEL. + * + * @param RundownRoutine + * Supplies a pointer to routine called on thread exit. + * + * @param NormalRoutine + * Supplies a pointer to routine called at IRQL 0. + * + * @param ApcMode + * Specifies processor mode, in which NormalRoutine gets called. + * + * @param Context + * Supplies a pointer to memory area containing data passed to NormalRoutine. + * + * @return This routine does not return any value. + * + * @since NT 3.5 + */ +XTCLINK +XTAPI +VOID +KeInitializeApc(IN PKAPC Apc, + IN PKTHREAD Thread, + IN KAPC_ENVIRONMENT Environment, + IN PKKERNEL_ROUTINE KernelRoutine, + IN PKRUNDOWN_ROUTINE RundownRoutine, + IN PKNORMAL_ROUTINE NormalRoutine, + IN KPROCESSOR_MODE ApcMode, + IN PVOID Context) +{ + KE::Apc::InitializeApc(Apc, Thread, Environment, KernelRoutine, RundownRoutine, NormalRoutine, ApcMode, Context); + +} + +/** + * Initializes Deferred Procedure Call (DPC) object. + * + * @param Dpc + * Supplies a pointer to the DPC being initialized. + * + * @param DpcRoutine + * Supplies a pointer to the DPC routine being called on object removal. + * + * @param DpcContext + * Supplies a pointer to memory area containing context data for DPC routine. + * + * @return This routine does not return any value. + * + * @since NT 3.5 + */ +XTCLINK +XTAPI +VOID +KeInitializeDpc(IN PKDPC Dpc, + IN PKDEFERRED_ROUTINE DpcRoutine, + IN PVOID DpcContext) +{ + KE::Dpc::InitializeDpc(Dpc, DpcRoutine, DpcContext); + +} + +/** + * Initializes Deferred Procedure Call (DPC) object. + * + * @param Dpc + * Supplies a pointer to the DPC being initialized. + * + * @param DpcRoutine + * Supplies a pointer to the DPC routine being called on object removal. + * + * @param DpcContext + * Supplies a pointer to memory area containing context data for DPC routine. + * + * @return This routine does not return any value. + * + * @since NT 5.2 + */ +XTCLINK +XTAPI +VOID +KeInitializeThreadedDpc(IN PKDPC Dpc, + IN PKDEFERRED_ROUTINE DpcRoutine, + IN PVOID DpcContext) +{ + KE::Dpc::InitializeThreadedDpc(Dpc, DpcRoutine, DpcContext); +} + +/** + * Initializes an extended kernel timer. + * + * @param Timer + * Supplies a pointer to a timer object. + * + * @param Type + * Supplies the type of the timer. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +VOID +KeInitializeTimer(OUT PKTIMER Timer, + IN KTIMER_TYPE Type) +{ + KE::Timer::InitializeTimer(Timer, Type); +} + +/** + * Initializes a kernel semaphore object. + * + * @param Semaphore + * Supplies a pointer to a semaphore object. + * + * @param Count + * Specifies the initial count value of the semaphore. + * + * @param Limit + * Specifies a maximum count value of the semaphore. + * + * @return This routine does not return any value. + * + * @since NT 3.5 + */ +XTCLINK +XTAPI +VOID +KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, + IN LONG Count, + IN LONG Limit) +{ + KE::Semaphore::InitializeSemaphore(Semaphore, Count, Limit); +} + +/** + * Initializes a kernel spinlock object. + * + * @param SpinLock + * Supplies a pointer to a kernel spin lock. + * + * @return This routine does not return any value. + * + * @since NT 3.5 + */ +XTCLINK +XTAPI +VOID +KeInitializeSpinLock(IN PKSPIN_LOCK SpinLock) +{ + KE::SpinLock::InitializeSpinLock(SpinLock); +} + +/** + * Lowers the running level of the current processor. + * + * @param RunLevel + * Supplies the new running level to lower to. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTFASTCALL +VOID +KeLowerRunLevel(KRUNLEVEL RunLevel) +{ + KE::RunLevel::LowerRunLevel(RunLevel); +} + +/** + * Raises the running level of the current processor. + * + * @param RunLevel + * Supplies the new running level to raise to. + * + * @return This routine returns the old running level. + * + * @since XT 1.0 + */ +XTCLINK +XTFASTCALL +KRUNLEVEL +KeRaiseRunLevel(KRUNLEVEL RunLevel) +{ + return KE::RunLevel::RaiseRunLevel(RunLevel); +} + +/** + * Reads semaphore's current signal state. + * + * @param Semaphore + * Supplies a pointer to a semaphore object. + * + * @return This routine returns the current signal state of the semaphore. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +LONG +KeReadSemaphoreState(IN PKSEMAPHORE Semaphore) +{ + return KE::Semaphore::ReadState(Semaphore); +} + +/** + * Releases a queued spinlock. + * + * @param LockLevel + * Supplies the queued spinlock level. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTFASTCALL +VOID +KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel) +{ + KE::SpinLock::ReleaseQueuedSpinLock(LockLevel); +} + +/** + * Releases a semaphore. + * + * @param Semaphore + * Supplies a pointer to a semaphore object. + * + * @param Increment + * Specifies the priority increment value of the semaphore. + * + * @param Adjustment + * Specifies adjustment value added to the semaphore's initial count value. + * + * @param Wait + * Determines whether release of the semaphore will be followed by a kernel wait routine call or not. + * + * @return This routine returns a previous signal state of the semaphore. + * + * @since NT 3.5 + */ +XTCLINK +XTAPI +LONG +KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, + IN KPRIORITY Increment, + IN LONG Adjustment, + IN BOOLEAN Wait) +{ + return KE::Semaphore::ReleaseSemaphore(Semaphore, Increment, Adjustment, Wait); +} + +/** + * Releases a kernel spin lock. + * + * @param SpinLock + * Supplies a pointer to the kernel spin lock. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTFASTCALL +VOID +KeReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock) +{ + KE::SpinLock::ReleaseSpinLock(SpinLock); +} + +/** + * Releases system resource. + * + * @param ResourceHeader + * Specifies a pointer to the system resource header. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +VOID +KeReleaseSystemResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader) +{ + KE::SystemResources::ReleaseResource(ResourceHeader); +} + +/** + * Sets the target processor number for DPC. + * + * @param Dpc + * Supplies a pointer to the DPC object. + * + * @param Number + * Supplies the target processor number. + * + * @return This routine does not return any value. + * + * @since NT 4.0 + */ +XTCLINK +XTAPI +VOID +KeSetTargetProcessorDpc(IN PKDPC Dpc, + IN CCHAR Number) +{ + KE::Dpc::SetTargetProcessor(Dpc, Number); +} + +/** + * Sets the supplied timer to expire at the specified time. + * + * @param Timer + * Supplies a pointer to a timer object. + * + * @param DueTime + * Supplies the time at which the timer should expire (both absolute and relative times are supported). + * + * @param Period + * Supplies the timer period. + * + * @param Dpc + * Supplies a pointer to a Deferred Procedure Call (DPC) object. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +VOID +KeSetTimer(IN PKTIMER Timer, + IN LARGE_INTEGER DueTime, + IN LONG Period, + IN PKDPC Dpc) +{ + KE::Timer::SetTimer(Timer, DueTime, Period, Dpc); +} + +/** + * Decrements the DPC call barier. + * + * @param SystemArgument + * Supplies an address of the DPC call barrier. + * + * @return This routine does not return any value. + * + * @since NT 5.2 + */ +XTCLINK +XTAPI +VOID +KeSignalCallDpcDone(IN PVOID SystemArgument) +{ + KE::Dpc::SignalCallDone(SystemArgument); +} + +/** + * Decrements the DPC call reverse barier. + * + * @param SystemArgument + * Supplies an address of the DPC call barrier. + * + * @return This routine returns TRUE if just one processor is waiting on the barrier, FALSE if more. + * + * @since NT 5.2 + */ +XTCLINK +XTAPI +BOOLEAN +KeSignalCallDpcSynchronize(IN PVOID SystemArgument) +{ + return KE::Dpc::SignalCallSynchronize(SystemArgument); +} diff --git a/xtoskrnl/ke/globals.c b/xtoskrnl/ke/globals.c deleted file mode 100644 index db00301..0000000 --- a/xtoskrnl/ke/globals.c +++ /dev/null @@ -1,37 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/globals.c - * DESCRIPTION: Architecture independent global variables related to KE subsystem - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/* Pointer to boot loader provided DbgPrint() routine */ -VOID (*KeDbgPrint)(IN PCWSTR Format, IN ...) = NULL; - -/* Kernel initialization block passed by boot loader */ -PKERNEL_INITIALIZATION_BLOCK KeInitializationBlock; - -/* Kernel initial process */ -EPROCESS KeInitialProcess; - -/* Kernel initial thread */ -ETHREAD KeInitialThread; - -/* Kernel service descriptor table */ -KSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable[KSERVICE_TABLES_COUNT]; - -/* Kernel process list */ -LIST_ENTRY KepProcessListHead; - -/* Kernel system resources list */ -LIST_ENTRY KepSystemResourcesListHead; - -/* Kernel system resources lock */ -KSPIN_LOCK KepSystemResourcesLock; - -/* Kernel UBSAN active frame flag */ -BOOLEAN KepUbsanActiveFrame = FALSE; diff --git a/xtoskrnl/ke/i686/irqs.c b/xtoskrnl/ke/i686/irq.cc similarity index 78% rename from xtoskrnl/ke/i686/irqs.c rename to xtoskrnl/ke/i686/irq.cc index 20aa214..556d006 100644 --- a/xtoskrnl/ke/i686/irqs.c +++ b/xtoskrnl/ke/i686/irq.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/i686/irqs.c + * FILE: xtoskrnl/ke/i686/irq.cc * DESCRIPTION: Kernel interrupts support for i686 architecture * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -24,13 +24,13 @@ */ XTAPI VOID -KeSetInterruptHandler(IN ULONG Vector, - IN PVOID Handler) +KE::Irq::SetInterruptHandler(IN ULONG Vector, + IN PVOID Handler) { PKPROCESSOR_BLOCK ProcessorBlock; /* Get current processor block */ - ProcessorBlock = KeGetCurrentProcessorBlock(); + ProcessorBlock = KE::Processor::GetCurrentProcessorBlock(); /* Update interrupt handler */ ProcessorBlock->IdtBase[(UCHAR) Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF); diff --git a/xtoskrnl/ke/i686/krnlinit.c b/xtoskrnl/ke/i686/krnlinit.cc similarity index 58% rename from xtoskrnl/ke/i686/krnlinit.c rename to xtoskrnl/ke/i686/krnlinit.cc index 6d0d725..c2a418a 100644 --- a/xtoskrnl/ke/i686/krnlinit.c +++ b/xtoskrnl/ke/i686/krnlinit.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/i686/krnlinit.c + * FILE: xtoskrnl/ke/i686/krnlinit.cc * DESCRIPTION: CPU architecture specific kernel initialization * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -18,17 +18,17 @@ */ XTAPI VOID -KepInitializeKernel(VOID) +KE::KernelInit::InitializeKernel(VOID) { XTSTATUS Status; /* Initialize hardware layer subsystem */ - Status = HlInitializeSystem(); + Status = HL::Init::InitializeSystem(); if(Status != STATUS_SUCCESS) { /* Hardware layer initialization failed, kernel panic */ DebugPrint(L"Failed to initialize hardware layer subsystem!\n"); - KePanic(0); + Crash::Panic(0); } } @@ -41,20 +41,20 @@ KepInitializeKernel(VOID) */ XTAPI VOID -KepInitializeMachine(VOID) +KE::KernelInit::InitializeMachine(VOID) { /* Re-enable IDE interrupts */ - HlIoPortOutByte(0x376, 0); - HlIoPortOutByte(0x3F6, 0); + HL::IoPort::WritePort8(0x376, 0); + HL::IoPort::WritePort8(0x3F6, 0); /* Initialize frame buffer */ - HlInitializeFrameBuffer(); + HL::FrameBuffer::InitializeFrameBuffer(); /* Initialize processor */ - HlInitializeProcessor(); + HL::Cpu::InitializeProcessor(); /* Initialize page map support */ - MmInitializePageMapSupport(); + MM::Paging::InitializePageMapSupport(); } /** @@ -66,7 +66,7 @@ KepInitializeMachine(VOID) */ XTAPI VOID -KepStartKernel(VOID) +KE::KernelInit::StartKernel(VOID) { PKPROCESSOR_CONTROL_BLOCK Prcb; ULONG_PTR PageDirectory[2]; @@ -74,33 +74,33 @@ KepStartKernel(VOID) PKTHREAD CurrentThread; /* Get processor control block and current thread */ - Prcb = KeGetCurrentProcessorControlBlock(); - CurrentThread = KeGetCurrentThread(); + Prcb = Processor::GetCurrentProcessorControlBlock(); + CurrentThread = Processor::GetCurrentThread(); /* Get current process */ CurrentProcess = CurrentThread->ApcState.Process; /* Initialize CPU power state structures */ - PoInitializeProcessorControlBlock(Prcb); + PO::Idle::InitializeProcessorIdleState(Prcb); /* Save processor state */ - KepSaveProcessorState(&Prcb->ProcessorState); + Processor::SaveProcessorState(&Prcb->ProcessorState); /* Lower to APC runlevel */ - KeLowerRunLevel(APC_LEVEL); + RunLevel::LowerRunLevel(APC_LEVEL); /* Initialize XTOS kernel */ - KepInitializeKernel(); + InitializeKernel(); /* Initialize Idle process */ - RtlInitializeListHead(&KepProcessListHead); PageDirectory[0] = 0; PageDirectory[1] = 0; - KeInitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE); + KProcess::InitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE); CurrentProcess->Quantum = MAXCHAR; /* Initialize Idle thread */ - KeInitializeThread(CurrentProcess, CurrentThread, NULL, NULL, NULL, NULL, NULL, ArKernelBootStack, TRUE); + KThread::InitializeThread(CurrentProcess, CurrentThread, NULLPTR, NULLPTR, NULLPTR, + NULLPTR, NULLPTR, AR::ProcSup::GetBootStack(), TRUE); CurrentThread->NextProcessor = Prcb->CpuNumber; CurrentThread->Priority = THREAD_HIGH_PRIORITY; CurrentThread->State = Running; @@ -109,31 +109,41 @@ KepStartKernel(VOID) CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber; /* Enter infinite loop */ - DebugPrint(L"KepStartKernel() finished. Entering infinite loop.\n"); - for(;;); + DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n"); + Crash::HaltSystem(); } /** - * Switches to a new kernel boot stack. + * Switches execution to a new boot stack and transfers control to the KernelInit::StartKernel() routine. * - * @return This routine does not return any value + * @return This routine does not return any value. * * @since XT 1.0 */ XTAPI VOID -KepSwitchBootStack(IN ULONG_PTR Stack) +KE::KernelInit::SwitchBootStack(VOID) { - /* Discard old stack frame, switch stack, make space for NPX and jump to KepStartKernel() */ + ULONG_PTR Stack; + PVOID StartKernel; + + /* Calculate the stack pointer at the top of the buffer, ensuring it is properly aligned as required by the ABI */ + Stack = ((ULONG_PTR)AR::ProcSup::GetBootStack() + KERNEL_STACK_SIZE) & ~(STACK_ALIGNMENT - 1); + + /* Get address of KernelInit::StartKernel() */ + StartKernel = (PVOID)KernelInit::StartKernel; + + /* Discard old stack frame, switch stack, make space for NPX and jump to KernelInit::StartKernel() */ __asm__ volatile("mov %0, %%edx\n" "xor %%ebp, %%ebp\n" "mov %%edx, %%esp\n" "sub %1, %%esp\n" "push %2\n" - "jmp _KepStartKernel@0\n" + "jmp *%3\n" : : "m" (Stack), "i" (KTRAP_FRAME_ALIGN | KTRAP_FRAME_SIZE | NPX_FRAME_SIZE | KRETURN_ADDRESS_SIZE), "i" (CR0_EM | CR0_MP | CR0_TS), - "p" (KepStartKernel)); + "r" (StartKernel) + : "edx", "ebp", "esp", "memory"); } diff --git a/xtoskrnl/ke/i686/kthread.c b/xtoskrnl/ke/i686/kthread.cc similarity index 84% rename from xtoskrnl/ke/i686/kthread.c rename to xtoskrnl/ke/i686/kthread.cc index 441911a..efae4f6 100644 --- a/xtoskrnl/ke/i686/kthread.c +++ b/xtoskrnl/ke/i686/kthread.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/i686/kthread.c + * FILE: xtoskrnl/ke/i686/kthread.cc * DESCRIPTION: I686 thread manipulation support * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -33,20 +33,20 @@ */ XTAPI VOID -KepInitializeThreadContext(IN PKTHREAD Thread, - IN PKSYSTEM_ROUTINE SystemRoutine, - IN PKSTART_ROUTINE StartRoutine, - IN PVOID StartContext, - IN PCONTEXT ContextRecord) +KE::KThread::InitializeThreadContext(IN PKTHREAD Thread, + IN PKSYSTEM_ROUTINE SystemRoutine, + IN PKSTART_ROUTINE StartRoutine, + IN PVOID StartContext, + IN PCONTEXT ContextRecord) { PKTHREAD_INIT_FRAME ThreadFrame; PFX_SAVE_FORMAT FxSaveFormat; /* Set initial thread frame */ - ThreadFrame = (PKTHREAD_INIT_FRAME)(Thread->InitialStack - sizeof(KTHREAD_INIT_FRAME)); + ThreadFrame = (PKTHREAD_INIT_FRAME)((ULONG_PTR)Thread->InitialStack - sizeof(KTHREAD_INIT_FRAME)); /* Fill floating point save area with zeroes */ - RtlZeroMemory(&ThreadFrame->NpxFrame, sizeof(FX_SAVE_AREA)); + RTL::Memory::ZeroMemory(&ThreadFrame->NpxFrame, sizeof(FX_SAVE_AREA)); /* Check if context provided for this thread */ if(ContextRecord) @@ -55,7 +55,7 @@ KepInitializeThreadContext(IN PKTHREAD Thread, UNIMPLEMENTED; /* Fill trap frame with zeroes */ - RtlZeroMemory(&ThreadFrame->TrapFrame, sizeof(KTRAP_FRAME)); + RTL::Memory::ZeroMemory(&ThreadFrame->TrapFrame, sizeof(KTRAP_FRAME)); /* Disable debug registers and enable context registers */ ContextRecord->ContextFlags &= ~CONTEXT_DEBUG_REGISTERS | CONTEXT_CONTROL; diff --git a/xtoskrnl/ke/i686/proc.c b/xtoskrnl/ke/i686/proc.c deleted file mode 100644 index e7bcf21..0000000 --- a/xtoskrnl/ke/i686/proc.c +++ /dev/null @@ -1,102 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/i686/proc.c - * DESCRIPTION: I686 processor-related functionality for the kernel - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/** - * Gets the processor block for the currently executing processor. - * - * @return This routine returns the current processor block read from the FS register. - * - * @since XT 1.0 - */ -XTAPI -PKPROCESSOR_BLOCK -KeGetCurrentProcessorBlock(VOID) -{ - /* Get processor block from FS register */ - return (PKPROCESSOR_BLOCK)ArReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Self)); -} - -/** - * Gets the processor control block for the currently executing processor. - * - * @return This routine returns the current processor control block read from the FS register. - * - * @since XT 1.0 - */ -XTAPI -PKPROCESSOR_CONTROL_BLOCK -KeGetCurrentProcessorControlBlock(VOID) -{ - return (PKPROCESSOR_CONTROL_BLOCK)ArReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CurrentPrcb)); -} - -/** - * Gets the number of the currently executing processor. - * - * @return This routine returns the zero-indexed processor number. - * - * @since XT 1.0 - */ -XTAPI -ULONG -KeGetCurrentProcessorNumber(VOID) -{ - return (ULONG)ArReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CpuNumber)); -} - -/** - * Gets the current thread running on the currently executing processor. - * - * @return This routine returns the address of the current thread object. - * - * @since NT 3.5 - */ -XTAPI -PKTHREAD -KeGetCurrentThread(VOID) -{ - return (PKTHREAD)ArReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Prcb.CurrentThread)); -} - -/** - * Saves the current processor state. - * - * @param State - * Supplies a pointer to the processor state structure. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -KepSaveProcessorState(OUT PKPROCESSOR_STATE CpuState) -{ - /* Save CR registers */ - CpuState->SpecialRegisters.Cr0 = ArReadControlRegister(0); - CpuState->SpecialRegisters.Cr2 = ArReadControlRegister(2); - CpuState->SpecialRegisters.Cr3 = ArReadControlRegister(3); - CpuState->SpecialRegisters.Cr4 = ArReadControlRegister(4); - - /* Save DR registers */ - CpuState->SpecialRegisters.KernelDr0 = ArReadDebugRegister(0); - CpuState->SpecialRegisters.KernelDr1 = ArReadDebugRegister(1); - CpuState->SpecialRegisters.KernelDr2 = ArReadDebugRegister(2); - CpuState->SpecialRegisters.KernelDr3 = ArReadDebugRegister(3); - CpuState->SpecialRegisters.KernelDr6 = ArReadDebugRegister(6); - CpuState->SpecialRegisters.KernelDr7 = ArReadDebugRegister(7); - - /* Save GDT, IDT, LDT and TaskRegister */ - ArStoreGlobalDescriptorTable(&CpuState->SpecialRegisters.Gdtr.Limit); - ArStoreInterruptDescriptorTable(&CpuState->SpecialRegisters.Idtr.Limit); - ArStoreLocalDescriptorTable(&CpuState->SpecialRegisters.Ldtr); - ArStoreTaskRegister(&CpuState->SpecialRegisters.Tr); -} diff --git a/xtoskrnl/ke/i686/proc.cc b/xtoskrnl/ke/i686/proc.cc new file mode 100644 index 0000000..c405675 --- /dev/null +++ b/xtoskrnl/ke/i686/proc.cc @@ -0,0 +1,102 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/ke/i686/proc.c + * DESCRIPTION: I686 processor-related functionality for the kernel + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * Gets the processor block for the currently executing processor. + * + * @return This routine returns the current processor block read from the FS register. + * + * @since XT 1.0 + */ +XTAPI +PKPROCESSOR_BLOCK +KE::Processor::GetCurrentProcessorBlock(VOID) +{ + /* Get processor block from FS register */ + return (PKPROCESSOR_BLOCK)AR::CpuFunc::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Self)); +} + +/** + * Gets the processor control block for the currently executing processor. + * + * @return This routine returns the current processor control block read from the FS register. + * + * @since XT 1.0 + */ +XTAPI +PKPROCESSOR_CONTROL_BLOCK +KE::Processor::GetCurrentProcessorControlBlock(VOID) +{ + return (PKPROCESSOR_CONTROL_BLOCK)AR::CpuFunc::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CurrentPrcb)); +} + +/** + * Gets the number of the currently executing processor. + * + * @return This routine returns the zero-indexed processor number. + * + * @since XT 1.0 + */ +XTAPI +ULONG +KE::Processor::GetCurrentProcessorNumber(VOID) +{ + return (ULONG)AR::CpuFunc::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CpuNumber)); +} + +/** + * Gets the current thread running on the currently executing processor. + * + * @return This routine returns the address of the current thread object. + * + * @since NT 3.5 + */ +XTAPI +PKTHREAD +KE::Processor::GetCurrentThread(VOID) +{ + return (PKTHREAD)AR::CpuFunc::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Prcb.CurrentThread)); +} + +/** + * Saves the current processor state. + * + * @param State + * Supplies a pointer to the processor state structure. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +KE::Processor::SaveProcessorState(OUT PKPROCESSOR_STATE CpuState) +{ + /* Save CR registers */ + CpuState->SpecialRegisters.Cr0 = AR::CpuFunc::ReadControlRegister(0); + CpuState->SpecialRegisters.Cr2 = AR::CpuFunc::ReadControlRegister(2); + CpuState->SpecialRegisters.Cr3 = AR::CpuFunc::ReadControlRegister(3); + CpuState->SpecialRegisters.Cr4 = AR::CpuFunc::ReadControlRegister(4); + + /* Save DR registers */ + CpuState->SpecialRegisters.KernelDr0 = AR::CpuFunc::ReadDebugRegister(0); + CpuState->SpecialRegisters.KernelDr1 = AR::CpuFunc::ReadDebugRegister(1); + CpuState->SpecialRegisters.KernelDr2 = AR::CpuFunc::ReadDebugRegister(2); + CpuState->SpecialRegisters.KernelDr3 = AR::CpuFunc::ReadDebugRegister(3); + CpuState->SpecialRegisters.KernelDr6 = AR::CpuFunc::ReadDebugRegister(6); + CpuState->SpecialRegisters.KernelDr7 = AR::CpuFunc::ReadDebugRegister(7); + + /* Save GDT, IDT, LDT and TaskRegister */ + AR::CpuFunc::StoreGlobalDescriptorTable(&CpuState->SpecialRegisters.Gdtr.Limit); + AR::CpuFunc::StoreInterruptDescriptorTable(&CpuState->SpecialRegisters.Idtr.Limit); + AR::CpuFunc::StoreLocalDescriptorTable(&CpuState->SpecialRegisters.Ldtr); + AR::CpuFunc::StoreTaskRegister(&CpuState->SpecialRegisters.Tr); +} diff --git a/xtoskrnl/ke/info.c b/xtoskrnl/ke/info.c deleted file mode 100644 index 8c01ef2..0000000 --- a/xtoskrnl/ke/info.c +++ /dev/null @@ -1,94 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/info.c - * DESCRIPTION: Generic kernel information support - * DEVELOPERS: Aiken Harris - */ - -#include - - -/** - * Retrieves the system firmware type (BIOS or UEFI). - * - * @return This routine returns the type of the system firmware. - * - * @since XT 1.0 - */ -XTAPI -SYSTEM_FIRMWARE_TYPE -KeGetFirmwareType(VOID) -{ - return KeInitializationBlock->FirmwareInformation.FirmwareType; -} - -/** - * Retrieves a pointer to the specified kernel parameter within the kernel parameters list. - * - * @param ParameterName - * Supplies a pointer to a null-terminated wide string specifying the name of the parameter to search for. - * - * @param Parameter - * Supplies a pointer to a variable that receives a pointer to the matching parameter, or NULL if not found. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTAPI -XTSTATUS -KeGetKernelParameter(IN PCWSTR ParameterName, - OUT PCWSTR *Parameter) -{ - PCWSTR KernelParameters,Match, SearchStart; - SIZE_T ParameterNameLength; - - /* Get the kernel parameters */ - KernelParameters = KeInitializationBlock->KernelParameters; - - /* Validate input parameters */ - if(!KernelParameters || !ParameterName || !Parameter) - { - /* Invalid input parameters, return error */ - return STATUS_INVALID_PARAMETER; - } - - /* Get the length of the parameter name we are looking for */ - ParameterNameLength = RtlWideStringLength(ParameterName, 0); - if(ParameterNameLength == 0) - { - /* Do not allow empty parameter names */ - return STATUS_INVALID_PARAMETER; - } - - /* Assume the requested parameter is not present in the kernel parameters */ - *Parameter = NULL; - - /* Start searching from the beginning of the list */ - SearchStart = KernelParameters; - - /* Search for the parameter name */ - while((Match = RtlFindWideStringInsensitive(SearchStart, ParameterName))) - { - /* Check if the match is at the start of the string or preceded by a space */ - if(Match == KernelParameters || *(Match - 1) == L' ') - { - /* Check the character after the match to avoid matching prefixes */ - if(Match[ParameterNameLength] == L'\0' || - Match[ParameterNameLength] == L' ' || - Match[ParameterNameLength] == L'=') - { - /* A valid parameter was found, return a pointer to it */ - *Parameter = Match; - return STATUS_SUCCESS; - } - } - - /* The match was a substring of a larger token, continue searching */ - SearchStart = Match + 1; - } - - /* Parameter not found */ - return STATUS_NOT_FOUND; -} diff --git a/xtoskrnl/ke/kprocess.c b/xtoskrnl/ke/kprocess.cc similarity index 79% rename from xtoskrnl/ke/kprocess.c rename to xtoskrnl/ke/kprocess.cc index 30a6d41..d04a620 100644 --- a/xtoskrnl/ke/kprocess.c +++ b/xtoskrnl/ke/kprocess.cc @@ -1,14 +1,21 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/kprocess.c + * FILE: xtoskrnl/ke/kprocess.cc * DESCRIPTION: XT kernel process manipulation support * DEVELOPERS: Rafal Kupiec */ -#include +#include +XTAPI +PEPROCESS +KE::KProcess::GetInitialProcess(VOID) +{ + return &InitialProcess; +} + /** * Initializes the process. * @@ -33,11 +40,11 @@ */ XTAPI VOID -KeInitializeProcess(IN OUT PKPROCESS Process, - IN KPRIORITY Priority, - IN KAFFINITY Affinity, - IN PULONG_PTR DirectoryTable, - IN BOOLEAN Alignment) +KE::KProcess::InitializeProcess(IN OUT PKPROCESS Process, + IN KPRIORITY Priority, + IN KAFFINITY Affinity, + IN PULONG_PTR DirectoryTable, + IN BOOLEAN Alignment) { /* Initialize process dispatcher header */ Process->Header.Type = ProcessObject; diff --git a/xtoskrnl/ke/krnlinit.c b/xtoskrnl/ke/krnlinit.cc similarity index 64% rename from xtoskrnl/ke/krnlinit.c rename to xtoskrnl/ke/krnlinit.cc index e8705a2..dbd8cdc 100644 --- a/xtoskrnl/ke/krnlinit.c +++ b/xtoskrnl/ke/krnlinit.cc @@ -1,14 +1,17 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/krnlinit.c + * FILE: xtoskrnl/ke/krnlinit.cc * DESCRIPTION: XT kernel initialization * DEVELOPERS: Rafal Kupiec */ -#include +#include +/* Use routines from Kernel Library */ +using namespace KE; + /** * This routine starts up the XT kernel. It is called by boot loader. * @@ -23,37 +26,37 @@ XTAPI VOID KeStartXtSystem(IN PKERNEL_INITIALIZATION_BLOCK Parameters) { - /* Save the kernel initialization block */ - KeInitializationBlock = Parameters; - /* Verify kernel and boot loader compatibility */ - if(KeInitializationBlock->BlockSize != sizeof(KERNEL_INITIALIZATION_BLOCK) || - KeInitializationBlock->BlockVersion != INITIALIZATION_BLOCK_VERSION || - KeInitializationBlock->ProtocolVersion != BOOT_PROTOCOL_VERSION) + if(Parameters->BlockSize != sizeof(KERNEL_INITIALIZATION_BLOCK) || + Parameters->BlockVersion != INITIALIZATION_BLOCK_VERSION || + Parameters->ProtocolVersion != BOOT_PROTOCOL_VERSION) { /* Kernel and boot loader version mismatch */ - KeHaltSystem(); + Crash::HaltSystem(); } + /* Save the kernel initialization block */ + BootInformation::InitializeInitializationBlock(Parameters); + /* Check if debugging enabled and if boot loader provided routine for debug printing */ - if(DEBUG && KeInitializationBlock->LoaderInformation.DbgPrint) + if(DEBUG && BootInformation::GetDebugPrint()) { /* Use loader's provided DbgPrint() routine for early printing to serial console */ - KdSetPrintRoutine(KeInitializationBlock->LoaderInformation.DbgPrint); + KD::DebugIo::SetPrintRoutine(BootInformation::GetDebugPrint()); DebugPrint(L"Initializing ExectOS v%d.%d for %s\n", XTOS_VERSION_MAJOR, XTOS_VERSION_MINOR, _ARCH_NAME); } /* Initialize boot CPU */ - ArInitializeProcessor(NULL); + AR::ProcSup::InitializeProcessor(NULLPTR); /* Initialize system resources */ - KepInitializeSystemResources(); + SystemResources::InitializeResources(); /* Check if debugging enabled */ if(DEBUG) { /* Initialize debug I/O */ - KdInitializeDebugIoProviders(); + KD::DebugIo::InitializeDebugIoProviders(); } /* Announce kernel startup */ @@ -63,11 +66,11 @@ KeStartXtSystem(IN PKERNEL_INITIALIZATION_BLOCK Parameters) XTOS_COMPILER_NAME, XTOS_COMPILER_VERSION); /* Architecture specific kernel initialization */ - KepInitializeMachine(); + KernelInit::InitializeMachine(); /* Raise to HIGH runlevel */ - KeRaiseRunLevel(HIGH_LEVEL); + RunLevel::RaiseRunLevel(HIGH_LEVEL); - /* Switch the boot stack, setting the pointer to the top of the buffer and aligning it as required by the ABI */ - KepSwitchBootStack(((ULONG_PTR)&ArKernelBootStack + KERNEL_STACK_SIZE) & ~(STACK_ALIGNMENT - 1)); + /* Switch the boot stack and transfer control to the KepStartKernel() routine */ + KernelInit::SwitchBootStack(); } diff --git a/xtoskrnl/ke/kthread.c b/xtoskrnl/ke/kthread.cc similarity index 73% rename from xtoskrnl/ke/kthread.c rename to xtoskrnl/ke/kthread.cc index d5c6385..1e531f4 100644 --- a/xtoskrnl/ke/kthread.c +++ b/xtoskrnl/ke/kthread.cc @@ -1,14 +1,41 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/kthread.c + * FILE: xtoskrnl/ke/kthread.cc * DESCRIPTION: XT kernel thread manipulation support * DEVELOPERS: Rafal Kupiec */ -#include +#include +XTAPI +PETHREAD +KE::KThread::GetInitialThread(VOID) +{ + return &InitialThread; +} + +/** + * Exits the dispatcher, switches context to a new thread and lowers runlevel to its original state. + * + * @param OldRunLevel + * Supplies the original runlevel state. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTFASTCALL +VOID +KE::KThread::ExitDispatcher(IN KRUNLEVEL OldRunLevel) +{ + UNIMPLEMENTED; + + /* Lower runlevel */ + RunLevel::LowerRunLevel(OldRunLevel); +} + /** * Initializes the thread. * @@ -42,15 +69,15 @@ */ XTAPI XTSTATUS -KeInitializeThread(IN PKPROCESS Process, - IN OUT PKTHREAD Thread, - IN PKSYSTEM_ROUTINE SystemRoutine, - IN PKSTART_ROUTINE StartRoutine, - IN PVOID StartContext, - IN PCONTEXT Context, - IN PVOID EnvironmentBlock, - IN PVOID Stack, - IN BOOLEAN StartThread) +KE::KThread::InitializeThread(IN PKPROCESS Process, + IN OUT PKTHREAD Thread, + IN PKSYSTEM_ROUTINE SystemRoutine, + IN PKSTART_ROUTINE StartRoutine, + IN PVOID StartContext, + IN PCONTEXT Context, + IN PVOID EnvironmentBlock, + IN PVOID Stack, + IN BOOLEAN RunThread) { PKWAIT_BLOCK TimerWaitBlock; BOOLEAN Allocation; @@ -86,10 +113,7 @@ KeInitializeThread(IN PKPROCESS Process, Thread->AdjustReason = AdjustNone; /* Initialize thread lock */ - KeInitializeSpinLock(&Thread->ThreadLock); - - /* Set thread service table */ - Thread->ServiceTable = KeServiceDescriptorTable; + SpinLock::InitializeSpinLock(&Thread->ThreadLock); /* Initialize thread APC */ Thread->ApcStatePointer[0] = &Thread->ApcState; @@ -103,17 +127,17 @@ KeInitializeThread(IN PKPROCESS Process, RtlInitializeListHead(&Thread->ApcState.ApcListHead[UserMode]); /* Initialize APC queue lock */ - KeInitializeSpinLock(&Thread->ApcQueueLock); + SpinLock::InitializeSpinLock(&Thread->ApcQueueLock); /* Initialize kernel-mode suspend APC */ - KeInitializeApc(&Thread->SuspendApc, Thread, OriginalApcEnvironment, KepSuspendNop, - KepSuspendRundown, KepSuspendThread, KernelMode, NULL); + Apc::InitializeApc(&Thread->SuspendApc, Thread, OriginalApcEnvironment, SuspendNop, + SuspendRundown, SuspendThread, KernelMode, NULLPTR); /* Initialize suspend semaphore */ - KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 2); + Semaphore::InitializeSemaphore(&Thread->SuspendSemaphore, 0, 2); /* Initialize the builtin timer */ - KeInitializeTimer(&Thread->Timer, NotificationTimer); + Timer::InitializeTimer(&Thread->Timer, NotificationTimer); TimerWaitBlock = &Thread->WaitBlock[KTIMER_WAIT_BLOCK]; TimerWaitBlock->Object = &Thread->Timer; TimerWaitBlock->WaitKey = STATUS_TIMEOUT; @@ -122,13 +146,13 @@ KeInitializeThread(IN PKPROCESS Process, TimerWaitBlock->WaitListEntry.Blink = &(&Thread->Timer)->Header.WaitListHead; /* Initialize Thread Environment Block*/ - Thread->EnvironmentBlock = EnvironmentBlock; + Thread->EnvironmentBlock = (PTHREAD_ENVIRONMENT_BLOCK)EnvironmentBlock; /* Make sure there is a valid stack available */ if(!Stack) { /* Allocate new stack */ - Status = MmAllocateKernelStack(&Stack, FALSE, 0); + Status = MM::KernelPool::AllocateKernelStack(&Stack, FALSE, 0); if(Status != STATUS_SUCCESS || !Stack) { /* Stack allocation failed */ @@ -141,12 +165,12 @@ KeInitializeThread(IN PKPROCESS Process, Thread->InitialStack = Stack; Thread->StackBase = Stack; - Thread->StackLimit = Stack - KERNEL_STACK_SIZE; + Thread->StackLimit = (PVOID)((ULONG_PTR)Stack - KERNEL_STACK_SIZE); __try { /* Initialize thread context */ - KepInitializeThreadContext(Thread, SystemRoutine, StartRoutine, StartContext, Context); + InitializeThreadContext(Thread, SystemRoutine, StartRoutine, StartContext, Context); } __except(EXCEPTION_EXECUTE_HANDLER) { @@ -154,9 +178,9 @@ KeInitializeThread(IN PKPROCESS Process, if(Allocation) { /* Deallocate stack */ - MmFreeKernelStack(Stack, FALSE); - Thread->InitialStack = NULL; - Thread->StackBase = NULL; + MM::KernelPool::FreeKernelStack(Stack, FALSE); + Thread->InitialStack = NULLPTR; + Thread->StackBase = NULLPTR; } /* Thread initialization failed */ @@ -167,10 +191,10 @@ KeInitializeThread(IN PKPROCESS Process, Thread->State = Initialized; /* Check if thread should be started */ - if(StartThread) + if(RunThread) { /* Start thread */ - KeStartThread(Thread); + StartThread(Thread); } /* Return success */ @@ -189,31 +213,11 @@ KeInitializeThread(IN PKPROCESS Process, */ XTAPI VOID -KeStartThread(IN PKTHREAD Thread) +KE::KThread::StartThread(IN PKTHREAD Thread) { UNIMPLEMENTED; } -/** - * Exits the dispatcher, switches context to a new thread and lowers runlevel to its original state. - * - * @param OldRunLevel - * Supplies the original runlevel state. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTFASTCALL -VOID -KepExitDispatcher(IN KRUNLEVEL OldRunLevel) -{ - UNIMPLEMENTED; - - /* Lower runlevel */ - KeLowerRunLevel(OldRunLevel); -} - /** * Suspend APC-built thread NOP routine. It takes no actions. * @@ -238,11 +242,11 @@ KepExitDispatcher(IN KRUNLEVEL OldRunLevel) */ XTAPI VOID -KepSuspendNop(IN PKAPC Apc, - IN OUT PKNORMAL_ROUTINE *NormalRoutine, - IN OUT PVOID *NormalContext, - IN OUT PVOID *SystemArgument1, - IN OUT PVOID *SystemArgument2) +KE::KThread::SuspendNop(IN PKAPC Apc, + IN OUT PKNORMAL_ROUTINE *NormalRoutine, + IN OUT PVOID *NormalContext, + IN OUT PVOID *SystemArgument1, + IN OUT PVOID *SystemArgument2) { /* No action here */ } @@ -259,7 +263,7 @@ KepSuspendNop(IN PKAPC Apc, */ XTAPI VOID -KepSuspendRundown(IN PKAPC Apc) +KE::KThread::SuspendRundown(IN PKAPC Apc) { /* No action here */ } @@ -282,9 +286,9 @@ KepSuspendRundown(IN PKAPC Apc) */ XTAPI VOID -KepSuspendThread(IN PVOID NormalContext, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2) +KE::KThread::SuspendThread(IN PVOID NormalContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2) { UNIMPLEMENTED; } diff --git a/xtoskrnl/ke/kubsan.c b/xtoskrnl/ke/kubsan.cc similarity index 79% rename from xtoskrnl/ke/kubsan.c rename to xtoskrnl/ke/kubsan.cc index 5aa11ad..3ba6626 100644 --- a/xtoskrnl/ke/kubsan.c +++ b/xtoskrnl/ke/kubsan.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/kubsan.c + * FILE: xtoskrnl/ke/kubsan.cc * DESCRIPTION: Kernel Undefined Behaviour Sanitizer (UBSAN) error reporting handler * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -21,10 +21,10 @@ */ XTCDECL BOOLEAN -KepCheckUbsanReport(PKUBSAN_SOURCE_LOCATION Location) +KE::KUbsan::CheckReport(PKUBSAN_SOURCE_LOCATION Location) { /* Make sure, this error should be reported */ - return !KepUbsanActiveFrame; + return !ActiveFrame; } /** @@ -42,11 +42,11 @@ KepCheckUbsanReport(PKUBSAN_SOURCE_LOCATION Location) */ XTCDECL VOID -KepEnterUbsanFrame(PKUBSAN_SOURCE_LOCATION Location, - PCCHAR Reason) +KE::KUbsan::EnterFrame(PKUBSAN_SOURCE_LOCATION Location, + PCCHAR Reason) { /* Enter UBSAN frame */ - KepUbsanActiveFrame = TRUE; + ActiveFrame = TRUE; /* Print generic error message to debug console */ DebugPrint(L"UBSAN: Undefined behavior (%s) in %s:%d:%d\n", @@ -68,8 +68,8 @@ KepEnterUbsanFrame(PKUBSAN_SOURCE_LOCATION Location, */ XTCDECL LONGLONG -KepGetSignedUbsanValue(PKUBSAN_TYPE_DESCRIPTOR Type, - PVOID Value) +KE::KUbsan::GetSignedValue(PKUBSAN_TYPE_DESCRIPTOR Type, + PVOID Value) { ULONG BitWidth, ExtraBits; ULONG_PTR LongValue; @@ -102,7 +102,7 @@ KepGetSignedUbsanValue(PKUBSAN_TYPE_DESCRIPTOR Type, */ XTCDECL PCCHAR -KepGetUbsanTypeKind(UCHAR TypeCheckKind) +KE::KUbsan::GetTypeKind(UCHAR TypeCheckKind) { /* Get type kind name */ switch(TypeCheckKind) @@ -147,8 +147,8 @@ KepGetUbsanTypeKind(UCHAR TypeCheckKind) */ XTCDECL ULONGLONG -KepGetUnsignedUbsanValue(PKUBSAN_TYPE_DESCRIPTOR Type, - PVOID Value) +KE::KUbsan::GetUnsignedValue(PKUBSAN_TYPE_DESCRIPTOR Type, + PVOID Value) { ULONG BitWidth; @@ -184,22 +184,22 @@ KepGetUnsignedUbsanValue(PKUBSAN_TYPE_DESCRIPTOR Type, */ XTCDECL VOID -KepHandleUbsanDivisionOverflow(PKUBSAN_OVERFLOW_DATA Data, - PVOID Lhs, - PVOID Rhs) +KE::KUbsan::HandleDivisionOverflow(PKUBSAN_OVERFLOW_DATA Data, + PVOID Lhs, + PVOID Rhs) { /* Check if this error was already reported */ - if(!KepCheckUbsanReport(&Data->Location)) + if(!CheckReport(&Data->Location)) { /* Don't report twice */ return; } /* Enter UBSAN frame */ - KepEnterUbsanFrame(&Data->Location, "Division-Overflow"); + EnterFrame(&Data->Location, "Division-Overflow"); /* Check if signed type, which value is -1 */ - if((Data->Type->TypeInfo & 1) && (KepGetSignedUbsanValue(Data->Type, Rhs) == -1)) + if((Data->Type->TypeInfo & 1) && (GetSignedValue(Data->Type, Rhs) == -1)) { /* Division by -1, print error message to debug console */ DebugPrint(L"UBSAN: Division by -1 cannot be represented in type %s\n", Data->Type->TypeName); @@ -211,7 +211,7 @@ KepHandleUbsanDivisionOverflow(PKUBSAN_OVERFLOW_DATA Data, } /* Leave UBSAN frame */ - KepLeaveUbsanFrame(); + LeaveFrame(); } /** @@ -232,25 +232,25 @@ KepHandleUbsanDivisionOverflow(PKUBSAN_OVERFLOW_DATA Data, */ XTCDECL VOID -KepHandleUbsanFloatCastOverflow(PKUBSAN_FLOAT_CAST_OVERFLOW_DATA Data, - ULONG_PTR Lhs, - ULONG_PTR Rhs) +KE::KUbsan::HandleFloatCastOverflow(PKUBSAN_FLOAT_CAST_OVERFLOW_DATA Data, + ULONG_PTR Lhs, + ULONG_PTR Rhs) { /* Check if this error was already reported */ - if(!KepCheckUbsanReport(&Data->Location)) + if(!CheckReport(&Data->Location)) { /* Don't report twice */ return; } /* Enter UBSAN frame */ - KepEnterUbsanFrame(&Data->Location, "Float-Cast-Overflow"); + EnterFrame(&Data->Location, "Float-Cast-Overflow"); /* Print error message to debug console */ DebugPrint(L"Value of type %s is outside the range of type %s\n", Data->LhsType->TypeName, Data->RhsType->TypeName); /* Leave UBSAN frame */ - KepLeaveUbsanFrame(); + LeaveFrame(); } /** @@ -268,25 +268,25 @@ KepHandleUbsanFloatCastOverflow(PKUBSAN_FLOAT_CAST_OVERFLOW_DATA Data, */ XTCDECL VOID -KepHandleUbsanFunctionTypeMismatch(PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA Data, - ULONG_PTR Pointer) +KE::KUbsan::HandleFunctionTypeMismatch(PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA Data, + ULONG_PTR Pointer) { /* Check if this error was already reported */ - if(!KepCheckUbsanReport(&Data->Location)) + if(!CheckReport(&Data->Location)) { /* Don't report twice */ return; } /* Enter UBSAN frame */ - KepEnterUbsanFrame(&Data->Location, "Float-Cast-Overflow"); + EnterFrame(&Data->Location, "Float-Cast-Overflow"); /* Print error message to debug console */ DebugPrint(L"UBSAN: Indirect function call through %P address of a wrong type %s\n", (PVOID)Pointer, Data->Type->TypeName); /* Leave UBSAN frame */ - KepLeaveUbsanFrame(); + LeaveFrame(); } /** @@ -307,25 +307,25 @@ KepHandleUbsanFunctionTypeMismatch(PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA Data, */ XTCDECL VOID -KepHandleUbsanIntegerOverflow(PKUBSAN_OVERFLOW_DATA Data, - ULONG_PTR Lhs, - ULONG_PTR Rhs) +KE::KUbsan::HandleIntegerOverflow(PKUBSAN_OVERFLOW_DATA Data, + ULONG_PTR Lhs, + ULONG_PTR Rhs) { /* Check if this error was already reported */ - if(!KepCheckUbsanReport(&Data->Location)) + if(!CheckReport(&Data->Location)) { /* Don't report twice */ return; } /* Enter UBSAN frame */ - KepEnterUbsanFrame(&Data->Location, "Integer-Overflow"); + EnterFrame(&Data->Location, "Integer-Overflow"); /* Print error message to debug console */ DebugPrint(L"UBSAN: The result of an arithmetic operation cannot be represented in type %s\n", Data->Type->TypeName); /* Leave UBSAN frame */ - KepLeaveUbsanFrame(); + LeaveFrame(); } /** @@ -340,17 +340,17 @@ KepHandleUbsanIntegerOverflow(PKUBSAN_OVERFLOW_DATA Data, */ XTCDECL VOID -KepHandleUbsanInvalidBuiltin(PKUBSAN_INVALID_BUILTIN_DATA Data) +KE::KUbsan::HandleInvalidBuiltin(PKUBSAN_INVALID_BUILTIN_DATA Data) { /* Check if this error was already reported */ - if(!KepCheckUbsanReport(&Data->Location)) + if(!CheckReport(&Data->Location)) { /* Don't report twice */ return; } /* Enter UBSAN frame */ - KepEnterUbsanFrame(&Data->Location, "Invalid-Builtin"); + EnterFrame(&Data->Location, "Invalid-Builtin"); /* Check kind of UBSAN error */ if(Data->Kind == 0 || Data->Kind == 1) @@ -365,7 +365,7 @@ KepHandleUbsanInvalidBuiltin(PKUBSAN_INVALID_BUILTIN_DATA Data) } /* Leave UBSAN frame */ - KepLeaveUbsanFrame(); + LeaveFrame(); } /** @@ -383,25 +383,25 @@ KepHandleUbsanInvalidBuiltin(PKUBSAN_INVALID_BUILTIN_DATA Data) */ XTCDECL VOID -KepHandleUbsanMisalignedAccess(PKUBSAN_TYPE_MISMATCH_DATA Data, - ULONG_PTR Pointer) +KE::KUbsan::HandleMisalignedAccess(PKUBSAN_TYPE_MISMATCH_DATA Data, + ULONG_PTR Pointer) { /* Check if this error was already reported */ - if(!KepCheckUbsanReport(&Data->Location)) + if(!CheckReport(&Data->Location)) { /* Don't report twice */ return; } /* Enter UBSAN frame */ - KepEnterUbsanFrame(&Data->Location, "Misaligned-Access"); + EnterFrame(&Data->Location, "Misaligned-Access"); /* Print error message to debug console */ DebugPrint(L"UBSAN: %s misaligned address %p for type %s which requires %ld byte alignment\n", - KepGetUbsanTypeKind(Data->TypeCheckKind), (PVOID)Pointer, Data->Type->TypeName, Data->Alignment); + GetTypeKind(Data->TypeCheckKind), (PVOID)Pointer, Data->Type->TypeName, Data->Alignment); /* Leave UBSAN frame */ - KepLeaveUbsanFrame(); + LeaveFrame(); } /** @@ -419,24 +419,24 @@ KepHandleUbsanMisalignedAccess(PKUBSAN_TYPE_MISMATCH_DATA Data, */ XTCDECL VOID -KepHandleUbsanNegateOverflow(PKUBSAN_OVERFLOW_DATA Data, - ULONG_PTR OldValue) +KE::KUbsan::HandleNegateOverflow(PKUBSAN_OVERFLOW_DATA Data, + ULONG_PTR OldValue) { /* Check if this error was already reported */ - if(!KepCheckUbsanReport(&Data->Location)) + if(!CheckReport(&Data->Location)) { /* Don't report twice */ return; } /* Enter UBSAN frame */ - KepEnterUbsanFrame(&Data->Location, "Negate-Overflow"); + EnterFrame(&Data->Location, "Negate-Overflow"); /* Print error message to debug console */ DebugPrint(L"UBSAN: Negation of %lu cannot be represented in type %s\n", OldValue, Data->Type->TypeName); /* Leave UBSAN frame */ - KepLeaveUbsanFrame(); + LeaveFrame(); } @@ -455,23 +455,23 @@ KepHandleUbsanNegateOverflow(PKUBSAN_OVERFLOW_DATA Data, */ XTCDECL VOID -KepHandleUbsanNullPointerDereference(PKUBSAN_TYPE_MISMATCH_DATA Data) +KE::KUbsan::HandleNullPointerDereference(PKUBSAN_TYPE_MISMATCH_DATA Data) { /* Check if this error was already reported */ - if(!KepCheckUbsanReport(&Data->Location)) + if(!CheckReport(&Data->Location)) { /* Don't report twice */ return; } /* Enter UBSAN frame */ - KepEnterUbsanFrame(&Data->Location, "NULL-Pointer-Dereference"); + EnterFrame(&Data->Location, "NULL-Pointer-Dereference"); /* Print error message to debug console */ - DebugPrint(L"UBSAN: %s NULL pointer of type %s\n", KepGetUbsanTypeKind(Data->TypeCheckKind), Data->Type->TypeName); + DebugPrint(L"UBSAN: %s NULL pointer of type %s\n", GetTypeKind(Data->TypeCheckKind), Data->Type->TypeName); /* Leave UBSAN frame */ - KepLeaveUbsanFrame(); + LeaveFrame(); } /** @@ -489,25 +489,25 @@ KepHandleUbsanNullPointerDereference(PKUBSAN_TYPE_MISMATCH_DATA Data) */ XTCDECL VOID -KepHandleUbsanObjectSizeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data, - ULONG_PTR Pointer) +KE::KUbsan::HandleObjectSizeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data, + ULONG_PTR Pointer) { /* Check if this error was already reported */ - if(!KepCheckUbsanReport(&Data->Location)) + if(!CheckReport(&Data->Location)) { /* Don't report twice */ return; } /* Enter UBSAN frame */ - KepEnterUbsanFrame(&Data->Location, "Object-Size-Mismatch"); + EnterFrame(&Data->Location, "Object-Size-Mismatch"); /* Print error message to debug console */ DebugPrint(L"UBSAN: %s address %p with insufficient space for an object of type %s\n", - KepGetUbsanTypeKind(Data->TypeCheckKind), (PVOID)Pointer, Data->Type->TypeName); + GetTypeKind(Data->TypeCheckKind), (PVOID)Pointer, Data->Type->TypeName); /* Leave UBSAN frame */ - KepLeaveUbsanFrame(); + LeaveFrame(); } /** @@ -525,24 +525,24 @@ KepHandleUbsanObjectSizeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data, */ XTCDECL VOID -KepHandleUbsanOutOfBounds(PKUBSAN_OUT_OF_BOUNDS_DATA Data, - ULONG_PTR Index) +KE::KUbsan::HandleOutOfBounds(PKUBSAN_OUT_OF_BOUNDS_DATA Data, + ULONG_PTR Index) { /* Check if this error was already reported */ - if(!KepCheckUbsanReport(&Data->Location)) + if(!CheckReport(&Data->Location)) { /* Don't report twice */ return; } /* Enter UBSAN frame */ - KepEnterUbsanFrame(&Data->Location, "Array-Index-Out-Of-Bounds"); + EnterFrame(&Data->Location, "Array-Index-Out-Of-Bounds"); /* Print error message to debug console */ DebugPrint(L"UBSAN: index is out of range for type %s", Data->ArrayType->TypeName); /* Leave UBSAN frame */ - KepLeaveUbsanFrame(); + LeaveFrame(); } /** @@ -563,26 +563,26 @@ KepHandleUbsanOutOfBounds(PKUBSAN_OUT_OF_BOUNDS_DATA Data, */ XTCDECL VOID -KepHandleUbsanPointerOverflow(PKUBSAN_OVERFLOW_DATA Data, - ULONG_PTR Lhs, - ULONG_PTR Rhs) +KE::KUbsan::HandlePointerOverflow(PKUBSAN_OVERFLOW_DATA Data, + ULONG_PTR Lhs, + ULONG_PTR Rhs) { /* Check if this error was already reported */ - if(!KepCheckUbsanReport(&Data->Location)) + if(!CheckReport(&Data->Location)) { /* Don't report twice */ return; } /* Enter UBSAN frame */ - KepEnterUbsanFrame(&Data->Location, "Pointer-Overflow"); + EnterFrame(&Data->Location, "Pointer-Overflow"); /* Print error message to debug console */ DebugPrint(L"UBSAN: Pointer operation %s %p to %p\n", Lhs > Rhs ? "overflowed" : "underflowed", (PVOID)Lhs, (PVOID)Rhs); /* Leave UBSAN frame */ - KepLeaveUbsanFrame(); + LeaveFrame(); } @@ -604,52 +604,52 @@ KepHandleUbsanPointerOverflow(PKUBSAN_OVERFLOW_DATA Data, */ XTCDECL VOID -KepHandleUbsanShiftOutOfBounds(PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA Data, - ULONG_PTR Lhs, - ULONG_PTR Rhs) +KE::KUbsan::HandleShiftOutOfBounds(PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA Data, + ULONG_PTR Lhs, + ULONG_PTR Rhs) { ULONG LhsBitWidth; /* Check if this error was already reported */ - if(!KepCheckUbsanReport(&Data->Location)) + if(!CheckReport(&Data->Location)) { /* Don't report twice */ return; } /* Enter UBSAN frame */ - KepEnterUbsanFrame(&Data->Location, "Shift-Out-Of-Bounds"); + EnterFrame(&Data->Location, "Shift-Out-Of-Bounds"); /* Calculate Lhs bit width */ LhsBitWidth = 1 << (Data->LhsType->TypeInfo >> 1); /* Check a type of out of bounds error */ - if((Data->RhsType->TypeInfo & 1) && (KepGetSignedUbsanValue(Data->RhsType, (PVOID)Rhs) < 0)) + if((Data->RhsType->TypeInfo & 1) && (GetSignedValue(Data->RhsType, (PVOID)Rhs) < 0)) { /* Negative shift exponent, print error message to debug console */ - DebugPrint(L"UBSAN: Shift exponent %lld is negative\n", KepGetSignedUbsanValue(Data->RhsType, (PVOID)Rhs)); + DebugPrint(L"UBSAN: Shift exponent %lld is negative\n", GetSignedValue(Data->RhsType, (PVOID)Rhs)); } - else if((Data->LhsType->TypeInfo & 1) && (KepGetSignedUbsanValue(Data->LhsType, (PVOID)Lhs) < 0)) + else if((Data->LhsType->TypeInfo & 1) && (GetSignedValue(Data->LhsType, (PVOID)Lhs) < 0)) { /* Negative left shift value, print error message to debug console */ - DebugPrint(L"UBSAN: Left shift of negative value %lld\n", KepGetSignedUbsanValue(Data->LhsType, (PVOID)Lhs)); + DebugPrint(L"UBSAN: Left shift of negative value %lld\n", GetSignedValue(Data->LhsType, (PVOID)Lhs)); } - else if(KepGetUnsignedUbsanValue(Data->RhsType, (PVOID)Rhs) >= LhsBitWidth) + else if(GetUnsignedValue(Data->RhsType, (PVOID)Rhs) >= LhsBitWidth) { /* Shift exponent too large, print error message to debug console */ DebugPrint(L"UBSAN: Shift exponent %lld is too large for %u-bit type %s\n", - KepGetUnsignedUbsanValue(Data->RhsType, (PVOID)Rhs), LhsBitWidth, Data->LhsType->TypeName); + GetUnsignedValue(Data->RhsType, (PVOID)Rhs), LhsBitWidth, Data->LhsType->TypeName); } else { /* Left shift too large, print error message to debug console */ DebugPrint(L"UBSAN: Left shift of %lld by %lld places cannot be represented in type %s\n", - KepGetSignedUbsanValue(Data->LhsType, (PVOID)Lhs), KepGetSignedUbsanValue(Data->RhsType, (PVOID)Rhs), + GetSignedValue(Data->LhsType, (PVOID)Lhs), GetSignedValue(Data->RhsType, (PVOID)Rhs), Data->LhsType->TypeName); } /* Leave UBSAN frame */ - KepLeaveUbsanFrame(); + LeaveFrame(); } /** @@ -667,24 +667,24 @@ KepHandleUbsanShiftOutOfBounds(PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA Data, */ XTCDECL VOID -KepHandleUbsanTypeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data, - ULONG_PTR Pointer) +KE::KUbsan::HandleTypeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data, + ULONG_PTR Pointer) { /* Check the type of mismatch */ if(!Pointer) { /* Handle NULL pointer dereference */ - KepHandleUbsanNullPointerDereference(Data); + HandleNullPointerDereference(Data); } - else if(Data->Alignment && (((Pointer) & ((typeof(Pointer))(Data->Alignment) - 1)) != 0)) + else if(Data->Alignment && (((Pointer) & ((decltype(Pointer))(Data->Alignment) - 1)) != 0)) { /* Handle misaligned access */ - KepHandleUbsanMisalignedAccess(Data, Pointer); + HandleMisalignedAccess(Data, Pointer); } else { /* Handle object size mismatch */ - KepHandleUbsanObjectSizeMismatch(Data, Pointer); + HandleObjectSizeMismatch(Data, Pointer); } } @@ -697,10 +697,10 @@ KepHandleUbsanTypeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data, */ XTCDECL VOID -KepLeaveUbsanFrame() +KE::KUbsan::LeaveFrame() { /* Leave UBSAN frame */ - KepUbsanActiveFrame = FALSE; + ActiveFrame = FALSE; } /** @@ -721,6 +721,7 @@ KepLeaveUbsanFrame() * * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113 */ +XTCLINK XTCDECL VOID __ubsan_handle_add_overflow(IN PKUBSAN_OVERFLOW_DATA Data, @@ -728,7 +729,7 @@ __ubsan_handle_add_overflow(IN PKUBSAN_OVERFLOW_DATA Data, IN ULONG_PTR Rhs) { /* Call UBSAN arithmetic overflow handler */ - KepHandleUbsanIntegerOverflow(Data, Lhs, Rhs); + KE::KUbsan::HandleIntegerOverflow(Data, Lhs, Rhs); } /** @@ -749,6 +750,7 @@ __ubsan_handle_add_overflow(IN PKUBSAN_OVERFLOW_DATA Data, * * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113 */ +XTCLINK XTCDECL VOID __ubsan_handle_divrem_overflow(IN PKUBSAN_OVERFLOW_DATA Data, @@ -756,7 +758,7 @@ __ubsan_handle_divrem_overflow(IN PKUBSAN_OVERFLOW_DATA Data, IN PVOID Rhs) { /* Call UBSAN division overflow handler */ - KepHandleUbsanDivisionOverflow(Data, Lhs, Rhs); + KE::KUbsan::HandleDivisionOverflow(Data, Lhs, Rhs); } /** @@ -777,6 +779,7 @@ __ubsan_handle_divrem_overflow(IN PKUBSAN_OVERFLOW_DATA Data, * * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113 */ +XTCLINK XTCDECL VOID __ubsan_handle_float_cast_overflow(IN PKUBSAN_FLOAT_CAST_OVERFLOW_DATA Data, @@ -784,7 +787,7 @@ __ubsan_handle_float_cast_overflow(IN PKUBSAN_FLOAT_CAST_OVERFLOW_DATA Data, IN ULONG_PTR Rhs) { /* Call UBSAN float cast overflow handler */ - KepHandleUbsanFloatCastOverflow(Data, Lhs, Rhs); + KE::KUbsan::HandleFloatCastOverflow(Data, Lhs, Rhs); } /** @@ -802,13 +805,14 @@ __ubsan_handle_float_cast_overflow(IN PKUBSAN_FLOAT_CAST_OVERFLOW_DATA Data, * * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113 */ +XTCLINK XTCDECL VOID __ubsan_handle_function_type_mismatch(IN PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA Data, IN ULONG_PTR Pointer) { /* Call UBSAN function type mismatch handler */ - KepHandleUbsanFunctionTypeMismatch(Data, Pointer); + KE::KUbsan::HandleFunctionTypeMismatch(Data, Pointer); } /** @@ -823,12 +827,13 @@ __ubsan_handle_function_type_mismatch(IN PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA Dat * * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113 */ +XTCLINK XTCDECL VOID __ubsan_handle_invalid_builtin(IN PKUBSAN_INVALID_BUILTIN_DATA Data) { /* Call UBSAN invalid builtin handler */ - KepHandleUbsanInvalidBuiltin(Data); + KE::KUbsan::HandleInvalidBuiltin(Data); } /** @@ -849,6 +854,7 @@ __ubsan_handle_invalid_builtin(IN PKUBSAN_INVALID_BUILTIN_DATA Data) * * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113 */ +XTCLINK XTCDECL VOID __ubsan_handle_mul_overflow(IN PKUBSAN_OVERFLOW_DATA Data, @@ -856,7 +862,7 @@ __ubsan_handle_mul_overflow(IN PKUBSAN_OVERFLOW_DATA Data, IN ULONG_PTR Rhs) { /* Call UBSAN arithmetic overflow handler */ - KepHandleUbsanIntegerOverflow(Data, Lhs, Rhs); + KE::KUbsan::HandleIntegerOverflow(Data, Lhs, Rhs); } /** @@ -874,13 +880,14 @@ __ubsan_handle_mul_overflow(IN PKUBSAN_OVERFLOW_DATA Data, * * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113 */ +XTCLINK XTCDECL VOID __ubsan_handle_negate_overflow(IN PKUBSAN_OVERFLOW_DATA Data, IN ULONG_PTR OldValue) { /* Call UBSAN negate overflow handler */ - KepHandleUbsanNegateOverflow(Data, OldValue); + KE::KUbsan::HandleNegateOverflow(Data, OldValue); } /** @@ -898,13 +905,14 @@ __ubsan_handle_negate_overflow(IN PKUBSAN_OVERFLOW_DATA Data, * * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113 */ +XTCLINK XTCDECL VOID __ubsan_handle_out_of_bounds(IN PKUBSAN_OUT_OF_BOUNDS_DATA Data, IN ULONG_PTR Index) { /* Call UBSAN out of bounds handler */ - KepHandleUbsanOutOfBounds(Data, Index); + KE::KUbsan::HandleOutOfBounds(Data, Index); } /** @@ -925,6 +933,7 @@ __ubsan_handle_out_of_bounds(IN PKUBSAN_OUT_OF_BOUNDS_DATA Data, * * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113 */ +XTCLINK XTCDECL VOID __ubsan_handle_pointer_overflow(IN PKUBSAN_OVERFLOW_DATA Data, @@ -932,7 +941,7 @@ __ubsan_handle_pointer_overflow(IN PKUBSAN_OVERFLOW_DATA Data, IN ULONG_PTR Rhs) { /* Call UBSAN pointer overflow handler */ - KepHandleUbsanPointerOverflow(Data, Lhs, Rhs); + KE::KUbsan::HandlePointerOverflow(Data, Lhs, Rhs); } /** @@ -953,6 +962,7 @@ __ubsan_handle_pointer_overflow(IN PKUBSAN_OVERFLOW_DATA Data, * * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113 */ +XTCLINK XTCDECL VOID __ubsan_handle_shift_out_of_bounds(IN PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA Data, @@ -960,7 +970,7 @@ __ubsan_handle_shift_out_of_bounds(IN PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA Data, IN ULONG_PTR Rhs) { /* Call UBSAN out of bounds handler */ - KepHandleUbsanShiftOutOfBounds(Data, Lhs, Rhs); + KE::KUbsan::HandleShiftOutOfBounds(Data, Lhs, Rhs); } /** @@ -981,6 +991,7 @@ __ubsan_handle_shift_out_of_bounds(IN PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA Data, * * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113 */ +XTCLINK XTCDECL VOID __ubsan_handle_sub_overflow(IN PKUBSAN_OVERFLOW_DATA Data, @@ -988,7 +999,7 @@ __ubsan_handle_sub_overflow(IN PKUBSAN_OVERFLOW_DATA Data, IN ULONG_PTR Rhs) { /* Call UBSAN arithmetic overflow handler */ - KepHandleUbsanIntegerOverflow(Data, Lhs, Rhs); + KE::KUbsan::HandleIntegerOverflow(Data, Lhs, Rhs); } /** @@ -1006,13 +1017,14 @@ __ubsan_handle_sub_overflow(IN PKUBSAN_OVERFLOW_DATA Data, * * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113 */ +XTCLINK XTCDECL VOID __ubsan_handle_type_mismatch(IN PKUBSAN_TYPE_MISMATCH_DATA Data, IN ULONG_PTR Pointer) { /* Call UBSAN type mismatch handler */ - KepHandleUbsanTypeMismatch(Data, Pointer); + KE::KUbsan::HandleTypeMismatch(Data, Pointer); } /** @@ -1030,6 +1042,7 @@ __ubsan_handle_type_mismatch(IN PKUBSAN_TYPE_MISMATCH_DATA Data, * * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113 */ +XTCLINK XTCDECL VOID __ubsan_handle_type_mismatch_v1(IN PKUBSAN_TYPE_MISMATCH_DATA_V1 Data, @@ -1044,5 +1057,5 @@ __ubsan_handle_type_mismatch_v1(IN PKUBSAN_TYPE_MISMATCH_DATA_V1 Data, MismatchData.TypeCheckKind = Data->TypeCheckKind; /* Call UBSAN type mismatch handler */ - KepHandleUbsanTypeMismatch(&MismatchData, Pointer); + KE::KUbsan::HandleTypeMismatch(&MismatchData, Pointer); } diff --git a/xtoskrnl/ke/runlevel.c b/xtoskrnl/ke/runlevel.cc similarity index 75% rename from xtoskrnl/ke/runlevel.c rename to xtoskrnl/ke/runlevel.cc index 4a6a548..7e447d3 100644 --- a/xtoskrnl/ke/runlevel.c +++ b/xtoskrnl/ke/runlevel.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/runlevel.c + * FILE: xtoskrnl/ke/runlevel.cc * DESCRIPTION: Running Level management support * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -18,9 +18,9 @@ */ XTFASTCALL KRUNLEVEL -KeGetCurrentRunLevel(VOID) +KE::RunLevel::GetCurrentRunLevel(VOID) { - return HlGetRunLevel(); + return HL::RunLevel::GetRunLevel(); } /** @@ -35,18 +35,18 @@ KeGetCurrentRunLevel(VOID) */ XTFASTCALL VOID -KeLowerRunLevel(IN KRUNLEVEL RunLevel) +KE::RunLevel::LowerRunLevel(IN KRUNLEVEL RunLevel) { KRUNLEVEL OldRunLevel; /* Read current run level */ - OldRunLevel = HlGetRunLevel(); + OldRunLevel = HL::RunLevel::GetRunLevel(); /* Validate run level lowerage */ if(OldRunLevel > RunLevel) { /* Set new, lower run level */ - HlSetRunLevel(RunLevel); + HL::RunLevel::SetRunLevel(RunLevel); } } @@ -62,18 +62,18 @@ KeLowerRunLevel(IN KRUNLEVEL RunLevel) */ XTFASTCALL KRUNLEVEL -KeRaiseRunLevel(IN KRUNLEVEL RunLevel) +KE::RunLevel::RaiseRunLevel(IN KRUNLEVEL RunLevel) { KRUNLEVEL OldRunLevel; /* Read current run level */ - OldRunLevel = HlGetRunLevel(); + OldRunLevel = HL::RunLevel::GetRunLevel(); /* Validate run level raise */ if(OldRunLevel < RunLevel) { /* Set new, higher run level */ - HlSetRunLevel(RunLevel); + HL::RunLevel::SetRunLevel(RunLevel); } /* Return old run level */ diff --git a/xtoskrnl/ke/semphore.c b/xtoskrnl/ke/semphore.cc similarity index 73% rename from xtoskrnl/ke/semphore.c rename to xtoskrnl/ke/semphore.cc index 2e95ce9..ff0c44c 100644 --- a/xtoskrnl/ke/semphore.c +++ b/xtoskrnl/ke/semphore.cc @@ -1,16 +1,16 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/semphore.c + * FILE: xtoskrnl/ke/semphore.cc * DESCRIPTION: Semaphores support * DEVELOPERS: Rafal Kupiec */ -#include +#include /** - * initializes a kernel semaphore object. + * Initializes a kernel semaphore object. * * @param Semaphore * Supplies a pointer to a semaphore object. @@ -27,9 +27,9 @@ */ XTAPI VOID -KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, - IN LONG Count, - IN LONG Limit) +KE::Semaphore::InitializeSemaphore(IN PKSEMAPHORE Semaphore, + IN LONG Count, + IN LONG Limit) { /* Initialize semaphore header and limit */ Semaphore->Header.Type = SemaphoreObject; @@ -37,7 +37,7 @@ KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, Semaphore->Limit = Limit; /* Initialize semaphore wait list */ - RtlInitializeListHead(&Semaphore->Header.WaitListHead); + RTL::LinkedList::InitializeListHead(&Semaphore->Header.WaitListHead); } /** @@ -52,7 +52,7 @@ KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, */ XTAPI LONG -KeReadSemaphoreState(IN PKSEMAPHORE Semaphore) +KE::Semaphore::ReadState(IN PKSEMAPHORE Semaphore) { /* Return semaphore's signal state */ return Semaphore->Header.SignalState; @@ -79,10 +79,10 @@ KeReadSemaphoreState(IN PKSEMAPHORE Semaphore) */ XTAPI LONG -KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, - IN KPRIORITY Increment, - IN LONG Adjustment, - IN BOOLEAN Wait) +KE::Semaphore::ReleaseSemaphore(IN PKSEMAPHORE Semaphore, + IN KPRIORITY Increment, + IN LONG Adjustment, + IN BOOLEAN Wait) { UNIMPLEMENTED; return 0; diff --git a/xtoskrnl/ke/spinlock.c b/xtoskrnl/ke/spinlock.cc similarity index 67% rename from xtoskrnl/ke/spinlock.c rename to xtoskrnl/ke/spinlock.cc index 5d11bfd..bb72ba3 100644 --- a/xtoskrnl/ke/spinlock.c +++ b/xtoskrnl/ke/spinlock.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/spinlock.c + * FILE: xtoskrnl/ke/spinlock.cc * DESCRIPTION: Spinlocks support * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -21,10 +21,10 @@ */ XTFASTCALL VOID -KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel) +KE::SpinLock::AcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel) { /* Acquire the queued spinlock */ - KeAcquireSpinLock(KeGetCurrentProcessorControlBlock()->LockQueue[LockLevel].Lock); + AcquireSpinLock(KE::Processor::GetCurrentProcessorControlBlock()->LockQueue[LockLevel].Lock); } /** @@ -39,21 +39,21 @@ KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel) */ XTFASTCALL VOID -KeAcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock) +KE::SpinLock::AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock) { /* Try to acquire the lock */ - while(RtlAtomicBitTestAndSet((PLONG)SpinLock, 0)) + while(RTL::Atomic::BitTestAndSet((PLONG)SpinLock, 0)) { /* Wait until locked is cleared */ while(*(VOLATILE PKSPIN_LOCK)SpinLock & 1) { /* Yield processor and keep waiting */ - ArYieldProcessor(); + AR::CpuFunc::YieldProcessor(); } } /* Add an explicit memory barrier */ - ArReadWriteBarrier(); + AR::CpuFunc::ReadWriteBarrier(); } /** @@ -68,7 +68,7 @@ KeAcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock) */ XTAPI VOID -KeInitializeSpinLock(IN PKSPIN_LOCK SpinLock) +KE::SpinLock::InitializeSpinLock(IN PKSPIN_LOCK SpinLock) { /* Zero initialize spinlock */ *SpinLock = 0; @@ -86,10 +86,10 @@ KeInitializeSpinLock(IN PKSPIN_LOCK SpinLock) */ XTFASTCALL VOID -KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel) +KE::SpinLock::ReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel) { /* Clear the lock */ - KeReleaseSpinLock(KeGetCurrentProcessorControlBlock()->LockQueue[LockLevel].Lock); + ReleaseSpinLock(KE::Processor::GetCurrentProcessorControlBlock()->LockQueue[LockLevel].Lock); } /** @@ -104,11 +104,11 @@ KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel) */ XTFASTCALL VOID -KeReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock) +KE::SpinLock::ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock) { /* Clear the lock */ - RtlAtomicAnd32((PLONG)SpinLock, 0); + RTL::Atomic::And32((PLONG)SpinLock, 0); /* Add an explicit memory barrier */ - ArReadWriteBarrier(); + AR::CpuFunc::ReadWriteBarrier(); } diff --git a/xtoskrnl/ke/sysres.c b/xtoskrnl/ke/sysres.cc similarity index 71% rename from xtoskrnl/ke/sysres.c rename to xtoskrnl/ke/sysres.cc index bf45dc3..1879c4e 100644 --- a/xtoskrnl/ke/sysres.c +++ b/xtoskrnl/ke/sysres.cc @@ -1,13 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/sysres.c + * FILE: xtoskrnl/ke/sysres.cc * DESCRIPTION: System resources management; This code is based on the MinocaOS implementation - * Copyright(C) 2012 Minoca Corp. (https://github.com/minoca/os/blob/master/kernel/ke/sysres.c) * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -25,59 +24,11 @@ */ XTAPI XTSTATUS -KeAcquireSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, - OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader) +KE::SystemResources::AcquireResource(IN SYSTEM_RESOURCE_TYPE ResourceType, + OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader) { /* Get system resource and acquire an ownership */ - return KepGetSystemResource(ResourceType, TRUE, ResourceHeader); -} - -/** - * Looks for an unacquired system resource of the specified type and returns it without acquiring an ownership. - * - * @param ResourceType - * Supplies system resource type. - * - * @param ResourceHeader - * Specifies a memory area where a pointer to the system resource header will be stored. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTAPI -XTSTATUS -KeGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, - OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader) -{ - /* Get system resource without acquiring an ownership */ - return KepGetSystemResource(ResourceType, FALSE, ResourceHeader); -} - -/** - * Releases system resource. - * - * @param ResourceHeader - * Specifies a pointer to the system resource header. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -KeReleaseSystemResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader) -{ - /* Disable interrupts and acquire a spinlock */ - ArClearInterruptFlag(); - KeAcquireSpinLock(&KepSystemResourcesLock); - - /* Release resource lock */ - ResourceHeader->ResourceLocked = FALSE; - - /* Release spinlock and enable interrupts */ - KeReleaseSpinLock(&KepSystemResourcesLock); - ArSetInterruptFlag(); + return GetSystemResource(ResourceType, TRUE, ResourceHeader); } /** @@ -98,9 +49,9 @@ KeReleaseSystemResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader) */ XTAPI XTSTATUS -KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, - IN BOOLEAN ResourceLock, - OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader) +KE::SystemResources::GetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, + IN BOOLEAN ResourceLock, + OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader) { PSYSTEM_RESOURCE_HEADER Resource; PLIST_ENTRY ListEntry; @@ -111,15 +62,15 @@ KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, Status = STATUS_SUCCESS; /* Check if interrupts are enabled */ - Interrupts = ArInterruptsEnabled(); + Interrupts = AR::CpuFunc::InterruptsEnabled(); /* Disable interrupts and acquire a spinlock */ - ArClearInterruptFlag(); - KeAcquireSpinLock(&KepSystemResourcesLock); + AR::CpuFunc::ClearInterruptFlag(); + SpinLock::AcquireSpinLock(&ResourcesLock); /* Iterate through system resources list */ - ListEntry = KepSystemResourcesListHead.Flink; - while(ListEntry != &KepSystemResourcesListHead) + ListEntry = ResourcesListHead.Flink; + while(ListEntry != &ResourcesListHead) { /* Get resource header */ Resource = CONTAIN_RECORD(ListEntry, SYSTEM_RESOURCE_HEADER, ListEntry); @@ -151,19 +102,19 @@ KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, } /* Check if resource was found */ - if(ListEntry == &KepSystemResourcesListHead) + if(ListEntry == &ResourcesListHead) { - /* Resource not found, return NULL */ - Resource = NULL; + /* Resource not found, return NULLPTR */ + Resource = NULLPTR; Status = STATUS_NOT_FOUND; } /* Release spinlock and re-enable interrupts if necessary */ - KeReleaseSpinLock(&KepSystemResourcesLock); + SpinLock::ReleaseSpinLock(&ResourcesLock); if(Interrupts) { /* Re-enable interrupts */ - ArSetInterruptFlag(); + AR::CpuFunc::SetInterruptFlag(); } /* Return resource header and status code */ @@ -171,6 +122,28 @@ KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, return Status; } +/** + * Looks for an unacquired system resource of the specified type and returns it without acquiring an ownership. + * + * @param ResourceType + * Supplies system resource type. + * + * @param ResourceHeader + * Specifies a memory area where a pointer to the system resource header will be stored. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTAPI +XTSTATUS +KE::SystemResources::GetResource(IN SYSTEM_RESOURCE_TYPE ResourceType, + OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader) +{ + /* Get system resource without acquiring an ownership */ + return GetSystemResource(ResourceType, FALSE, ResourceHeader); +} + /** * Initializes system resource management. * @@ -180,22 +153,22 @@ KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, */ XTAPI VOID -KepInitializeSystemResources(VOID) +KE::SystemResources::InitializeResources(VOID) { PSYSTEM_RESOURCE_HEADER ResourceHeader; PLIST_ENTRY ListEntry, NextListEntry; ULONG ResourceSize; /* Initialize system resources spin lock and resource list */ - KeInitializeSpinLock(&KepSystemResourcesLock); - RtlInitializeListHead(&KepSystemResourcesListHead); + SpinLock::InitializeSpinLock(&ResourcesLock); + RTL::LinkedList::InitializeListHead(&ResourcesListHead); /* Make sure there are some system resources available */ - if(!RtlListEmpty(&KeInitializationBlock->SystemResourcesListHead)) + if(!RTL::LinkedList::ListEmpty(BootInformation::GetSystemResources())) { /* Iterate through system resources list */ - ListEntry = KeInitializationBlock->SystemResourcesListHead.Flink; - while(ListEntry != &KeInitializationBlock->SystemResourcesListHead) + ListEntry = BootInformation::GetSystemResources()->Flink; + while(ListEntry != BootInformation::GetSystemResources()) { /* Get resource header and next list entry */ ResourceHeader = CONTAIN_RECORD(ListEntry, SYSTEM_RESOURCE_HEADER, ListEntry); @@ -222,8 +195,8 @@ KepInitializeSystemResources(VOID) if(ResourceSize != 0 && ResourceSize == ResourceHeader->ResourceSize) { /* Move valid resource to the internal kernel list of system resources */ - RtlRemoveEntryList(&ResourceHeader->ListEntry); - RtlInsertTailList(&KepSystemResourcesListHead, &ResourceHeader->ListEntry); + RTL::LinkedList::RemoveEntryList(&ResourceHeader->ListEntry); + RTL::LinkedList::InsertTailList(&ResourcesListHead, &ResourceHeader->ListEntry); } /* Go to the next list entry */ @@ -231,3 +204,29 @@ KepInitializeSystemResources(VOID) } } } + +/** + * Releases boot system resource. + * + * @param ResourceHeader + * Specifies a pointer to the boot system resource header. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +KE::SystemResources::ReleaseResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader) +{ + /* Disable interrupts and acquire a spinlock */ + AR::CpuFunc::ClearInterruptFlag(); + SpinLock::AcquireSpinLock(&ResourcesLock); + + /* Release resource lock */ + ResourceHeader->ResourceLocked = FALSE; + + /* Release spinlock and enable interrupts */ + SpinLock::ReleaseSpinLock(&ResourcesLock); + AR::CpuFunc::SetInterruptFlag(); +} diff --git a/xtoskrnl/ke/timer.c b/xtoskrnl/ke/timer.cc similarity index 74% rename from xtoskrnl/ke/timer.c rename to xtoskrnl/ke/timer.cc index 8c7bbee..b556067 100644 --- a/xtoskrnl/ke/timer.c +++ b/xtoskrnl/ke/timer.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/timer.c + * FILE: xtoskrnl/ke/timer.cc * DESCRIPTION: Kernel timer object support * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -21,7 +21,7 @@ */ XTAPI BOOLEAN -KeCancelTimer(IN PKTIMER Timer) +KE::Timer::CancelTimer(IN PKTIMER Timer) { BOOLEAN Result; KRUNLEVEL RunLevel; @@ -30,20 +30,20 @@ KeCancelTimer(IN PKTIMER Timer) Result = FALSE; /* Raise run level and acquire dispatcher lock */ - RunLevel = KeRaiseRunLevel(SYNC_LEVEL); - KeAcquireQueuedSpinLock(DispatcherLock); + RunLevel = KE::RunLevel::RaiseRunLevel(SYNC_LEVEL); + SpinLock::AcquireQueuedSpinLock(DispatcherLock); /* Check timer status */ if(Timer->Header.Inserted) { /* Remove the timer from the list */ - KepRemoveTimer(Timer); + RemoveTimer(Timer); Result = TRUE; } /* Release dispatcher lock and process the deferred ready list */ - KeReleaseQueuedSpinLock(DispatcherLock); - KepExitDispatcher(RunLevel); + SpinLock::ReleaseQueuedSpinLock(DispatcherLock); + KThread::ExitDispatcher(RunLevel); /* Return result */ return Result; @@ -61,7 +61,7 @@ KeCancelTimer(IN PKTIMER Timer) */ XTAPI VOID -KeClearTimer(IN PKTIMER Timer) +KE::Timer::ClearTimer(IN PKTIMER Timer) { /* Clear signal state */ Timer->Header.SignalState = 0; @@ -79,7 +79,7 @@ KeClearTimer(IN PKTIMER Timer) */ XTAPI BOOLEAN -KeGetTimerState(IN PKTIMER Timer) +KE::Timer::GetState(IN PKTIMER Timer) { /* Return timer state */ return (BOOLEAN)Timer->Header.SignalState; @@ -100,11 +100,11 @@ KeGetTimerState(IN PKTIMER Timer) */ XTAPI VOID -KeInitializeTimer(OUT PKTIMER Timer, - IN KTIMER_TYPE Type) +KE::Timer::InitializeTimer(OUT PKTIMER Timer, + IN KTIMER_TYPE Type) { /* Initialize the header */ - Timer->Header.Type = TimerNotificationObject + Type; + Timer->Header.Type = TimerNotificationObject + (UCHAR)Type; Timer->Header.Inserted = 0; Timer->Header.SignalState = 0; @@ -113,8 +113,8 @@ KeInitializeTimer(OUT PKTIMER Timer, Timer->Period = 0; /* Initialize linked lists */ - RtlInitializeListHead(&Timer->Header.WaitListHead); - RtlInitializeListHead(&Timer->TimerListEntry); + RTL::LinkedList::InitializeListHead(&Timer->Header.WaitListHead); + RTL::LinkedList::InitializeListHead(&Timer->TimerListEntry); } /** @@ -129,7 +129,7 @@ KeInitializeTimer(OUT PKTIMER Timer, */ XTAPI ULONGLONG -KeQueryTimer(IN PKTIMER Timer) +KE::Timer::QueryTimer(IN PKTIMER Timer) { KRUNLEVEL RunLevel; ULONGLONG DueTime; @@ -138,8 +138,8 @@ KeQueryTimer(IN PKTIMER Timer) DueTime = 0; /* Raise run level and acquire dispatcher lock */ - RunLevel = KeRaiseRunLevel(SYNC_LEVEL); - KeAcquireQueuedSpinLock(DispatcherLock); + RunLevel = KE::RunLevel::RaiseRunLevel(SYNC_LEVEL); + SpinLock::AcquireQueuedSpinLock(DispatcherLock); /* Check timer status */ if(Timer->Header.Inserted) @@ -149,8 +149,8 @@ KeQueryTimer(IN PKTIMER Timer) } /* Release dispatcher lock and process the deferred ready list */ - KeReleaseQueuedSpinLock(DispatcherLock); - KepExitDispatcher(RunLevel); + SpinLock::ReleaseQueuedSpinLock(DispatcherLock); + KThread::ExitDispatcher(RunLevel); /* Return timer's due time */ return DueTime; @@ -177,10 +177,10 @@ KeQueryTimer(IN PKTIMER Timer) */ XTAPI VOID -KeSetTimer(IN PKTIMER Timer, - IN LARGE_INTEGER DueTime, - IN LONG Period, - IN PKDPC Dpc) +KE::Timer::SetTimer(IN PKTIMER Timer, + IN LARGE_INTEGER DueTime, + IN LONG Period, + IN PKDPC Dpc) { UNIMPLEMENTED; } @@ -197,9 +197,9 @@ KeSetTimer(IN PKTIMER Timer, */ XTAPI VOID -KepRemoveTimer(IN OUT PKTIMER Timer) +KE::Timer::RemoveTimer(IN OUT PKTIMER Timer) { /* Remove the timer from the list */ Timer->Header.Inserted = FALSE; - RtlRemoveEntryList(&Timer->TimerListEntry); + RTL::LinkedList::RemoveEntryList(&Timer->TimerListEntry); } diff --git a/xtoskrnl/mm/amd64/globals.c b/xtoskrnl/mm/amd64/globals.c deleted file mode 100644 index f5959a1..0000000 --- a/xtoskrnl/mm/amd64/globals.c +++ /dev/null @@ -1,26 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/amd64/globals.c - * DESCRIPTION: AMD64-specific global variables for the Memory Manager - * DEVELOPERS: Aiken Harris - */ - -#include - - -/* Page mapping routines for systems using 4-level paging (PML4) */ -CMMPAGEMAP_ROUTINES MmpPml4Routines = { - .ClearPte = MmpClearPte, - .PteValid = MmpPteValid, - .SetPteCaching = MmpSetPteCaching, - .SetPte = MmpSetPte, -}; - -/* Page mapping routines for systems using 5-level paging (PML5) */ -CMMPAGEMAP_ROUTINES MmpPml5Routines = { - .ClearPte = MmpClearPte, - .PteValid = MmpPteValid, - .SetPteCaching = MmpSetPteCaching, - .SetPte = MmpSetPte, -}; diff --git a/xtoskrnl/mm/amd64/init.c b/xtoskrnl/mm/amd64/init.c deleted file mode 100644 index 31483d4..0000000 --- a/xtoskrnl/mm/amd64/init.c +++ /dev/null @@ -1,75 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/amd64/init.c - * DESCRIPTION: Architecture specific Memory Manager initialization routines - * DEVELOPERS: Rafal Kupiec - * Aiken Harris - */ - -#include - - -/** - * Detects if eXtended Physical Addressing (XPA) is enabled and initializes page map support. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -MmInitializePageMapSupport(VOID) -{ - /* Check if XPA is enabled */ - if(MmpGetExtendedPhysicalAddressingStatus()) - { - /* XPA enabled, use LA57 paging (PML5) */ - MmpPageMapRoutines = &MmpPml5Routines; - - /* Set PML5 page map information */ - MmpPageMapInfo.Xpa = TRUE; - - /* Set PML5 base addresses */ - MmpPageMapInfo.PteBase = MM_PTE_LA57_BASE; - MmpPageMapInfo.PdeBase = MM_PDE_LA57_BASE; - MmpPageMapInfo.PpeBase = MM_PPE_LA57_BASE; - MmpPageMapInfo.PxeBase = MM_PXE_LA57_BASE; - MmpPageMapInfo.P5eBase = MM_P5E_LA57_BASE; - - /* PML5 use 57-bit virtual addresses */ - MmpPageMapInfo.VaBits = 57; - } - else - { - /* XPA disabled, use LA48 paging (PML4) */ - MmpPageMapRoutines = &MmpPml4Routines; - - /* Set PML4 page map information */ - MmpPageMapInfo.Xpa = FALSE; - - /* Set PML4 base addresses */ - MmpPageMapInfo.PteBase = MM_PTE_BASE; - MmpPageMapInfo.PdeBase = MM_PDE_BASE; - MmpPageMapInfo.PpeBase = MM_PPE_BASE; - MmpPageMapInfo.PxeBase = MM_PXE_BASE; - MmpPageMapInfo.P5eBase = 0x0; - - /* PML use 48-bit virtual addresses */ - MmpPageMapInfo.VaBits = 48; - } -} - -/** - * Performs architecture specific initialization of the XTOS Memory Manager. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -MmpInitializeArchitecture(VOID) -{ - UNIMPLEMENTED; -} diff --git a/xtoskrnl/mm/amd64/init.cc b/xtoskrnl/mm/amd64/init.cc new file mode 100644 index 0000000..7e7a9d8 --- /dev/null +++ b/xtoskrnl/mm/amd64/init.cc @@ -0,0 +1,25 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/mm/amd64/init.cc + * DESCRIPTION: Architecture specific Memory Manager initialization routines + * DEVELOPERS: Rafal Kupiec + * Aiken Harris + */ + +#include + + +/** + * Performs architecture specific initialization of the XTOS Memory Manager. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::Init::InitializeArchitecture(VOID) +{ + UNIMPLEMENTED; +} diff --git a/xtoskrnl/mm/amd64/pmap.c b/xtoskrnl/mm/amd64/pagemap.cc similarity index 50% rename from xtoskrnl/mm/amd64/pmap.c rename to xtoskrnl/mm/amd64/pagemap.cc index bc29a75..62fa00b 100644 --- a/xtoskrnl/mm/amd64/pmap.c +++ b/xtoskrnl/mm/amd64/pagemap.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/amd64/pmap.c - * DESCRIPTION: Low-level support for AMD64 page map manipulation + * FILE: xtoskrnl/mm/i686/pagemap.cc + * DESCRIPTION: Low-level support for i686 page map manipulation * DEVELOPERS: Aiken Harris */ -#include +#include /** @@ -21,7 +21,7 @@ */ XTAPI VOID -MmpClearPte(PHARDWARE_PTE PtePointer) +MM::PageMap::ClearPte(PHARDWARE_PTE PtePointer) { PtePointer->CacheDisable = 0; PtePointer->PageFrameNumber = 0; @@ -30,39 +30,25 @@ MmpClearPte(PHARDWARE_PTE PtePointer) PtePointer->WriteThrough = 0; } -/** - * Checks if eXtended Physical Addressing (XPA) is enabled. - * - * @return This routine returns TRUE if LA57 is enabled, or FALSE otherwise. - * - * @since XT 1.0 - */ -XTAPI -BOOLEAN -MmpGetExtendedPhysicalAddressingStatus(VOID) -{ - /* Check if LA57 is enabled */ - return ((ArReadControlRegister(4) & CR4_LA57) != 0) ? TRUE : FALSE; -} - /** * Gets the address of the P5E (Page Map Level 5 Entry), that maps given address. * * @param Address * Specifies the virtual address for which to retrieve the corresponding P5E. * - * @return This routine returns the address of the P5E, or NULL if LA57 is not enabled. + * @return This routine returns the address of the P5E, or NULLPTR if LA57 is not enabled. * * @since XT 1.0 */ XTAPI PMMP5E -MmpGetP5eAddress(PVOID Address) +MM::PageMap::GetP5eAddress(PVOID Address) { ULONGLONG Offset; - Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << MmpPageMapInfo.VaBits) - 1)) >> MM_P5I_SHIFT) << MM_PTE_SHIFT); - return (PMMP5E)((MmpPageMapInfo.P5eBase + Offset) * MmpPageMapInfo.Xpa); + /* Calculate offset and return P5E address */ + Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << PageMapInfo.VaBits) - 1)) >> MM_P5I_SHIFT) << MM_PTE_SHIFT); + return (PMMP5E)((PageMapInfo.P5eBase + Offset) * PageMapInfo.Xpa); } /** @@ -77,19 +63,20 @@ MmpGetP5eAddress(PVOID Address) */ XTAPI PMMPDE -MmpGetPdeAddress(PVOID Address) +MM::PageMap::GetPdeAddress(PVOID Address) { ULONGLONG Offset; - Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << MmpPageMapInfo.VaBits) - 1)) >> MM_PDI_SHIFT) << MM_PTE_SHIFT); - return (PMMPDE)(MmpPageMapInfo.PdeBase + Offset); + /* Calculate offset and return PDE address */ + Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << PageMapInfo.VaBits) - 1)) >> MM_PDI_SHIFT) << MM_PTE_SHIFT); + return (PMMPDE)(PageMapInfo.PdeBase + Offset); } /** * Gets the address of the PPE (Page Directory Pointer Table Entry), that maps given address. * * @param Address - * Specifies the virtual address for which to retrieve the corresponding PPE. + * Specifies the virtual address for which to retrieve the corresponding PDE. * * @return This routine returns the address of the PPE. * @@ -97,12 +84,13 @@ MmpGetPdeAddress(PVOID Address) */ XTAPI PMMPPE -MmpGetPpeAddress(PVOID Address) +MM::PageMap::GetPpeAddress(PVOID Address) { ULONGLONG Offset; - Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << MmpPageMapInfo.VaBits) - 1)) >> MM_PPI_SHIFT) << MM_PTE_SHIFT); - return (PMMPPE)(MmpPageMapInfo.PpeBase + Offset); + /* Calculate offset and return PPE address */ + Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << PageMapInfo.VaBits) - 1)) >> MM_PPI_SHIFT) << MM_PTE_SHIFT); + return (PMMPPE)(PageMapInfo.PpeBase + Offset); } /** @@ -117,12 +105,13 @@ MmpGetPpeAddress(PVOID Address) */ XTAPI PMMPTE -MmpGetPteAddress(PVOID Address) +MM::PageMap::GetPteAddress(PVOID Address) { ULONGLONG Offset; - Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << MmpPageMapInfo.VaBits) - 1)) >> MM_PTI_SHIFT) << MM_PTE_SHIFT); - return (PMMPTE)(MmpPageMapInfo.PteBase + Offset); + /* Calculate offset and return PTE address */ + Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << PageMapInfo.VaBits) - 1)) >> MM_PTI_SHIFT) << MM_PTE_SHIFT); + return (PMMPTE)(PageMapInfo.PteBase + Offset); } /** @@ -137,16 +126,16 @@ MmpGetPteAddress(PVOID Address) */ XTAPI PMMPXE -MmpGetPxeAddress(PVOID Address) +MM::PageMap::GetPxeAddress(PVOID Address) { ULONGLONG Offset; - Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << MmpPageMapInfo.VaBits) - 1)) >> MM_PXI_SHIFT) << MM_PTE_SHIFT); - return (PMMPXE)(MmpPageMapInfo.PxeBase + Offset); + Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << PageMapInfo.VaBits) - 1)) >> MM_PXI_SHIFT) << MM_PTE_SHIFT); + return (PMMPXE)(PageMapInfo.PxeBase + Offset); } /** - * Checks whether the given page table entry (PTE) is valid. + * Checks whether the given PML2 page table entry (PTE) is valid. * * @param PtePointer * Pointer to the page table entry (PTE) to check. @@ -157,13 +146,13 @@ MmpGetPxeAddress(PVOID Address) */ XTAPI BOOLEAN -MmpPteValid(PHARDWARE_PTE PtePointer) +MM::PageMap::PteValid(PHARDWARE_PTE PtePointer) { return (BOOLEAN)PtePointer->Valid; } /** - * Sets a page table entry (PTE) with the specified physical page and access flags. + * Sets a PML2 page table entry (PTE) with the specified physical page and access flags. * * @param PtePointer * Pointer to the page table entry (PTE) to set. @@ -180,9 +169,9 @@ MmpPteValid(PHARDWARE_PTE PtePointer) */ XTAPI VOID -MmpSetPte(PHARDWARE_PTE PtePointer, - PFN_NUMBER PageFrameNumber, - BOOLEAN Writable) +MM::PageMap::SetPte(PHARDWARE_PTE PtePointer, + PFN_NUMBER PageFrameNumber, + BOOLEAN Writable) { PtePointer->PageFrameNumber = PageFrameNumber; PtePointer->Valid = 1; @@ -190,7 +179,7 @@ MmpSetPte(PHARDWARE_PTE PtePointer, } /** - * Sets caching attributes for a page table entry (PTE). + * Sets caching attributes for a PML2 page table entry (PTE). * * @param PtePointer * Pointer to the page table entry (PTE) to modify. @@ -207,10 +196,60 @@ MmpSetPte(PHARDWARE_PTE PtePointer, */ XTAPI VOID -MmpSetPteCaching(PHARDWARE_PTE PtePointer, - BOOLEAN CacheDisable, - BOOLEAN WriteThrough) +MM::PageMap::SetPteCaching(PHARDWARE_PTE PtePointer, + BOOLEAN CacheDisable, + BOOLEAN WriteThrough) { PtePointer->CacheDisable = CacheDisable; PtePointer->WriteThrough = WriteThrough; } + +/** + * Initializes page map information for basic paging (PML4). + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::PageMapBasic::InitializePageMapInfo(VOID) +{ + /* Set PML4 page map information */ + PageMapInfo.Xpa = FALSE; + + /* Set PML4 base addresses */ + PageMapInfo.PteBase = MM_PTE_BASE; + PageMapInfo.PdeBase = MM_PDE_BASE; + PageMapInfo.PpeBase = MM_PPE_BASE; + PageMapInfo.PxeBase = MM_PXE_BASE; + PageMapInfo.P5eBase = 0x0; + + /* PML use 48-bit virtual addresses */ + PageMapInfo.VaBits = 48; +} + +/** + * Initializes page map information for XPA paging (PML5). + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::PageMapXpa::InitializePageMapInfo(VOID) +{ + /* Set PML5 page map information */ + PageMapInfo.Xpa = TRUE; + + /* Set PML5 base addresses */ + PageMapInfo.PteBase = MM_PTE_LA57_BASE; + PageMapInfo.PdeBase = MM_PDE_LA57_BASE; + PageMapInfo.PpeBase = MM_PPE_LA57_BASE; + PageMapInfo.PxeBase = MM_PXE_LA57_BASE; + PageMapInfo.P5eBase = MM_P5E_LA57_BASE; + + /* PML5 use 57-bit virtual addresses */ + PageMapInfo.VaBits = 57; +} diff --git a/xtoskrnl/mm/amd64/pages.c b/xtoskrnl/mm/amd64/paging.cc similarity index 64% rename from xtoskrnl/mm/amd64/pages.c rename to xtoskrnl/mm/amd64/paging.cc index 7471ec5..0ab73ef 100644 --- a/xtoskrnl/mm/amd64/pages.c +++ b/xtoskrnl/mm/amd64/paging.cc @@ -1,14 +1,30 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/amd64/pages.c + * FILE: xtoskrnl/mm/amd64/paging.cc * DESCRIPTION: Architecture dependent paging support * DEVELOPERS: Rafal Kupiec + * Aiken Harris */ -#include +#include +/** + * Checks if eXtended Physical Addressing (XPA) is enabled. + * + * @return This routine returns TRUE if LA57 is enabled, or FALSE otherwise. + * + * @since XT 1.0 + */ +XTAPI +BOOLEAN +MM::Paging::GetExtendedPhysicalAddressingStatus(VOID) +{ + /* Check if LA57 is enabled */ + return ((AR::CpuFunc::ReadControlRegister(4) & CR4_LA57) != 0) ? TRUE : FALSE; +} + /** * Fills a section of memory with zeroes like RtlZeroMemory(), but in more efficient way. * @@ -24,8 +40,8 @@ */ XTFASTCALL VOID -MmZeroPages(IN PVOID Address, - IN ULONG Size) +MM::Paging::ZeroPages(IN PVOID Address, + IN ULONG Size) { __asm__ volatile("xor %%rax, %%rax\n" "mov %0, %%rdi\n" diff --git a/xtoskrnl/mm/data.cc b/xtoskrnl/mm/data.cc new file mode 100644 index 0000000..7869827 --- /dev/null +++ b/xtoskrnl/mm/data.cc @@ -0,0 +1,40 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/mm/data.cc + * DESCRIPTION: Memory Manager global and static data + * DEVELOPERS: Aiken Harris + */ + +#include + + +/* Allocation descriptors dedicated for hardware layer */ +LOADER_MEMORY_DESCRIPTOR MM::HardwarePool::HardwareAllocationDescriptors[MM_HARDWARE_ALLOCATION_DESCRIPTORS]; + +/* Live address of kernel's hardware heap */ +PVOID MM::HardwarePool::HardwareHeapStart = MM_HARDWARE_HEAP_START_ADDRESS; + +/* Number of used hardware allocation descriptors */ +ULONG MM::HardwarePool::UsedHardwareAllocationDescriptors = 0; + +/* Biggest free memory descriptor */ +PLOADER_MEMORY_DESCRIPTOR MM::Init::FreeDescriptor; + +/* Highest physical page number */ +ULONG_PTR MM::Init::HighestPhysicalPage; + +/* Lowest physical page number */ +ULONG_PTR MM::Init::LowestPhysicalPage = -1; + +/* Number of physical pages */ +ULONG MM::Init::NumberOfPhysicalPages; + +/* Old biggest free memory descriptor */ +LOADER_MEMORY_DESCRIPTOR MM::Init::OldFreeDescriptor; + +/* Processor structures data (THIS IS A TEMPORARY HACK) */ +UCHAR MM::KernelPool::ProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE] = {{0}}; + +/* Instance of the page map routines for the current PML level */ +MM::PPAGEMAP MM::Paging::PmlRoutines; diff --git a/xtoskrnl/mm/globals.c b/xtoskrnl/mm/globals.c deleted file mode 100644 index f3e0878..0000000 --- a/xtoskrnl/mm/globals.c +++ /dev/null @@ -1,43 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/globals.c - * DESCRIPTION: Memory Manager initialization routines - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/* Biggest free memory descriptor */ -PLOADER_MEMORY_DESCRIPTOR MmFreeDescriptor; - -/* Highest physical page number */ -ULONG_PTR MmHighestPhysicalPage; - -/* Lowest physical page number */ -ULONG_PTR MmLowestPhysicalPage = -1; - -/* Number of physical pages */ -ULONG MmNumberOfPhysicalPages; - -/* Old biggest free memory descriptor */ -LOADER_MEMORY_DESCRIPTOR MmOldFreeDescriptor; - -/* Processor structures data (THIS IS A TEMPORARY HACK) */ -UCHAR MmProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE] = {0}; - -/* Allocation descriptors dedicated for hardware layer */ -LOADER_MEMORY_DESCRIPTOR MmpHardwareAllocationDescriptors[MM_HARDWARE_ALLOCATION_DESCRIPTORS]; - -/* Live address of kernel's hardware heap */ -PVOID MmpHardwareHeapStart = MM_HARDWARE_HEAP_START_ADDRESS; - -/* Information about the current page map */ -MMPAGEMAP_INFO MmpPageMapInfo; - -/* Pointers to page map routines for the current paging mode */ -PCMMPAGEMAP_ROUTINES MmpPageMapRoutines; - -/* Number of used hardware allocation descriptors */ -ULONG MmpUsedHardwareAllocationDescriptors = 0; diff --git a/xtoskrnl/mm/hlpool.c b/xtoskrnl/mm/hlpool.cc similarity index 70% rename from xtoskrnl/mm/hlpool.c rename to xtoskrnl/mm/hlpool.cc index 5b96fa9..8728b8f 100644 --- a/xtoskrnl/mm/hlpool.c +++ b/xtoskrnl/mm/hlpool.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/hlpool.c + * FILE: xtoskrnl/mm/hlpool.cc * DESCRIPTION: Hardware layer pool memory management * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -27,14 +27,14 @@ */ XTAPI XTSTATUS -MmAllocateHardwareMemory(IN PFN_NUMBER PageCount, - IN BOOLEAN Aligned, - OUT PPHYSICAL_ADDRESS Buffer) +MM::HardwarePool::AllocateHardwareMemory(IN PFN_NUMBER PageCount, + IN BOOLEAN Aligned, + OUT PPHYSICAL_ADDRESS Buffer) { PLOADER_MEMORY_DESCRIPTOR Descriptor, ExtraDescriptor, HardwareDescriptor; PFN_NUMBER Alignment, MaxPage; ULONGLONG PhysicalAddress; - PLIST_ENTRY ListEntry; + PLIST_ENTRY ListEntry, LoaderMemoryDescriptors; /* Assume failure */ (*Buffer).QuadPart = 0; @@ -43,15 +43,18 @@ MmAllocateHardwareMemory(IN PFN_NUMBER PageCount, MaxPage = MM_MAXIMUM_PHYSICAL_ADDRESS >> MM_PAGE_SHIFT; /* Make sure there are at least 2 descriptors available */ - if((MmpUsedHardwareAllocationDescriptors + 2) > MM_HARDWARE_ALLOCATION_DESCRIPTORS) + if((UsedHardwareAllocationDescriptors + 2) > MM_HARDWARE_ALLOCATION_DESCRIPTORS) { /* Not enough descriptors, return error */ return STATUS_INSUFFICIENT_RESOURCES; } + /* Get a list of memory descriptors provided by the boot loader */ + LoaderMemoryDescriptors = KE::BootInformation::GetMemoryDescriptors(); + /* Scan memory descriptors provided by the boot loader */ - ListEntry = KeInitializationBlock->MemoryDescriptorListHead.Flink; - while(ListEntry != &KeInitializationBlock->MemoryDescriptorListHead) + ListEntry = LoaderMemoryDescriptors->Flink; + while(ListEntry != LoaderMemoryDescriptors) { Descriptor = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_DESCRIPTOR, ListEntry); @@ -77,20 +80,20 @@ MmAllocateHardwareMemory(IN PFN_NUMBER PageCount, } /* Make sure we found a descriptor */ - if(ListEntry == &KeInitializationBlock->MemoryDescriptorListHead) + if(ListEntry == LoaderMemoryDescriptors) { /* Descriptor not found, return error */ return STATUS_INSUFFICIENT_RESOURCES; } /* Allocate new descriptor */ - HardwareDescriptor = &MmpHardwareAllocationDescriptors[MmpUsedHardwareAllocationDescriptors]; + HardwareDescriptor = &HardwareAllocationDescriptors[UsedHardwareAllocationDescriptors]; HardwareDescriptor->BasePage = Descriptor->BasePage + Alignment; HardwareDescriptor->MemoryType = LoaderHardwareCachedMemory; HardwareDescriptor->PageCount = PageCount; /* Update hardware allocation descriptors count */ - MmpUsedHardwareAllocationDescriptors++; + UsedHardwareAllocationDescriptors++; /* Check if alignment was done */ if(Alignment) @@ -99,23 +102,23 @@ MmAllocateHardwareMemory(IN PFN_NUMBER PageCount, if(Descriptor->PageCount > (PageCount + Alignment)) { /* Initialize extra descriptor */ - ExtraDescriptor = &MmpHardwareAllocationDescriptors[MmpUsedHardwareAllocationDescriptors]; + ExtraDescriptor = &HardwareAllocationDescriptors[UsedHardwareAllocationDescriptors]; ExtraDescriptor->BasePage = Descriptor->BasePage + Alignment + (ULONG)PageCount; ExtraDescriptor->MemoryType = LoaderFree; ExtraDescriptor->PageCount = Descriptor->PageCount - (Alignment + (ULONG)PageCount); /* Update hardware allocation descriptors count */ - MmpUsedHardwareAllocationDescriptors++; + UsedHardwareAllocationDescriptors++; /* Insert extra descriptor in the list */ - RtlInsertHeadList(&Descriptor->ListEntry, &ExtraDescriptor->ListEntry); + RTL::LinkedList::InsertHeadList(&Descriptor->ListEntry, &ExtraDescriptor->ListEntry); } /* Trim source descriptor to the alignment */ Descriptor->PageCount = Alignment; /* Insert new descriptor in the list */ - RtlInsertHeadList(&Descriptor->ListEntry, &HardwareDescriptor->ListEntry); + RTL::LinkedList::InsertHeadList(&Descriptor->ListEntry, &HardwareDescriptor->ListEntry); } else { @@ -124,13 +127,13 @@ MmAllocateHardwareMemory(IN PFN_NUMBER PageCount, Descriptor->PageCount -= (ULONG)PageCount; /* Insert new descriptor in the list */ - RtlInsertTailList(&Descriptor->ListEntry, &HardwareDescriptor->ListEntry); + RTL::LinkedList::InsertTailList(&Descriptor->ListEntry, &HardwareDescriptor->ListEntry); /* Check if source descriptor is fully consumed */ if(Descriptor->PageCount == 0) { /* Remove descriptor from the list */ - RtlRemoveEntryList(&Descriptor->ListEntry); + RTL::LinkedList::RemoveEntryList(&Descriptor->ListEntry); } } @@ -160,37 +163,37 @@ MmAllocateHardwareMemory(IN PFN_NUMBER PageCount, */ XTAPI XTSTATUS -MmMapHardwareMemory(IN PHYSICAL_ADDRESS PhysicalAddress, - IN PFN_NUMBER PageCount, - IN BOOLEAN FlushTlb, - OUT PVOID *VirtualAddress) +MM::HardwarePool::MapHardwareMemory(IN PHYSICAL_ADDRESS PhysicalAddress, + IN PFN_NUMBER PageCount, + IN BOOLEAN FlushTlb, + OUT PVOID *VirtualAddress) { PVOID BaseAddress, ReturnAddress; PFN_NUMBER MappedPages; PHARDWARE_PTE PtePointer; /* Initialize variables */ - BaseAddress = MmpHardwareHeapStart; + BaseAddress = HardwareHeapStart; MappedPages = 0; ReturnAddress = BaseAddress; - *VirtualAddress = NULL; + *VirtualAddress = NULLPTR; /* Iterate through all pages */ while(MappedPages < PageCount) { /* Check if address overflows */ - if(BaseAddress == NULL) + if(BaseAddress == NULLPTR) { /* Not enough free pages, return error */ return STATUS_INSUFFICIENT_RESOURCES; } /* Get PTE pointer and advance to next page */ - PtePointer = (PHARDWARE_PTE)MmpGetPteAddress(ReturnAddress); - ReturnAddress = (PVOID)(ULONG_PTR)ReturnAddress + MM_PAGE_SIZE; + PtePointer = (PHARDWARE_PTE)MM::Paging::GetPteAddress(ReturnAddress); + ReturnAddress = (PVOID)((ULONG_PTR)ReturnAddress + MM_PAGE_SIZE); /* Check if PTE is valid */ - if(MmpPageMapRoutines->PteValid(PtePointer)) + if(MM::Paging::PteValid(PtePointer)) { /* PTE is not available, go to the next one */ BaseAddress = ReturnAddress; @@ -203,23 +206,23 @@ MmMapHardwareMemory(IN PHYSICAL_ADDRESS PhysicalAddress, } /* Take the actual base address with an offset */ - ReturnAddress = (PVOID)(ULONG_PTR)(BaseAddress + PAGE_OFFSET(PhysicalAddress.LowPart)); + ReturnAddress = (PVOID)((ULONG_PTR)BaseAddress + PAGE_OFFSET(PhysicalAddress.LowPart)); /* Check if base address starts at the beginning of the heap */ - if(BaseAddress == MmpHardwareHeapStart) + if(BaseAddress == HardwareHeapStart) { /* Move heap beyond base address */ - MmpHardwareHeapStart = (PVOID)((ULONG_PTR)BaseAddress + ((ULONG_PTR)PageCount << MM_PAGE_SHIFT)); + HardwareHeapStart = (PVOID)((ULONG_PTR)BaseAddress + ((ULONG_PTR)PageCount << MM_PAGE_SHIFT)); } /* Iterate through mapped pages */ while(MappedPages--) { /* Get PTE pointer */ - PtePointer = (PHARDWARE_PTE)MmpGetPteAddress(BaseAddress); + PtePointer = (PHARDWARE_PTE)MM::Paging::GetPteAddress(BaseAddress); /* Fill the PTE */ - MmpPageMapRoutines->SetPte(PtePointer, (PFN_NUMBER)(PhysicalAddress.QuadPart >> MM_PAGE_SHIFT), TRUE); + MM::Paging::SetPte(PtePointer, (PFN_NUMBER)(PhysicalAddress.QuadPart >> MM_PAGE_SHIFT), TRUE); /* Advance to the next address */ PhysicalAddress.QuadPart += MM_PAGE_SIZE; @@ -230,7 +233,7 @@ MmMapHardwareMemory(IN PHYSICAL_ADDRESS PhysicalAddress, if(FlushTlb) { /* Flush the TLB */ - MmFlushTlb(); + MM::Paging::FlushTlb(); } /* Return virtual address */ @@ -253,20 +256,20 @@ MmMapHardwareMemory(IN PHYSICAL_ADDRESS PhysicalAddress, */ XTAPI VOID -MmMarkHardwareMemoryWriteThrough(IN PVOID VirtualAddress, - IN PFN_NUMBER PageCount) +MM::HardwarePool::MarkHardwareMemoryWriteThrough(IN PVOID VirtualAddress, + IN PFN_NUMBER PageCount) { PHARDWARE_PTE PtePointer; PFN_NUMBER Page; /* Get PTE address from virtual address */ - PtePointer = (PHARDWARE_PTE)MmpGetPteAddress(VirtualAddress); + PtePointer = (PHARDWARE_PTE)MM::Paging::GetPteAddress(VirtualAddress); /* Iterate through mapped pages */ for(Page = 0; Page < PageCount; Page++) { /* Mark pages as CD/WT */ - MmpPageMapRoutines->SetPteCaching(PtePointer, TRUE, TRUE); + MM::Paging::SetPteCaching(PtePointer, TRUE, TRUE); PtePointer++; } } @@ -289,23 +292,23 @@ MmMarkHardwareMemoryWriteThrough(IN PVOID VirtualAddress, */ XTAPI VOID -MmRemapHardwareMemory(IN PVOID VirtualAddress, - IN PHYSICAL_ADDRESS PhysicalAddress, - IN BOOLEAN FlushTlb) +MM::HardwarePool::RemapHardwareMemory(IN PVOID VirtualAddress, + IN PHYSICAL_ADDRESS PhysicalAddress, + IN BOOLEAN FlushTlb) { PHARDWARE_PTE PtePointer; /* Get PTE address from virtual address */ - PtePointer = (PHARDWARE_PTE)MmpGetPteAddress(VirtualAddress); + PtePointer = (PHARDWARE_PTE)MM::Paging::GetPteAddress(VirtualAddress); /* Remap the PTE */ - MmpPageMapRoutines->SetPte(PtePointer, (PFN_NUMBER)(PhysicalAddress.QuadPart >> MM_PAGE_SHIFT), TRUE); + MM::Paging::SetPte(PtePointer, (PFN_NUMBER)(PhysicalAddress.QuadPart >> MM_PAGE_SHIFT), TRUE); /* Check if TLB needs to be flushed */ if(FlushTlb) { /* Flush the TLB */ - MmFlushTlb(); + MM::Paging::FlushTlb(); } } @@ -327,9 +330,9 @@ MmRemapHardwareMemory(IN PVOID VirtualAddress, */ XTAPI XTSTATUS -MmUnmapHardwareMemory(IN PVOID VirtualAddress, - IN PFN_NUMBER PageCount, - IN BOOLEAN FlushTlb) +MM::HardwarePool::UnmapHardwareMemory(IN PVOID VirtualAddress, + IN PFN_NUMBER PageCount, + IN BOOLEAN FlushTlb) { PHARDWARE_PTE PtePointer; PFN_NUMBER Page; @@ -345,13 +348,13 @@ MmUnmapHardwareMemory(IN PVOID VirtualAddress, VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress & ~(MM_PAGE_SIZE - 1)); /* Get PTE address from virtual address */ - PtePointer = (PHARDWARE_PTE)MmpGetPteAddress(VirtualAddress); + PtePointer = (PHARDWARE_PTE)MM::Paging::GetPteAddress(VirtualAddress); /* Iterate through mapped pages */ for(Page = 0; Page < PageCount; Page++) { /* Unmap the PTE and get the next one */ - MmpPageMapRoutines->ClearPte(PtePointer); + MM::Paging::ClearPte(PtePointer); PtePointer++; } @@ -359,14 +362,14 @@ MmUnmapHardwareMemory(IN PVOID VirtualAddress, if(FlushTlb) { /* Flush the TLB */ - MmFlushTlb(); + MM::Paging::FlushTlb(); } /* Check if heap can be reused */ - if(MmpHardwareHeapStart > VirtualAddress) + if(HardwareHeapStart > VirtualAddress) { /* Free VA space */ - MmpHardwareHeapStart = VirtualAddress; + HardwareHeapStart = VirtualAddress; } /* Return success */ diff --git a/xtoskrnl/mm/i686/globals.c b/xtoskrnl/mm/i686/globals.c deleted file mode 100644 index 97db43e..0000000 --- a/xtoskrnl/mm/i686/globals.c +++ /dev/null @@ -1,26 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/i686/globals.c - * DESCRIPTION: i686-specific global variables for the Memory Manager - * DEVELOPERS: Aiken Harris - */ - -#include - - -/* Page mapping routines for systems using 2-level paging (PML2) */ -CMMPAGEMAP_ROUTINES MmpPml2Routines = { - .ClearPte = MmpClearPte, - .PteValid = MmpPml2PteValid, - .SetPteCaching = MmpSetPml2PteCaching, - .SetPte = MmpSetPml2Pte, -}; - -/* Page mapping routines for systems using 3-level paging (PML3) */ -CMMPAGEMAP_ROUTINES MmpPml3Routines = { - .ClearPte = MmpClearPte, - .PteValid = MmpPml3PteValid, - .SetPteCaching = MmpSetPml3PteCaching, - .SetPte = MmpSetPml3Pte, -}; diff --git a/xtoskrnl/mm/i686/init.c b/xtoskrnl/mm/i686/init.c deleted file mode 100644 index a473449..0000000 --- a/xtoskrnl/mm/i686/init.c +++ /dev/null @@ -1,71 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/i686/init.c - * DESCRIPTION: Architecture specific Memory Manager initialization routines - * DEVELOPERS: Rafal Kupiec - * Aiken Harris - */ - -#include - - -/** - * Detects if eXtended Physical Addressing (XPA) is enabled and initializes page map support. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -MmInitializePageMapSupport(VOID) -{ - /* Check if XPA is enabled */ - if(MmpGetExtendedPhysicalAddressingStatus()) - { - /* XPA enabled, use modern PAE paging (PML3) */ - MmpPageMapRoutines = &MmpPml3Routines; - - /* Set PML3 page map information */ - MmpPageMapInfo.Xpa = TRUE; - - /* Set PML3 base addresses */ - MmpPageMapInfo.PteBase = MM_PTE_BASE; - MmpPageMapInfo.PdeBase = MM_PDE_BASE; - - /* Set PML3 shift values */ - MmpPageMapInfo.PdiShift = MM_PDI_SHIFT; - MmpPageMapInfo.PteShift = MM_PTE_SHIFT; - } - else - { - /* XPA disabled, use legacy i386 paging (PML2) */ - MmpPageMapRoutines = &MmpPml2Routines; - - /* Set PML2 page map information */ - MmpPageMapInfo.Xpa = FALSE; - - /* Set PML2 base addresses */ - MmpPageMapInfo.PteBase = MM_PTE_BASE; - MmpPageMapInfo.PdeBase = MM_PDE_LEGACY_BASE; - - /* Set PML2 shift values */ - MmpPageMapInfo.PdiShift = MM_PDI_LEGACY_SHIFT; - MmpPageMapInfo.PteShift = MM_PTE_LEGACY_SHIFT; - } -} - -/** - * Performs architecture specific initialization of the XTOS Memory Manager. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -MmpInitializeArchitecture(VOID) -{ - UNIMPLEMENTED; -} diff --git a/xtoskrnl/mm/i686/init.cc b/xtoskrnl/mm/i686/init.cc new file mode 100644 index 0000000..ab1892d --- /dev/null +++ b/xtoskrnl/mm/i686/init.cc @@ -0,0 +1,25 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/mm/i686/init.cc + * DESCRIPTION: Architecture specific Memory Manager initialization routines + * DEVELOPERS: Rafal Kupiec + * Aiken Harris + */ + +#include + + +/** + * Performs architecture specific initialization of the XTOS Memory Manager. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::Init::InitializeArchitecture(VOID) +{ + UNIMPLEMENTED; +} diff --git a/xtoskrnl/mm/i686/pmap.c b/xtoskrnl/mm/i686/pagemap.cc similarity index 65% rename from xtoskrnl/mm/i686/pmap.c rename to xtoskrnl/mm/i686/pagemap.cc index 4decaba..2ff1ed9 100644 --- a/xtoskrnl/mm/i686/pmap.c +++ b/xtoskrnl/mm/i686/pagemap.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/i686/pmap.c + * FILE: xtoskrnl/mm/i686/pagemap.cc * DESCRIPTION: Low-level support for i686 page map manipulation * DEVELOPERS: Aiken Harris */ -#include +#include /** @@ -21,26 +21,11 @@ */ XTAPI VOID -MmpClearPte(PHARDWARE_PTE PtePointer) +MM::PageMap::ClearPte(PHARDWARE_PTE PtePointer) { PtePointer->Long = 0; } -/** - * Checks if eXtended Physical Addressing (XPA) is enabled. - * - * @return This routine returns TRUE if PAE is enabled, or FALSE otherwise. - * - * @since XT 1.0 - */ -XTAPI -BOOLEAN -MmpGetExtendedPhysicalAddressingStatus(VOID) -{ - /* Check if PAE is enabled */ - return ((ArReadControlRegister(4) & CR4_PAE) != 0) ? TRUE : FALSE; -} - /** * Gets the address of the PDE (Page Directory Entry), that maps given address. * @@ -53,13 +38,13 @@ MmpGetExtendedPhysicalAddressingStatus(VOID) */ XTAPI PMMPDE -MmpGetPdeAddress(PVOID Address) +MM::PageMap::GetPdeAddress(PVOID Address) { ULONG Offset; - /* Calculate offset and return PTE address */ - Offset = ((((ULONG)(Address)) >> MmpPageMapInfo.PdiShift) << MmpPageMapInfo.PteShift); - return (PMMPTE)(MmpPageMapInfo.PdeBase + Offset); + /* Calculate offset and return PDE address */ + Offset = ((((ULONG_PTR)(Address)) >> PageMapInfo.PdiShift) << PageMapInfo.PteShift); + return (PMMPDE)(PageMapInfo.PdeBase + Offset); } /** @@ -74,10 +59,10 @@ MmpGetPdeAddress(PVOID Address) */ XTAPI PMMPPE -MmpGetPpeAddress(PVOID Address) +MM::PageMap::GetPpeAddress(PVOID Address) { /* Return zero */ - return 0; + return (PMMPPE)0; } /** @@ -92,15 +77,38 @@ MmpGetPpeAddress(PVOID Address) */ XTAPI PMMPTE -MmpGetPteAddress(PVOID Address) +MM::PageMap::GetPteAddress(PVOID Address) { ULONG Offset; /* Calculate offset and return PTE address */ - Offset = ((((ULONG)(Address)) >> MM_PTI_SHIFT) << MmpPageMapInfo.PteShift); + Offset = ((((ULONG_PTR)(Address)) >> MM_PTI_SHIFT) << PageMapInfo.PteShift); return (PMMPTE)(MM_PTE_BASE + Offset); } +/** + * Initializes page map information for basic paging (PML2). + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::PageMapBasic::InitializePageMapInfo(VOID) +{ + /* Set PML2 page map information */ + PageMapInfo.Xpa = FALSE; + + /* Set PML2 base addresses */ + PageMapInfo.PteBase = MM_PTE_BASE; + PageMapInfo.PdeBase = MM_PDE_LEGACY_BASE; + + /* Set PML2 shift values */ + PageMapInfo.PdiShift = MM_PDI_LEGACY_SHIFT; + PageMapInfo.PteShift = MM_PTE_LEGACY_SHIFT; +} + /** * Checks whether the given PML2 page table entry (PTE) is valid. * @@ -113,7 +121,7 @@ MmpGetPteAddress(PVOID Address) */ XTAPI BOOLEAN -MmpPml2PteValid(PHARDWARE_PTE PtePointer) +MM::PageMapBasic::PteValid(PHARDWARE_PTE PtePointer) { return (BOOLEAN)PtePointer->Pml2.Valid; } @@ -136,9 +144,9 @@ MmpPml2PteValid(PHARDWARE_PTE PtePointer) */ XTAPI VOID -MmpSetPml2Pte(PHARDWARE_PTE PtePointer, - PFN_NUMBER PageFrameNumber, - BOOLEAN Writable) +MM::PageMapBasic::SetPte(PHARDWARE_PTE PtePointer, + PFN_NUMBER PageFrameNumber, + BOOLEAN Writable) { PtePointer->Pml2.PageFrameNumber = PageFrameNumber; PtePointer->Pml2.Valid = 1; @@ -163,14 +171,37 @@ MmpSetPml2Pte(PHARDWARE_PTE PtePointer, */ XTAPI VOID -MmpSetPml2PteCaching(PHARDWARE_PTE PtePointer, - BOOLEAN CacheDisable, - BOOLEAN WriteThrough) +MM::PageMapBasic::SetPteCaching(PHARDWARE_PTE PtePointer, + BOOLEAN CacheDisable, + BOOLEAN WriteThrough) { PtePointer->Pml2.CacheDisable = CacheDisable; PtePointer->Pml2.WriteThrough = WriteThrough; } +/** + * Initializes page map information for basic paging (PML3). + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::PageMapXpa::InitializePageMapInfo(VOID) +{ + /* Set PML2 page map information */ + PageMapInfo.Xpa = TRUE; + + /* Set PML2 base addresses */ + PageMapInfo.PteBase = MM_PTE_BASE; + PageMapInfo.PdeBase = MM_PDE_BASE; + + /* Set PML2 shift values */ + PageMapInfo.PdiShift = MM_PDI_SHIFT; + PageMapInfo.PteShift = MM_PTE_SHIFT; +} + /** * Checks whether the given PML3 page table entry (PTE) is valid. * @@ -183,9 +214,9 @@ MmpSetPml2PteCaching(PHARDWARE_PTE PtePointer, */ XTAPI BOOLEAN -MmpPml3PteValid(PHARDWARE_PTE PtePointer) +MM::PageMapXpa::PteValid(PHARDWARE_PTE PtePointer) { - return PtePointer->Pml3.Valid; + return (BOOLEAN)PtePointer->Pml3.Valid; } /** @@ -206,9 +237,9 @@ MmpPml3PteValid(PHARDWARE_PTE PtePointer) */ XTAPI VOID -MmpSetPml3Pte(PHARDWARE_PTE PtePointer, - PFN_NUMBER PageFrameNumber, - BOOLEAN Writable) +MM::PageMapXpa::SetPte(PHARDWARE_PTE PtePointer, + PFN_NUMBER PageFrameNumber, + BOOLEAN Writable) { PtePointer->Pml3.PageFrameNumber = PageFrameNumber; PtePointer->Pml3.Valid = 1; @@ -233,9 +264,9 @@ MmpSetPml3Pte(PHARDWARE_PTE PtePointer, */ XTAPI VOID -MmpSetPml3PteCaching(PHARDWARE_PTE PtePointer, - BOOLEAN CacheDisable, - BOOLEAN WriteThrough) +MM::PageMapXpa::SetPteCaching(PHARDWARE_PTE PtePointer, + BOOLEAN CacheDisable, + BOOLEAN WriteThrough) { PtePointer->Pml3.CacheDisable = CacheDisable; PtePointer->Pml3.WriteThrough = WriteThrough; diff --git a/xtoskrnl/mm/i686/pages.c b/xtoskrnl/mm/i686/paging.cc similarity index 61% rename from xtoskrnl/mm/i686/pages.c rename to xtoskrnl/mm/i686/paging.cc index b0b4fe9..ed85f18 100644 --- a/xtoskrnl/mm/i686/pages.c +++ b/xtoskrnl/mm/i686/paging.cc @@ -1,14 +1,30 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/i686/pages.c + * FILE: xtoskrnl/mm/i686/paging.cc * DESCRIPTION: Architecture dependent paging support * DEVELOPERS: Rafal Kupiec + * Aiken Harris */ -#include +#include +/** + * Checks if eXtended Physical Addressing (XPA) is enabled. + * + * @return This routine returns TRUE if PAE is enabled, or FALSE otherwise. + * + * @since XT 1.0 + */ +XTAPI +BOOLEAN +MM::Paging::GetExtendedPhysicalAddressingStatus(VOID) +{ + /* Check if PAE is enabled */ + return ((AR::CpuFunc::ReadControlRegister(4) & CR4_PAE) != 0) ? TRUE : FALSE; +} + /** * Fills a section of memory with zeroes like RtlZeroMemory(), but in more efficient way. * @@ -24,8 +40,8 @@ */ XTFASTCALL VOID -MmZeroPages(IN PVOID Address, - IN ULONG Size) +MM::Paging::ZeroPages(IN PVOID Address, + IN ULONG Size) { __asm__ volatile("xor %%eax, %%eax\n" "rep stosb" diff --git a/xtoskrnl/mm/init.c b/xtoskrnl/mm/init.cc similarity index 65% rename from xtoskrnl/mm/init.c rename to xtoskrnl/mm/init.cc index a0917b9..d7694d8 100644 --- a/xtoskrnl/mm/init.c +++ b/xtoskrnl/mm/init.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/init.c + * FILE: xtoskrnl/mm/init.cc * DESCRIPTION: Memory Manager initialization routines * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -18,21 +18,21 @@ */ XTAPI VOID -MmInitializeMemoryManager(VOID) +MM::Init::InitializeMemoryManager(VOID) { /* Scan memory descriptors provided by the boot loader */ - MmpScanMemoryDescriptors(); + ScanMemoryDescriptors(); /* Check if there are enough physical pages */ - if(MmNumberOfPhysicalPages < MM_MINIMUM_PHYSICAL_PAGES) + if(NumberOfPhysicalPages < MM_MINIMUM_PHYSICAL_PAGES) { /* Insufficient physical pages, kernel panic */ DebugPrint(L"Insufficient physical pages! Install additional memory\n"); - KePanic(0); + KE::Crash::Panic(0); } /* Proceed with architecture specific initialization */ - MmpInitializeArchitecture(); + InitializeArchitecture(); } /** @@ -44,24 +44,27 @@ MmInitializeMemoryManager(VOID) */ XTAPI VOID -MmpScanMemoryDescriptors(VOID) +MM::Init::ScanMemoryDescriptors(VOID) { + PLIST_ENTRY LoaderMemoryDescriptors, MemoryMappings; PLOADER_MEMORY_DESCRIPTOR MemoryDescriptor; - PLIST_ENTRY MemoryMappings; PFN_NUMBER FreePages; /* Initially, set number of free pages to 0 */ FreePages = 0; + /* Get a list of memory descriptors provided by the boot loader */ + LoaderMemoryDescriptors = KE::BootInformation::GetMemoryDescriptors(); + /* Iterate through memory mappings provided by the boot loader */ - MemoryMappings = KeInitializationBlock->MemoryDescriptorListHead.Flink; - while(MemoryMappings != &KeInitializationBlock->MemoryDescriptorListHead) + MemoryMappings = LoaderMemoryDescriptors->Flink; + while(MemoryMappings != LoaderMemoryDescriptors) { /* Get memory descriptor */ MemoryDescriptor = CONTAIN_RECORD(MemoryMappings, LOADER_MEMORY_DESCRIPTOR, ListEntry); /* Check if memory type is invisible or cached */ - if(MmpVerifyMemoryTypeInvisible(MemoryDescriptor->MemoryType) || + if(VerifyMemoryTypeInvisible(MemoryDescriptor->MemoryType) || (MemoryDescriptor->MemoryType == LoaderHardwareCachedMemory)) { /* Skip this mapping */ @@ -73,32 +76,32 @@ MmpScanMemoryDescriptors(VOID) if(MemoryDescriptor->MemoryType != LoaderBad) { /* Increment number of physical pages */ - MmNumberOfPhysicalPages += MemoryDescriptor->PageCount; + NumberOfPhysicalPages += MemoryDescriptor->PageCount; } /* Find lowest physical page */ - if(MemoryDescriptor->BasePage < MmLowestPhysicalPage) + if(MemoryDescriptor->BasePage < LowestPhysicalPage) { /* Update lowest physical page */ - MmLowestPhysicalPage = MemoryDescriptor->BasePage; + LowestPhysicalPage = MemoryDescriptor->BasePage; } /* Find highest physical page */ - if(MemoryDescriptor->BasePage + MemoryDescriptor->PageCount > MmHighestPhysicalPage) + if(MemoryDescriptor->BasePage + MemoryDescriptor->PageCount > HighestPhysicalPage) { /* Update highest physical page */ - MmHighestPhysicalPage = (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount) - 1; + HighestPhysicalPage = (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount) - 1; } /* Check if memory type should be considered as free */ - if(MmpVerifyMemoryTypeFree(MemoryDescriptor->MemoryType)) + if(VerifyMemoryTypeFree(MemoryDescriptor->MemoryType)) { /* Check if this descriptor contains more free pages */ if(MemoryDescriptor->PageCount >= FreePages) { /* Update free descriptor */ FreePages = MemoryDescriptor->PageCount; - MmFreeDescriptor = MemoryDescriptor; + FreeDescriptor = MemoryDescriptor; } } @@ -107,7 +110,7 @@ MmpScanMemoryDescriptors(VOID) } /* Store original free descriptor */ - RtlCopyMemory(&MmOldFreeDescriptor, MmFreeDescriptor, sizeof(LOADER_MEMORY_DESCRIPTOR)); + RTL::Memory::CopyMemory(&OldFreeDescriptor, FreeDescriptor, sizeof(LOADER_MEMORY_DESCRIPTOR)); } /** Checks whether the specified memory type should be considered as free. @@ -121,10 +124,10 @@ MmpScanMemoryDescriptors(VOID) */ XTAPI BOOLEAN -MmpVerifyMemoryTypeFree(LOADER_MEMORY_TYPE MemoryType) +MM::Init::VerifyMemoryTypeFree(LOADER_MEMORY_TYPE MemoryType) { - return (MemoryType == LoaderFree) || (MemoryType == LoaderFirmwareTemporary) || - (MemoryType == LoaderLoadedProgram) || (MemoryType == LoaderOsloaderStack); + return ((MemoryType == LoaderFree) || (MemoryType == LoaderFirmwareTemporary) || + (MemoryType == LoaderLoadedProgram) || (MemoryType == LoaderOsloaderStack)); } /** @@ -139,9 +142,9 @@ MmpVerifyMemoryTypeFree(LOADER_MEMORY_TYPE MemoryType) */ XTAPI BOOLEAN -MmpVerifyMemoryTypeInvisible(LOADER_MEMORY_TYPE MemoryType) +MM::Init::VerifyMemoryTypeInvisible(LOADER_MEMORY_TYPE MemoryType) { - return (MemoryType == LoaderFirmwarePermanent) || - (MemoryType == LoaderSpecialMemory) || - (MemoryType == LoaderBBTMemory); + return ((MemoryType == LoaderFirmwarePermanent) || + (MemoryType == LoaderSpecialMemory) || + (MemoryType == LoaderBBTMemory)); } diff --git a/xtoskrnl/mm/kpools.c b/xtoskrnl/mm/kpool.cc similarity index 77% rename from xtoskrnl/mm/kpools.c rename to xtoskrnl/mm/kpool.cc index 5acea49..190c7da 100644 --- a/xtoskrnl/mm/kpools.c +++ b/xtoskrnl/mm/kpool.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/kpools.c + * FILE: xtoskrnl/mm/kpool.cc * DESCRIPTION: Kernel pool memory management * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -27,9 +27,9 @@ */ XTAPI XTSTATUS -MmAllocateKernelStack(IN PVOID *Stack, - IN BOOLEAN LargeStack, - IN UCHAR SystemNode) +MM::KernelPool::AllocateKernelStack(IN PVOID *Stack, + IN BOOLEAN LargeStack, + IN UCHAR SystemNode) { UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED; @@ -50,8 +50,8 @@ MmAllocateKernelStack(IN PVOID *Stack, */ XTAPI XTSTATUS -MmAllocateProcessorStructures(IN ULONG CpuNumber, - OUT PVOID *StructuresData) +MM::KernelPool::AllocateProcessorStructures(IN ULONG CpuNumber, + OUT PVOID *StructuresData) { PKPROCESSOR_BLOCK ProcessorBlock; PVOID ProcessorStructures; @@ -61,14 +61,14 @@ MmAllocateProcessorStructures(IN ULONG CpuNumber, UNIMPLEMENTED; /* Assign memory for processor structures from preallocated buffer */ - ProcessorStructures = &MmProcessorStructuresData[CpuNumber - 1]; + ProcessorStructures = &ProcessorStructuresData[CpuNumber - 1]; /* Make sure all structures are zeroed */ - RtlZeroMemory(ProcessorStructures, KPROCESSOR_STRUCTURES_SIZE); + RTL::Memory::ZeroMemory(ProcessorStructures, KPROCESSOR_STRUCTURES_SIZE); /* Align address to page size boundary and find a space for processor block */ Address = ROUND_UP((UINT_PTR)ProcessorStructures, MM_PAGE_SIZE); - ProcessorBlock = (PKPROCESSOR_BLOCK)((PUCHAR)Address + (2 * KERNEL_STACK_SIZE) + sizeof(ArInitialGdt)); + ProcessorBlock = (PKPROCESSOR_BLOCK)((PUCHAR)Address + (2 * KERNEL_STACK_SIZE) + (GDT_ENTRIES * sizeof(KGDTENTRY))); /* Store processor number in the processor block */ ProcessorBlock->CpuNumber = CpuNumber; @@ -95,8 +95,8 @@ MmAllocateProcessorStructures(IN ULONG CpuNumber, */ XTAPI VOID -MmFreeKernelStack(IN PVOID Stack, - IN BOOLEAN LargeStack) +MM::KernelPool::FreeKernelStack(IN PVOID Stack, + IN BOOLEAN LargeStack) { UNIMPLEMENTED; } @@ -113,7 +113,7 @@ MmFreeKernelStack(IN PVOID Stack, */ XTAPI VOID -MmFreeProcessorStructures(IN PVOID StructuresData) +MM::KernelPool::FreeProcessorStructures(IN PVOID StructuresData) { UNIMPLEMENTED; } diff --git a/xtoskrnl/mm/pages.c b/xtoskrnl/mm/pages.c deleted file mode 100644 index 13bbd58..0000000 --- a/xtoskrnl/mm/pages.c +++ /dev/null @@ -1,62 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/mm/pages.c - * DESCRIPTION: Low level page management support - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/** - * Flushes current Translation Lookaside Buffer (TLB) - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -MmFlushTlb(VOID) -{ - CPUID_REGISTERS CpuRegisters; - BOOLEAN Interrupts; - ULONG_PTR Cr4; - - /* Save interrupts state and disable them */ - Interrupts = ArInterruptsEnabled(); - ArClearInterruptFlag(); - - /* Get CPU features */ - CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES; - ArCpuId(&CpuRegisters); - - /* Check if Paging Global Extensions (PGE) is supported */ - if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PGE) - { - /* Read CR4 */ - Cr4 = ArReadControlRegister(4); - - /* Disable PGE */ - ArWriteControlRegister(4, Cr4 & ~CR4_PGE); - - /* Flush the TLB */ - ArFlushTlb(); - - /* Restore CR4 */ - ArWriteControlRegister(4, Cr4); - } - else - { - /* Simply flush the TLB */ - ArFlushTlb(); - } - - /* Check if interrupts should be enabled */ - if(Interrupts) - { - /* Re-enable interrupts */ - ArSetInterruptFlag(); - } -} diff --git a/xtoskrnl/mm/paging.cc b/xtoskrnl/mm/paging.cc new file mode 100644 index 0000000..58833b1 --- /dev/null +++ b/xtoskrnl/mm/paging.cc @@ -0,0 +1,254 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/mm/paging.cc + * DESCRIPTION: Low level page management support + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * Clears the contents of a page table entry (PTE). + * + * @param PtePointer + * Pointer to the page table entry (PTE) to be cleared. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::Paging::ClearPte(PHARDWARE_PTE PtePointer) +{ + PmlRoutines->ClearPte(PtePointer); +} + +/** + * Flushes current Translation Lookaside Buffer (TLB) + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::Paging::FlushTlb(VOID) +{ + CPUID_REGISTERS CpuRegisters; + BOOLEAN Interrupts; + ULONG_PTR Cr4; + + /* Save interrupts state and disable them */ + Interrupts = AR::CpuFunc::InterruptsEnabled(); + AR::CpuFunc::ClearInterruptFlag(); + + /* Get CPU features */ + CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES; + AR::CpuFunc::CpuId(&CpuRegisters); + + /* Check if Paging Global Extensions (PGE) is supported */ + if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PGE) + { + /* Read CR4 */ + Cr4 = AR::CpuFunc::ReadControlRegister(4); + + /* Disable PGE */ + AR::CpuFunc::WriteControlRegister(4, Cr4 & ~CR4_PGE); + + /* Flush the TLB */ + AR::CpuFunc::FlushTlb(); + + /* Restore CR4 */ + AR::CpuFunc::WriteControlRegister(4, Cr4); + } + else + { + /* Simply flush the TLB */ + AR::CpuFunc::FlushTlb(); + } + + /* Check if interrupts should be enabled */ + if(Interrupts) + { + /* Re-enable interrupts */ + AR::CpuFunc::SetInterruptFlag(); + } +} + +/** + * Gets the page map routines for basic paging mode (non-XPA). + * + * @return This routine returns the address of the object containing non-XPA page map routines. + * + * @since XT 1.0 + */ +XTAPI +MM::PPAGEMAP +MM::Paging::GetPageMapBasicRoutines(VOID) +{ + static MM::PageMapBasic PageMapBasicRoutines; + return &PageMapBasicRoutines; +} + +/** + * Gets the page map routines for eXtended Physical Addressing (XPA) mode. + * + * @return This routine returns the address of the object containing XPA page map routines. + * + * @since XT 1.0 + */ +XTAPI +MM::PPAGEMAP +MM::Paging::GetPageMapXpaRoutines(VOID) +{ + static MM::PageMapXpa PageMapXpaRoutines; + return &PageMapXpaRoutines; +} + +/** + * Gets the address of the PDE (Page Directory Entry), that maps given address. + * + * @param Address + * Specifies the virtual address for which to retrieve the corresponding PDE. + * + * @return This routine returns the address of the PDE. + * + * @since XT 1.0 + */ +XTAPI +PMMPDE +MM::Paging::GetPdeAddress(PVOID Address) +{ + return PmlRoutines->GetPdeAddress(Address); +} + +/** + * Gets the address of the PPE (Page Directory Pointer Table Entry), that maps given address. + * + * @param Address + * Specifies the virtual address for which to retrieve the corresponding PDE. + * + * @return This routine returns the address of the PPE. + * + * @since XT 1.0 + */ +XTAPI +PMMPPE +MM::Paging::GetPpeAddress(PVOID Address) +{ + return PmlRoutines->GetPpeAddress(Address); +} + +/** + * Gets the address of the PTE (Page Table Entry), that maps given address. + * + * @param Address + * Specifies the virtual address for which to retrieve the corresponding PTE. + * + * @return This routine returns the address of the PTE. + * + * @since XT 1.0 + */ +XTAPI +PMMPTE +MM::Paging::GetPteAddress(PVOID Address) +{ + return PmlRoutines->GetPteAddress(Address); +} + +/** + * Detects if eXtended Physical Addressing (XPA) is enabled and initializes page map support. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::Paging::InitializePageMapSupport(VOID) +{ + /* Check if XPA is enabled */ + if(GetExtendedPhysicalAddressingStatus()) + { + /* XPA enabled, use modern paging (PAE / LA57) */ + PmlRoutines = GetPageMapXpaRoutines(); + } + else + { + /* XPA disabled, use basic paging (PML2 / PML4) */ + PmlRoutines = GetPageMapBasicRoutines(); + } + + /* Set page map information */ + PmlRoutines->InitializePageMapInfo(); +} + +/** + * Checks whether the given PML2 page table entry (PTE) is valid. + * + * @param PtePointer + * Pointer to the page table entry (PTE) to check. + * + * @return Returns TRUE if the entry is valid, FALSE otherwise. + * + * @since XT 1.0 + */ +XTAPI +BOOLEAN +MM::Paging::PteValid(PHARDWARE_PTE PtePointer) +{ + return PmlRoutines->PteValid(PtePointer); +} + +/** + * Sets a PML2 page table entry (PTE) with the specified physical page and access flags. + * + * @param PtePointer + * Pointer to the page table entry (PTE) to set. + * + * @param PageFrameNumber + * Physical frame number to map. + * + * @param Writable + * Indicates whether the page should be writable. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::Paging::SetPte(PHARDWARE_PTE PtePointer, + PFN_NUMBER PageFrameNumber, + BOOLEAN Writable) +{ + PmlRoutines->SetPte(PtePointer, PageFrameNumber, Writable); +} + +/** + * Sets caching attributes for a PML2 page table entry (PTE). + * + * @param PtePointer + * Pointer to the page table entry (PTE) to modify. + * + * @param CacheDisable + * Indicates whether caching should be disabled for this page. + * + * @param WriteThrough + * Indicates whether write-through caching should be enabled. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::Paging::SetPteCaching(PHARDWARE_PTE PtePointer, + BOOLEAN CacheDisable, + BOOLEAN WriteThrough) +{ + PmlRoutines->SetPteCaching(PtePointer, CacheDisable, WriteThrough); +} diff --git a/xtoskrnl/po/idle.c b/xtoskrnl/po/idle.cc similarity index 78% rename from xtoskrnl/po/idle.c rename to xtoskrnl/po/idle.cc index 9fad09b..92b802a 100644 --- a/xtoskrnl/po/idle.c +++ b/xtoskrnl/po/idle.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/po/idle.c + * FILE: xtoskrnl/po/idle.cc * DESCRIPTION: Processor idle functionality support * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -21,7 +21,7 @@ */ XTAPI VOID -PoInitializeProcessorControlBlock(IN OUT PKPROCESSOR_CONTROL_BLOCK Prcb) +PO::Idle::InitializeProcessorIdleState(IN OUT PKPROCESSOR_CONTROL_BLOCK Prcb) { /* Zero memory */ RtlZeroMemory(&Prcb->PowerState, sizeof(Prcb->PowerState)); @@ -30,10 +30,10 @@ PoInitializeProcessorControlBlock(IN OUT PKPROCESSOR_CONTROL_BLOCK Prcb) Prcb->PowerState.Idle0TimeLimit = 0xFFFFFFFF; Prcb->PowerState.CurrentThrottle = 100; Prcb->PowerState.CurrentThrottleIndex = 0; - Prcb->PowerState.IdleFunction = PopIdle0Function; + Prcb->PowerState.IdleFunction = Idle0Function; /* Initialize DPC and Timer */ - KeInitializeDpc(&Prcb->PowerState.PerfDpc, PopPerfIdleDpc, Prcb); + KeInitializeDpc(&Prcb->PowerState.PerfDpc, PerfIdleDpc, Prcb); KeSetTargetProcessorDpc(&Prcb->PowerState.PerfDpc, Prcb->CpuNumber); KeInitializeTimer(&Prcb->PowerState.PerfTimer, SynchronizationTimer); } @@ -50,7 +50,7 @@ PoInitializeProcessorControlBlock(IN OUT PKPROCESSOR_CONTROL_BLOCK Prcb) */ XTFASTCALL VOID -PopIdle0Function(IN PPROCESSOR_POWER_STATE PowerState) +PO::Idle::Idle0Function(IN PPROCESSOR_POWER_STATE PowerState) { UNIMPLEMENTED; } @@ -67,7 +67,7 @@ PopIdle0Function(IN PPROCESSOR_POWER_STATE PowerState) */ XTAPI VOID -PopPerfIdle(PPROCESSOR_POWER_STATE PowerState) +PO::Idle::PerfIdle(PPROCESSOR_POWER_STATE PowerState) { UNIMPLEMENTED; } @@ -93,10 +93,10 @@ PopPerfIdle(PPROCESSOR_POWER_STATE PowerState) */ XTAPI VOID -PopPerfIdleDpc(IN PKDPC Dpc, - IN PVOID DeferredContext, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2) +PO::Idle::PerfIdleDpc(IN PKDPC Dpc, + IN PVOID DeferredContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2) { UNIMPLEMENTED; } diff --git a/xtoskrnl/rtl/amd64/dispatch.c b/xtoskrnl/rtl/amd64/dispatch.cc similarity index 73% rename from xtoskrnl/rtl/amd64/dispatch.c rename to xtoskrnl/rtl/amd64/dispatch.cc index 61c664e..7aa6f50 100644 --- a/xtoskrnl/rtl/amd64/dispatch.c +++ b/xtoskrnl/rtl/amd64/dispatch.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/rtl/amd64/dispatch.c + * FILE: xtoskrnl/rtl/amd64/dispatch.cc * DESCRIPTION: Dispatching support for AMD64 architecture * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -24,10 +24,10 @@ */ XTAPI VOID -RtlGetStackLimits(OUT PULONG_PTR StackBase, - OUT PULONG_PTR StackLimit) +RTL::Dispatcher::GetStackLimits(OUT PULONG_PTR StackBase, + OUT PULONG_PTR StackLimit) { - PKTHREAD Thread = KeGetCurrentThread(); + PKTHREAD Thread = KE::Processor::GetCurrentThread(); *StackBase = (ULONG_PTR)Thread->StackBase; *StackLimit = (ULONG_PTR)Thread->StackLimit; } diff --git a/xtoskrnl/rtl/amd64/exsup.c b/xtoskrnl/rtl/amd64/exsup.c deleted file mode 100644 index b861b86..0000000 --- a/xtoskrnl/rtl/amd64/exsup.c +++ /dev/null @@ -1,36 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/rtl/amd64/exsup.c - * DESCRIPTION: Exception handling for AMD64 architecture - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -XTAPI -EXCEPTION_DISPOSITION -__C_specific_handler(IN PEXCEPTION_RECORD ExceptionRecord, - IN PVOID EstablisherFrame, - IN OUT PCONTEXT ContextRecord, - IN OUT PVOID DispatcherContext) -{ - UNIMPLEMENTED; - - /* Continue execution */ - return ExceptionContinueExecution; -} - -XTCDECL -INT -_except_handler3(PEXCEPTION_RECORD ExceptionRecord, - PVOID Registration, - PCONTEXT Context, - PVOID Dispatcher) -{ - UNIMPLEMENTED; - - /* Handler not found */ - return 0; -} diff --git a/xtoskrnl/rtl/amd64/exsup.cc b/xtoskrnl/rtl/amd64/exsup.cc new file mode 100644 index 0000000..39aff65 --- /dev/null +++ b/xtoskrnl/rtl/amd64/exsup.cc @@ -0,0 +1,133 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/rtl/amd64/exsup.cc + * DESCRIPTION: Exception handling for AMD64 architecture + * DEVELOPERS: Rafal Kupiec + * Aiken Harris + */ + +#include + + +/** + * Handles SEH structured exception frames. + * + * @param ExceptionRecord + * A pointer to the exception record. + * + * @param EstablisherFrame + * The address of the base of the fixed stack allocation. + * + * @param ContextRecord + * A pointer to the context record at the time the exception was raised. + * + * @param DispatcherContext + * A pointer to the dispatcher context for the function. + * + * @return This routine returns an exception disposition value if the exception was not handled by any filter. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +EXCEPTION_DISPOSITION +__C_specific_handler(IN PEXCEPTION_RECORD ExceptionRecord, + IN PVOID EstablisherFrame, + IN OUT PCONTEXT ContextRecord, + IN OUT PVOID DispatcherContext) +{ + UNIMPLEMENTED; + + /* Continue execution */ + return ExceptionContinueExecution; +} + +/** + * Handles C++ structured exception frames. This implementation displays a panic screen and halts the system. + * + * @param ExceptionRecord + * A pointer to the exception record that is passed to the possible catch statements. + * + * @param EstablisherFrame + * A pointer to the stack frame that is used to handle the exception. + * + * @param ContextRecord + * A pointer to the context record (not used on Intel CPUs). + * + * @param DispatcherContext + * A pointer to the dispatcher provding information about function entry and stack frame (not used on Intel CPUs). + * + * @return This routine returns an exception disposition value if the exception was not handled by any filter. + * + * @since XT 1.0 + */ +XTCLINK +XTCDECL +EXCEPTION_DISPOSITION +__CxxFrameHandler3(IN PEXCEPTION_RECORD ExceptionRecord, + IN PVOID EstablisherFrame, + IN OUT PCONTEXT ContextRecord, + IN OUT PVOID DispatcherContext) +{ + UNIMPLEMENTED; + + /* Disable interrupts and hang */ + AR::CpuFunc::ClearInterruptFlag(); + KE::Crash::Panic(0); // CXX_FRAME_HANDLER_CALLED + + /* Continue search */ + return ExceptionContinueSearch; +} + +/** + * Finds the appropriate exception handler to process the current exception. + * + * @param ExceptionRecord + * A pointer to the exception record providing information about the specific exception. + * + * @param Registration + * A pointer to the record that indicates which scope table should be used to find the exception handler. + * + * @param Context + * Reserved. + * + * @param Dispatcher + * Reserved. + * + * @return This routine returns DISPOSITION_DISMISS or DISPOSITION_CONTINUE_SEARCH. + * + * @since XT 1.0 + */ +XTCLINK +XTCDECL +INT +_except_handler3(IN PEXCEPTION_RECORD ExceptionRecord, + IN PVOID Registration, + IN PCONTEXT Context, + IN PVOID Dispatcher) +{ + UNIMPLEMENTED; + + /* Handler not found */ + return 0; +} + +/** + * Handles pure virtual function call error. This implementation displays a panic screen and halts the system. + * + * @return This function does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTCDECL +VOID +_purecall(VOID) +{ + UNIMPLEMENTED; + + /* Disable interrupts and hang */ + AR::CpuFunc::ClearInterruptFlag(); + KE::Crash::Panic(0); // PURE_VIRTUAL_FUNCTION_CALL +} diff --git a/xtoskrnl/rtl/atomic.c b/xtoskrnl/rtl/atomic.cc similarity index 80% rename from xtoskrnl/rtl/atomic.c rename to xtoskrnl/rtl/atomic.cc index 46b2fe8..86b16d8 100644 --- a/xtoskrnl/rtl/atomic.c +++ b/xtoskrnl/rtl/atomic.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/rtl/atomic.c + * FILE: xtoskrnl/rtl/atomic.cc * DESCRIPTION: Atomic operations support * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -24,8 +24,8 @@ */ XTFASTCALL CHAR -RtlAtomicAnd8(IN VOLATILE PCHAR Address, - IN CHAR Mask) +RTL::Atomic::And8(IN PCHAR Address, + IN CHAR Mask) { return __sync_fetch_and_and(Address, Mask); } @@ -45,8 +45,8 @@ RtlAtomicAnd8(IN VOLATILE PCHAR Address, */ XTFASTCALL SHORT -RtlAtomicAnd16(IN VOLATILE PSHORT Address, - IN SHORT Mask) +RTL::Atomic::And16(IN PSHORT Address, + IN SHORT Mask) { return __sync_fetch_and_and(Address, Mask); } @@ -66,8 +66,8 @@ RtlAtomicAnd16(IN VOLATILE PSHORT Address, */ XTFASTCALL LONG -RtlAtomicAnd32(IN VOLATILE PLONG Address, - IN LONG Mask) +RTL::Atomic::And32(IN PLONG Address, + IN LONG Mask) { return __sync_fetch_and_and(Address, Mask); } @@ -87,8 +87,8 @@ RtlAtomicAnd32(IN VOLATILE PLONG Address, */ XTFASTCALL LONG_PTR -RtlAtomicAnd64(IN VOLATILE PLONG_PTR Address, - IN LONG_PTR Mask) +RTL::Atomic::And64(IN PLONG_PTR Address, + IN LONG_PTR Mask) { return __sync_fetch_and_and(Address, Mask); } @@ -108,8 +108,8 @@ RtlAtomicAnd64(IN VOLATILE PLONG_PTR Address, */ XTFASTCALL UCHAR -RtlAtomicBitTestAndSet(IN VOLATILE PLONG Base, - IN LONG Offset) +RTL::Atomic::BitTestAndSet(IN PLONG Base, + IN LONG Offset) { return (__atomic_fetch_or(Base, 1l << Offset, __ATOMIC_SEQ_CST) >> Offset) & 1; } @@ -129,8 +129,8 @@ RtlAtomicBitTestAndSet(IN VOLATILE PLONG Base, */ XTFASTCALL UCHAR -RtlAtomicBitTestAndSet64(IN VOLATILE PLONGLONG Base, - IN LONGLONG Offset) +RTL::Atomic::BitTestAndSet64(IN PLONGLONG Base, + IN LONGLONG Offset) { return (__atomic_fetch_or(Base, 1ll << Offset, __ATOMIC_SEQ_CST) >> Offset) & 1; } @@ -153,9 +153,9 @@ RtlAtomicBitTestAndSet64(IN VOLATILE PLONGLONG Base, */ XTFASTCALL CHAR -RtlAtomicCompareExchange8(IN VOLATILE PCHAR Address, - IN CHAR Comperand, - IN CHAR Exchange) +RTL::Atomic::CompareExchange8(IN PCHAR Address, + IN CHAR Comperand, + IN CHAR Exchange) { return __sync_val_compare_and_swap(Address, Comperand, Exchange); } @@ -178,9 +178,9 @@ RtlAtomicCompareExchange8(IN VOLATILE PCHAR Address, */ XTFASTCALL SHORT -RtlAtomicCompareExchange16(IN VOLATILE PSHORT Address, - IN SHORT Comperand, - IN SHORT Exchange) +RTL::Atomic::CompareExchange16(IN PSHORT Address, + IN SHORT Comperand, + IN SHORT Exchange) { return __sync_val_compare_and_swap(Address, Comperand, Exchange); } @@ -203,9 +203,9 @@ RtlAtomicCompareExchange16(IN VOLATILE PSHORT Address, */ XTFASTCALL LONG -RtlAtomicCompareExchange32(IN VOLATILE PLONG Address, - IN LONG Comperand, - IN LONG Exchange) +RTL::Atomic::CompareExchange32(IN PLONG Address, + IN LONG Comperand, + IN LONG Exchange) { return __sync_val_compare_and_swap(Address, Comperand, Exchange); } @@ -228,9 +228,9 @@ RtlAtomicCompareExchange32(IN VOLATILE PLONG Address, */ XTFASTCALL LONG_PTR -RtlAtomicCompareExchange64(IN VOLATILE PLONG_PTR Address, - IN LONG_PTR Comperand, - IN LONG_PTR Exchange) +RTL::Atomic::CompareExchange64(IN PLONG_PTR Address, + IN LONG_PTR Comperand, + IN LONG_PTR Exchange) { return __sync_val_compare_and_swap(Address, Comperand, Exchange); } @@ -253,9 +253,9 @@ RtlAtomicCompareExchange64(IN VOLATILE PLONG_PTR Address, */ XTFASTCALL PVOID -RtlAtomicCompareExchangePointer(IN VOLATILE PVOID *Address, - IN PVOID Comperand, - IN PVOID Exchange) +RTL::Atomic::CompareExchangePointer(IN PVOID *Address, + IN PVOID Comperand, + IN PVOID Exchange) { return (PVOID)__sync_val_compare_and_swap(Address, Comperand, Exchange); } @@ -272,7 +272,7 @@ RtlAtomicCompareExchangePointer(IN VOLATILE PVOID *Address, */ XTFASTCALL CHAR -RtlAtomicDecrement8(IN VOLATILE PCHAR Address) +RTL::Atomic::Decrement8(IN PCHAR Address) { return __sync_sub_and_fetch(Address, 1); } @@ -289,7 +289,7 @@ RtlAtomicDecrement8(IN VOLATILE PCHAR Address) */ XTFASTCALL SHORT -RtlAtomicDecrement16(IN VOLATILE PSHORT Address) +RTL::Atomic::Decrement16(IN PSHORT Address) { return __sync_sub_and_fetch(Address, 1); } @@ -306,7 +306,7 @@ RtlAtomicDecrement16(IN VOLATILE PSHORT Address) */ XTFASTCALL LONG -RtlAtomicDecrement32(IN VOLATILE PLONG Address) +RTL::Atomic::Decrement32(IN PLONG Address) { return __sync_sub_and_fetch(Address, 1); } @@ -323,7 +323,7 @@ RtlAtomicDecrement32(IN VOLATILE PLONG Address) */ XTFASTCALL LONG_PTR -RtlAtomicDecrement64(IN VOLATILE PLONG_PTR Address) +RTL::Atomic::Decrement64(IN PLONG_PTR Address) { return __sync_sub_and_fetch(Address, 1); } @@ -343,8 +343,8 @@ RtlAtomicDecrement64(IN VOLATILE PLONG_PTR Address) */ XTFASTCALL CHAR -RtlAtomicExchange8(IN VOLATILE PCHAR Address, - IN CHAR Exchange) +RTL::Atomic::Exchange8(IN PCHAR Address, + IN CHAR Exchange) { return __sync_lock_test_and_set(Address, Exchange); } @@ -364,8 +364,8 @@ RtlAtomicExchange8(IN VOLATILE PCHAR Address, */ XTFASTCALL SHORT -RtlAtomicExchange16(IN VOLATILE PSHORT Address, - IN SHORT Exchange) +RTL::Atomic::Exchange16(IN PSHORT Address, + IN SHORT Exchange) { return __sync_lock_test_and_set(Address, Exchange); } @@ -385,8 +385,8 @@ RtlAtomicExchange16(IN VOLATILE PSHORT Address, */ XTFASTCALL LONG -RtlAtomicExchange32(IN VOLATILE PLONG Address, - IN LONG Exchange) +RTL::Atomic::Exchange32(IN PLONG Address, + IN LONG Exchange) { return __sync_lock_test_and_set(Address, Exchange); } @@ -406,8 +406,8 @@ RtlAtomicExchange32(IN VOLATILE PLONG Address, */ XTFASTCALL LONG_PTR -RtlAtomicExchange64(IN VOLATILE PLONG_PTR Address, - IN LONG_PTR Exchange) +RTL::Atomic::Exchange64(IN PLONG_PTR Address, + IN LONG_PTR Exchange) { return __sync_lock_test_and_set(Address, Exchange); } @@ -427,8 +427,8 @@ RtlAtomicExchange64(IN VOLATILE PLONG_PTR Address, */ XTFASTCALL CHAR -RtlAtomicExchangeAdd8(IN VOLATILE PCHAR Address, - IN CHAR Value) +RTL::Atomic::ExchangeAdd8(IN PCHAR Address, + IN CHAR Value) { return __sync_fetch_and_add(Address, Value); } @@ -448,8 +448,8 @@ RtlAtomicExchangeAdd8(IN VOLATILE PCHAR Address, */ XTFASTCALL SHORT -RtlAtomicExchangeAdd16(IN VOLATILE PSHORT Address, - IN SHORT Value) +RTL::Atomic::ExchangeAdd16(IN PSHORT Address, + IN SHORT Value) { return __sync_fetch_and_add(Address, Value); } @@ -469,8 +469,8 @@ RtlAtomicExchangeAdd16(IN VOLATILE PSHORT Address, */ XTFASTCALL LONG -RtlAtomicExchangeAdd32(IN VOLATILE PLONG Address, - IN LONG Value) +RTL::Atomic::ExchangeAdd32(IN PLONG Address, + IN LONG Value) { return __sync_fetch_and_add(Address, Value); } @@ -490,8 +490,8 @@ RtlAtomicExchangeAdd32(IN VOLATILE PLONG Address, */ XTFASTCALL LONG_PTR -RtlAtomicExchangeAdd64(IN VOLATILE PLONG_PTR Address, - IN LONG_PTR Value) +RTL::Atomic::ExchangeAdd64(IN PLONG_PTR Address, + IN LONG_PTR Value) { return __sync_fetch_and_add(Address, Value); } @@ -511,8 +511,8 @@ RtlAtomicExchangeAdd64(IN VOLATILE PLONG_PTR Address, */ XTFASTCALL PVOID -RtlAtomicExchangePointer(IN VOLATILE PVOID *Address, - IN PVOID Exchange) +RTL::Atomic::ExchangePointer(IN PVOID *Address, + IN PVOID Exchange) { __sync_synchronize(); return (PVOID)__sync_lock_test_and_set(Address, Exchange); @@ -524,15 +524,15 @@ RtlAtomicExchangePointer(IN VOLATILE PVOID *Address, * @param Header * Supplies a pointer to the header of linked list. * - * @return This routine returns a pointer to the original list, or NULL if the list was already empty. + * @return This routine returns a pointer to the original list, or NULLPTR if the list was already empty. * * @since XT 1.0 */ XTFASTCALL PSINGLE_LIST_ENTRY -RtlAtomicFlushSingleList(IN PSINGLE_LIST_HEADER Header) +RTL::Atomic::FlushSingleList(IN PSINGLE_LIST_HEADER Header) { - return (PSINGLE_LIST_ENTRY)RtlAtomicExchange64((PLONG_PTR)&Header->Alignment, (LONGLONG)NULL); + return (PSINGLE_LIST_ENTRY)Exchange64((PLONG_PTR)&Header->Alignment, (LONGLONG)NULLPTR); } /** @@ -547,7 +547,7 @@ RtlAtomicFlushSingleList(IN PSINGLE_LIST_HEADER Header) */ XTFASTCALL CHAR -RtlAtomicIncrement8(IN VOLATILE PCHAR Address) +RTL::Atomic::Increment8(IN PCHAR Address) { return __sync_add_and_fetch(Address, 1); } @@ -564,7 +564,7 @@ RtlAtomicIncrement8(IN VOLATILE PCHAR Address) */ XTFASTCALL SHORT -RtlAtomicIncrement16(IN VOLATILE PSHORT Address) +RTL::Atomic::Increment16(IN PSHORT Address) { return __sync_add_and_fetch(Address, 1); } @@ -581,7 +581,7 @@ RtlAtomicIncrement16(IN VOLATILE PSHORT Address) */ XTFASTCALL LONG -RtlAtomicIncrement32(IN VOLATILE PLONG Address) +RTL::Atomic::Increment32(IN PLONG Address) { return __sync_add_and_fetch(Address, 1); } @@ -598,7 +598,7 @@ RtlAtomicIncrement32(IN VOLATILE PLONG Address) */ XTFASTCALL LONG_PTR -RtlAtomicIncrement64(IN VOLATILE PLONG_PTR Address) +RTL::Atomic::Increment64(IN PLONG_PTR Address) { return __sync_add_and_fetch(Address, 1); } @@ -618,8 +618,8 @@ RtlAtomicIncrement64(IN VOLATILE PLONG_PTR Address) */ XTFASTCALL CHAR -RtlAtomicOr8(IN VOLATILE PCHAR Address, - IN CHAR Mask) +RTL::Atomic::Or8(IN PCHAR Address, + IN CHAR Mask) { return __sync_fetch_and_or(Address, Mask); } @@ -639,8 +639,8 @@ RtlAtomicOr8(IN VOLATILE PCHAR Address, */ XTFASTCALL SHORT -RtlAtomicOr16(IN VOLATILE PSHORT Address, - IN SHORT Mask) +RTL::Atomic::Or16(IN PSHORT Address, + IN SHORT Mask) { return __sync_fetch_and_or(Address, Mask); } @@ -660,8 +660,8 @@ RtlAtomicOr16(IN VOLATILE PSHORT Address, */ XTFASTCALL LONG -RtlAtomicOr32(IN VOLATILE PLONG Address, - IN LONG Mask) +RTL::Atomic::Or32(IN PLONG Address, + IN LONG Mask) { return __sync_fetch_and_or(Address, Mask); } @@ -681,8 +681,8 @@ RtlAtomicOr32(IN VOLATILE PLONG Address, */ XTFASTCALL LONG_PTR -RtlAtomicOr64(IN VOLATILE PLONG_PTR Address, - IN LONG_PTR Mask) +RTL::Atomic::Or64(IN PLONG_PTR Address, + IN LONG_PTR Mask) { return __sync_fetch_and_or(Address, Mask); } @@ -693,18 +693,18 @@ RtlAtomicOr64(IN VOLATILE PLONG_PTR Address, * @param Header * Supplies a pointer to the header of a single linked list. * - * @return This routine returns a pointer to the removed element, or NULL if the list was empty. + * @return This routine returns a pointer to the removed element, or NULLPTR if the list was empty. * * @since XT 1.0 */ XTFASTCALL PSINGLE_LIST_ENTRY -RtlAtomicPopEntrySingleList(IN PSINGLE_LIST_HEADER Header) +RTL::Atomic::PopEntrySingleList(IN PSINGLE_LIST_HEADER Header) { PSINGLE_LIST_ENTRY ListHead, FirstEntry, NextEntry; /* Save header and first entry */ - ListHead = (PVOID)Header; + ListHead = (PSINGLE_LIST_ENTRY)Header; FirstEntry = ListHead->Next; do { @@ -712,16 +712,16 @@ RtlAtomicPopEntrySingleList(IN PSINGLE_LIST_HEADER Header) if(!FirstEntry) { /* Empty list */ - return NULL; + return NULLPTR; } /* Update link */ NextEntry = FirstEntry; /* Compare and exchange */ - FirstEntry = (PVOID)RtlAtomicCompareExchange64((PLONG_PTR)ListHead, - (LONG_PTR)FirstEntry->Next, - (LONG_PTR)FirstEntry); + FirstEntry = (PSINGLE_LIST_ENTRY)CompareExchange64((PLONG_PTR)ListHead, + (LONG_PTR)FirstEntry->Next, + (LONG_PTR)FirstEntry); } while(FirstEntry != NextEntry); /* Return removed element */ @@ -737,20 +737,20 @@ RtlAtomicPopEntrySingleList(IN PSINGLE_LIST_HEADER Header) * @param Entry * Supplies a pointer to entry, that will be inserted into linked list. * - * @return This routine returns a pointer to original heading, or NULL if the list was originally empty. + * @return This routine returns a pointer to original heading, or NULLPTR if the list was originally empty. * * @since XT 1.0 */ XTFASTCALL PSINGLE_LIST_ENTRY -RtlAtomicPushEntrySingleList(IN PSINGLE_LIST_HEADER Header, - IN PSINGLE_LIST_ENTRY Entry) +RTL::Atomic::PushEntrySingleList(IN PSINGLE_LIST_HEADER Header, + IN PSINGLE_LIST_ENTRY Entry) { PSINGLE_LIST_ENTRY ListHead, ListEntry, FirstEntry, NextEntry; /* Save header and new entry */ - ListHead = (PVOID)Header; - ListEntry = (PVOID)Entry; + ListHead = (PSINGLE_LIST_ENTRY)Header; + ListEntry = Entry; /* Save next link in new first element */ FirstEntry = ListHead->Next; @@ -761,9 +761,9 @@ RtlAtomicPushEntrySingleList(IN PSINGLE_LIST_HEADER Header, NextEntry = FirstEntry; /* Compare and exchange */ - FirstEntry = (PVOID)RtlAtomicCompareExchange64((PLONG_PTR)ListHead, - (LONG_PTR)ListEntry, - (LONG_PTR)FirstEntry); + FirstEntry = (PSINGLE_LIST_ENTRY)CompareExchange64((PLONG_PTR)ListHead, + (LONG_PTR)ListEntry, + (LONG_PTR)FirstEntry); } while(FirstEntry != NextEntry); /* Return original first element */ @@ -785,8 +785,8 @@ RtlAtomicPushEntrySingleList(IN PSINGLE_LIST_HEADER Header, */ XTFASTCALL CHAR -RtlAtomicXor8(IN VOLATILE PCHAR Address, - IN CHAR Mask) +RTL::Atomic::Xor8(IN PCHAR Address, + IN CHAR Mask) { return __sync_fetch_and_xor(Address, Mask); } @@ -806,8 +806,8 @@ RtlAtomicXor8(IN VOLATILE PCHAR Address, */ XTFASTCALL SHORT -RtlAtomicXor16(IN VOLATILE PSHORT Address, - IN SHORT Mask) +RTL::Atomic::Xor16(IN PSHORT Address, + IN SHORT Mask) { return __sync_fetch_and_xor(Address, Mask); } @@ -827,8 +827,8 @@ RtlAtomicXor16(IN VOLATILE PSHORT Address, */ XTFASTCALL LONG -RtlAtomicXor32(IN VOLATILE PLONG Address, - IN LONG Mask) +RTL::Atomic::Xor32(IN PLONG Address, + IN LONG Mask) { return __sync_fetch_and_xor(Address, Mask); } @@ -848,8 +848,8 @@ RtlAtomicXor32(IN VOLATILE PLONG Address, */ XTFASTCALL LONG_PTR -RtlAtomicXor64(IN VOLATILE PLONG_PTR Address, - IN LONG_PTR Mask) +RTL::Atomic::Xor64(IN PLONG_PTR Address, + IN LONG_PTR Mask) { return __sync_fetch_and_xor(Address, Mask); } diff --git a/xtoskrnl/rtl/bitmap.c b/xtoskrnl/rtl/bitmap.cc similarity index 82% rename from xtoskrnl/rtl/bitmap.c rename to xtoskrnl/rtl/bitmap.cc index 8eec4ea..df9b80b 100644 --- a/xtoskrnl/rtl/bitmap.c +++ b/xtoskrnl/rtl/bitmap.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/rtl/bitmap.c + * FILE: xtoskrnl/rtl/bitmap.cc * DESCRIPTION: Bit maps support related routines * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -21,10 +21,10 @@ */ XTAPI VOID -RtlClearAllBits(IN PRTL_BITMAP BitMap) +RTL::BitMap::ClearAllBits(IN PRTL_BITMAP BitMap) { /* Clear all bits */ - RtlSetMemory(BitMap->Buffer, 0, ((BitMap->Size + BITS_PER_LONG - 1) / BITS_PER_LONG) * sizeof(ULONG_PTR)); + RTL::Memory::SetMemory(BitMap->Buffer, 0, ((BitMap->Size + BITS_PER_LONG - 1) / BITS_PER_LONG) * sizeof(ULONG_PTR)); } /** @@ -42,8 +42,8 @@ RtlClearAllBits(IN PRTL_BITMAP BitMap) */ XTAPI VOID -RtlClearBit(IN PRTL_BITMAP BitMap, - IN ULONG_PTR Bit) +RTL::BitMap::ClearBit(IN PRTL_BITMAP BitMap, + IN ULONG_PTR Bit) { /* Check if bit is in range */ if(Bit >= BitMap->Size) @@ -74,9 +74,9 @@ RtlClearBit(IN PRTL_BITMAP BitMap, */ XTAPI VOID -RtlClearBits(IN PRTL_BITMAP BitMap, - IN ULONG_PTR StartingIndex, - IN ULONG_PTR Length) +RTL::BitMap::ClearBits(IN PRTL_BITMAP BitMap, + IN ULONG_PTR StartingIndex, + IN ULONG_PTR Length) { ULONG_PTR BitOffset, Mask; PULONG_PTR Buffer; @@ -118,7 +118,7 @@ RtlClearBits(IN PRTL_BITMAP BitMap, } /* Clear remaining bits */ - RtlSetMemory(Buffer, 0, Length >> 3); + RTL::Memory::SetMemory(Buffer, 0, Length >> 3); /* Look for any remaining bits to clear */ Buffer += Length / BITS_PER_LONG; @@ -148,26 +148,85 @@ RtlClearBits(IN PRTL_BITMAP BitMap, */ XTAPI ULONG -RtlClearSetBits(IN PRTL_BITMAP BitMap, - IN ULONG_PTR Length, - IN ULONG_PTR Index) +RTL::BitMap::ClearSetBits(IN PRTL_BITMAP BitMap, + IN ULONG_PTR Length, + IN ULONG_PTR Index) { ULONG_PTR StartingIndex; /* Find set bits */ - StartingIndex = RtlFindSetBits(BitMap, Length, Index); + StartingIndex = FindSetBits(BitMap, Length, Index); /* Check if set bits were found */ if(StartingIndex != MAXULONG_PTR) { /* Clear bits */ - RtlClearBits(BitMap, StartingIndex, Length); + ClearBits(BitMap, StartingIndex, Length); } /* Return position of bits found */ return StartingIndex; } +/** + * Counts the number of either set or clear bits in the contiguous region of the bit map. + * + * @param BitMap + * Supplies a pointer to the bit map. + * + * @param Length + * Supplies the maximum length (number of bits) to count. + * + * @param StartingIndex + * Supplies the starting index of the first bit to count. + * + * @param SetBits + * Specifies whether count bits that are set or clear. + * + * @return This routine returns the number of equal bits found in the contiguous region. + * + * @since XT 1.0 + */ +XTAPI +ULONG_PTR +RTL::BitMap::CountBits(IN PRTL_BITMAP BitMap, + IN ULONG_PTR Length, + IN ULONG_PTR StartingIndex, + IN BOOLEAN SetBits) +{ + PULONG_PTR Buffer, BufferEnd; + ULONG_PTR BitOffset, Size; + ULONGLONG Value; + + /* Get pointers to first and last bytes to check */ + Buffer = &BitMap->Buffer[StartingIndex / BITS_PER_LONG]; + BufferEnd = Buffer + ((Length + BITS_PER_LONG - 1) / BITS_PER_LONG); + + /* Get offset and value */ + BitOffset = StartingIndex & (BITS_PER_LONG - 1); + Value = (SetBits ? ~*Buffer : *Buffer) >> BitOffset << BitOffset; + + /* Find first bit set until the end of the buffer */ + while(!Value && Buffer + 1 < BufferEnd) + { + /* Advance buffer pointer and get value */ + Value = SetBits ? ~*(++Buffer) : *(++Buffer); + } + + /* Check if value found */ + if(!Value) + { + /* No bits found, return length */ + return Length; + } + + /* Calculate size */ + Size = ((Buffer - BitMap->Buffer) * BITS_PER_LONG) - StartingIndex + (ULONG_PTR)RTL::Math::CountTrailingZeroes64(Value); + + /* Return whatever is smaller */ + return Size > Length ? Length : Size; +} + /** * Dumps the contents of the bit map. * @@ -180,7 +239,7 @@ RtlClearSetBits(IN PRTL_BITMAP BitMap, */ XTAPI VOID -RtlDumpBitMap(IN PRTL_BITMAP BitMap) +RTL::BitMap::DumpBitMap(IN PRTL_BITMAP BitMap) { ULONG_PTR Index; @@ -194,6 +253,99 @@ RtlDumpBitMap(IN PRTL_BITMAP BitMap) } } +/** + * Searches the bit map for a contiguous region of either set or clear bits. + * + * @param BitMap + * Supplies a pointer to the bit map. + * + * @param Length + * Supplies the length (number of equal bits) to look for. + * + * @param StartingIndex + * Supplies the starting index of the first bit to start the search at a given position. + * + * @param SetBits + * Specifies whether count bits that are set or clear. + * + * @return This routine returns the bit map index position of the contiguous region found, or MAXULONG_PTR if not found. + * + * @since XT 1.0 + */ +XTAPI +ULONG_PTR +RTL::BitMap::FindBits(IN PRTL_BITMAP BitMap, + IN ULONG_PTR Length, + IN ULONG_PTR StartingIndex, + IN BOOLEAN SetBits) +{ + ULONG_PTR BitMapEnd, BitOffset, Size; + ULONG Tries; + + /* Validate length */ + if(Length > BitMap->Size) + { + /* Length exceeds bit map size, return MAXULONG_PTR */ + return (ULONG_PTR)-1; + } + else if(!Length) + { + /* Length not specified, return starting index */ + return StartingIndex; + } + + /* Check if starting index is in range of bit map size */ + if(StartingIndex >= BitMap->Size) + { + /* Starting index exceeds bit map size, start from the beginning */ + StartingIndex = 0; + } + + /* Try from starting index */ + BitOffset = StartingIndex; + BitMapEnd = BitMap->Size; + + /* At least two tries are required */ + Tries = (StartingIndex != 0) + 2; + while(Tries) + { + /* Find until the end of the bit map */ + while(BitOffset + Length < BitMapEnd) + { + /* Increment offset */ + BitOffset += CountBits(BitMap, BitMap->Size - BitOffset, BitOffset, !SetBits); + if(BitOffset + Length > BitMapEnd) + { + /* No match found, break loop execution */ + break; + } + + /* Count bits in the contiguous region and check if match found */ + Size = CountBits(BitMap, Length, BitOffset, SetBits); + if(Size >= Length) + { + /* Match found, return offset */ + return BitOffset; + } + + /* Increment offset */ + BitOffset += Size; + } + + /* Try again if possible */ + Tries--; + if(Tries) + { + /* Restart from the beginning up to the starting index */ + BitOffset = 0; + BitMapEnd = StartingIndex; + } + } + + /* No match found, return MAXULONG_PTR */ + return (ULONG_PTR)-1; +} + /** * Searches the bit map for a contiguous region of clear bits. * @@ -212,12 +364,12 @@ RtlDumpBitMap(IN PRTL_BITMAP BitMap) */ XTAPI ULONG_PTR -RtlFindClearBits(IN PRTL_BITMAP BitMap, - IN ULONG_PTR Length, - IN ULONG_PTR Index) +RTL::BitMap::FindClearBits(IN PRTL_BITMAP BitMap, + IN ULONG_PTR Length, + IN ULONG_PTR Index) { /* Find clear bits */ - return RtlpFindBits(BitMap, Length, Index, FALSE); + return FindBits(BitMap, Length, Index, FALSE); } /** @@ -238,12 +390,12 @@ RtlFindClearBits(IN PRTL_BITMAP BitMap, */ XTAPI ULONG_PTR -RtlFindSetBits(IN PRTL_BITMAP BitMap, - IN ULONG_PTR Length, - IN ULONG_PTR Index) +RTL::BitMap::FindSetBits(IN PRTL_BITMAP BitMap, + IN ULONG_PTR Length, + IN ULONG_PTR Index) { /* Find set bits */ - return RtlpFindBits(BitMap, Length, Index, TRUE); + return FindBits(BitMap, Length, Index, TRUE); } /** @@ -264,9 +416,9 @@ RtlFindSetBits(IN PRTL_BITMAP BitMap, */ XTAPI VOID -RtlInitializeBitMap(IN PRTL_BITMAP BitMap, - IN PULONG_PTR Buffer, - IN ULONG Size) +RTL::BitMap::InitializeBitMap(IN PRTL_BITMAP BitMap, + IN PULONG_PTR Buffer, + IN ULONG Size) { /* Initialize bit map */ BitMap->Buffer = Buffer; @@ -285,10 +437,10 @@ RtlInitializeBitMap(IN PRTL_BITMAP BitMap, */ XTAPI VOID -RtlSetAllBits(IN PRTL_BITMAP BitMap) +RTL::BitMap::SetAllBits(IN PRTL_BITMAP BitMap) { /* Set all bits */ - RtlSetMemory(BitMap->Buffer, 0xFF, ((BitMap->Size + BITS_PER_LONG - 1) / BITS_PER_LONG) * sizeof(ULONG_PTR)); + RTL::Memory::SetMemory(BitMap->Buffer, 0xFF, ((BitMap->Size + BITS_PER_LONG - 1) / BITS_PER_LONG) * sizeof(ULONG_PTR)); } /** @@ -306,8 +458,8 @@ RtlSetAllBits(IN PRTL_BITMAP BitMap) */ XTAPI VOID -RtlSetBit(IN PRTL_BITMAP BitMap, - IN ULONG_PTR Bit) +RTL::BitMap::SetBit(IN PRTL_BITMAP BitMap, + IN ULONG_PTR Bit) { /* Check if bit is in range */ if(Bit >= BitMap->Size) @@ -338,9 +490,9 @@ RtlSetBit(IN PRTL_BITMAP BitMap, */ XTAPI VOID -RtlSetBits(IN PRTL_BITMAP BitMap, - IN ULONG_PTR StartingIndex, - IN ULONG_PTR Length) +RTL::BitMap::SetBits(IN PRTL_BITMAP BitMap, + IN ULONG_PTR StartingIndex, + IN ULONG_PTR Length) { ULONG_PTR BitOffset, Mask; PULONG_PTR Buffer; @@ -382,7 +534,7 @@ RtlSetBits(IN PRTL_BITMAP BitMap, } /* Set remaining bits */ - RtlSetMemory(Buffer, 0xFF, Length >> 3); + RTL::Memory::SetMemory(Buffer, 0xFF, Length >> 3); /* Look for any remaining bits to set */ Buffer += Length / BITS_PER_LONG; @@ -412,20 +564,20 @@ RtlSetBits(IN PRTL_BITMAP BitMap, */ XTAPI ULONG -RtlSetClearBits(IN PRTL_BITMAP BitMap, - IN ULONG_PTR Length, - IN ULONG_PTR Index) +RTL::BitMap::SetClearBits(IN PRTL_BITMAP BitMap, + IN ULONG_PTR Length, + IN ULONG_PTR Index) { ULONG_PTR StartingIndex; /* Find clear bits */ - StartingIndex = RtlFindClearBits(BitMap, Length, Index); + StartingIndex = FindClearBits(BitMap, Length, Index); /* Check if clear bits were found */ if(StartingIndex != MAXULONG_PTR) { /* Set bits */ - RtlSetBits(BitMap, StartingIndex, Length); + SetBits(BitMap, StartingIndex, Length); } /* Return position of bits found */ @@ -447,8 +599,8 @@ RtlSetClearBits(IN PRTL_BITMAP BitMap, */ XTAPI BOOLEAN -RtlTestBit(IN PRTL_BITMAP BitMap, - IN ULONG_PTR Bit) +RTL::BitMap::TestBit(IN PRTL_BITMAP BitMap, + IN ULONG_PTR Bit) { /* Check if bit is in range */ if(Bit >= BitMap->Size) @@ -460,155 +612,3 @@ RtlTestBit(IN PRTL_BITMAP BitMap, /* Test specified bit and return result */ return ((BitMap->Buffer[Bit / BITS_PER_LONG] >> (Bit & (BITS_PER_LONG - 1))) & 1) ? TRUE : FALSE; } - -/** - * Counts the number of either set or clear bits in the contiguous region of the bit map. - * - * @param BitMap - * Supplies a pointer to the bit map. - * - * @param Length - * Supplies the maximum length (number of bits) to count. - * - * @param StartingIndex - * Supplies the starting index of the first bit to count. - * - * @param SetBits - * Specifies whether count bits that are set or clear. - * - * @return This routine returns the number of equal bits found in the contiguous region. - * - * @since XT 1.0 - */ -XTAPI -ULONG_PTR -RtlpCountBits(IN PRTL_BITMAP BitMap, - IN ULONG_PTR Length, - IN ULONG_PTR StartingIndex, - IN BOOLEAN SetBits) -{ - PULONG_PTR Buffer, BufferEnd; - ULONG_PTR BitOffset, Size; - ULONGLONG Value; - - /* Get pointers to first and last bytes to check */ - Buffer = &BitMap->Buffer[StartingIndex / BITS_PER_LONG]; - BufferEnd = Buffer + ((Length + BITS_PER_LONG - 1) / BITS_PER_LONG); - - /* Get offset and value */ - BitOffset = StartingIndex & (BITS_PER_LONG - 1); - Value = (SetBits ? ~*Buffer : *Buffer) >> BitOffset << BitOffset; - - /* Find first bit set until the end of the buffer */ - while(!Value && Buffer + 1 < BufferEnd) - { - /* Advance buffer pointer and get value */ - Value = SetBits ? ~*(++Buffer) : *(++Buffer); - } - - /* Check if value found */ - if(!Value) - { - /* No bits found, return length */ - return Length; - } - - /* Calculate size */ - Size = ((Buffer - BitMap->Buffer) * BITS_PER_LONG) - StartingIndex + (ULONG_PTR)RtlCountTrailingZeroes64(Value); - - /* Return whatever is smaller */ - return Size > Length ? Length : Size; -} - -/** - * Searches the bit map for a contiguous region of either set or clear bits. - * - * @param BitMap - * Supplies a pointer to the bit map. - * - * @param Length - * Supplies the length (number of equal bits) to look for. - * - * @param StartingIndex - * Supplies the starting index of the first bit to start the search at a given position. - * - * @param SetBits - * Specifies whether count bits that are set or clear. - * - * @return This routine returns the bit map index position of the contiguous region found, or MAXULONG_PTR if not found. - * - * @since XT 1.0 - */ -XTAPI -ULONG_PTR -RtlpFindBits(IN PRTL_BITMAP BitMap, - IN ULONG_PTR Length, - IN ULONG_PTR StartingIndex, - IN BOOLEAN SetBits) -{ - ULONG_PTR BitMapEnd, BitOffset, Size; - ULONG Tries; - - /* Validate length */ - if(Length > BitMap->Size) - { - /* Length exceeds bit map size, return MAXULONG_PTR */ - return (ULONG_PTR)-1; - } - else if(!Length) - { - /* Length not specified, return starting index */ - return StartingIndex; - } - - /* Check if starting index is in range of bit map size */ - if(StartingIndex >= BitMap->Size) - { - /* Starting index exceeds bit map size, start from the beginning */ - StartingIndex = 0; - } - - /* Try from starting index */ - BitOffset = StartingIndex; - BitMapEnd = BitMap->Size; - - /* At least two tries are required */ - Tries = (StartingIndex != 0) + 2; - while(Tries) - { - /* Find until the end of the bit map */ - while(BitOffset + Length < BitMapEnd) - { - /* Increment offset */ - BitOffset += RtlpCountBits(BitMap, BitMap->Size - BitOffset, BitOffset, !SetBits); - if(BitOffset + Length > BitMapEnd) - { - /* No match found, break loop execution */ - break; - } - - /* Count bits in the contiguous region and check if match found */ - Size = RtlpCountBits(BitMap, Length, BitOffset, SetBits); - if(Size >= Length) - { - /* Match found, return offset */ - return BitOffset; - } - - /* Increment offset */ - BitOffset += Size; - } - - /* Try again if possible */ - Tries--; - if(Tries) - { - /* Restart from the beginning up to the starting index */ - BitOffset = 0; - BitMapEnd = StartingIndex; - } - } - - /* No match found, return MAXULONG_PTR */ - return (ULONG_PTR)-1; -} diff --git a/xtoskrnl/rtl/globals.c b/xtoskrnl/rtl/data.cc similarity index 59% rename from xtoskrnl/rtl/globals.c rename to xtoskrnl/rtl/data.cc index c452dd5..03f2057 100644 --- a/xtoskrnl/rtl/globals.c +++ b/xtoskrnl/rtl/data.cc @@ -1,13 +1,13 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/rtl/globals.c - * DESCRIPTION: Kernel runtime library global variables + * FILE: xtoskrnl/rtl/data.cc + * DESCRIPTION: Runtime Library global and static data * DEVELOPERS: Rafal Kupiec */ -#include +#include /* This is required for floating numbers to keep LLVM happy */ -int _fltused = 0xFEEDBULL; +XTCLINK INT _fltused = 0xFEEDBULL; diff --git a/xtoskrnl/rtl/byteswap.c b/xtoskrnl/rtl/endian.cc similarity index 88% rename from xtoskrnl/rtl/byteswap.c rename to xtoskrnl/rtl/endian.cc index 6984565..2eb6c48 100644 --- a/xtoskrnl/rtl/byteswap.c +++ b/xtoskrnl/rtl/endian.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/rtl/byteswap.c + * FILE: xtoskrnl/rtl/endian.cc * DESCRIPTION: Endian conversion routines * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -21,7 +21,7 @@ */ XTFASTCALL USHORT -RtlByteSwap16(IN USHORT Source) +RTL::Endianness::SwapByte16(IN USHORT Source) { return (USHORT)(((Source >> 8) & 0x00FF) | ((Source << 8) & 0xFF00)); @@ -39,7 +39,7 @@ RtlByteSwap16(IN USHORT Source) */ XTFASTCALL ULONG -RtlByteSwap32(IN ULONG Source) +RTL::Endianness::SwapByte32(IN ULONG Source) { return (ULONG)(((Source >> 24) & 0x000000FF) | ((Source >> 8) & 0x0000FF00) | @@ -59,7 +59,7 @@ RtlByteSwap32(IN ULONG Source) */ XTFASTCALL ULONGLONG -RtlByteSwap64(IN ULONGLONG Source) +RTL::Endianness::SwapByte64(IN ULONGLONG Source) { return (ULONGLONG)(((Source >> 56) & 0x00000000000000FF) | ((Source >> 40) & 0x000000000000FF00) | diff --git a/xtoskrnl/rtl/exports.cc b/xtoskrnl/rtl/exports.cc new file mode 100644 index 0000000..f5158fd --- /dev/null +++ b/xtoskrnl/rtl/exports.cc @@ -0,0 +1,1310 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/rtl/exports.cc + * DESCRIPTION: C-compatible API wrappers for exported kernel functions + * DEVELOPERS: Aiken Harris + */ + +#include + + +/** + * Clears all bits in the bit map. + * + * @param BitMap + * Supplies a pointer to the bit map. + * + * @return This routine does not return any value. + * + * @since NT 3.5 + */ +XTCLINK +XTAPI +VOID +RtlClearAllBits(IN PRTL_BITMAP BitMap) +{ + RTL::BitMap::ClearAllBits(BitMap); +} + +/** + * Clears a single bit in the bit map. + * + * @param BitMap + * Supplies a pointer to the bit map. + * + * @param Bit + * Specifies the number of the bit to be cleared. + * + * @return This routine does not return any value. + * + * @since NT 5.1 + */ +XTCLINK +XTAPI +VOID +RtlClearBit(IN PRTL_BITMAP BitMap, + IN ULONG_PTR Bit) +{ + RTL::BitMap::ClearBit(BitMap, Bit); +} + +/** + * Clears a specified set of bits within a bit map. + * + * @param BitMap + * Supplies a pointer to the bit map. + * + * @param StartingIndex + * Supplies the starting index of the first bit to clear. + * + * @param Length + * Supplies the length (number of bits) to clear. + * + * @return This routine does not return any value. + * + * @since NT 3.5 + */ +XTCLINK +XTAPI +VOID +RtlClearBits(IN PRTL_BITMAP BitMap, + IN ULONG_PTR StartingIndex, + IN ULONG_PTR Length) +{ + RTL::BitMap::ClearBits(BitMap, StartingIndex, Length); +} + +/** + * Searches the bit map for a contiguous region of set bits and clears them. + * + * @param BitMap + * Supplies a pointer to the bit map. + * + * @param Length + * Supplies the length of contiguous region (number of set bits) to look for. + * + * @param Index + * Supplies the index of the first bit to start the search at a given position. + * + * @return This routine returns the bit map index position of the contiguous region found, or MAXULONG_PTR if not found. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +ULONG +RtlClearSetBits(IN PRTL_BITMAP BitMap, + IN ULONG_PTR Length, + IN ULONG_PTR Index) +{ + return RTL::BitMap::ClearSetBits(BitMap, Length, Index); +} + +/** + * Compares two GUIDs (Globally Unique Identifiers). + * + * @param Guid1 + * Supplies the first GUID to compare. + * + * @param Guid2 + * Supplies the second GUID to compare. + * + * @return This routine returns TRUE if the provided GUIDs are equal, or FALSE otherwise. + * + * @since XT 1.0 + */ +XTAPI +BOOLEAN +RtlCompareGuids(IN PGUID Guid1, + IN PGUID Guid2) +{ + return RTL::Guid::CompareGuids(Guid1, Guid2); +} + +/** + * This routine compares the first bytes of the specified memory buffers. + * + * @param LeftBuffer + * Supplies a pointer to the first block of memory to compare. + * + * @param RightBuffer + * Supplies a pointer to the second block of memory to compare. + * + * @param Length + * Specifies a number of bytes to compare. + * + * @return This routine returns a number of bytes that are equal in both memory blocks. + * + * @since NT 3.5 + */ +XTCLINK +XTAPI +SIZE_T +RtlCompareMemory(IN PCVOID LeftBuffer, + IN PCVOID RightBuffer, + IN SIZE_T Length) +{ + return RTL::Memory::CompareMemory(LeftBuffer, RightBuffer, Length); +} + +/** + * Compares at most specified number of characters of two C strings. + * + * @param String1 + * String to be compared. + * + * @param String2 + * String to be compared. + * + * @param Length + * Maximum number of characters to compare. If no limit set, it compares whole strings. + * + * @return Integral value indicating the relationship between the strings. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +SIZE_T +RtlCompareString(IN PCSTR String1, + IN PCSTR String2, + IN SIZE_T Length) +{ + return RTL::String::CompareString(String1, String2, Length); +} + +/** + * Compares at most specified number of characters of two C strings, while ignoring differences in case. + * + * @param String1 + * String to be compared. + * + * @param String2 + * String to be compared. + * + * @param Length + * Maximum number of characters to compare. If no limit set, it compares whole strings. + * + * @return Integral value indicating the relationship between the strings. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +SIZE_T +RtlCompareStringInsensitive(IN PCSTR String1, + IN PCSTR String2, + IN SIZE_T Length) +{ + return RTL::String::CompareStringInsensitive(String1, String2, Length); +} + +/** + * Compares at most specified number of characters of two C wide strings. + * + * @param String1 + * Wide string to be compared. + * + * @param String2 + * Wide string to be compared. + * + * @param Length + * Maximum number of characters to compare. If no limit set, it compares whole wide strings. + * + * @return Integral value indicating the relationship between the wide strings. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +SIZE_T +RtlCompareWideString(IN PCWSTR String1, + IN PCWSTR String2, + IN SIZE_T Length) +{ + return RTL::WideString::CompareWideString(String1, String2, Length); +} + +/** + * Compares at most specified number of characters of two C wide strings, while ignoring differences in case. + * + * @param String1 + * Wide string to be compared. + * + * @param String2 + * Wide string to be compared. + * + * @param Length + * Maximum number of characters to compare. If no limit set, it compares whole wide strings. + * + * @return Integral value indicating the relationship between the wide strings. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +SIZE_T +RtlCompareWideStringInsensitive(IN PCWSTR String1, + IN PCWSTR String2, + IN SIZE_T Length) +{ + return RTL::WideString::CompareWideStringInsensitive(String1, String2, Length); +} + +/** + * Appends a copy of the source string to the end of the destination string. + * + * @param Destination + * Supplies a pointer to the NULL-terminated string to append to. + * + * @param Source + * Supplies a pointer to the NULL-terminated string to copy from. + * + * @param Count + * Sets a maximum number of characters to copy. If no limit set, appends whole string. + * + * @return This routine returns a copy of a destination string. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +PCHAR +RtlConcatenateString(OUT PCHAR Destination, + IN PCHAR Source, + IN SIZE_T Count) +{ + return RTL::String::ConcatenateString(Destination, Source, Count); +} + +/** + * Appends a copy of the source wide string to the end of the destination wide string. + * + * @param Destination + * Supplies a pointer to the NULL-terminated wide string to append to. + * + * @param Source + * Supplies a pointer to the NULL-terminated wide string to copy from. + * + * @param Count + * Sets a maximum number of wide characters to copy. If no limit set, appends whole wide string. + * + * @return This routine returns a copy of a destination wide string. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +PWCHAR +RtlConcatenateWideString(OUT PWCHAR Destination, + IN PWCHAR Source, + IN SIZE_T Count) +{ + return RTL::WideString::ConcatenateWideString(Destination, Source, Count); +} + +/** + * Converts the 32-bit signed value to a large integer. + * + * @param Value + * Supplies the value to convert. + * + * @return This routine returns the large integer representation of the given value. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +LARGE_INTEGER +RtlConvertToLargeInteger32(IN LONG Value) +{ + return RTL::Math::ConvertToLargeInteger32(Value); +} + +/** + * Converts the 32-bit unsigned value to a large integer. + * + * @param Value + * Supplies the value to convert. + * + * @return This routine returns the large integer representation of the given value. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +LARGE_INTEGER +RtlConvertToLargeIntegerUnsigned32(IN ULONG Value) +{ + return RTL::Math::ConvertToLargeIntegerUnsigned32(Value); +} + +/** + * This routine copies a block of memory. + * + * @param Destination + * Supplies a pointer to the buffer where data will be copied to. + * + * @param Source + * Supplies a pointer to the source buffer that will be copied. + * + * @param Length + * Specifies the number of bytes to copy. + * + * @return This routine does not return any value. + * + * @since NT 3.5 + */ +XTCLINK +XTAPI +VOID +RtlCopyMemory(OUT PVOID Destination, + IN PCVOID Source, + IN SIZE_T Length) +{ + RTL::Memory::CopyMemory(Destination, Source, Length); +} + +/** + * Copies a string from a buffer into another buffer, ensuring that the destination string is NULL-terminated. + * + * @param Destination + * Supplies a pointer to the destination buffer. + * + * @param Source + * Supplies a pointer to the source buffer. + * + * @param Length + * Supplies the length of the string to copy. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +VOID +RtlCopyString(IN PCHAR Destination, + IN PCSTR Source, + IN ULONG Length) +{ + RTL::String::CopyString(Destination, Source, Length); +} + +/** + * Copies a wide string from a buffer into another buffer, ensuring that the destination string is NULL-terminated. + * + * @param Destination + * Supplies a pointer to the destination buffer. + * + * @param Source + * Supplies a pointer to the source buffer. + * + * @param Length + * Supplies the length of the wide string to copy. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +VOID +RtlCopyWideString(IN PWCHAR Destination, + IN PCWSTR Source, + IN ULONG Length) +{ + RTL::WideString::CopyWideString(Destination, Source, Length); +} + +/** + * Divides a signed large integer by a 32-bit divisor. + * + * @param Dividend + * Supplies a large integer to be divided. + * + * @param Divisor + * Supplies a 32-bit divisor. + * + * @param Remainder + * Supplies a pointer that receives the divide remainder. + * + * @return This routine returns the quotient. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +LARGE_INTEGER +RtlDivideLargeInteger(IN LARGE_INTEGER Dividend, + IN ULONG Divisor, + OUT PULONG Remainder) +{ + return RTL::Math::DivideLargeInteger(Dividend, Divisor, Remainder); +} + +/** + * Searches the bit map for a contiguous region of clear bits. + * + * @param BitMap + * Supplies a pointer to the bit map. + * + * @param Length + * Supplies the length of contiguous region (number of clear bits) to look for. + * + * @param Index + * Supplies the index of the first bit to start the search at a given position. + * + * @return This routine returns the bit map index position of the contiguous region found, or MAXULONG_PTR if not found. + * + * @since NT 3.5 + */ +XTCLINK +XTAPI +ULONG_PTR +RtlFindClearBits(IN PRTL_BITMAP BitMap, + IN ULONG_PTR Length, + IN ULONG_PTR Index) +{ + return RTL::BitMap::FindClearBits(BitMap, Length, Index); +} + +/** + * Searches the bit map for a contiguous region of set bits. + * + * @param BitMap + * Supplies a pointer to the bit map. + * + * @param Length + * Supplies the length of contiguous region (number of set bits) to look for. + * + * @param Index + * Supplies the index of the first bit to start the search at a given position. + * + * @return This routine returns the bit map index position of the contiguous region found, or MAXULONG_PTR if not found. + * + * @since NT 3.5 + */ +XTCLINK +XTAPI +ULONG_PTR +RtlFindSetBits(IN PRTL_BITMAP BitMap, + IN ULONG_PTR Length, + IN ULONG_PTR Index) +{ + return RTL::BitMap::FindSetBits(BitMap, Length, Index); +} + +/** + * Finds the first occurrence of the search string in the source string. + * + * @param Source + * Supplies a pointer to the source string. + * + * @param Search + * Supplies a pointer to the search string. + * + * @return This routine returns a pointer to the first occurrence of the search string in the source string. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +PCSTR +RtlFindString(IN PCSTR Source, + IN PCSTR Search) +{ + return RTL::String::FindString(Source, Search); +} + +/** + * Finds the first case-insensitive occurrence of the search string in the source string. + * + * @param Source + * Supplies a pointer to the source string. + * + * @param Search + * Supplies a pointer to the search string. + * + * @return This routine returns a pointer to the first occurrence of the search string in the source string. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +PCSTR +RtlFindStringInsensitive(IN PCSTR Source, + IN PCSTR Search) +{ + return RTL::String::FindStringInsensitive(Source, Search); +} + +/** + * Finds the first occurrence of the search wide string in the source wide string. + * + * @param Source + * Supplies a pointer to the source wide string. + * + * @param Search + * Supplies a pointer to the search wide string. + * + * @return This routine returns a pointer to the first occurrence of the search wide string in the source wide string. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +PCWSTR +RtlFindWideString(IN PCWSTR Source, + IN PCWSTR Search) +{ + return RTL::WideString::FindWideString(Source, Search); +} + +/** + * Finds the first case-insensitive occurrence of the search wide string in the source wide string. + * + * @param Source + * Supplies a pointer to the source wide string. + * + * @param Search + * Supplies a pointer to the search wide string. + * + * @return This routine returns a pointer to the first occurrence of the search wide string in the source wide string. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +PCWSTR +RtlFindWideStringInsensitive(IN PCWSTR Source, + IN PCWSTR Search) +{ + return RTL::WideString::FindWideStringInsensitive(Source, Search); +} + +/** + * Initializes a bit map. + * + * @param BitMap + * Supplies a pointer to the bit map to initialize. + * + * @param Buffer + * Supplies a pointer to the buffer that will be used as a bit map. + * + * @param Size + * Supplies a size of the bit map. + * + * @return This routine does not return any value. + * + * @since NT 3.5 + */ +XTCLINK +XTAPI +VOID +RtlInitializeBitMap(IN PRTL_BITMAP BitMap, + IN PULONG_PTR Buffer, + IN ULONG Size) +{ + RTL::BitMap::InitializeBitMap(BitMap, Buffer, Size); +} + +/** + * This routine initializes a structure representing the head of a double-linked list. + * + * @param ListHead + * Pointer to a structure that serves as the list header. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTCDECL +VOID +RtlInitializeListHead(IN PLIST_ENTRY ListHead) +{ + RTL::LinkedList::InitializeListHead(ListHead); +} + +/** + * This routine inserts an entry at the head of a doubly linked list. + * + * @param ListHead + * Pointer to the head of the list. + * + * @param Entry + * Pointer to the entry that will be inserted in the list. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTCDECL +VOID +RtlInsertHeadList(IN OUT PLIST_ENTRY ListHead, + IN PLIST_ENTRY Entry) +{ + RTL::LinkedList::InsertHeadList(ListHead, Entry); +} + +/** + * This routine inserts an entry at the tail of a doubly linked list. + * + * @param ListHead + * Pointer to the head of the list. + * + * @param Entry + * Pointer to the entry that will be inserted in the list. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTCDECL +VOID +RtlInsertTailList(IN OUT PLIST_ENTRY ListHead, + IN PLIST_ENTRY Entry) +{ + RTL::LinkedList::InsertTailList(ListHead, Entry); +} + +/** + * Indicates whether a doubly linked list structure is empty, or not initialized at all. + * + * @param ListHead + * Pointer to a structure that represents the head of the list. + * + * @return TRUE if there are currently no entries in the list or FALSE otherwise. + * + * @since XT 1.0 + */ +XTCLINK +XTCDECL +BOOLEAN +RtlListEmpty(IN PLIST_ENTRY ListHead) +{ + return RTL::LinkedList::ListEmpty(ListHead); +} + +/** + * This routine detects a loop in a doubly linked list. + * + * @param ListHead + * Pointer to a structure that represents the head of the list. + * + * @return TRUE if linked list contains a loop or FALSE otherwise. + * + * @since XT 1.0 + */ +XTCLINK +XTCDECL +BOOLEAN +RtlListLoop(IN PLIST_ENTRY ListHead) +{ + return RTL::LinkedList::ListLoop(ListHead); +} + +/** + * This routine copies a block of memory either forward of backward, depeding + * if source and destination buffers overlap or not. + * + * @param Destination + * Supplies a pointer to the buffer where data will be copied to. + * + * @param Source + * Supplies a pointer to the source buffer that will be copied. + * + * @param Length + * Specifies the number of bytes to copy. + * + * @return This routine does not return any value. + * + * @since NT 3.5 + */ +XTCLINK +XTAPI +VOID +RtlMoveMemory(OUT PVOID Destination, + IN PCVOID Source, + IN SIZE_T Length) +{ + RTL::Memory::MoveMemory(Destination, Source, Length); +} + +/** + * Multiplies a signed large integer by a signed integer. + * + * @param Multiplicand + * Supplies a large integer to be multiplied. + * + * @param Multiplier + * Supplies an integer by which the large integer is multiplied. + * + * @return This routine returns the result of the multiplication. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +LARGE_INTEGER +RtlMultiplyLargeInteger(IN LARGE_INTEGER Multiplicand, + IN LONG Multiplier) +{ + return RTL::Math::MultiplyLargeInteger(Multiplicand, Multiplier); +} + +/** + * This routine removes an entry from a doubly linked list. + * + * @param Entry + * Pointer to the entry that will be removed from the list. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTCDECL +VOID +RtlRemoveEntryList(IN PLIST_ENTRY Entry) +{ + RTL::LinkedList::RemoveEntryList(Entry); +} + +/** + * Reverses a characters order in a string. It modifies the original, input variable. + * + * @param String + * Supplies a pointer to the string to reverse. + * + * @param Length + * Supplies the length of the string to reverse. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +VOID +RtlReverseString(IN OUT PCHAR String, + IN ULONG Length) +{ + RTL::String::ReverseString(String, Length); +} + +/** + * Reverses a characters order in a wide string. It modifies the original, input variable. + * + * @param String + * Supplies a pointer to the wide string to reverse. + * + * @param Length + * Supplies the length of the wide string to reverse. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +VOID +RtlReverseWideString(IN OUT PWCHAR String, + IN ULONG Length) +{ + RTL::WideString::ReverseWideString(String, Length); +} + +/** + * This routine compares the first bytes of the specified memory buffers. + * + * @param LeftBuffer + * Supplies a pointer to the first block of memory to compare. + * + * @param RightBuffer + * Supplies a pointer to the second block of memory to compare. + * + * @param Length + * Specifies a number of bytes to compare. + * + * @return Returns TRUE if both buffers are equal up to the specified length, or FALSE otherwise. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +BOOLEAN +RtlSameMemory(IN PCVOID LeftBuffer, + IN PCVOID RightBuffer, + IN SIZE_T Length) +{ + return RTL::Memory::SameMemory(LeftBuffer, RightBuffer, Length); +} + +/** + * Sets all bits in the bit map. + * + * @param BitMap + * Supplies a pointer to the bit map. + * + * @return This routine does not return any value. + * + * @since NT 3.5 + */ +XTCLINK +XTAPI +VOID +RtlSetAllBits(IN PRTL_BITMAP BitMap) +{ + RTL::BitMap::SetAllBits(BitMap); +} + +/** + * Sets a single bit in the bit map. + * + * @param BitMap + * Supplies a pointer to the bit map. + * + * @param Bit + * Specifies the number of the bit to be set. + * + * @return This routine does not return any value. + * + * @since NT 5.1 + */ +XTCLINK +XTAPI +VOID +RtlSetBit(IN PRTL_BITMAP BitMap, + IN ULONG_PTR Bit) +{ + RTL::BitMap::SetBit(BitMap, Bit); +} + +/** + * Sets a specified set of bits within a bit map. + * + * @param BitMap + * Supplies a pointer to the bit map. + * + * @param StartingIndex + * Supplies the starting index of the first bit to set. + * + * @param Length + * Supplies the length (number of bits) to set. + * + * @return This routine does not return any value. + * + * @since NT 3.5 + */ +XTCLINK +XTAPI +VOID +RtlSetBits(IN PRTL_BITMAP BitMap, + IN ULONG_PTR StartingIndex, + IN ULONG_PTR Length) +{ + RTL::BitMap::SetBits(BitMap, StartingIndex, Length); +} + +/** + * Searches the bit map for a contiguous region of clear bits and sets them. + * + * @param BitMap + * Supplies a pointer to the bit map. + * + * @param Length + * Supplies the length of contiguous region (number of clear bits) to look for. + * + * @param Index + * Supplies the index of the first bit to start the search at a given position. + * + * @return This routine returns the bit map index position of the contiguous region found, or MAXULONG_PTR if not found. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +ULONG +RtlSetClearBits(IN PRTL_BITMAP BitMap, + IN ULONG_PTR Length, + IN ULONG_PTR Index) +{ + return RTL::BitMap::SetClearBits(BitMap, Length, Index); +} + +/** + * This routine fills a section of memory with a specified byte. + * + * @param Destination + * Supplies a pointer to the buffer to fill. + * + * @param Byte + * Supplies a pattern to fill memory. + * + * @param Length + * Specifies a number of bytes to store in memory. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +VOID +RtlSetMemory(OUT PVOID Destination, + IN UCHAR Byte, + IN SIZE_T Length) +{ + RTL::Memory::SetMemory(Destination, Byte, Length); +} + +/** + * Calculates the length of a given string. + * + * @param String + * Pointer to the NULL-terminated string to be examined. + * + * @param MaxLength + * Maximum number of characters to examine. If no limit set, it examines whole string. + * + * @return The length of the NULL-terminated string. + * + * @since: XT 1.0 + */ +XTCLINK +XTAPI +SIZE_T +RtlStringLength(IN PCSTR String, + IN SIZE_T MaxLength) +{ + return RTL::String::StringLength(String, MaxLength); +} + +/** + * Converts a multibyte character string to its wide character representation. + * + * @param Destination + * Pointer to wide character array where the wide string will be stored + * + * @param Source + * Pointer to the first element of a multibyte string to convert. + * + * @param Length + * Number of characters in the source string. + * + * @return Returns the number of wide characters written to the destination array on success, or -1 on error. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +SIZE_T +RtlStringToWideString(OUT PWCHAR Destination, + IN PCSTR *Source, + IN SIZE_T Length) +{ + return RTL::String::StringToWideString(Destination, Source, Length); +} + +/** + * Tests a state of a single bit in the bit map. + * + * @param BitMap + * Supplies a pointer to the bit map. + * + * @param Bit + * Specifies the number of the bit to be tested. + * + * @return This routine returns TRUE when bit is set, or FALSE otherwise. + * + * @since NT 5.1 + */ +XTCLINK +XTAPI +BOOLEAN +RtlTestBit(IN PRTL_BITMAP BitMap, + IN ULONG_PTR Bit) +{ + return RTL::BitMap::TestBit(BitMap, Bit); +} + +/** + * Finds the next token in a NULL-terminated string. + * + * @param String + * Pointer to the NULL-terminated string to tokenize. + * + * @param Delimiter + * Pointer to the NULL-terminated string identifying delimiters. + * + * @param SavePtr + * Pointer to an object used to store routine internal state. + * + * @return Pointer to the beginning of the next token or NULL if there are no more tokens. + * + * @since: XT 1.0 + */ +XTCLINK +XTAPI +PCHAR +RtlTokenizeString(IN PCHAR String, + IN PCSTR Delimiter, + IN OUT PCHAR *SavePtr) +{ + return RTL::String::TokenizeString(String, Delimiter, SavePtr); +} + +/** + * Finds the next token in a NULL-terminated wide string. + * + * @param String + * Pointer to the NULL-terminated wide string to tokenize. + * + * @param Delimiter + * Pointer to the NULL-terminated wide string identifying delimiters. + * + * @param SavePtr + * Pointer to an object used to store routine internal state. + * + * @return Pointer to the beginning of the next token or NULLPTR if there are no more tokens. + * + * @since: XT 1.0 + */ +XTCLINK +XTAPI +PWCHAR +RtlTokenizeWideString(IN PWCHAR String, + IN PCWSTR Delimiter, + IN OUT PWCHAR *SavePtr) +{ + return RTL::WideString::TokenizeWideString(String, Delimiter, SavePtr); +} + +/** + * Converts a character to lowercase. + * + * @param Character + * Character to be converted. + * + * @return Converted character or original character if it was not uppercase. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +CHAR +RtlToLowerCharacter(IN CHAR Character) +{ + return RTL::String::ToLowerCharacter(Character); +} + +/** + * Converts a wide character to lowercase. + * + * @param Character + * Wide character to be converted. + * + * @return Converted wide character or original character if it was not uppercase. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +WCHAR +RtlToLowerWideCharacter(IN WCHAR Character) +{ + return RTL::WideString::ToLowerWideCharacter(Character); +} + +/** + * Converts a character to uppercase. + * + * @param Character + * Character to be converted. + * + * @return Converted character or original character if it was not lowercase. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +CHAR +RtlToUpperCharacter(IN CHAR Character) +{ + return RTL::String::ToUpperCharacter(Character); +} + +/** + * Converts a wide character to uppercase. + * + * @param Character + * Wide character to be converted. + * + * @return Converted wide character or original character if it was not lowercase. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +WCHAR +RtlToUpperWideCharacter(IN WCHAR Character) +{ + return RTL::WideString::ToUpperWideCharacter(Character); +} + +/** + * Removes certain characters from a beginning of the string. + * + * @param String + * Pointer to the NULL-terminated string to be trimmed. + * + * @return This routine returns a pointer to the left-trimmed string. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +PCHAR +RtlTrimLeftString(IN PCHAR String) +{ + return RTL::String::TrimLeftString(String); +} + +/** + * Removes certain characters from a beginning of the wide string. + * + * @param String + * Pointer to the NULL-terminated wide string to be trimmed. + * + * @return This routine returns a pointer to the left-trimmed wide string. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +PWCHAR +RtlTrimLeftWideString(IN PWCHAR String) +{ + return RTL::WideString::TrimLeftWideString(String); +} + +/** + * Removes certain characters from the end of the string. + * + * @param String + * Pointer to the NULL-terminated string to be trimmed. + * + * @return This routine returns a pointer to the right-trimmed string. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +PCHAR +RtlTrimRightString(IN PCHAR String) +{ + return RTL::String::TrimRightString(String); +} + +/** + * Removes certain characters from the end of the wide string. + * + * @param String + * Pointer to the NULL-terminated wide string to be trimmed. + * + * @return This routine returns a pointer to the right-trimmed wide string. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +PWCHAR +RtlTrimRightWideString(IN PWCHAR String) +{ + return RTL::WideString::TrimRightWideString(String); +} + +/** + * Removes certain characters from the beginning and the end of the string. + * + * @param String + * Pointer to the NULL-terminated string to be trimmed. + * + * @return This routine returns a pointer to the trimmed string. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +PCHAR +RtlTrimString(IN PCHAR String) +{ + return RTL::String::TrimLeftString(RTL::String::TrimRightString(String)); +} + +/** + * Removes certain characters from the beginning and the end of the wide string. + * + * @param String + * Pointer to the NULL-terminated wide string to be trimmed. + * + * @return This routine returns a pointer to the trimmed wide string. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +PWCHAR +RtlTrimWideString(IN PWCHAR String) +{ + return RTL::WideString::TrimWideString(String); +} + +/** + * Calculates the length of a given wide string. + * + * @param String + * Pointer to the NULL-terminated wide string to be examined. + * + * @param MaxLength + * Maximum number of wide characters to examine. If no limit set, it examines whole string. + * + * @return The length of the NULL-terminated wide string. + * + * @since: XT 1.0 + */ +XTCLINK +XTAPI +SIZE_T +RtlWideStringLength(IN PCWSTR String, + IN SIZE_T MaxLength) +{ + return RTL::WideString::WideStringLength(String, MaxLength); +} + +/** + * This routine fills a section of memory with zeroes. + * + * @param Destination + * Supplies a pointer to the buffer to fill. + * + * @param Length + * Specifies a number of bytes to be filled with zeroes. + * + * @return This routine does not return any value. + * + * @since NT 3.5 + */ +XTCLINK +XTAPI +VOID +RtlZeroMemory(OUT PVOID Destination, + IN SIZE_T Length) +{ + RTL::Memory::ZeroMemory(Destination, Length); +} diff --git a/xtoskrnl/rtl/guid.c b/xtoskrnl/rtl/guid.cc similarity index 71% rename from xtoskrnl/rtl/guid.c rename to xtoskrnl/rtl/guid.cc index 4919b73..7290721 100644 --- a/xtoskrnl/rtl/guid.c +++ b/xtoskrnl/rtl/guid.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/rtl/guid.c + * FILE: xtoskrnl/rtl/guid.cc * DESCRIPTION: GUID manipulation routines * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -24,8 +24,8 @@ */ XTAPI BOOLEAN -RtlCompareGuids(IN PGUID Guid1, - IN PGUID Guid2) +RTL::Guid::CompareGuids(IN PGUID Guid1, + IN PGUID Guid2) { PUINT Guid1Ptr, Guid2Ptr; @@ -34,6 +34,6 @@ RtlCompareGuids(IN PGUID Guid1, Guid2Ptr = (PUINT)Guid2; /* Compare GUIDs */ - return(Guid1Ptr[0] == Guid2Ptr[0] && Guid1Ptr[1] == Guid2Ptr[1] && - Guid1Ptr[2] == Guid2Ptr[2] && Guid1Ptr[3] == Guid2Ptr[3]); + return (Guid1Ptr[0] == Guid2Ptr[0] && Guid1Ptr[1] == Guid2Ptr[1] && + Guid1Ptr[2] == Guid2Ptr[2] && Guid1Ptr[3] == Guid2Ptr[3]); } diff --git a/xtoskrnl/rtl/i686/dispatch.c b/xtoskrnl/rtl/i686/dispatch.cc similarity index 74% rename from xtoskrnl/rtl/i686/dispatch.c rename to xtoskrnl/rtl/i686/dispatch.cc index 0c8ac96..9ef4aa0 100644 --- a/xtoskrnl/rtl/i686/dispatch.c +++ b/xtoskrnl/rtl/i686/dispatch.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/rtl/i686/dispatch.c + * FILE: xtoskrnl/rtl/i686/dispatch.cc * DESCRIPTION: Dispatching support for i686 architecture * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -24,10 +24,10 @@ */ XTAPI VOID -RtlGetStackLimits(OUT PULONG_PTR StackBase, - OUT PULONG_PTR StackLimit) +RTL::Dispatcher::GetStackLimits(OUT PULONG_PTR StackBase, + OUT PULONG_PTR StackLimit) { - PKTHREAD Thread = KeGetCurrentThread(); + PKTHREAD Thread = KE::Processor::GetCurrentThread(); *StackBase = (ULONG_PTR)Thread->StackBase - sizeof(FX_SAVE_AREA); *StackLimit = (ULONG_PTR)Thread->StackLimit; } diff --git a/xtoskrnl/rtl/i686/exsup.c b/xtoskrnl/rtl/i686/exsup.c deleted file mode 100644 index e9398ce..0000000 --- a/xtoskrnl/rtl/i686/exsup.c +++ /dev/null @@ -1,36 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/rtl/i686/exsup.c - * DESCRIPTION: Exception handling for i686 architecture - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -XTCDECL -EXCEPTION_DISPOSITION -__C_specific_handler(IN PEXCEPTION_RECORD ExceptionRecord, - IN PVOID EstablisherFrame, - IN OUT PCONTEXT ContextRecord, - IN OUT PVOID DispatcherContext) -{ - UNIMPLEMENTED; - - /* Continue execution */ - return ExceptionContinueExecution; -} - -XTCDECL -INT -_except_handler3(PEXCEPTION_RECORD ExceptionRecord, - PVOID Registration, - PCONTEXT Context, - PVOID Dispatcher) -{ - UNIMPLEMENTED; - - /* Handler not found */ - return 0; -} diff --git a/xtoskrnl/rtl/i686/exsup.cc b/xtoskrnl/rtl/i686/exsup.cc new file mode 100644 index 0000000..03019d6 --- /dev/null +++ b/xtoskrnl/rtl/i686/exsup.cc @@ -0,0 +1,133 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/rtl/i686/exsup.cc + * DESCRIPTION: Exception handling for i686 architecture + * DEVELOPERS: Rafal Kupiec + * Aiken Harris + */ + +#include + + +/** + * Handles SEH structured exception frames. + * + * @param ExceptionRecord + * A pointer to the exception record. + * + * @param EstablisherFrame + * The address of the base of the fixed stack allocation. + * + * @param ContextRecord + * A pointer to the context record at the time the exception was raised. + * + * @param DispatcherContext + * A pointer to the dispatcher context for the function. + * + * @return This routine returns an exception disposition value if the exception was not handled by any filter. + * + * @since XT 1.0 + */ +XTCLINK +XTCDECL +EXCEPTION_DISPOSITION +__C_specific_handler(IN PEXCEPTION_RECORD ExceptionRecord, + IN PVOID EstablisherFrame, + IN OUT PCONTEXT ContextRecord, + IN OUT PVOID DispatcherContext) +{ + UNIMPLEMENTED; + + /* Continue execution */ + return ExceptionContinueExecution; +} + +/** + * Handles C++ structured exception frames. This implementation displays a panic screen and halts the system. + * + * @param ExceptionRecord + * A pointer to the exception record that is passed to the possible catch statements. + * + * @param EstablisherFrame + * A pointer to the stack frame that is used to handle the exception. + * + * @param ContextRecord + * A pointer to the context record (not used on Intel CPUs). + * + * @param DispatcherContext + * A pointer to the dispatcher provding information about function entry and stack frame (not used on Intel CPUs). + * + * @return This routine returns an exception disposition value if the exception was not handled by any filter. + * + * @since XT 1.0 + */ +XTCLINK +XTCDECL +EXCEPTION_DISPOSITION +__CxxFrameHandler3(IN PEXCEPTION_RECORD ExceptionRecord, + IN PVOID EstablisherFrame, + IN OUT PCONTEXT ContextRecord, + IN OUT PVOID DispatcherContext) +{ + UNIMPLEMENTED; + + /* Disable interrupts and hang */ + AR::CpuFunc::ClearInterruptFlag(); + KE::Crash::Panic(0); // CXX_FRAME_HANDLER_CALLED + + /* Continue search */ + return ExceptionContinueSearch; +} + +/** + * Finds the appropriate exception handler to process the current exception. + * + * @param ExceptionRecord + * A pointer to the exception record providing information about the specific exception. + * + * @param Registration + * A pointer to the record that indicates which scope table should be used to find the exception handler. + * + * @param Context + * Reserved. + * + * @param Dispatcher + * Reserved. + * + * @return This routine returns DISPOSITION_DISMISS or DISPOSITION_CONTINUE_SEARCH. + * + * @since XT 1.0 + */ +XTCLINK +XTCDECL +INT +_except_handler3(IN PEXCEPTION_RECORD ExceptionRecord, + IN PVOID Registration, + IN PCONTEXT Context, + IN PVOID Dispatcher) +{ + UNIMPLEMENTED; + + /* Handler not found */ + return 0; +} + +/** + * Handles pure virtual function call error. This implementation displays a panic screen and halts the system. + * + * @return This function does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTCDECL +VOID +_purecall(VOID) +{ + UNIMPLEMENTED; + + /* Disable interrupts and hang */ + AR::CpuFunc::ClearInterruptFlag(); + KE::Crash::Panic(0); // PURE_VIRTUAL_FUNCTION_CALL +} diff --git a/xtoskrnl/rtl/plist.c b/xtoskrnl/rtl/llist.cc similarity index 81% rename from xtoskrnl/rtl/plist.c rename to xtoskrnl/rtl/llist.cc index e63483c..58bff64 100644 --- a/xtoskrnl/rtl/plist.c +++ b/xtoskrnl/rtl/llist.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/rtl/plist.c + * FILE: xtoskrnl/rtl/llist.cc * DESCRIPTION: Linked list manipulation routines * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -21,7 +21,7 @@ */ XTCDECL VOID -RtlInitializeListHead(IN PLIST_ENTRY ListHead) +RTL::LinkedList::InitializeListHead(IN PLIST_ENTRY ListHead) { ListHead->Blink = ListHead; ListHead->Flink = ListHead; @@ -39,7 +39,7 @@ RtlInitializeListHead(IN PLIST_ENTRY ListHead) */ XTCDECL VOID -RtlInitializeListHead32(IN PLIST_ENTRY32 ListHead) +RTL::LinkedList::InitializeListHead32(IN PLIST_ENTRY32 ListHead) { ListHead->Blink = PtrToUlong(ListHead); ListHead->Flink = PtrToUlong(ListHead); @@ -60,8 +60,8 @@ RtlInitializeListHead32(IN PLIST_ENTRY32 ListHead) */ XTCDECL VOID -RtlInsertHeadList(IN OUT PLIST_ENTRY ListHead, - IN PLIST_ENTRY Entry) +RTL::LinkedList::InsertHeadList(IN OUT PLIST_ENTRY ListHead, + IN PLIST_ENTRY Entry) { Entry->Flink = ListHead->Flink; Entry->Blink = ListHead; @@ -84,8 +84,8 @@ RtlInsertHeadList(IN OUT PLIST_ENTRY ListHead, */ XTCDECL VOID -RtlInsertTailList(IN OUT PLIST_ENTRY ListHead, - IN PLIST_ENTRY Entry) +RTL::LinkedList::InsertTailList(IN OUT PLIST_ENTRY ListHead, + IN PLIST_ENTRY Entry) { Entry->Flink = ListHead; Entry->Blink = ListHead->Blink; @@ -105,9 +105,9 @@ RtlInsertTailList(IN OUT PLIST_ENTRY ListHead, */ XTCDECL BOOLEAN -RtlListEmpty(IN PLIST_ENTRY ListHead) +RTL::LinkedList::ListEmpty(IN PLIST_ENTRY ListHead) { - return (((ListHead->Flink == NULL) && (ListHead->Blink == NULL)) || (ListHead->Flink == ListHead)); + return (((ListHead->Flink == NULLPTR) && (ListHead->Blink == NULLPTR)) || (ListHead->Flink == ListHead)); } /** @@ -122,12 +122,12 @@ RtlListEmpty(IN PLIST_ENTRY ListHead) */ XTCDECL BOOLEAN -RtlListLoop(IN PLIST_ENTRY ListHead) +RTL::LinkedList::ListLoop(IN PLIST_ENTRY ListHead) { PLIST_ENTRY SlowEntry, FastEntry; /* Check if list exists */ - if(ListHead == NULL) + if(ListHead == NULLPTR) { /* No loop in non-existen list */ return FALSE; @@ -138,7 +138,7 @@ RtlListLoop(IN PLIST_ENTRY ListHead) SlowEntry = ListHead; /* Iterate through the linked list to find a loop */ - while(SlowEntry != NULL && FastEntry != NULL && FastEntry->Flink != NULL) + while(SlowEntry != NULLPTR && FastEntry != NULLPTR && FastEntry->Flink != NULLPTR) { /* Move slow and fast pointers by one and two positions accordingly */ SlowEntry = SlowEntry->Flink; @@ -168,7 +168,7 @@ RtlListLoop(IN PLIST_ENTRY ListHead) */ XTCDECL VOID -RtlRemoveEntryList(IN PLIST_ENTRY Entry) +RTL::LinkedList::RemoveEntryList(IN PLIST_ENTRY Entry) { Entry->Flink->Blink = Entry->Blink; Entry->Blink->Flink = Entry->Flink; diff --git a/xtoskrnl/rtl/math.c b/xtoskrnl/rtl/math.cc similarity index 89% rename from xtoskrnl/rtl/math.c rename to xtoskrnl/rtl/math.cc index f6003b4..0c35e79 100644 --- a/xtoskrnl/rtl/math.c +++ b/xtoskrnl/rtl/math.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/rtl/math.c + * FILE: xtoskrnl/rtl/math.cc * DESCRIPTION: Kernel math support * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -21,7 +21,7 @@ */ XTAPI LARGE_INTEGER -RtlConvertToLargeInteger32(IN LONG Value) +RTL::Math::ConvertToLargeInteger32(IN LONG Value) { LARGE_INTEGER LargeInt; @@ -42,7 +42,7 @@ RtlConvertToLargeInteger32(IN LONG Value) */ XTAPI LARGE_INTEGER -RtlConvertToLargeIntegerUnsigned32(IN ULONG Value) +RTL::Math::ConvertToLargeIntegerUnsigned32(IN ULONG Value) { LARGE_INTEGER LargeInt; @@ -63,7 +63,7 @@ RtlConvertToLargeIntegerUnsigned32(IN ULONG Value) */ XTAPI INT -RtlCountLeadingZeroes32(IN ULONG Value) +RTL::Math::CountLeadingZeroes32(IN ULONG Value) { /* Return a number of leading zero bits */ return __builtin_clzl(Value); @@ -81,7 +81,7 @@ RtlCountLeadingZeroes32(IN ULONG Value) */ XTAPI INT -RtlCountLeadingZeroes64(IN ULONGLONG Value) +RTL::Math::CountLeadingZeroes64(IN ULONGLONG Value) { /* Return a number of leading zero bits */ return __builtin_clzll(Value); @@ -99,7 +99,7 @@ RtlCountLeadingZeroes64(IN ULONGLONG Value) */ XTAPI INT -RtlCountTrailingZeroes32(IN ULONG Value) +RTL::Math::CountTrailingZeroes32(IN ULONG Value) { /* Return a number of trailing zero bits */ return __builtin_ctzl(Value); @@ -117,7 +117,7 @@ RtlCountTrailingZeroes32(IN ULONG Value) */ XTAPI INT -RtlCountTrailingZeroes64(IN ULONGLONG Value) +RTL::Math::CountTrailingZeroes64(IN ULONGLONG Value) { /* Return a number of trailing zero bits */ return __builtin_ctzll(Value); @@ -141,9 +141,9 @@ RtlCountTrailingZeroes64(IN ULONGLONG Value) */ XTAPI LONGLONG -RtlDivide32(IN LONG Dividend, - IN LONG Divisor, - OUT PLONG Remainder) +RTL::Math::Divide32(IN LONG Dividend, + IN LONG Divisor, + OUT PLONG Remainder) { LONG Quotient; @@ -179,9 +179,9 @@ RtlDivide32(IN LONG Dividend, */ XTAPI LONGLONG -RtlDivide64(IN LONGLONG Dividend, - IN LONGLONG Divisor, - OUT PLONGLONG Remainder) +RTL::Math::Divide64(IN LONGLONG Dividend, + IN LONGLONG Divisor, + OUT PLONGLONG Remainder) { LONGLONG DividendSign, DivisorSign, Quotient, UDividend, UDivisor; @@ -193,7 +193,7 @@ RtlDivide64(IN LONGLONG Dividend, /* Calculate the quotient */ DividendSign ^= DivisorSign; - Quotient = (RtlDivideUnsigned64(UDividend, UDivisor, NULL) ^ DividendSign) - DividendSign; + Quotient = (DivideUnsigned64(UDividend, UDivisor, NULLPTR) ^ DividendSign) - DividendSign; /* Make sure a pointer to remainder provided */ if(Remainder) @@ -224,9 +224,9 @@ RtlDivide64(IN LONGLONG Dividend, */ XTAPI ULONGLONG -RtlDivideUnsigned32(IN ULONG Dividend, - IN ULONG Divisor, - OUT PULONG Remainder) +RTL::Math::DivideUnsigned32(IN ULONG Dividend, + IN ULONG Divisor, + OUT PULONG Remainder) { /* Make sure a pointer to remainder provided */ if(Remainder) @@ -257,9 +257,9 @@ RtlDivideUnsigned32(IN ULONG Dividend, */ XTAPI ULONGLONG -RtlDivideUnsigned64(IN ULONGLONG Dividend, - IN ULONGLONG Divisor, - OUT PULONGLONG Remainder) +RTL::Math::DivideUnsigned64(IN ULONGLONG Dividend, + IN ULONGLONG Divisor, + OUT PULONGLONG Remainder) { ULARGE_INTEGER DividendParts, DivisorParts, QuotientParts, RemainderParts; LONGLONG Difference; @@ -284,7 +284,7 @@ RtlDivideUnsigned64(IN ULONGLONG Dividend, if(DivisorParts.u.HighPart == 0) { /* 32-bit divide operation, check if remainder provided */ - if(Remainder != NULL) + if(Remainder != NULLPTR) { /* Calculate remainder */ *Remainder = DividendParts.u.LowPart % DivisorParts.u.LowPart; @@ -295,7 +295,7 @@ RtlDivideUnsigned64(IN ULONGLONG Dividend, } /* 32-bit value divided by a 64-bit value, check if remainder provided */ - if(Remainder != NULL) + if(Remainder != NULLPTR) { /* Calculate remainder */ *Remainder = DividendParts.u.LowPart; @@ -312,13 +312,13 @@ RtlDivideUnsigned64(IN ULONGLONG Dividend, if(DivisorParts.u.HighPart != 0) { /* Divisor is 64-bit value, calculate the shift count */ - Shift = RtlCountLeadingZeroes32(DivisorParts.u.HighPart) - RtlCountLeadingZeroes32(DividendParts.u.HighPart); + Shift = CountLeadingZeroes32(DivisorParts.u.HighPart) - CountLeadingZeroes32(DividendParts.u.HighPart); /* Check if shift count exceeds 32-bits */ if(Shift > ((sizeof(ULONG) * BITS_PER_BYTE) - 1)) { /* Check if remainder provided */ - if(Remainder != NULL) + if(Remainder != NULLPTR) { /* Calculate remainder */ *Remainder = DividendParts.QuadPart; @@ -349,8 +349,8 @@ RtlDivideUnsigned64(IN ULONGLONG Dividend, { /* Divisor is 32-bit value, calculate the shift count */ Shift = (sizeof(ULONG) * BITS_PER_BYTE) + 1 + - RtlCountLeadingZeroes32(DivisorParts.u.LowPart) - - RtlCountLeadingZeroes32(DividendParts.u.HighPart); + CountLeadingZeroes32(DivisorParts.u.LowPart) - + CountLeadingZeroes32(DividendParts.u.HighPart); /* Check if shift is 32-bit */ if(Shift == (sizeof(ULONG) * BITS_PER_BYTE)) @@ -388,7 +388,7 @@ RtlDivideUnsigned64(IN ULONGLONG Dividend, if(DividendParts.u.LowPart == 0) { /* Check if remainder provided */ - if(Remainder != NULL) + if(Remainder != NULLPTR) { /* Calculate the remainder */ RemainderParts.u.HighPart = DividendParts.u.HighPart % DivisorParts.u.HighPart; @@ -401,13 +401,13 @@ RtlDivideUnsigned64(IN ULONGLONG Dividend, } /* Calculate the shift count */ - Shift = RtlCountLeadingZeroes32(DivisorParts.u.HighPart) - RtlCountLeadingZeroes32(DividendParts.u.HighPart); + Shift = CountLeadingZeroes32(DivisorParts.u.HighPart) - CountLeadingZeroes32(DividendParts.u.HighPart); /* Check if shift exceeds 32-bits */ if(Shift > ((sizeof(ULONG) * BITS_PER_BYTE) - 2)) { /* Check if remainder provided */ - if(Remainder != NULL) + if(Remainder != NULLPTR) { /* Calculate the remainder */ *Remainder = DividendParts.QuadPart; @@ -457,7 +457,7 @@ RtlDivideUnsigned64(IN ULONGLONG Dividend, QuotientParts.QuadPart = (QuotientParts.QuadPart << 1) | Carry; /* Check if remainder provided */ - if(Remainder != NULL) + if(Remainder != NULLPTR) { /* Calculate the remainder */ *Remainder = RemainderParts.QuadPart; @@ -485,9 +485,9 @@ RtlDivideUnsigned64(IN ULONGLONG Dividend, */ XTAPI LARGE_INTEGER -RtlDivideLargeInteger(IN LARGE_INTEGER Dividend, - IN ULONG Divisor, - OUT PULONG Remainder) +RTL::Math::DivideLargeInteger(IN LARGE_INTEGER Dividend, + IN ULONG Divisor, + OUT PULONG Remainder) { LONGLONG DividendSign, UDividend; LARGE_INTEGER LargeInt; @@ -497,7 +497,7 @@ RtlDivideLargeInteger(IN LARGE_INTEGER Dividend, UDividend = (Dividend.QuadPart ^ DividendSign) - DividendSign; /* Calculate the quotient */ - LargeInt.QuadPart = (RtlDivideUnsigned64(UDividend, Divisor, NULL) ^ DividendSign) - DividendSign; + LargeInt.QuadPart = (DivideUnsigned64(UDividend, Divisor, NULLPTR) ^ DividendSign) - DividendSign; /* Make sure a pointer to remainder provided */ if(Remainder) @@ -525,8 +525,8 @@ RtlDivideLargeInteger(IN LARGE_INTEGER Dividend, */ XTAPI LONG -RtlGetBaseExponent(IN DOUBLE Value, - OUT PDOUBLE PowerOfTen) +RTL::Math::GetBaseExponent(IN DOUBLE Value, + OUT PDOUBLE PowerOfTen) { LONG BaseExponent, CurrentExponent, Exponent; ULONG ExponentShift, ExponentMask; @@ -610,9 +610,9 @@ RtlGetBaseExponent(IN DOUBLE Value, * * @since XT 1.0 */ -XTCDECL +XTAPI BOOLEAN -RtlInfiniteDouble(IN DOUBLE Value) +RTL::Math::InfiniteDouble(IN DOUBLE Value) { /* DOUBLE argument in IEEE 754 standard format */ union @@ -649,8 +649,8 @@ RtlInfiniteDouble(IN DOUBLE Value) */ XTAPI LARGE_INTEGER -RtlMultiplyLargeInteger(IN LARGE_INTEGER Multiplicand, - IN LONG Multiplier) +RTL::Math::MultiplyLargeInteger(IN LARGE_INTEGER Multiplicand, + IN LONG Multiplier) { LARGE_INTEGER LargeInt; @@ -669,9 +669,9 @@ RtlMultiplyLargeInteger(IN LARGE_INTEGER Multiplicand, * * @since XT 1.0 */ -XTCDECL +XTAPI BOOLEAN -RtlNanDouble(IN DOUBLE Value) +RTL::Math::NanDouble(IN DOUBLE Value) { /* DOUBLE argument in IEEE 754 standard format */ union diff --git a/xtoskrnl/rtl/memory.c b/xtoskrnl/rtl/memory.cc similarity index 82% rename from xtoskrnl/rtl/memory.c rename to xtoskrnl/rtl/memory.cc index 3d59f01..0244e78 100644 --- a/xtoskrnl/rtl/memory.c +++ b/xtoskrnl/rtl/memory.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/rtl/memory.c + * FILE: xtoskrnl/rtl/memory.cc * DESCRIPTION: Memory related routines * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -27,9 +27,9 @@ */ XTAPI SIZE_T -RtlCompareMemory(IN PCVOID LeftBuffer, - IN PCVOID RightBuffer, - IN SIZE_T Length) +RTL::Memory::CompareMemory(IN PCVOID LeftBuffer, + IN PCVOID RightBuffer, + IN SIZE_T Length) { SIZE_T Bytes = 0; @@ -73,9 +73,9 @@ RtlCompareMemory(IN PCVOID LeftBuffer, */ XTAPI VOID -RtlCopyMemory(OUT PVOID Destination, - IN PCVOID Source, - IN SIZE_T Length) +RTL::Memory::CopyMemory(OUT PVOID Destination, + IN PCVOID Source, + IN SIZE_T Length) { PCHAR DestinationBytes = (PCHAR)Destination; PCCHAR SourceBytes = (PCHAR)Source; @@ -106,9 +106,9 @@ RtlCopyMemory(OUT PVOID Destination, */ XTAPI VOID -RtlMoveMemory(OUT PVOID Destination, - IN PCVOID Source, - IN SIZE_T Length) +RTL::Memory::MoveMemory(OUT PVOID Destination, + IN PCVOID Source, + IN SIZE_T Length) { PCHAR DestinationBytes = (PCHAR)Destination; PCHAR SourceBytes = (PCHAR)Source; @@ -154,11 +154,11 @@ RtlMoveMemory(OUT PVOID Destination, */ XTAPI BOOLEAN -RtlSameMemory(IN PCVOID LeftBuffer, - IN PCVOID RightBuffer, - IN SIZE_T Length) +RTL::Memory::SameMemory(IN PCVOID LeftBuffer, + IN PCVOID RightBuffer, + IN SIZE_T Length) { - return (RtlCompareMemory(LeftBuffer, RightBuffer, Length) == Length) ? TRUE : FALSE; + return (CompareMemory(LeftBuffer, RightBuffer, Length) == Length) ? TRUE : FALSE; } /** @@ -179,9 +179,9 @@ RtlSameMemory(IN PCVOID LeftBuffer, */ XTAPI VOID -RtlSetMemory(OUT PVOID Destination, - IN UCHAR Byte, - IN SIZE_T Length) +RTL::Memory::SetMemory(OUT PVOID Destination, + IN UCHAR Byte, + IN SIZE_T Length) { PCHAR DestinationBytes = (PCHAR)Destination; @@ -207,9 +207,9 @@ RtlSetMemory(OUT PVOID Destination, */ XTAPI VOID -RtlZeroMemory(OUT PVOID Destination, - IN SIZE_T Length) +RTL::Memory::ZeroMemory(OUT PVOID Destination, + IN SIZE_T Length) { /* Fill the buffer with zeroes */ - RtlSetMemory(Destination, 0, Length); + SetMemory(Destination, 0, Length); } diff --git a/xtoskrnl/rtl/string.c b/xtoskrnl/rtl/string.cc similarity index 81% rename from xtoskrnl/rtl/string.c rename to xtoskrnl/rtl/string.cc index bec887a..df0812a 100644 --- a/xtoskrnl/rtl/string.c +++ b/xtoskrnl/rtl/string.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/rtl/string.c + * FILE: xtoskrnl/rtl/string.cc * DESCRIPTION: String support * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -27,9 +27,9 @@ */ XTAPI SIZE_T -RtlCompareString(IN PCSTR String1, - IN PCSTR String2, - IN SIZE_T Length) +RTL::String::CompareString(IN PCSTR String1, + IN PCSTR String2, + IN SIZE_T Length) { SIZE_T Index; @@ -79,9 +79,9 @@ RtlCompareString(IN PCSTR String1, */ XTAPI SIZE_T -RtlCompareStringInsensitive(IN PCSTR String1, - IN PCSTR String2, - IN SIZE_T Length) +RTL::String::CompareStringInsensitive(IN PCSTR String1, + IN PCSTR String2, + IN SIZE_T Length) { CHAR Character1; CHAR Character2; @@ -132,10 +132,10 @@ RtlCompareStringInsensitive(IN PCSTR String1, * Appends a copy of the source string to the end of the destination string. * * @param Destination - * Supplies a pointer to the null-terminated string to append to. + * Supplies a pointer to the NULL-terminated string to append to. * * @param Source - * Supplies a pointer to the null-terminated string to copy from. + * Supplies a pointer to the NULL-terminated string to copy from. * * @param Count * Sets a maximum number of characters to copy. If no limit set, appends whole string. @@ -146,9 +146,9 @@ RtlCompareStringInsensitive(IN PCSTR String1, */ XTAPI PCHAR -RtlConcatenateString(OUT PCHAR Destination, - IN PCHAR Source, - IN SIZE_T Count) +RTL::String::ConcatenateString(OUT PCHAR Destination, + IN PCHAR Source, + IN SIZE_T Count) { PCHAR DestString = Destination; @@ -164,7 +164,7 @@ RtlConcatenateString(OUT PCHAR Destination, /* Copy character-by-character */ do { - /* Check if NULL terminated character found */ + /* Check if NULL-terminated character found */ if((*Destination = *Source++) == '\0') { /* Break on '\0' character */ @@ -174,7 +174,7 @@ RtlConcatenateString(OUT PCHAR Destination, } while(--Count != 0); - /* Add NULL termination character to the end of destination string */ + /* Add NULL-termination character to the end of destination string */ *Destination = '\0'; } else @@ -205,9 +205,9 @@ RtlConcatenateString(OUT PCHAR Destination, */ XTAPI VOID -RtlCopyString(IN PCHAR Destination, - IN PCSTR Source, - IN ULONG Length) +RTL::String::CopyString(IN PCHAR Destination, + IN PCSTR Source, + IN ULONG Length) { ULONG Index; @@ -217,7 +217,7 @@ RtlCopyString(IN PCHAR Destination, /* Copy source character */ Destination[Index] = Source[Index]; - /* Check if NULL terminated character found */ + /* Check if NULL-terminated character found */ if(Source[Index] == '\0') { /* End of source string reached */ @@ -244,8 +244,8 @@ RtlCopyString(IN PCHAR Destination, */ XTAPI PCSTR -RtlFindString(IN PCSTR Source, - IN PCSTR Search) +RTL::String::FindString(IN PCSTR Source, + IN PCSTR Search) { PCSTR CurrentSource; PCSTR CurrentSearch; @@ -253,8 +253,8 @@ RtlFindString(IN PCSTR Source, /* Validate input parameters */ if(!Source || !Search) { - /* Invalid input parameters, return NULL */ - return NULL; + /* Invalid input parameters, return NULLPTR */ + return NULLPTR; } /* Check if search string is empty */ @@ -287,8 +287,8 @@ RtlFindString(IN PCSTR Source, } } - /* No match found, return NULL */ - return NULL; + /* No match found, return NULLPTR */ + return NULLPTR; } /** @@ -306,8 +306,8 @@ RtlFindString(IN PCSTR Source, */ XTAPI PCSTR -RtlFindStringInsensitive(IN PCSTR Source, - IN PCSTR Search) +RTL::String::FindStringInsensitive(IN PCSTR Source, + IN PCSTR Search) { PCSTR CurrentSource; PCSTR CurrentSearch; @@ -315,8 +315,8 @@ RtlFindStringInsensitive(IN PCSTR Source, /* Validate input parameters */ if(!Source || !Search) { - /* Invalid input parameters, return NULL */ - return NULL; + /* Invalid input parameters, return NULLPTR */ + return NULLPTR; } /* Check if search string is empty */ @@ -335,7 +335,7 @@ RtlFindStringInsensitive(IN PCSTR Source, /* Check if the substring matches starting at the current position */ while(*CurrentSource != '\0' && *CurrentSearch != '\0' && - RtlToLowerCharacter(*CurrentSource) == RtlToLowerCharacter(*CurrentSearch)) + ToLowerCharacter(*CurrentSource) == ToLowerCharacter(*CurrentSearch)) { /* Go to the next character */ CurrentSource++; @@ -350,8 +350,8 @@ RtlFindStringInsensitive(IN PCSTR Source, } } - /* No match found, return NULL */ - return NULL; + /* No match found, return NULLPTR */ + return NULLPTR; } /** @@ -369,8 +369,8 @@ RtlFindStringInsensitive(IN PCSTR Source, */ XTAPI VOID -RtlReverseString(IN OUT PCHAR String, - IN ULONG Length) +RTL::String::ReverseString(IN OUT PCHAR String, + IN ULONG Length) { UCHAR TempChar; ULONG Index; @@ -389,24 +389,24 @@ RtlReverseString(IN OUT PCHAR String, * Calculates the length of a given string. * * @param String - * Pointer to the null-terminated string to be examined. + * Pointer to the NULL-terminated string to be examined. * * @param MaxLength * Maximum number of characters to examine. If no limit set, it examines whole string. * - * @return The length of the null-terminated string. + * @return The length of the NULL-terminated string. * * @since: XT 1.0 */ XTAPI SIZE_T -RtlStringLength(IN PCSTR String, - IN SIZE_T MaxLength) +RTL::String::StringLength(IN PCSTR String, + IN SIZE_T MaxLength) { SIZE_T Length; /* Check if NULL pointer passed */ - if(String == NULL) + if(String == NULLPTR) { return 0; } @@ -445,15 +445,15 @@ RtlStringLength(IN PCSTR String, */ XTAPI SIZE_T -RtlStringToWideString(OUT PWCHAR Destination, - IN PCSTR *Source, - IN SIZE_T Length) +RTL::String::StringToWideString(OUT PWCHAR Destination, + IN PCSTR *Source, + IN SIZE_T Length) { PCSTR LocalSource = *Source; SIZE_T Count = Length; /* Check if NULL pointer passed */ - if(Destination == NULL) + if(Destination == NULLPTR) { /* No wide characters written */ return 0; @@ -466,7 +466,7 @@ RtlStringToWideString(OUT PWCHAR Destination, if((*Destination = *LocalSource) == 0) { /* End of string reached */ - LocalSource = NULL; + LocalSource = NULLPTR; break; } @@ -488,13 +488,13 @@ RtlStringToWideString(OUT PWCHAR Destination, } /** - * Finds the next token in a null-terminated string. + * Finds the next token in a NULL-terminated string. * * @param String - * Pointer to the null-terminated string to tokenize. + * Pointer to the NULL-terminated string to tokenize. * * @param Delimiter - * Pointer to the null-terminated string identifying delimiters. + * Pointer to the NULL-terminated string identifying delimiters. * * @param SavePtr * Pointer to an object used to store routine internal state. @@ -505,26 +505,26 @@ RtlStringToWideString(OUT PWCHAR Destination, */ XTAPI PCHAR -RtlTokenizeString(IN PCHAR String, - IN PCSTR Delimiter, - IN OUT PCHAR *SavePtr) +RTL::String::TokenizeString(IN PCHAR String, + IN PCSTR Delimiter, + IN OUT PCHAR *SavePtr) { PCHAR Span, Token; CHAR Char, SpanChar; /* Check if there is anything to tokenize */ - if(String == NULL && (String = *SavePtr) == NULL) + if(String == NULLPTR && (String = *SavePtr) == NULLPTR) { /* Empty string given */ - return NULL; + return NULLPTR; } /* Check non-delimiter characters */ Char = *String++; if(Char == '\0') { - *SavePtr = NULL; - return NULL; + *SavePtr = NULLPTR; + return NULLPTR; } Token = String - 1; @@ -542,7 +542,7 @@ RtlTokenizeString(IN PCHAR String, if(Char == '\0') { /* End of string reached, no more tokens */ - String = NULL; + String = NULLPTR; } else { @@ -573,7 +573,7 @@ RtlTokenizeString(IN PCHAR String, */ XTAPI CHAR -RtlToLowerCharacter(IN CHAR Character) +RTL::String::ToLowerCharacter(IN CHAR Character) { /* Check if character is uppercase */ if(Character >= 'A' && Character <= 'Z') @@ -598,7 +598,7 @@ RtlToLowerCharacter(IN CHAR Character) */ XTAPI CHAR -RtlToUpperCharacter(IN CHAR Character) +RTL::String::ToUpperCharacter(IN CHAR Character) { /* Check if character is lowercase */ if(Character >= 'a' && Character <= 'z') @@ -615,7 +615,7 @@ RtlToUpperCharacter(IN CHAR Character) * Removes certain characters from a beginning of the string. * * @param String - * Pointer to the null-terminated string to be trimmed. + * Pointer to the NULL-terminated string to be trimmed. * * @return This routine returns a pointer to the left-trimmed string. * @@ -623,7 +623,7 @@ RtlToUpperCharacter(IN CHAR Character) */ XTAPI PCHAR -RtlTrimLeftString(IN PCHAR String) +RTL::String::TrimLeftString(IN PCHAR String) { PCHAR Start; @@ -645,7 +645,7 @@ RtlTrimLeftString(IN PCHAR String) * Removes certain characters from the end of the string. * * @param String - * Pointer to the null-terminated string to be trimmed. + * Pointer to the NULL-terminated string to be trimmed. * * @return This routine returns a pointer to the right-trimmed string. * @@ -653,12 +653,12 @@ RtlTrimLeftString(IN PCHAR String) */ XTAPI PCHAR -RtlTrimRightString(IN PCHAR String) +RTL::String::TrimRightString(IN PCHAR String) { PCHAR End; /* Find end of the string */ - End = String + RtlStringLength(String, 0); + End = String + StringLength(String, 0); /* Skip all trailing whitespaces */ while((End != String) && (*End == ' ' || *End == '\n' || *End == '\t' || *End == '\r' || *End == '\v' || *End == '\f')) @@ -678,7 +678,7 @@ RtlTrimRightString(IN PCHAR String) * Removes certain characters from the beginning and the end of the string. * * @param String - * Pointer to the null-terminated string to be trimmed. + * Pointer to the NULL-terminated string to be trimmed. * * @return This routine returns a pointer to the trimmed string. * @@ -686,7 +686,7 @@ RtlTrimRightString(IN PCHAR String) */ XTAPI PCHAR -RtlTrimString(IN PCHAR String) +RTL::String::TrimString(IN PCHAR String) { - return RtlTrimLeftString(RtlTrimRightString(String)); + return TrimLeftString(TrimRightString(String)); } diff --git a/xtoskrnl/rtl/widestr.c b/xtoskrnl/rtl/widestr.cc similarity index 85% rename from xtoskrnl/rtl/widestr.c rename to xtoskrnl/rtl/widestr.cc index da5a21b..dc8dbec 100644 --- a/xtoskrnl/rtl/widestr.c +++ b/xtoskrnl/rtl/widestr.cc @@ -1,12 +1,12 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/rtl/widestr.c + * FILE: xtoskrnl/rtl/widestr.cc * DESCRIPTION: Wide string support * DEVELOPERS: Rafal Kupiec */ -#include +#include /** @@ -27,9 +27,9 @@ */ XTAPI SIZE_T -RtlCompareWideString(IN PCWSTR String1, - IN PCWSTR String2, - IN SIZE_T Length) +RTL::WideString::CompareWideString(IN PCWSTR String1, + IN PCWSTR String2, + IN SIZE_T Length) { SIZE_T Index; @@ -79,9 +79,9 @@ RtlCompareWideString(IN PCWSTR String1, */ XTAPI SIZE_T -RtlCompareWideStringInsensitive(IN PCWSTR String1, - IN PCWSTR String2, - IN SIZE_T Length) +RTL::WideString::CompareWideStringInsensitive(IN PCWSTR String1, + IN PCWSTR String2, + IN SIZE_T Length) { WCHAR Character1; WCHAR Character2; @@ -132,10 +132,10 @@ RtlCompareWideStringInsensitive(IN PCWSTR String1, * Appends a copy of the source wide string to the end of the destination wide string. * * @param Destination - * Supplies a pointer to the null-terminated wide string to append to. + * Supplies a pointer to the NULL-terminated wide string to append to. * * @param Source - * Supplies a pointer to the null-terminated wide string to copy from. + * Supplies a pointer to the NULL-terminated wide string to copy from. * * @param Count * Sets a maximum number of wide characters to copy. If no limit set, appends whole wide string. @@ -146,9 +146,9 @@ RtlCompareWideStringInsensitive(IN PCWSTR String1, */ XTAPI PWCHAR -RtlConcatenateWideString(OUT PWCHAR Destination, - IN PWCHAR Source, - IN SIZE_T Count) +RTL::WideString::ConcatenateWideString(OUT PWCHAR Destination, + IN PWCHAR Source, + IN SIZE_T Count) { PWCHAR DestString = Destination; @@ -203,12 +203,11 @@ RtlConcatenateWideString(OUT PWCHAR Destination, * * @since XT 1.0 */ - XTAPI VOID -RtlCopyWideString(IN PWCHAR Destination, - IN PCWSTR Source, - IN ULONG Length) +RTL::WideString::CopyWideString(IN PWCHAR Destination, + IN PCWSTR Source, + IN ULONG Length) { ULONG Index; @@ -245,8 +244,8 @@ RtlCopyWideString(IN PWCHAR Destination, */ XTAPI PCWSTR -RtlFindWideString(IN PCWSTR Source, - IN PCWSTR Search) +RTL::WideString::FindWideString(IN PCWSTR Source, + IN PCWSTR Search) { PCWSTR CurrentSource; PCWSTR CurrentSearch; @@ -254,8 +253,8 @@ RtlFindWideString(IN PCWSTR Source, /* Validate input parameters */ if(!Source || !Search) { - /* Invalid input parameters, return NULL */ - return NULL; + /* Invalid input parameters, return NULLPTR */ + return NULLPTR; } /* Check if search string is empty */ @@ -288,8 +287,8 @@ RtlFindWideString(IN PCWSTR Source, } } - /* No match found, return NULL */ - return NULL; + /* No match found, return NULLPTR */ + return NULLPTR; } /** @@ -307,8 +306,8 @@ RtlFindWideString(IN PCWSTR Source, */ XTAPI PCWSTR -RtlFindWideStringInsensitive(IN PCWSTR Source, - IN PCWSTR Search) +RTL::WideString::FindWideStringInsensitive(IN PCWSTR Source, + IN PCWSTR Search) { PCWSTR CurrentSource; PCWSTR CurrentSearch; @@ -316,8 +315,8 @@ RtlFindWideStringInsensitive(IN PCWSTR Source, /* Validate input parameters */ if(!Source || !Search) { - /* Invalid input parameters, return NULL */ - return NULL; + /* Invalid input parameters, return NULLPTR */ + return NULLPTR; } /* Check if search string is empty */ @@ -336,7 +335,7 @@ RtlFindWideStringInsensitive(IN PCWSTR Source, /* Check if the substring matches starting at the current position */ while(*CurrentSource != L'\0' && *CurrentSearch != L'\0' && - RtlToLowerWideCharacter(*CurrentSource) == RtlToLowerWideCharacter(*CurrentSearch)) + ToLowerWideCharacter(*CurrentSource) == ToLowerWideCharacter(*CurrentSearch)) { /* Go to the next character */ CurrentSource++; @@ -351,360 +350,8 @@ RtlFindWideStringInsensitive(IN PCWSTR Source, } } - /* No match found, return NULL */ - return NULL; -} - -/** - * Formats a wide string according to the given printf-alike format string. - * - * @param Context - * Supplies a pointer to the print context structure. - * - * @param Format - * Supplies a pointer to the printf-alike format string. - * - * @param ArgumentList - * Supplies a list of arguments to the format string. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTAPI -XTSTATUS -RtlFormatWideString(IN PRTL_PRINT_CONTEXT Context, - IN PCWSTR Format, - IN VA_LIST ArgumentList) -{ - VA_LIST LocalArgumentList; - XTSTATUS Status; - ULONG Index; - - /* Make sure, that we have valid context and write routine */ - if(Context == NULL || Context->WriteWideCharacter == NULL) - { - /* Invalid context or write routine not set */ - return FALSE; - } - - /* Check format string pointer */ - if(Format == NULL) - { - /* Write null string */ - Format = L"(null)"; - } - - /* Make a copy of the argument list */ - VA_COPY(LocalArgumentList, ArgumentList); - - /* Iterate through format string */ - Index = 0; - while(Format[Index] != L'\0') - { - /* Look for format specifier */ - if(Format[Index] == L'%') - { - /* Handle format along with arguments */ - Status = RtlpFormatWideStringArgumentSpecifier(Context, Format, &LocalArgumentList, &Index); - } - else - { - /* Write wide character and increase string index */ - Status = RtlpWriteWideCharacter(Context, Format[Index]); - Index++; - } - - /* Make sure character written successfully */ - if(Status != STATUS_SUCCESS) - { - /* Return status code */ - return Status; - } - } - - /* Clean up the argument list */ - VA_END(LocalArgumentList); - - /* Return success */ - return STATUS_SUCCESS; -} - -/** - * Reverses a characters order in a wide string. It modifies the original, input variable. - * - * @param String - * Supplies a pointer to the wide string to reverse. - * - * @param Length - * Supplies the length of the wide string to reverse. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -RtlReverseWideString(IN OUT PWCHAR String, - IN ULONG Length) -{ - WCHAR TempChar; - ULONG Index; - - /* Iterate through the string */ - for(Index = 0; Index < (Length / 2); Index++) - { - /* Swap characters */ - TempChar = String[Index]; - String[Index] = String[Length - Index - 1]; - String[Length - Index - 1] = TempChar; - } -} - -/** - * Finds the next token in a null-terminated wide string. - * - * @param String - * Pointer to the null-terminated wide string to tokenize. - * - * @param Delimiter - * Pointer to the null-terminated wide string identifying delimiters. - * - * @param SavePtr - * Pointer to an object used to store routine internal state. - * - * @return Pointer to the beginning of the next token or NULL if there are no more tokens. - * - * @since: XT 1.0 - */ -XTAPI -PWCHAR -RtlTokenizeWideString(IN PWCHAR String, - IN PCWSTR Delimiter, - IN OUT PWCHAR *SavePtr) -{ - PWCHAR Span, Token; - WCHAR Char, SpanChar; - - /* Check if there is anything to tokenize */ - if(String == NULL && (String = *SavePtr) == NULL) - { - /* Empty string given */ - return NULL; - } - - /* Check non-delimiter characters */ - Char = *String++; - if(Char == L'\0') - { - *SavePtr = NULL; - return NULL; - } - Token = String - 1; - - /* Scan token for delimiters */ - for(;;) - { - Char = *String++; - Span = (PWCHAR)Delimiter; - do - { - /* Check if delimiter found */ - if((SpanChar = *Span++) == Char) - { - /* Check if end of string reached */ - if(Char == L'\0') - { - /* End of string reached, no more tokens */ - String = NULL; - } - else - { - /* Terminate token */ - String[-1] = L'\0'; - } - - /* Store pointer to the next token */ - *SavePtr = String; - - /* Return token */ - return Token; - } - } - while(SpanChar != L'\0'); - } -} - -/** - * Converts a wide character to lowercase. - * - * @param Character - * Wide character to be converted. - * - * @return Converted wide character or original character if it was not uppercase. - * - * @since XT 1.0 - */ -XTAPI -WCHAR -RtlToLowerWideCharacter(IN WCHAR Character) -{ - /* Check if wide character is uppercase */ - if(Character >= L'A' && Character <= L'Z') - { - /* Convert wide character to lowercase */ - return (WCHAR)(Character + (L'a' - L'A')); - } - - /* Return original wide character */ - return Character; -} - -/** - * Converts a wide character to uppercase. - * - * @param Character - * Wide character to be converted. - * - * @return Converted wide character or original character if it was not lowercase. - * - * @since XT 1.0 - */ -XTAPI -WCHAR -RtlToUpperWideCharacter(IN WCHAR Character) -{ - /* Check if wide character is lowercase */ - if(Character >= L'a' && Character <= L'z') - { - /* Convert wide character to uppercase */ - return (WCHAR)(Character - (L'a' - L'A')); - } - - /* Return original wide character */ - return Character; -} - -/** - * Removes certain characters from a beginning of the wide string. - * - * @param String - * Pointer to the null-terminated wide string to be trimmed. - * - * @return This routine returns a pointer to the left-trimmed wide string. - * - * @since XT 1.0 - */ -XTAPI -PWCHAR -RtlTrimLeftWideString(IN PWCHAR String) -{ - PWCHAR Start; - - /* Initialize pointer */ - Start = String; - - /* Skip all leading whitespaces */ - while(*Start == L' ' || *Start == L'\n' || *Start == L'\t' || *Start == L'\r' || *Start == L'\v' || *Start == L'\f') - { - /* Advance to the next character */ - Start++; - } - - /* Return left-trimmed string */ - return Start; -} - -/** - * Removes certain characters from the end of the wide string. - * - * @param String - * Pointer to the null-terminated wide string to be trimmed. - * - * @return This routine returns a pointer to the right-trimmed wide string. - * - * @since XT 1.0 - */ -XTAPI -PWCHAR -RtlTrimRightWideString(IN PWCHAR String) -{ - PWCHAR End; - - /* Find end of the string */ - End = String + RtlWideStringLength(String, 0); - - /* Skip all trailing whitespaces */ - while((End != String) && (*End == L' ' || *End == L'\n' || *End == L'\t' || *End == L'\r' || *End == L'\v' || *End == L'\f')) - { - /* Move to the previous character */ - End--; - } - - /* Terminate the string */ - *End = 0; - - /* Return right-trimmed string */ - return String; -} - -/** - * Removes certain characters from the beginning and the end of the wide string. - * - * @param String - * Pointer to the null-terminated wide string to be trimmed. - * - * @return This routine returns a pointer to the trimmed wide string. - * - * @since XT 1.0 - */ -XTAPI -PWCHAR -RtlTrimWideString(IN PWCHAR String) -{ - return RtlTrimLeftWideString(RtlTrimRightWideString(String)); -} - -/** - * Calculates the length of a given wide string. - * - * @param String - * Pointer to the null-terminated wide string to be examined. - * - * @param MaxLength - * Maximum number of wide characters to examine. If no limit set, it examines whole string. - * - * @return The length of the null-terminated wide string. - * - * @since: XT 1.0 - */ -XTAPI -SIZE_T -RtlWideStringLength(IN PCWSTR String, - IN SIZE_T MaxLength) -{ - SIZE_T Length; - - /* Check if NULL pointer passed */ - if(String == NULL) - { - return 0; - } - - /* Iterate through the wide string */ - for(Length = 0; ; Length++) - { - - /* Check if NULL found or max length limit reached */ - if((Length != 0 && Length == MaxLength) || !String[Length]) - { - /* Finish examination */ - break; - } - } - - /* Return wide string length */ - return Length; + /* No match found, return NULLPTR */ + return NULLPTR; } /** @@ -728,10 +375,10 @@ RtlWideStringLength(IN PCWSTR String, */ XTAPI XTSTATUS -RtlpFormatWideStringArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context, - IN PCWSTR Format, - IN PVA_LIST ArgumentList, - IN OUT PULONG Index) +RTL::WideString::FormatArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context, + IN PCWSTR Format, + IN PVA_LIST ArgumentList, + IN OUT PULONG Index) { RTL_PRINT_FORMAT_PROPERTIES FormatProperties; PUNICODE_STRING UnicodeStrArg; @@ -742,7 +389,7 @@ RtlpFormatWideStringArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context, LARGE_DOUBLE FloatArg; PCWSTR FormatIndex; ULONG ArgPosition; - PWCHAR WideStrArg; + PCWSTR WideStrArg; ULONGLONG IntArg; XTSTATUS Status; PGUID GuidArg; @@ -754,7 +401,7 @@ RtlpFormatWideStringArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context, ArgPosition = 0; /* Initialize format properties */ - RtlZeroMemory(&FormatProperties, sizeof(RTL_PRINT_FORMAT_PROPERTIES)); + RTL::Memory::ZeroMemory(&FormatProperties, sizeof(RTL_PRINT_FORMAT_PROPERTIES)); FormatProperties.IntegerSize = sizeof(INT); FormatProperties.Precision = -1; @@ -766,7 +413,7 @@ RtlpFormatWideStringArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context, if((*FormatIndex >= L'1') && (*FormatIndex <= L'9')) { /* POSIX extension found, read its value */ - SpecifierValue = RtlpGetWideStringSpecifierValue((PWSTR*)&FormatIndex); + SpecifierValue = GetSpecifierValue((PWSTR*)&FormatIndex); /* Make sure parameter field ends with '$' character */ if(*FormatIndex == L'$') @@ -852,7 +499,7 @@ RtlpFormatWideStringArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context, else if((*FormatIndex >= L'1') && (*FormatIndex <= L'9')) { /* Read a numeric width value */ - FormatProperties.FieldWidth = RtlpGetWideStringSpecifierValue((PWSTR*)&FormatIndex); + FormatProperties.FieldWidth = GetSpecifierValue((PWSTR*)&FormatIndex); } /* Check if field width is set to negative value */ @@ -879,7 +526,7 @@ RtlpFormatWideStringArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context, else if((*FormatIndex >= L'0') && (*FormatIndex <= L'9')) { /* Read a numeric precision value */ - FormatProperties.Precision = RtlpGetWideStringSpecifierValue((PWSTR*)&FormatIndex); + FormatProperties.Precision = GetSpecifierValue((PWSTR*)&FormatIndex); } else { @@ -1000,156 +647,157 @@ RtlpFormatWideStringArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context, { case L'a': /* Double argument as hexadecimal number (lowercase) */ - FormatProperties.VariableType = Float; + FormatProperties.VariableType = TypeFloat; FormatProperties.Flags |= PFL_SCI_FORMAT; FormatProperties.Radix = 16; break; case L'A': /* Double argument as hexadecimal number (uppercase) */ - FormatProperties.VariableType = Float; + FormatProperties.VariableType = TypeFloat; FormatProperties.Flags |= PFL_SCI_FORMAT | PFL_UPPERCASE; FormatProperties.Radix = 16; break; case L'b': /* XTOS extension: Boolean argument (lowercase) */ - FormatProperties.VariableType = Boolean; + FormatProperties.VariableType = TypeBoolean; break; case L'B': /* XTOS extension: Boolean argument (uppercase) */ - FormatProperties.VariableType = Boolean; + FormatProperties.VariableType = TypeBoolean; FormatProperties.Flags |= PFL_UPPERCASE; break; case L'c': /* Character argument */ - FormatProperties.VariableType = Char; + FormatProperties.VariableType = TypeChar; break; case L'C': /* Wide character argument */ - FormatProperties.VariableType = WideChar; + FormatProperties.VariableType = TypeWideChar; break; case L'd': case L'i': /* Signed integer argument as decimal number */ - FormatProperties.VariableType = Integer; + FormatProperties.VariableType = TypeInteger; FormatProperties.Flags &= ~PFL_UNSIGNED; FormatProperties.Radix = 10; break; case L'e': /* Double argument in scientific notation (lowercase) */ - FormatProperties.VariableType = Float; + FormatProperties.VariableType = TypeFloat; FormatProperties.Flags |= PFL_SCI_FORMAT; break; case L'E': /* Double argument in scientific notation (uppercase) */ - FormatProperties.VariableType = Float; + FormatProperties.VariableType = TypeFloat; FormatProperties.Flags |= PFL_SCI_FORMAT | PFL_UPPERCASE; break; case L'f': /* Double argument as floating point number (lowercase) */ - FormatProperties.VariableType = Float; + FormatProperties.VariableType = TypeFloat; FormatProperties.Flags |= PFL_FLOAT_FORMAT; break; case L'F': /* Double argument as floating point number (uppercase) */ - FormatProperties.VariableType = Float; + FormatProperties.VariableType = TypeFloat; FormatProperties.Flags |= PFL_FLOAT_FORMAT | PFL_UPPERCASE; break; case L'g': /* Double argument as either floating point number or in scientific notation (lowercase) */ - FormatProperties.VariableType = Float; + FormatProperties.VariableType = TypeFloat; FormatProperties.Flags |= PFL_DIGIT_PRECISION; break; case L'G': /* Double argument as either floating point number or in scientific notation (uppercase) */ - FormatProperties.VariableType = Float; + FormatProperties.VariableType = TypeFloat; FormatProperties.Flags |= PFL_DIGIT_PRECISION | PFL_UPPERCASE; break; case L'n': /* Write number of characters written so far into an integer pointer parameter */ - FormatProperties.VariableType = Integer; + FormatProperties.VariableType = TypeInteger; FormatProperties.IntegerSize = sizeof(PVOID); break; case L'o': /* Unsigned integer argument as octal number */ - FormatProperties.VariableType = Integer; + FormatProperties.VariableType = TypeInteger; FormatProperties.Radix = 8; break; case L'p': /* Pointer argument as hexadecimal number (lowercase) */ - FormatProperties.VariableType = Integer; + FormatProperties.VariableType = TypeInteger; FormatProperties.IntegerSize = sizeof(UINT_PTR); FormatProperties.Flags |= PFL_PRINT_RADIX; FormatProperties.Radix = 16; break; case L'P': /* XTOS extension: Pointer argument as hexadecimal number (uppercase) */ - FormatProperties.VariableType = Integer; + FormatProperties.VariableType = TypeInteger; FormatProperties.IntegerSize = sizeof(UINT_PTR); FormatProperties.Flags |= PFL_PRINT_RADIX | PFL_UPPERCASE; FormatProperties.Radix = 16; break; case L's': /* String argument */ - FormatProperties.VariableType = String; + FormatProperties.VariableType = TypeString; break; case L'S': /* Wide string argument */ - FormatProperties.VariableType = WideString; + FormatProperties.VariableType = TypeWideString; break; case L'u': /* Unsigned integer argument as decimal number */ - FormatProperties.VariableType = Integer; + FormatProperties.VariableType = TypeInteger; FormatProperties.Radix = 10; break; case L'v': /* XTOS extension: UUID/GUID argument (lowercase) */ - FormatProperties.VariableType = Guid; + FormatProperties.VariableType = TypeGuid; break; case L'V': /* XTOS extension: UUID/GUID argument (uppercase) */ - FormatProperties.VariableType = Guid; + FormatProperties.VariableType = TypeGuid; FormatProperties.Flags |= PFL_UPPERCASE; break; case L'x': /* Unsigned integer argument as hexadecimal number (lowercase) */ - FormatProperties.VariableType = Integer; + FormatProperties.VariableType = TypeInteger; FormatProperties.Radix = 16; break; case L'X': /* Unsigned integer argument as hexadecimal number (uppercase) */ - FormatProperties.VariableType = Integer; + FormatProperties.VariableType = TypeInteger; FormatProperties.Flags |= PFL_UPPERCASE; FormatProperties.Radix = 16; break; case L'Z': /* MSVC extension: ANSI/Unicode string argument */ - FormatProperties.VariableType = (FormatProperties.Flags & PFL_WIDE_CHARACTER) ? UnicodeString : AnsiString; + FormatProperties.VariableType = (FormatProperties.Flags & PFL_WIDE_CHARACTER) ? TypeUnicodeString + : TypeAnsiString; break; case L'%': /* Print '%' character */ - FormatProperties.VariableType = Unknown; + FormatProperties.VariableType = TypeUnknown; WideCharArg = L'%'; break; default: /* Unknown format specifier, print '?' character */ - FormatProperties.VariableType = Unknown; + FormatProperties.VariableType = TypeUnknown; WideCharArg = L'?'; break; } /* Finally, write the formatted argument */ - if(FormatProperties.VariableType == Unknown) + if(FormatProperties.VariableType == TypeUnknown) { /* Write defined wide character */ - Status = RtlpWriteWideStringValue(Context, &FormatProperties, &WideCharArg, 1); + Status = WriteValue(Context, &FormatProperties, &WideCharArg, 1); } - if(FormatProperties.VariableType == Boolean) + if(FormatProperties.VariableType == TypeBoolean) { /* Boolean type */ if(ArgPosition != 0) { /* Get argument value from specified argument position */ - IntArg = RtlpGetWideStringArgument(&ArgumentsCopy, ArgPosition, FormatProperties.IntegerSize); + IntArg = GetArgument(&ArgumentsCopy, ArgPosition, FormatProperties.IntegerSize); } else { @@ -1170,15 +818,15 @@ RtlpFormatWideStringArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context, } /* Write formatted boolean string */ - Status = RtlpWriteWideStringValue(Context, &FormatProperties, WideStrArg, RtlWideStringLength(WideStrArg, 0)); + Status = WriteValue(Context, &FormatProperties, WideStrArg, WideStringLength(WideStrArg, 0)); } - else if(FormatProperties.VariableType == Guid) + else if(FormatProperties.VariableType == TypeGuid) { /* GUID type */ if(ArgPosition != 0) { /* Get argument value from specified argument position */ - IntArg = RtlpGetWideStringArgument(&ArgumentsCopy, ArgPosition, sizeof(PGUID)); + IntArg = GetArgument(&ArgumentsCopy, ArgPosition, sizeof(PGUID)); GuidArg = (PGUID)(UINT_PTR)IntArg; } else @@ -1187,8 +835,8 @@ RtlpFormatWideStringArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context, GuidArg = VA_ARG(*ArgumentList, PGUID); } - /* Make sure a pointer to GUID is not NULL */ - if(GuidArg != NULL) + /* Make sure a pointer to GUID is not NULL pointer */ + if(GuidArg != NULLPTR) { /* Check if using uppercase format */ if(FormatProperties.Flags & PFL_UPPERCASE) @@ -1202,19 +850,19 @@ RtlpFormatWideStringArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context, WideStrArg = L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"; } /* Write formatted GUID string */ - Status = RtlpWriteWideStringCustomValue(Context, WideStrArg, GuidArg->Data1, GuidArg->Data2, GuidArg->Data3, - GuidArg->Data4[0], GuidArg->Data4[1], GuidArg->Data4[2], - GuidArg->Data4[3], GuidArg->Data4[4], GuidArg->Data4[5], - GuidArg->Data4[6], GuidArg->Data4[7]); + Status = WriteCustomValue(Context, WideStrArg, GuidArg->Data1, GuidArg->Data2, GuidArg->Data3, + GuidArg->Data4[0], GuidArg->Data4[1], GuidArg->Data4[2], + GuidArg->Data4[3], GuidArg->Data4[4], GuidArg->Data4[5], + GuidArg->Data4[6], GuidArg->Data4[7]); } } - else if(FormatProperties.VariableType == Char) + else if(FormatProperties.VariableType == TypeChar) { /* Character type */ if(ArgPosition != 0) { /* Get argument value from specified argument position */ - CharArg = (UCHAR)RtlpGetWideStringArgument(&ArgumentsCopy, ArgPosition, sizeof(UCHAR)); + CharArg = (UCHAR)GetArgument(&ArgumentsCopy, ArgPosition, sizeof(UCHAR)); } else { @@ -1223,15 +871,15 @@ RtlpFormatWideStringArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context, } /* Write formatted character */ - Status = RtlpWriteWideStringStringValue(Context, &FormatProperties, &CharArg, 1); + Status = WriteStringValue(Context, &FormatProperties, &CharArg, 1); } - else if(FormatProperties.VariableType == WideChar) + else if(FormatProperties.VariableType == TypeWideChar) { /* Wide character type */ if(ArgPosition != 0) { /* Get argument value from specified argument position */ - WideCharArg = (WCHAR)RtlpGetWideStringArgument(&ArgumentsCopy, ArgPosition, sizeof(WCHAR)); + WideCharArg = (WCHAR)GetArgument(&ArgumentsCopy, ArgPosition, sizeof(WCHAR)); } else { @@ -1240,15 +888,15 @@ RtlpFormatWideStringArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context, } /* Write formatted wide character */ - Status = RtlpWriteWideStringValue(Context, &FormatProperties, &WideCharArg, 1); + Status = WriteValue(Context, &FormatProperties, &WideCharArg, 1); } - else if(FormatProperties.VariableType == Float) + else if(FormatProperties.VariableType == TypeFloat) { /* Float/Double type */ if(ArgPosition != 0) { /* Get argument value from specified argument position */ - FloatArg.QuadPart = RtlpGetWideStringArgument(&ArgumentsCopy, ArgPosition, sizeof(ULONGLONG)); + FloatArg.QuadPart = GetArgument(&ArgumentsCopy, ArgPosition, sizeof(ULONGLONG)); } else { @@ -1264,15 +912,15 @@ RtlpFormatWideStringArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context, } /* Write formatted double value */ - Status = RtlpWriteWideStringDoubleValue(Context, &FormatProperties, FloatArg.DoublePart); + Status = WriteDoubleValue(Context, &FormatProperties, FloatArg.DoublePart); } - else if(FormatProperties.VariableType == Integer) + else if(FormatProperties.VariableType == TypeInteger) { /* Integer type */ if(ArgPosition != 0) { /* Get argument value from specified argument position */ - IntArg = RtlpGetWideStringArgument(&ArgumentsCopy, ArgPosition, FormatProperties.IntegerSize); + IntArg = GetArgument(&ArgumentsCopy, ArgPosition, FormatProperties.IntegerSize); /* Convert to required integer size */ switch(FormatProperties.IntegerSize) @@ -1319,7 +967,7 @@ RtlpFormatWideStringArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context, if(Specifier == L'n') { /* Make sure, that integer pointer parameter is not NULL */ - if(IntArg != (UINT_PTR)NULL) + if(IntArg != (UINT_PTR)NULLPTR) { /* Store number of characters written in integer pointer parameter */ *((PINT)(UINT_PTR)IntArg) = Context->CharactersWritten; @@ -1328,16 +976,16 @@ RtlpFormatWideStringArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context, else { /* Write formatted integer value */ - Status = RtlpWriteWideStringIntegerValue(Context, &FormatProperties, IntArg); + Status = WriteIntegerValue(Context, &FormatProperties, IntArg); } } - else if(FormatProperties.VariableType == String) + else if(FormatProperties.VariableType == TypeString) { /* String type */ if(ArgPosition != 0) { /* Get argument value from specified argument position */ - IntArg = RtlpGetWideStringArgument(&ArgumentsCopy, ArgPosition, sizeof(PCHAR)); + IntArg = GetArgument(&ArgumentsCopy, ArgPosition, sizeof(PCHAR)); StrArg = (PCHAR)(UINT_PTR)IntArg; } else @@ -1347,16 +995,16 @@ RtlpFormatWideStringArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context, } /* Write formatted string value */ - Status = RtlpWriteWideStringStringValue(Context, &FormatProperties, StrArg, RtlStringLength(StrArg, 0)); + Status = WriteStringValue(Context, &FormatProperties, StrArg, RTL::String::StringLength(StrArg, 0)); } - else if(FormatProperties.VariableType == WideString) + else if(FormatProperties.VariableType == TypeWideString) { /* Wide string type */ if(ArgPosition != 0) { /* Get argument value from specified argument position */ - IntArg = RtlpGetWideStringArgument(&ArgumentsCopy, ArgPosition, sizeof(PWCHAR)); - WideStrArg = (PWCHAR)(UINT_PTR)IntArg; + IntArg = GetArgument(&ArgumentsCopy, ArgPosition, sizeof(PWCHAR)); + WideStrArg = (PCWSTR)(UINT_PTR)IntArg; } else { @@ -1365,15 +1013,15 @@ RtlpFormatWideStringArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context, } /* Write formatted wide string value */ - Status = RtlpWriteWideStringValue(Context, &FormatProperties, WideStrArg, RtlWideStringLength(WideStrArg, 0)); + Status = WriteValue(Context, &FormatProperties, WideStrArg, RtlWideStringLength(WideStrArg, 0)); } - else if(FormatProperties.VariableType == AnsiString ) + else if(FormatProperties.VariableType == TypeAnsiString ) { /* ANSI string type */ if(ArgPosition != 0) { /* Get argument value from specified argument position */ - IntArg = RtlpGetWideStringArgument(&ArgumentsCopy, ArgPosition, sizeof(PANSI_STRING)); + IntArg = GetArgument(&ArgumentsCopy, ArgPosition, sizeof(PANSI_STRING)); AnsiStrArg = (PANSI_STRING)(UINT_PTR)IntArg; } else @@ -1383,19 +1031,19 @@ RtlpFormatWideStringArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context, } /* Make sure a pointer to ANSI_STRING is not NULL */ - if(AnsiStrArg != NULL) + if(AnsiStrArg != NULLPTR) { /* Write formatted ANSI string value */ - Status = RtlpWriteWideStringStringValue(Context, &FormatProperties, AnsiStrArg->Buffer, AnsiStrArg->Length); + Status = WriteStringValue(Context, &FormatProperties, AnsiStrArg->Buffer, AnsiStrArg->Length); } } - else if(FormatProperties.VariableType == UnicodeString) + else if(FormatProperties.VariableType == TypeUnicodeString) { /* Unicode string type */ if(ArgPosition != 0) { /* Get argument value from specified argument position */ - IntArg = RtlpGetWideStringArgument(&ArgumentsCopy, ArgPosition, sizeof(PUNICODE_STRING)); + IntArg = GetArgument(&ArgumentsCopy, ArgPosition, sizeof(PUNICODE_STRING)); UnicodeStrArg = (PUNICODE_STRING)(UINT_PTR)IntArg; } else @@ -1405,10 +1053,10 @@ RtlpFormatWideStringArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context, } /* Make sure a pointer to UNICODE_STRING is not NULL */ - if(UnicodeStrArg != NULL) + if(UnicodeStrArg != NULLPTR) { /* Write formatted UNICODE string value */ - Status = RtlpWriteWideStringValue(Context, &FormatProperties, UnicodeStrArg->Buffer, UnicodeStrArg->Length); + Status = WriteValue(Context, &FormatProperties, UnicodeStrArg->Buffer, UnicodeStrArg->Length); } } @@ -1422,6 +1070,81 @@ RtlpFormatWideStringArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context, return Status; } +/** + * Formats a wide string according to the given printf-alike format string. + * + * @param Context + * Supplies a pointer to the print context structure. + * + * @param Format + * Supplies a pointer to the printf-alike format string. + * + * @param ArgumentList + * Supplies a list of arguments to the format string. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTAPI +XTSTATUS +RTL::WideString::FormatWideString(IN PRTL_PRINT_CONTEXT Context, + IN PCWSTR Format, + IN VA_LIST ArgumentList) +{ + VA_LIST LocalArgumentList; + XTSTATUS Status; + ULONG Index; + + /* Make sure, that we have valid context and write routine */ + if(Context == NULLPTR || Context->WriteWideCharacter == NULLPTR) + { + /* Invalid context or write routine not set */ + return FALSE; + } + + /* Check format string pointer */ + if(Format == NULLPTR) + { + /* Write null string */ + Format = L"(null)"; + } + + /* Make a copy of the argument list */ + VA_COPY(LocalArgumentList, ArgumentList); + + /* Iterate through format string */ + Index = 0; + while(Format[Index] != L'\0') + { + /* Look for format specifier */ + if(Format[Index] == L'%') + { + /* Handle format along with arguments */ + Status = FormatArgumentSpecifier(Context, Format, &LocalArgumentList, &Index); + } + else + { + /* Write wide character and increase string index */ + Status = WriteWideCharacter(Context, Format[Index]); + Index++; + } + + /* Make sure character written successfully */ + if(Status != STATUS_SUCCESS) + { + /* Return status code */ + return Status; + } + } + + /* Clean up the argument list */ + VA_END(LocalArgumentList); + + /* Return success */ + return STATUS_SUCCESS; +} + /** * Gets the positional argument by scanning the argument list. * @@ -1436,9 +1159,9 @@ RtlpFormatWideStringArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context, */ XTAPI ULONGLONG -RtlpGetWideStringArgument(IN PVA_LIST ArgumentList, - IN ULONG ArgumentNumber, - IN LONG ArgumentSize) +RTL::WideString::GetArgument(IN PVA_LIST ArgumentList, + IN ULONG ArgumentNumber, + IN LONG ArgumentSize) { VA_LIST ArgumentsCopy; ULONGLONG Value; @@ -1494,7 +1217,7 @@ RtlpGetWideStringArgument(IN PVA_LIST ArgumentList, */ XTAPI ULONGLONG -RtlpGetWideStringSpecifierValue(IN PWCHAR *Format) +RTL::WideString::GetSpecifierValue(IN PWCHAR *Format) { ULONG Count; PWCHAR Fmt; @@ -1523,6 +1246,284 @@ RtlpGetWideStringSpecifierValue(IN PWCHAR *Format) return 0; } +/** + * Reverses a characters order in a wide string. It modifies the original, input variable. + * + * @param String + * Supplies a pointer to the wide string to reverse. + * + * @param Length + * Supplies the length of the wide string to reverse. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +RTL::WideString::ReverseWideString(IN OUT PWCHAR String, + IN ULONG Length) +{ + WCHAR TempChar; + ULONG Index; + + /* Iterate through the string */ + for(Index = 0; Index < (Length / 2); Index++) + { + /* Swap characters */ + TempChar = String[Index]; + String[Index] = String[Length - Index - 1]; + String[Length - Index - 1] = TempChar; + } +} + +/** + * Finds the next token in a NULL-terminated wide string. + * + * @param String + * Pointer to the NULL-terminated wide string to tokenize. + * + * @param Delimiter + * Pointer to the NULL-terminated wide string identifying delimiters. + * + * @param SavePtr + * Pointer to an object used to store routine internal state. + * + * @return Pointer to the beginning of the next token or NULLPTR if there are no more tokens. + * + * @since: XT 1.0 + */ +XTAPI +PWCHAR +RTL::WideString::TokenizeWideString(IN PWCHAR String, + IN PCWSTR Delimiter, + IN OUT PWCHAR *SavePtr) +{ + PWCHAR Span, Token; + WCHAR Char, SpanChar; + + /* Check if there is anything to tokenize */ + if(String == NULLPTR && (String = *SavePtr) == NULLPTR) + { + /* Empty string given */ + return NULLPTR; + } + + /* Check non-delimiter characters */ + Char = *String++; + if(Char == L'\0') + { + *SavePtr = NULLPTR; + return NULLPTR; + } + Token = String - 1; + + /* Scan token for delimiters */ + for(;;) + { + Char = *String++; + Span = (PWCHAR)Delimiter; + do + { + /* Check if delimiter found */ + if((SpanChar = *Span++) == Char) + { + /* Check if end of string reached */ + if(Char == L'\0') + { + /* End of string reached, no more tokens */ + String = NULLPTR; + } + else + { + /* Terminate token */ + String[-1] = L'\0'; + } + + /* Store pointer to the next token */ + *SavePtr = String; + + /* Return token */ + return Token; + } + } + while(SpanChar != L'\0'); + } +} + +/** + * Converts a wide character to lowercase. + * + * @param Character + * Wide character to be converted. + * + * @return Converted wide character or original character if it was not uppercase. + * + * @since XT 1.0 + */ +XTAPI +WCHAR +RTL::WideString::ToLowerWideCharacter(IN WCHAR Character) +{ + /* Check if wide character is uppercase */ + if(Character >= L'A' && Character <= L'Z') + { + /* Convert wide character to lowercase */ + return (WCHAR)(Character + (L'a' - L'A')); + } + + /* Return original wide character */ + return Character; +} + +/** + * Converts a wide character to uppercase. + * + * @param Character + * Wide character to be converted. + * + * @return Converted wide character or original character if it was not lowercase. + * + * @since XT 1.0 + */ +XTAPI +WCHAR +RTL::WideString::ToUpperWideCharacter(IN WCHAR Character) +{ + /* Check if wide character is lowercase */ + if(Character >= L'a' && Character <= L'z') + { + /* Convert wide character to uppercase */ + return (WCHAR)(Character - (L'a' - L'A')); + } + + /* Return original wide character */ + return Character; +} + +/** + * Removes certain characters from a beginning of the wide string. + * + * @param String + * Pointer to the NULL-terminated wide string to be trimmed. + * + * @return This routine returns a pointer to the left-trimmed wide string. + * + * @since XT 1.0 + */ +XTAPI +PWCHAR +RTL::WideString::TrimLeftWideString(IN PWCHAR String) +{ + PWCHAR Start; + + /* Initialize pointer */ + Start = String; + + /* Skip all leading whitespaces */ + while(*Start == L' ' || *Start == L'\n' || *Start == L'\t' || *Start == L'\r' || *Start == L'\v' || *Start == L'\f') + { + /* Advance to the next character */ + Start++; + } + + /* Return left-trimmed string */ + return Start; +} + +/** + * Removes certain characters from the end of the wide string. + * + * @param String + * Pointer to the NULL-terminated wide string to be trimmed. + * + * @return This routine returns a pointer to the right-trimmed wide string. + * + * @since XT 1.0 + */ +XTAPI +PWCHAR +RTL::WideString::TrimRightWideString(IN PWCHAR String) +{ + PWCHAR End; + + /* Find end of the string */ + End = String + RtlWideStringLength(String, 0); + + /* Skip all trailing whitespaces */ + while((End != String) && (*End == L' ' || *End == L'\n' || *End == L'\t' || + *End == L'\r' || *End == L'\v' || *End == L'\f')) + { + /* Move to the previous character */ + End--; + } + + /* Terminate the string */ + *End = 0; + + /* Return right-trimmed string */ + return String; +} + +/** + * Removes certain characters from the beginning and the end of the wide string. + * + * @param String + * Pointer to the NULL-terminated wide string to be trimmed. + * + * @return This routine returns a pointer to the trimmed wide string. + * + * @since XT 1.0 + */ +XTAPI +PWCHAR +RTL::WideString::TrimWideString(IN PWCHAR String) +{ + return RtlTrimLeftWideString(RtlTrimRightWideString(String)); +} + +/** + * Calculates the length of a given wide string. + * + * @param String + * Pointer to the NULL-terminated wide string to be examined. + * + * @param MaxLength + * Maximum number of wide characters to examine. If no limit set, it examines whole string. + * + * @return The length of the NULL-terminated wide string. + * + * @since: XT 1.0 + */ +XTAPI +SIZE_T +RTL::WideString::WideStringLength(IN PCWSTR String, + IN SIZE_T MaxLength) +{ + SIZE_T Length; + + /* Check if NULL pointer passed */ + if(String == NULLPTR) + { + return 0; + } + + /* Iterate through the wide string */ + for(Length = 0; ; Length++) + { + + /* Check if NULL found or max length limit reached */ + if((Length != 0 && Length == MaxLength) || !String[Length]) + { + /* Finish examination */ + break; + } + } + + /* Return wide string length */ + return Length; +} + /** * Writes a wide character to the destination provided by the print context. * @@ -1538,8 +1539,8 @@ RtlpGetWideStringSpecifierValue(IN PWCHAR *Format) */ XTAPI XTSTATUS -RtlpWriteWideCharacter(IN PRTL_PRINT_CONTEXT Context, - IN WCHAR Character) +RTL::WideString::WriteWideCharacter(IN PRTL_PRINT_CONTEXT Context, + IN WCHAR Character) { XTSTATUS Status; @@ -1569,9 +1570,9 @@ RtlpWriteWideCharacter(IN PRTL_PRINT_CONTEXT Context, */ XTCDECL XTSTATUS -RtlpWriteWideStringCustomValue(IN PRTL_PRINT_CONTEXT Context, - IN PCWSTR Format, - IN ...) +RTL::WideString::WriteCustomValue(IN PRTL_PRINT_CONTEXT Context, + IN PCWSTR Format, + IN ...) { VA_LIST Arguments; XTSTATUS Status; @@ -1580,7 +1581,7 @@ RtlpWriteWideStringCustomValue(IN PRTL_PRINT_CONTEXT Context, VA_START(Arguments, Format); /* Format and print the string to the desired output */ - Status = RtlFormatWideString(Context, Format, Arguments); + Status = FormatWideString(Context, Format, Arguments); /* Clean up the va_list */ VA_END(Arguments); @@ -1591,9 +1592,9 @@ RtlpWriteWideStringCustomValue(IN PRTL_PRINT_CONTEXT Context, XTAPI XTSTATUS -RtlpWriteWideStringDoubleValue(IN PRTL_PRINT_CONTEXT Context, - IN PRTL_PRINT_FORMAT_PROPERTIES FormatProperties, - IN DOUBLE Value) +RTL::WideString::WriteDoubleValue(IN PRTL_PRINT_CONTEXT Context, + IN PRTL_PRINT_FORMAT_PROPERTIES FormatProperties, + IN DOUBLE Value) { LONG CurrentExponent, DigitCount, Exponent, Precision, PrecisionIndex, SignificantDigits; WCHAR Character, Digit, ExponentCharacter, SignCharacter; @@ -1601,7 +1602,7 @@ RtlpWriteWideStringDoubleValue(IN PRTL_PRINT_CONTEXT Context, WCHAR Buffer[MAX_DOUBLE_STRING_SIZE]; BOOLEAN NegativeValue, WriteExponent; DOUBLE RoundingAmount, TenPower; - PWCHAR NonNumberString; + PCWSTR NonNumberString; LARGE_DOUBLE Parts; XTSTATUS Status; @@ -1627,10 +1628,10 @@ RtlpWriteWideStringDoubleValue(IN PRTL_PRINT_CONTEXT Context, } /* Determine whether the value is infinite or nan */ - if(RtlInfiniteDouble(Value)) + if(RTL::Math::InfiniteDouble(Value)) { /* Check if the value is nan */ - if(RtlNanDouble(Value)) + if(RTL::Math::NanDouble(Value)) { /* Set non-number string depending on the selection of upper or lowercase */ if(FormatProperties->Flags & PFL_UPPERCASE) @@ -1683,15 +1684,15 @@ RtlpWriteWideStringDoubleValue(IN PRTL_PRINT_CONTEXT Context, } /* Copy string to buffer and write it to wide string context */ - RtlCopyWideString(Buffer + Index, NonNumberString, sizeof(Buffer) - Index); - return RtlpWriteWideStringValue(Context, FormatProperties, Buffer, RtlWideStringLength(Buffer, 0)); + CopyWideString(Buffer + Index, NonNumberString, sizeof(Buffer) - Index); + return WriteValue(Context, FormatProperties, Buffer, WideStringLength(Buffer, 0)); } /* Check whether we need to handle hexadecimal format */ if(FormatProperties->Radix == 16) { /* Handle it as hex value */ - return RtlpWriteWideStringHexDoubleValue(Context, FormatProperties, Value); + return WriteHexDoubleValue(Context, FormatProperties, Value); } /* Check if the value is negative */ @@ -1703,11 +1704,11 @@ RtlpWriteWideStringDoubleValue(IN PRTL_PRINT_CONTEXT Context, } /* Calculate the exponent */ - Exponent = RtlGetBaseExponent(Value, &TenPower); + Exponent = RTL::Math::GetBaseExponent(Value, &TenPower); RoundingAmount = 0.5; /* Determine whether or not to write the exponent */ - WriteExponent = (FormatProperties->Flags & PFL_SCI_FORMAT); + WriteExponent = (BOOLEAN)(FormatProperties->Flags & PFL_SCI_FORMAT); if((WriteExponent == FALSE) && !(FormatProperties->Flags & PFL_FLOAT_FORMAT)) { if((Exponent < DOUBLE_SCIENTIFIC_PRECISION) || (Exponent >= Precision)) @@ -1960,7 +1961,7 @@ RtlpWriteWideStringDoubleValue(IN PRTL_PRINT_CONTEXT Context, if(SignCharacter != 0) { /* Write the sign character */ - Status = RtlpWriteWideCharacter(Context, SignCharacter); + Status = WriteWideCharacter(Context, SignCharacter); if(Status != STATUS_SUCCESS) { /* Failed to write the character, return status code */ @@ -1991,7 +1992,7 @@ RtlpWriteWideStringDoubleValue(IN PRTL_PRINT_CONTEXT Context, for(FieldIndex = 0; FieldIndex < FieldCount; FieldIndex++) { /* Write the leading character */ - Status = RtlpWriteWideCharacter(Context, Character); + Status = WriteWideCharacter(Context, Character); if(Status != STATUS_SUCCESS) { /* Failed to write the character, return status code */ @@ -2007,7 +2008,7 @@ RtlpWriteWideStringDoubleValue(IN PRTL_PRINT_CONTEXT Context, if(SignCharacter != 0) { /* Write the sign character */ - Status = RtlpWriteWideCharacter(Context, SignCharacter); + Status = WriteWideCharacter(Context, SignCharacter); if(Status != STATUS_SUCCESS) { /* Failed to write the character, return status code */ @@ -2033,7 +2034,7 @@ RtlpWriteWideStringDoubleValue(IN PRTL_PRINT_CONTEXT Context, } /* Write the digit */ - Status = RtlpWriteWideCharacter(Context, Digit); + Status = WriteWideCharacter(Context, Digit); if(Status != STATUS_SUCCESS) { /* Failed to write the character, return status code */ @@ -2051,7 +2052,7 @@ RtlpWriteWideStringDoubleValue(IN PRTL_PRINT_CONTEXT Context, if((Precision != 0) || (FormatProperties->Flags & PFL_PRINT_RADIX)) { /* Write the radix character */ - Status = RtlpWriteWideCharacter(Context, L'.'); + Status = WriteWideCharacter(Context, L'.'); if(Status != STATUS_SUCCESS) { /* Failed to write the character, return status code */ @@ -2076,7 +2077,7 @@ RtlpWriteWideStringDoubleValue(IN PRTL_PRINT_CONTEXT Context, } /* Write the digit */ - Status = RtlpWriteWideCharacter(Context, Digit); + Status = WriteWideCharacter(Context, Digit); if(Status != STATUS_SUCCESS) { /* Failed to write the character, return status code */ @@ -2097,7 +2098,7 @@ RtlpWriteWideStringDoubleValue(IN PRTL_PRINT_CONTEXT Context, } /* Write the exponent string */ - Status = RtlpWriteWideStringCustomValue(Context, L"%C%+0.2d", ExponentCharacter, Exponent); + Status = WriteCustomValue(Context, L"%C%+0.2d", ExponentCharacter, Exponent); if(Status != STATUS_SUCCESS) { /* Failed to write the characters, return status code */ @@ -2127,7 +2128,7 @@ RtlpWriteWideStringDoubleValue(IN PRTL_PRINT_CONTEXT Context, } /* Write the digit */ - Status = RtlpWriteWideCharacter(Context, Digit); + Status = WriteWideCharacter(Context, Digit); if(Status != STATUS_SUCCESS) { /* Failed to write the character, return status code */ @@ -2148,7 +2149,7 @@ RtlpWriteWideStringDoubleValue(IN PRTL_PRINT_CONTEXT Context, else { /* Exponent is negative, write '0' */ - Status = RtlpWriteWideCharacter(Context, L'0'); + Status = WriteWideCharacter(Context, L'0'); if(Status != STATUS_SUCCESS) { /* Failed to write the character, return status code */ @@ -2163,7 +2164,7 @@ RtlpWriteWideStringDoubleValue(IN PRTL_PRINT_CONTEXT Context, if((Precision != 0) || (FormatProperties->Flags & PFL_PRINT_RADIX)) { /* Write the radix character */ - Status = RtlpWriteWideCharacter(Context, L'.'); + Status = WriteWideCharacter(Context, L'.'); if(Status != STATUS_SUCCESS) { /* Failed to write the character, return status code */ @@ -2193,7 +2194,7 @@ RtlpWriteWideStringDoubleValue(IN PRTL_PRINT_CONTEXT Context, } /* Write the digit */ - Status = RtlpWriteWideCharacter(Context, Digit); + Status = WriteWideCharacter(Context, Digit); if(Status != STATUS_SUCCESS) { /* Failed to write the character, return status code */ @@ -2209,7 +2210,7 @@ RtlpWriteWideStringDoubleValue(IN PRTL_PRINT_CONTEXT Context, for(FieldIndex = 0; FieldIndex < FieldCount; FieldIndex++) { /* Fill the remaining space with spaces */ - Status = RtlpWriteWideCharacter(Context, L' '); + Status = WriteWideCharacter(Context, L' '); if(Status != STATUS_SUCCESS) { /* Failed to write the character, return status code */ @@ -2239,9 +2240,9 @@ RtlpWriteWideStringDoubleValue(IN PRTL_PRINT_CONTEXT Context, */ XTAPI XTSTATUS -RtlpWriteWideStringHexDoubleValue(IN PRTL_PRINT_CONTEXT Context, - IN PRTL_PRINT_FORMAT_PROPERTIES FormatProperties, - IN DOUBLE Double) +RTL::WideString::WriteHexDoubleValue(IN PRTL_PRINT_CONTEXT Context, + IN PRTL_PRINT_FORMAT_PROPERTIES FormatProperties, + IN DOUBLE Double) { LONG AbsoluteExponent, Exponent, FieldCount, Index, NumberLength; WCHAR Character, Digit, ExponentCharacter, IntegerValue; @@ -2462,7 +2463,7 @@ RtlpWriteWideStringHexDoubleValue(IN PRTL_PRINT_CONTEXT Context, while(PrefixSize--) { /* Write the prefix character */ - Status = RtlpWriteWideCharacter(Context, Prefix[PrefixIndex]); + Status = WriteWideCharacter(Context, Prefix[PrefixIndex]); if(Status != STATUS_SUCCESS) { /* Failed to write character, return error code */ @@ -2483,7 +2484,7 @@ RtlpWriteWideStringHexDoubleValue(IN PRTL_PRINT_CONTEXT Context, while(FieldCount) { /* Write the field character */ - Status = RtlpWriteWideCharacter(Context, Character); + Status = WriteWideCharacter(Context, Character); if(Status != STATUS_SUCCESS) { /* Failed to write character, return error code */ @@ -2499,7 +2500,7 @@ RtlpWriteWideStringHexDoubleValue(IN PRTL_PRINT_CONTEXT Context, for(PrefixIndex = 0; PrefixIndex < PrefixSize; PrefixIndex++) { /* Write the prefix character */ - Status = RtlpWriteWideCharacter(Context, Prefix[PrefixIndex]); + Status = WriteWideCharacter(Context, Prefix[PrefixIndex]); if(Status != STATUS_SUCCESS) { /* Failed to write character, return error code */ @@ -2508,7 +2509,7 @@ RtlpWriteWideStringHexDoubleValue(IN PRTL_PRINT_CONTEXT Context, } /* Write the integer value */ - Status = RtlpWriteWideCharacter(Context, IntegerValue); + Status = WriteWideCharacter(Context, IntegerValue); if(Status != STATUS_SUCCESS) { /* Failed to write character, return error code */ @@ -2519,7 +2520,7 @@ RtlpWriteWideStringHexDoubleValue(IN PRTL_PRINT_CONTEXT Context, if((FormatProperties->Flags & PFL_PRINT_RADIX) || (Precision != 0)) { /* Write the radix character */ - Status = RtlpWriteWideCharacter(Context, L'.'); + Status = WriteWideCharacter(Context, L'.'); if(Status != STATUS_SUCCESS) { /* Failed to write character, return error code */ @@ -2543,7 +2544,7 @@ RtlpWriteWideStringHexDoubleValue(IN PRTL_PRINT_CONTEXT Context, } /* Write the precision character */ - Status = RtlpWriteWideCharacter(Context, Digit); + Status = WriteWideCharacter(Context, Digit); if(Status != STATUS_SUCCESS) { /* Failed to write character, return error code */ @@ -2552,7 +2553,7 @@ RtlpWriteWideStringHexDoubleValue(IN PRTL_PRINT_CONTEXT Context, } /* Write the exponent characters */ - Status = RtlpWriteWideStringCustomValue(Context, L"%C%+d", ExponentCharacter, Exponent); + Status = WriteCustomValue(Context, L"%C%+d", ExponentCharacter, Exponent); if(Status != STATUS_SUCCESS) { /* Failed to write character, return error code */ @@ -2563,7 +2564,7 @@ RtlpWriteWideStringHexDoubleValue(IN PRTL_PRINT_CONTEXT Context, while(FieldCount) { /* Write the field character */ - Status = RtlpWriteWideCharacter(Context, L' '); + Status = WriteWideCharacter(Context, L' '); if(Status != STATUS_SUCCESS) { /* Failed to write character, return error code */ @@ -2596,9 +2597,9 @@ RtlpWriteWideStringHexDoubleValue(IN PRTL_PRINT_CONTEXT Context, */ XTAPI XTSTATUS -RtlpWriteWideStringIntegerValue(IN PRTL_PRINT_CONTEXT Context, - IN PRTL_PRINT_FORMAT_PROPERTIES FormatProperties, - IN ULONGLONG Integer) +RTL::WideString::WriteIntegerValue(IN PRTL_PRINT_CONTEXT Context, + IN PRTL_PRINT_FORMAT_PROPERTIES FormatProperties, + IN ULONGLONG Integer) { LONG BufferIndex, FieldLength, IntegerLength, PrecisionLength, PrefixIndex, PrefixLength; WCHAR Buffer[MAX_INTEGER_STRING_SIZE]; @@ -2649,13 +2650,13 @@ RtlpWriteWideStringIntegerValue(IN PRTL_PRINT_CONTEXT Context, } /* Initialize the buffer */ - RtlZeroMemory(Buffer, sizeof(Buffer)); + RTL::Memory::ZeroMemory(Buffer, sizeof(Buffer)); /* Convert the integer into a reversed wide string */ do { /* Get the next digit */ - NextInteger = RtlDivideUnsigned64(Integer, FormatProperties->Radix, &Remainder); + NextInteger = RTL::Math::DivideUnsigned64(Integer, FormatProperties->Radix, &Remainder); /* Convert the digit into a character */ Character = (WCHAR)Remainder; @@ -2689,7 +2690,7 @@ RtlpWriteWideStringIntegerValue(IN PRTL_PRINT_CONTEXT Context, while(Integer > 0); /* Reverse the string representation of the integer */ - RtlReverseWideString(Buffer, IntegerLength); + ReverseWideString(Buffer, IntegerLength); } /* Handle the sign decoration */ @@ -2763,7 +2764,7 @@ RtlpWriteWideStringIntegerValue(IN PRTL_PRINT_CONTEXT Context, Character = L'0'; for(PrefixIndex = 0; PrefixIndex < PrefixLength; PrefixIndex++) { - Status = RtlpWriteWideCharacter(Context, Prefix[PrefixIndex]); + Status = WriteWideCharacter(Context, Prefix[PrefixIndex]); if(Status != STATUS_SUCCESS) { /* Failed to write character, return status code */ @@ -2778,7 +2779,7 @@ RtlpWriteWideStringIntegerValue(IN PRTL_PRINT_CONTEXT Context, /* Write additional field width characters */ while(FieldLength > 0) { - Status = RtlpWriteWideCharacter(Context, Character); + Status = WriteWideCharacter(Context, Character); if(Status != STATUS_SUCCESS) { /* Failed to write character, return status code */ @@ -2793,7 +2794,7 @@ RtlpWriteWideStringIntegerValue(IN PRTL_PRINT_CONTEXT Context, /* Write the prefix characters */ for(PrefixIndex = 0; PrefixIndex < PrefixLength; PrefixIndex++) { - Status = RtlpWriteWideCharacter(Context, Prefix[PrefixIndex]); + Status = WriteWideCharacter(Context, Prefix[PrefixIndex]); if(Status != STATUS_SUCCESS) { /* Failed to write character, return status code */ @@ -2804,7 +2805,7 @@ RtlpWriteWideStringIntegerValue(IN PRTL_PRINT_CONTEXT Context, /* Fill the precision characters with '0' */ while(PrecisionLength > 0) { - Status = RtlpWriteWideCharacter(Context, L'0'); + Status = WriteWideCharacter(Context, L'0'); if(Status != STATUS_SUCCESS) { /* Failed to write character, return status code */ @@ -2818,7 +2819,7 @@ RtlpWriteWideStringIntegerValue(IN PRTL_PRINT_CONTEXT Context, /* Write the actual integer value */ for(BufferIndex = 0; BufferIndex < IntegerLength; BufferIndex++) { - Status = RtlpWriteWideCharacter(Context, Buffer[BufferIndex]); + Status = WriteWideCharacter(Context, Buffer[BufferIndex]); if(Status != STATUS_SUCCESS) { /* Failed to write character, return status code */ @@ -2829,7 +2830,7 @@ RtlpWriteWideStringIntegerValue(IN PRTL_PRINT_CONTEXT Context, /* Write additional field width with ' ' characters */ while(FieldLength > 0) { - Status = RtlpWriteWideCharacter(Context, L' '); + Status = WriteWideCharacter(Context, L' '); if(Status != STATUS_SUCCESS) { /* Failed to write character, return status code */ @@ -2865,17 +2866,17 @@ RtlpWriteWideStringIntegerValue(IN PRTL_PRINT_CONTEXT Context, */ XTAPI XTSTATUS -RtlpWriteWideStringStringValue(PRTL_PRINT_CONTEXT Context, - PRTL_PRINT_FORMAT_PROPERTIES FormatProperties, - PCHAR String, - SIZE_T StringLength) +RTL::WideString::WriteStringValue(PRTL_PRINT_CONTEXT Context, + PRTL_PRINT_FORMAT_PROPERTIES FormatProperties, + PCSTR String, + SIZE_T StringLength) { WCHAR WideCharacter[2]; ULONG PaddingLength; XTSTATUS Status; /* Check for NULL string */ - if(String == NULL) + if(String == NULLPTR) { /* Print '(null)' instead */ String = "(null)"; @@ -2903,7 +2904,7 @@ RtlpWriteWideStringStringValue(PRTL_PRINT_CONTEXT Context, while(PaddingLength > 0) { /* Write space */ - Status = RtlpWriteWideCharacter(Context, L' '); + Status = WriteWideCharacter(Context, L' '); if(Status != STATUS_SUCCESS) { /* Failed to write character, return status code */ @@ -2923,7 +2924,7 @@ RtlpWriteWideStringStringValue(PRTL_PRINT_CONTEXT Context, WideCharacter[1] = 0; /* Write wide character */ - Status = RtlpWriteWideCharacter(Context, *WideCharacter); + Status = WriteWideCharacter(Context, *WideCharacter); if(Status != STATUS_SUCCESS) { /* Failed to write character, return status code */ @@ -2939,7 +2940,7 @@ RtlpWriteWideStringStringValue(PRTL_PRINT_CONTEXT Context, while(PaddingLength > 0) { /* Write space */ - Status = RtlpWriteWideCharacter(Context, L' '); + Status = WriteWideCharacter(Context, L' '); if(Status != STATUS_SUCCESS) { /* Failed to write character, return status code */ @@ -2975,16 +2976,16 @@ RtlpWriteWideStringStringValue(PRTL_PRINT_CONTEXT Context, */ XTAPI XTSTATUS -RtlpWriteWideStringValue(PRTL_PRINT_CONTEXT Context, - PRTL_PRINT_FORMAT_PROPERTIES FormatProperties, - PWCHAR String, - SIZE_T StringLength) +RTL::WideString::WriteValue(PRTL_PRINT_CONTEXT Context, + PRTL_PRINT_FORMAT_PROPERTIES FormatProperties, + PCWSTR String, + SIZE_T StringLength) { ULONG PaddingLength; XTSTATUS Status; /* Check for NULL string */ - if(String == NULL) + if(String == NULLPTR) { /* Print '(null)' instead */ String = L"(null)"; @@ -3013,7 +3014,7 @@ RtlpWriteWideStringValue(PRTL_PRINT_CONTEXT Context, while(PaddingLength > 0) { /* Write space */ - Status = RtlpWriteWideCharacter(Context, L' '); + Status = WriteWideCharacter(Context, L' '); if(Status != STATUS_SUCCESS) { /* Failed to write character, return status code */ @@ -3029,7 +3030,7 @@ RtlpWriteWideStringValue(PRTL_PRINT_CONTEXT Context, while(StringLength != 0) { /* Write wide character */ - Status = RtlpWriteWideCharacter(Context, *String); + Status = WriteWideCharacter(Context, *String); if(Status != STATUS_SUCCESS) { /* Failed to write character, return status code */ @@ -3045,7 +3046,7 @@ RtlpWriteWideStringValue(PRTL_PRINT_CONTEXT Context, while(PaddingLength > 0) { /* Write space */ - Status = RtlpWriteWideCharacter(Context, L' '); + Status = WriteWideCharacter(Context, L' '); if(Status != STATUS_SUCCESS) { /* Failed to write character, return status code */ diff --git a/xtoskrnl/xtoskrnl.spec b/xtoskrnl/xtoskrnl.spec index f1a58c3..8ab66b0 100644 --- a/xtoskrnl/xtoskrnl.spec +++ b/xtoskrnl/xtoskrnl.spec @@ -1,16 +1,23 @@ # XTOS kernel exports +@ cdecl DbgPrint(wstr) @ fastcall ExAcquireRundownProtection(ptr) @ fastcall ExCompleteRundownProtection(ptr) @ fastcall ExInitializeRundownProtection(ptr) @ fastcall ExReInitializeRundownProtection(ptr) @ fastcall ExReleaseRundownProtection(ptr) @ fastcall ExWaitForRundownProtectionRelease(ptr) -@ cdecl HlIoPortInByte(ptr) -@ cdecl HlIoPortInLong(ptr) -@ cdecl HlIoPortInShort(ptr) -@ cdecl HlIoPortOutByte(ptr long) -@ cdecl HlIoPortOutLong(ptr long) -@ cdecl HlIoPortOutShort(ptr long) +@ cdecl HlReadPort8(ptr) +@ cdecl HlReadPort16(ptr) +@ cdecl HlReadPort32(ptr) +@ stdcall HlReadRegister8(ptr) +@ stdcall HlReadRegister16(ptr) +@ stdcall HlReadRegister32(ptr) +@ cdecl HlWritePort8(ptr long) +@ cdecl HlWritePort16(ptr long) +@ cdecl HlWritePort32(ptr long) +@ stdcall HlWriteRegister8(ptr long) +@ stdcall HlWriteRegister16(ptr long) +@ stdcall HlWriteRegister32(ptr long) @ fastcall KeAcquireQueuedSpinLock(long) @ fastcall KeAcquireSpinLock(ptr) @ stdcall KeAcquireSystemResource(long ptr) @@ -60,11 +67,14 @@ @ stdcall RtlFindWideString(wstr wstr) @ stdcall RtlFindWideStringInsensitive(wstr wstr) @ stdcall RtlInitializeBitMap(ptr ptr long) +@ stdcall RtlInitializeListHead(ptr) +@ stdcall RtlInsertHeadList(ptr ptr) +@ stdcall RtlInsertTailList(ptr ptr) +@ stdcall RtlListEmpty(ptr) +@ stdcall RtlListLoop(ptr) @ stdcall RtlMoveMemory(ptr ptr long) @ stdcall RtlMultiplyLargeInteger(long long long) -@ stdcall RtlReadRegisterByte(ptr) -@ stdcall RtlReadRegisterLong(ptr) -@ stdcall RtlReadRegisterShort(ptr) +@ stdcall RtlRemoveEntryList(ptr) @ stdcall RtlReverseString(str long) @ stdcall RtlReverseWideString(wstr long) @ stdcall RtlSameMemory(ptr ptr long) @@ -89,7 +99,4 @@ @ stdcall RtlTrimString(str) @ stdcall RtlTrimWideString(wstr) @ stdcall RtlWideStringLength(wstr long) -@ stdcall RtlWriteRegisterByte(ptr long) -@ stdcall RtlWriteRegisterLong(ptr long) -@ stdcall RtlWriteRegisterShort(ptr long) @ stdcall RtlZeroMemory(ptr long)