Compare commits
59 Commits
40d54743e0
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
cec5e8b16b
|
|||
|
a08e07e515
|
|||
|
d7f390b236
|
|||
|
55cb12c978
|
|||
|
7d8bfa8f0a
|
|||
|
d00e96baa4
|
|||
|
17f044cb3f
|
|||
|
1fa6e90439
|
|||
|
f15790e25b
|
|||
|
53c5946c04
|
|||
|
9ffb03217a
|
|||
|
4f65773aa9
|
|||
|
f1476912f3
|
|||
|
adb591f8c7
|
|||
|
4ef068dadc
|
|||
|
a0d5ee17c2
|
|||
|
9935d2d26b
|
|||
|
9eff9874c5
|
|||
|
09516835d0
|
|||
|
2a24ce9a35
|
|||
|
9ea79c92a6
|
|||
|
c30df8e5b5
|
|||
|
397d0a9f29
|
|||
|
0fa23ccf40
|
|||
|
87a91bfeb1
|
|||
|
232b92fd7e
|
|||
|
d88f9f0a15
|
|||
|
154b2062ba
|
|||
|
38d49eece4
|
|||
|
d00577ac8d
|
|||
|
620fc24cd2
|
|||
|
494b615dc2
|
|||
|
d834b7e0c8
|
|||
|
987b8f45d7
|
|||
|
52ecbdeaff
|
|||
|
121f461491
|
|||
|
f4b189adef
|
|||
|
40c4860548
|
|||
|
d2a7ae46ac
|
|||
|
8a02a5aca3
|
|||
|
96df5a80b8
|
|||
|
489ef8a514
|
|||
|
8c6c63465f
|
|||
|
e9aaeab982
|
|||
|
a608b26fde
|
|||
|
3ce009db41
|
|||
|
a0b0938099
|
|||
|
32d3672a51
|
|||
|
0c17337388
|
|||
|
9c449bed43
|
|||
|
a64aa83eb8
|
|||
|
64b5de98c8
|
|||
|
4e02664977
|
|||
|
bad3aaf6e0
|
|||
|
9b19bc94b3
|
|||
|
9479f3d364
|
|||
|
8d97ea4112
|
|||
|
576a2b7f1b
|
|||
|
916d124c9b
|
@@ -55,6 +55,9 @@ add_definitions(-D__XTOS__)
|
||||
add_definitions(-DXTOS_SOURCE_DIR="${EXECTOS_SOURCE_DIR}")
|
||||
add_definitions(-DXTOS_BINARY_DIR="${EXECTOS_BINARY_DIR}")
|
||||
|
||||
# Add assembler flags
|
||||
add_compiler_asmflags(-D__XTOS_ASSEMBLER__)
|
||||
|
||||
# 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]")
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
add_subdirectory("xtadk")
|
||||
|
||||
set_sdk_target("xtdk/" "include")
|
||||
|
||||
@@ -59,6 +59,86 @@ function(add_module_linker_flags MODULE FLAGS)
|
||||
set_module_property(${MODULE} LINK_FLAGS ${FLAGS})
|
||||
endfunction()
|
||||
|
||||
# This function compiles XT Assembly Development Kit
|
||||
function(generate_xtadk TARGET_NAME SOURCE_FILES)
|
||||
# Define the absolute destination path for the generated header file
|
||||
set(HEADER_OUTPUT "${EXECTOS_BINARY_DIR}/sdk/includes/${TARGET_NAME}.h")
|
||||
get_filename_component(HEADER_OUTPUT_DIRECTORY "${HEADER_OUTPUT}" DIRECTORY)
|
||||
|
||||
# Tokenize global CXX flags into a list to ensure correct argument expansion
|
||||
separate_arguments(COMPILER_FLAGS NATIVE_COMMAND "${CMAKE_CXX_FLAGS}")
|
||||
|
||||
# Resolve and tokenize build-configuration specific flags
|
||||
string(TOUPPER "${CMAKE_BUILD_TYPE}" BUILD_TYPE)
|
||||
if(BUILD_TYPE)
|
||||
separate_arguments(BUILD_TYPE_SPECIFIC_FLAGS NATIVE_COMMAND "${CMAKE_CXX_FLAGS_${BUILD_TYPE}}")
|
||||
endif()
|
||||
|
||||
# Retrieve compiler definitions, include paths, and options
|
||||
get_directory_property(COMPILE_DEFINITIONS COMPILE_DEFINITIONS)
|
||||
get_directory_property(INCLUDE_DIRECTORIES INCLUDE_DIRECTORIES)
|
||||
get_directory_property(COMPILE_OPTIONS COMPILE_OPTIONS)
|
||||
|
||||
# Initialize the final compiler argument list
|
||||
set(COMPILER_ARGUMENTS "")
|
||||
list(APPEND COMPILER_ARGUMENTS ${COMPILER_FLAGS} ${BUILD_TYPE_SPECIFIC_FLAGS})
|
||||
|
||||
# Transform definitions into MSVC-style
|
||||
foreach(DEFINITION ${COMPILE_DEFINITIONS})
|
||||
list(APPEND COMPILER_ARGUMENTS "/D${DEFINITION}")
|
||||
endforeach()
|
||||
|
||||
# Transform include paths into MSVC-style
|
||||
foreach(INCLUDE_PATH ${INCLUDE_DIRECTORIES})
|
||||
list(APPEND COMPILER_ARGUMENTS "/I${INCLUDE_PATH}")
|
||||
endforeach()
|
||||
|
||||
# Append all supplemental compiler options
|
||||
list(APPEND COMPILER_ARGUMENTS ${COMPILE_OPTIONS})
|
||||
set(COLLECTED_ASSEMBLY_OUTPUTS "")
|
||||
|
||||
# Iterate through each source file to create individual assembly generation rules
|
||||
foreach(SOURCE_FILE_PATH ${SOURCE_FILES})
|
||||
# Extract the base filename
|
||||
get_filename_component(FILENAME_WITHOUT_EXTENSION "${SOURCE_FILE_PATH}" NAME_WE)
|
||||
|
||||
# Define the unique output path for the intermediate assembly file
|
||||
set(CURRENT_ASSEMBLY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FILENAME_WITHOUT_EXTENSION}.S")
|
||||
list(APPEND COLLECTED_ASSEMBLY_OUTPUTS "${CURRENT_ASSEMBLY_OUTPUT}")
|
||||
get_filename_component(CURRENT_ASSEMBLY_DIRECTORY "${CURRENT_ASSEMBLY_OUTPUT}" DIRECTORY)
|
||||
|
||||
# Execute the compiler to generate assembly code
|
||||
add_custom_command(
|
||||
OUTPUT "${CURRENT_ASSEMBLY_OUTPUT}"
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${CURRENT_ASSEMBLY_DIRECTORY}"
|
||||
COMMAND ${CMAKE_CXX_COMPILER}
|
||||
${COMPILER_ARGUMENTS}
|
||||
/c /FAs /Fa${CURRENT_ASSEMBLY_OUTPUT}
|
||||
-- ${SOURCE_FILE_PATH}
|
||||
DEPENDS "${SOURCE_FILE_PATH}"
|
||||
COMMENT "Generating XTADK Assembly: ${FILENAME_WITHOUT_EXTENSION}"
|
||||
VERBATIM
|
||||
COMMAND_EXPAND_LISTS
|
||||
)
|
||||
endforeach()
|
||||
|
||||
# Aggregate all generated assembly units into a single consolidated XTADK header
|
||||
add_custom_command(
|
||||
OUTPUT "${HEADER_OUTPUT}"
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${HEADER_OUTPUT_DIRECTORY}"
|
||||
COMMAND xtadkgen ${COLLECTED_ASSEMBLY_OUTPUTS} -O "${HEADER_OUTPUT}"
|
||||
DEPENDS ${COLLECTED_ASSEMBLY_OUTPUTS}
|
||||
COMMENT "Generating XTADK header: ${TARGET_NAME}"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# Establish the generation target and expose the header directory via an interface library
|
||||
add_custom_target(${TARGET_NAME}_gen DEPENDS "${HEADER_OUTPUT}")
|
||||
add_library(${TARGET_NAME} INTERFACE)
|
||||
add_dependencies(${TARGET_NAME} ${TARGET_NAME}_gen)
|
||||
target_include_directories(${TARGET_NAME} INTERFACE "${EXECTOS_BINARY_DIR}/sdk/includes")
|
||||
endfunction()
|
||||
|
||||
# This function compiles an assembly bootsector file into a flat binary
|
||||
function(compile_bootsector NAME SOURCE BASEADDR ENTRYPOINT)
|
||||
set(BINARY_NAME "${NAME}.bin")
|
||||
|
||||
@@ -13,6 +13,10 @@ The ovmf_vars files, store UEFI variables, which are used to store and retrieve
|
||||
boot options, device settings, and system preferences. The ovmf_vars file contains the persistent variables specific to
|
||||
a virtual machine, allowing it to maintain its configuration across multiple boot sessions.
|
||||
|
||||
## BOCHS ROM BIOS
|
||||
The rombios.bin file contains the ROM BIOS image for Bochs. This image is distributed under the GNU Lesser General Public
|
||||
License (LGPL).
|
||||
|
||||
## Video BIOS (LGPL'd VGABios)
|
||||
The vgabios.bin file contains the Video Bios for Bochs and QEMU. This VGA Bios is very specific to the emulated VGA card.
|
||||
It is NOT meant to drive a physical vga card. It also implements support for VBE version 2.0.
|
||||
|
||||
14
sdk/xtadk/CMakeLists.txt
Normal file
14
sdk/xtadk/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
# XT Assembly Development Kit
|
||||
PROJECT(XTADK)
|
||||
|
||||
# Specify include directories
|
||||
include_directories(
|
||||
${EXECTOS_SOURCE_DIR}/sdk/xtdk
|
||||
${XTADK_SOURCE_DIR}/includes)
|
||||
|
||||
# Specify list of XTADK source code files
|
||||
list(APPEND XTADK_SOURCE
|
||||
${XTADK_SOURCE_DIR}/${ARCH}/ke.cc)
|
||||
|
||||
# Generate assembly header from XTADK sources
|
||||
generate_xtadk(xtadk "${XTADK_SOURCE}")
|
||||
83
sdk/xtadk/amd64/ke.cc
Normal file
83
sdk/xtadk/amd64/ke.cc
Normal file
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: sdk/xtadk/amd64/ke.cc
|
||||
* DESCRIPTION: ADK generator for AMD64 version of Kernel Library
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtkmapi.h>
|
||||
#include <adkdefs.h>
|
||||
|
||||
|
||||
/**
|
||||
* Generates a definitions file for the Kernel Library used by the XTOS kernel assembly code
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCLINK
|
||||
XTAPI
|
||||
VOID
|
||||
GenerateAssemblyDefinitions(VOID)
|
||||
{
|
||||
/* Generate KTRAP_FRAME offsets */
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm0);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm1);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm2);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm3);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm4);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm5);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm6);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm7);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm8);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm9);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm10);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm11);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm12);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm13);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm14);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm15);
|
||||
ADK_OFFSET(KTRAP_FRAME, MxCsr);
|
||||
ADK_OFFSET(KTRAP_FRAME, PreviousMode);
|
||||
ADK_OFFSET(KTRAP_FRAME, Cr2);
|
||||
ADK_OFFSET(KTRAP_FRAME, Cr3);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr0);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr1);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr2);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr3);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr6);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr7);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegDs);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegEs);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegFs);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegGs);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rax);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rbx);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rcx);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rdx);
|
||||
ADK_OFFSET(KTRAP_FRAME, R8);
|
||||
ADK_OFFSET(KTRAP_FRAME, R9);
|
||||
ADK_OFFSET(KTRAP_FRAME, R10);
|
||||
ADK_OFFSET(KTRAP_FRAME, R11);
|
||||
ADK_OFFSET(KTRAP_FRAME, R12);
|
||||
ADK_OFFSET(KTRAP_FRAME, R13);
|
||||
ADK_OFFSET(KTRAP_FRAME, R14);
|
||||
ADK_OFFSET(KTRAP_FRAME, R15);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rsi);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rdi);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rbp);
|
||||
ADK_OFFSET(KTRAP_FRAME, Vector);
|
||||
ADK_OFFSET(KTRAP_FRAME, ErrorCode);
|
||||
ADK_OFFSET(KTRAP_FRAME, ExceptionFrame);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rip);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegCs);
|
||||
ADK_OFFSET(KTRAP_FRAME, Flags);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rsp);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegSs);
|
||||
|
||||
/* Generate KTRAP_FRAME size and REGISTERS_SIZE */
|
||||
ADK_SIZE(KTRAP_FRAME);
|
||||
ADK_SIZE_FROM(REGISTERS_SIZE, KTRAP_FRAME, Rax);
|
||||
}
|
||||
57
sdk/xtadk/i686/ke.cc
Normal file
57
sdk/xtadk/i686/ke.cc
Normal file
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: sdk/xtadk/i686/ke.cc
|
||||
* DESCRIPTION: ADK generator for i686 version of Kernel Library
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtkmapi.h>
|
||||
#include <adkdefs.h>
|
||||
|
||||
|
||||
/**
|
||||
* Generates a definitions file for the Kernel Library used by the XTOS kernel assembly code
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCLINK
|
||||
XTAPI
|
||||
VOID
|
||||
GenerateAssemblyDefinitions(VOID)
|
||||
{
|
||||
/* Generate KTRAP_FRAME offsets */
|
||||
ADK_OFFSET(KTRAP_FRAME, PreviousMode);
|
||||
ADK_OFFSET(KTRAP_FRAME, Cr2);
|
||||
ADK_OFFSET(KTRAP_FRAME, Cr3);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr0);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr1);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr2);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr3);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr6);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr7);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegDs);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegEs);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegFs);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegGs);
|
||||
ADK_OFFSET(KTRAP_FRAME, Eax);
|
||||
ADK_OFFSET(KTRAP_FRAME, Ebx);
|
||||
ADK_OFFSET(KTRAP_FRAME, Ecx);
|
||||
ADK_OFFSET(KTRAP_FRAME, Edx);
|
||||
ADK_OFFSET(KTRAP_FRAME, Esi);
|
||||
ADK_OFFSET(KTRAP_FRAME, Edi);
|
||||
ADK_OFFSET(KTRAP_FRAME, Ebp);
|
||||
ADK_OFFSET(KTRAP_FRAME, Vector);
|
||||
ADK_OFFSET(KTRAP_FRAME, ErrorCode);
|
||||
ADK_OFFSET(KTRAP_FRAME, Eip);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegCs);
|
||||
ADK_OFFSET(KTRAP_FRAME, Flags);
|
||||
ADK_OFFSET(KTRAP_FRAME, Esp);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegSs);
|
||||
|
||||
/* Generate KTRAP_FRAME size and REGISTERS_SIZE */
|
||||
ADK_SIZE(KTRAP_FRAME);
|
||||
ADK_SIZE_FROM(REGISTERS_SIZE, KTRAP_FRAME, Eax);
|
||||
}
|
||||
19
sdk/xtadk/includes/adkdefs.h
Normal file
19
sdk/xtadk/includes/adkdefs.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: sdk/xtadk/adkdefs.h
|
||||
* DESCRIPTION: Definitions for XTADK
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTADK_ADKDEFS_H
|
||||
#define __XTADK_ADKDEFS_H
|
||||
|
||||
|
||||
/* Macros for calculating structure size and offsets for assembler code */
|
||||
#define ADK_DEFINE(Symbol, Value) __asm__ volatile("\n\t# ==> " #Symbol " %c0" : : "i" ((SIZE_T)(Value)))
|
||||
#define ADK_OFFSET(Structure, Member) ADK_DEFINE(Structure ## _ ## Member, FIELD_OFFSET(Structure, Member))
|
||||
#define ADK_SIZE(Structure) ADK_DEFINE(Structure ## _SIZE, sizeof(Structure))
|
||||
#define ADK_SIZE_FROM(Name, Structure, Member) ADK_DEFINE(Structure ## _ ## Name, sizeof(Structure) - FIELD_OFFSET(Structure, Member))
|
||||
|
||||
#endif /* __XTADK_ADKDEFS_H */
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <xtdefs.h>
|
||||
#include <xtstruct.h>
|
||||
#include <xttypes.h>
|
||||
#include ARCH_HEADER(xtstruct.h)
|
||||
|
||||
|
||||
/* Control Register 0 constants */
|
||||
@@ -127,6 +128,10 @@
|
||||
#define X86_EFLAGS_VIP_MASK 0x00100000 /* Virtual Interrupt Pending */
|
||||
#define X86_EFLAGS_ID_MASK 0x00200000 /* Identification */
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* CPU vendor enumeration list */
|
||||
typedef enum _CPU_VENDOR
|
||||
{
|
||||
@@ -135,6 +140,18 @@ typedef enum _CPU_VENDOR
|
||||
CPU_VENDOR_UNKNOWN = 0xFFFFFFFF
|
||||
} CPU_VENDOR, *PCPU_VENDOR;
|
||||
|
||||
/* CPUID advanced power management features (0x80000007) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT
|
||||
{
|
||||
CPUID_FEATURES_EDX_TS = 1 << 0, /* Temperature Sensor */
|
||||
CPUID_FEATURES_EDX_FIS = 1 << 1, /* Frequency ID Selection */
|
||||
CPUID_FEATURES_EDX_VIS = 1 << 2, /* Voltage ID Selection */
|
||||
CPUID_FEATURES_EDX_TTS = 1 << 3, /* ThermaTrip Support */
|
||||
CPUID_FEATURES_EDX_HTC = 1 << 4, /* Hardware Thermal Throttling */
|
||||
CPUID_FEATURES_EDX_STC = 1 << 5, /* Software Thermal Throttling */
|
||||
CPUID_FEATURES_EDX_TSCI = 1 << 8 /* TSC Invariant */
|
||||
} CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT, *PCPUID_FEATURES_ADVANCED_POWER_MANAGEMENT;
|
||||
|
||||
/* CPUID extended features (0x80000001) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_EXTENDED
|
||||
{
|
||||
@@ -176,6 +193,23 @@ typedef enum _CPUID_FEATURES_EXTENDED
|
||||
CPUID_FEATURES_EDX_3DNOW = 1 << 31
|
||||
} CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
|
||||
|
||||
/* CPUID Thermal and Power Management features (0x00000006) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_POWER_MANAGEMENT
|
||||
{
|
||||
CPUID_FEATURES_EAX_DTHERM = 1 << 0,
|
||||
CPUID_FEATURES_EAX_IDA = 1 << 1,
|
||||
CPUID_FEATURES_EAX_ARAT = 1 << 2,
|
||||
CPUID_FEATURES_EAX_PLN = 1 << 4,
|
||||
CPUID_FEATURES_EAX_PTS = 1 << 6,
|
||||
CPUID_FEATURES_EAX_HWP = 1 << 7,
|
||||
CPUID_FEATURES_EAX_HWP_NOTIFY = 1 << 8,
|
||||
CPUID_FEATURES_EAX_HWP_ACT_WINDOW = 1 << 9,
|
||||
CPUID_FEATURES_EAX_HWP_EPP = 1 << 10,
|
||||
CPUID_FEATURES_EAX_HWP_PKG_REQ = 1 << 11,
|
||||
CPUID_FEATURES_EAX_HWP_HIGHEST_PERF_CHANGE = 1 << 15,
|
||||
CPUID_FEATURES_EAX_HFI = 1 << 19
|
||||
} CPUID_FEATURES_LEAF6, *PCPUID_FEATURES_LEAF6;
|
||||
|
||||
/* CPUID STD1 features (0x00000001) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_STANDARD1
|
||||
{
|
||||
@@ -202,7 +236,7 @@ typedef enum _CPUID_FEATURES_STANDARD1
|
||||
CPUID_FEATURES_ECX_X2APIC = 1 << 21,
|
||||
CPUID_FEATURES_ECX_MOVBE = 1 << 22,
|
||||
CPUID_FEATURES_ECX_POPCNT = 1 << 23,
|
||||
CPUID_FEATURES_ECX_TSC = 1 << 24,
|
||||
CPUID_FEATURES_ECX_TSC_DEADLINE = 1 << 24,
|
||||
CPUID_FEATURES_ECX_AES = 1 << 25,
|
||||
CPUID_FEATURES_ECX_XSAVE = 1 << 26,
|
||||
CPUID_FEATURES_ECX_OSXSAVE = 1 << 27,
|
||||
@@ -376,16 +410,23 @@ typedef enum _CPUID_FEATURES_STANDARD7_LEAF1
|
||||
/* CPUID requests */
|
||||
typedef enum _CPUID_REQUESTS
|
||||
{
|
||||
CPUID_GET_VENDOR_STRING,
|
||||
CPUID_GET_STANDARD1_FEATURES,
|
||||
CPUID_GET_TLB_CACHE,
|
||||
CPUID_GET_SERIAL,
|
||||
CPUID_GET_CACHE_TOPOLOGY,
|
||||
CPUID_GET_MONITOR_MWAIT,
|
||||
CPUID_GET_POWER_MANAGEMENT,
|
||||
CPUID_GET_STANDARD7_FEATURES
|
||||
CPUID_GET_VENDOR_STRING = 0x00000000,
|
||||
CPUID_GET_STANDARD1_FEATURES = 0x00000001,
|
||||
CPUID_GET_TLB_CACHE = 0x00000002,
|
||||
CPUID_GET_SERIAL = 0x00000003,
|
||||
CPUID_GET_CACHE_TOPOLOGY = 0x00000004,
|
||||
CPUID_GET_MONITOR_MWAIT = 0x00000005,
|
||||
CPUID_GET_POWER_MANAGEMENT = 0x00000006,
|
||||
CPUID_GET_STANDARD7_FEATURES = 0x00000007,
|
||||
CPUID_GET_TSC_CRYSTAL_CLOCK = 0x00000015,
|
||||
CPUID_GET_EXTENDED_MAX = 0x80000000,
|
||||
CPUID_GET_EXTENDED_FEATURES = 0x80000001,
|
||||
CPUID_GET_ADVANCED_POWER_MANAGEMENT = 0x80000007
|
||||
} CPUID_REQUESTS, *PCPUID_REQUESTS;
|
||||
|
||||
/* Interrupt handler */
|
||||
typedef VOID (*PINTERRUPT_HANDLER)(PKTRAP_FRAME TrapFrame);
|
||||
|
||||
/* Processor identification information */
|
||||
typedef struct _CPU_IDENTIFICATION
|
||||
{
|
||||
@@ -426,4 +467,5 @@ typedef enum _TRAMPOLINE_TYPE
|
||||
TrampolineEnableXpa
|
||||
} TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_AMD64_ARTYPES_H */
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
#include <amd64/xtstruct.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Hardware layer routines forward references */
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
@@ -49,4 +52,5 @@ VOID
|
||||
HlWritePort32(IN USHORT Port,
|
||||
IN ULONG Value);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_AMD64_HLFUNCS_H */
|
||||
|
||||
@@ -62,6 +62,10 @@
|
||||
/* PIC vector definitions */
|
||||
#define PIC1_VECTOR_SPURIOUS 0x37
|
||||
|
||||
/* PIT ports definitions */
|
||||
#define PIT_COMMAND_PORT 0x43
|
||||
#define PIT_DATA_PORT0 0x40
|
||||
|
||||
/* Serial ports information */
|
||||
#define COMPORT_ADDRESS {0x3F8, 0x2F8, 0x3E8, 0x2E8, 0x5F8, 0x4F8, 0x5E8, 0x4E8}
|
||||
#define COMPORT_COUNT 8
|
||||
@@ -69,6 +73,10 @@
|
||||
/* Initial stall factor */
|
||||
#define INITIAL_STALL_FACTOR 100
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* APIC delivery mode enumeration list */
|
||||
typedef enum _APIC_DM
|
||||
{
|
||||
@@ -126,6 +134,7 @@ typedef enum _APIC_REGISTER
|
||||
APIC_TICR = 0x38, /* Initial Count Register for Timer */
|
||||
APIC_TCCR = 0x39, /* Current Count Register for Timer */
|
||||
APIC_TDCR = 0x3E, /* Timer Divide Configuration Register */
|
||||
APIC_SIPI = 0x3F, /* Self-IPI Register */
|
||||
APIC_EAFR = 0x40, /* extended APIC Feature register */
|
||||
APIC_EACR = 0x41, /* Extended APIC Control Register */
|
||||
APIC_SEOI = 0x42, /* Specific End Of Interrupt Register */
|
||||
@@ -135,6 +144,19 @@ typedef enum _APIC_REGISTER
|
||||
APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */
|
||||
} APIC_REGISTER, *PAPIC_REGISTER;
|
||||
|
||||
/* APIC Timer Divide enumeration list */
|
||||
typedef enum _APIC_TIMER_DIVISOR
|
||||
{
|
||||
TIMER_DivideBy2 = 0,
|
||||
TIMER_DivideBy4 = 1,
|
||||
TIMER_DivideBy8 = 2,
|
||||
TIMER_DivideBy16 = 3,
|
||||
TIMER_DivideBy32 = 8,
|
||||
TIMER_DivideBy64 = 9,
|
||||
TIMER_DivideBy128 = 10,
|
||||
TIMER_DivideBy1 = 11,
|
||||
} APIC_TIMER_DIVISOR, *PAPIC_TIMER_DIVISOR;
|
||||
|
||||
/* I8259 PIC interrupt mode enumeration list */
|
||||
typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE
|
||||
{
|
||||
@@ -317,4 +339,17 @@ typedef union _PIC_I8259_ICW4
|
||||
UCHAR Bits;
|
||||
} PIC_I8259_ICW4, *PPIC_I8259_ICW4;
|
||||
|
||||
typedef struct _TIMER_CAPABILITIES
|
||||
{
|
||||
BOOLEAN Arat;
|
||||
BOOLEAN Art;
|
||||
BOOLEAN InvariantTsc;
|
||||
BOOLEAN RDTSCP;
|
||||
ULONG TimerFrequency;
|
||||
BOOLEAN TscDeadline;
|
||||
ULONG TscDenominator;
|
||||
ULONG TscNumerator;
|
||||
} TIMER_CAPABILITIES, *PTIMER_CAPABILITIES;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_AMD64_HLTYPES_H */
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
/* GDT selector names */
|
||||
#define KGDT_NULL 0x0000
|
||||
#define KGDT_R0_CMCODE 0x0008
|
||||
#define KGDT_R0_CODE 0x0010
|
||||
#define KGDT_R0_DATA 0x0018
|
||||
#define KGDT_R3_CMCODE 0x0020
|
||||
@@ -46,7 +47,7 @@
|
||||
#define KGDT_DESCRIPTOR_CODE 0x08
|
||||
|
||||
/* GDT descriptor type codes */
|
||||
#define KGDT_TYPE_NONE 0x0
|
||||
#define KGDT_TYPE_NONE 0x00
|
||||
#define KGDT_TYPE_CODE (0x10 | KGDT_DESCRIPTOR_CODE | KGDT_DESCRIPTOR_EXECUTE_READ)
|
||||
#define KGDT_TYPE_DATA (0x10 | KGDT_DESCRIPTOR_READ_WRITE)
|
||||
|
||||
@@ -58,6 +59,7 @@
|
||||
#define KIDT_IST_RESERVED 0
|
||||
#define KIDT_IST_PANIC 1
|
||||
#define KIDT_IST_MCA 2
|
||||
#define KIDT_IST_NMI 3
|
||||
|
||||
/* AMD64 Segment Types */
|
||||
#define AMD64_TASK_GATE 0x5
|
||||
@@ -110,6 +112,7 @@
|
||||
|
||||
/* XTOS Kernel stack size */
|
||||
#define KERNEL_STACK_SIZE 0x8000
|
||||
#define KERNEL_STACKS 3
|
||||
|
||||
/* XTOS Kernel stack guard pages */
|
||||
#define KERNEL_STACK_GUARD_PAGES 1
|
||||
@@ -135,6 +138,10 @@
|
||||
#define NPX_STATE_SCRUB 0x1
|
||||
#define NPX_STATE_SWITCH 0x2
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Floating point state storing structure */
|
||||
typedef struct _FLOATING_SAVE_AREA
|
||||
{
|
||||
@@ -516,6 +523,7 @@ typedef struct _KPROCESSOR_BLOCK
|
||||
KAFFINITY SetMember;
|
||||
ULONG StallScaleFactor;
|
||||
UCHAR CpuNumber;
|
||||
PINTERRUPT_HANDLER InterruptDispatchTable[256];
|
||||
} KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK;
|
||||
|
||||
/* Thread Environment Block (TEB) structure definition */
|
||||
@@ -524,4 +532,5 @@ typedef struct _THREAD_ENVIRONMENT_BLOCK
|
||||
THREAD_INFORMATION_BLOCK InformationBlock;
|
||||
} THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_AMD64_KETYPES_H */
|
||||
|
||||
@@ -119,6 +119,10 @@
|
||||
/* Number of pool tracking tables */
|
||||
#define MM_POOL_TRACKING_TABLES 64
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Page size enumeration list */
|
||||
typedef enum _PAGE_SIZE
|
||||
{
|
||||
@@ -344,4 +348,5 @@ typedef struct _POOL_DESCRIPTOR
|
||||
SIZE_T Reserved;
|
||||
} POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_AMD64_MMTYPES_H */
|
||||
|
||||
@@ -12,13 +12,19 @@
|
||||
#include <xtdefs.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Architecture-specific enumeration lists forward references */
|
||||
typedef enum _APIC_DM APIC_DM, *PAPIC_DM;
|
||||
typedef enum _APIC_DSH APIC_DSH, *PAPIC_DSH;
|
||||
typedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE;
|
||||
typedef enum _APIC_REGISTER APIC_REGISTER, *PAPIC_REGISTER;
|
||||
typedef enum _APIC_TIMER_DIVISOR APIC_TIMER_DIVISOR, *PAPIC_TIMER_DIVISOR;
|
||||
typedef enum _CPU_VENDOR CPU_VENDOR, *PCPU_VENDOR;
|
||||
typedef enum _CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT, *PCPUID_FEATURES_ADVANCED_POWER_MANAGEMENT;
|
||||
typedef enum _CPUID_FEATURES_EXTENDED CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
|
||||
typedef enum _CPUID_FEATURES_POWER_MANAGEMENT CPUID_FEATURES_POWER_MANAGEMENT, *PCPUID_FEATURES_POWER_MANAGEMENT;
|
||||
typedef enum _CPUID_FEATURES_STANDARD1 CPUID_FEATURES_STANDARD1, *PCPUID_FEATURES_STANDARD1;
|
||||
typedef enum _CPUID_FEATURES_STANDARD7_LEAF0 CPUID_FEATURES_STANDARD7_LEAF0, *PCPUID_FEATURES_STANDARD7_LEAF0;
|
||||
typedef enum _CPUID_FEATURES_STANDARD7_LEAF1 CPUID_FEATURES_STANDARD7_LEAF1, *PCPUID_FEATURES_STANDARD7_LEAF1;
|
||||
@@ -63,6 +69,7 @@ typedef struct _MMPTE_SUBSECTION MMPTE_SUBSECTION, *PMMPTE_SUBSECTION;
|
||||
typedef struct _MMPTE_TRANSITION MMPTE_TRANSITION, *PMMPTE_TRANSITION;
|
||||
typedef struct _POOL_DESCRIPTOR POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
||||
typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
||||
typedef struct _TIMER_CAPABILITIES TIMER_CAPABILITIES, *PTIMER_CAPABILITIES;
|
||||
|
||||
/* Unions forward references */
|
||||
typedef union _APIC_BASE_REGISTER APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER;
|
||||
@@ -79,4 +86,5 @@ typedef union _PIC_I8259_ICW2 PIC_I8259_ICW2, *PPIC_I8259_ICW2;
|
||||
typedef union _PIC_I8259_ICW3 PIC_I8259_ICW3, *PPIC_I8259_ICW3;
|
||||
typedef union _PIC_I8259_ICW4 PIC_I8259_ICW4, *PPIC_I8259_ICW4;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_AMD64_XTSTRUCT_H */
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
#include <xtuefi.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef D__XTOS_ASSEMBLER__
|
||||
|
||||
/* XT BootLoader routines forward references */
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
@@ -21,4 +24,5 @@ BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable,
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
OUT PXTBL_LOADER_PROTOCOL *ProtocolHandler);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_BLFUNCS_H */
|
||||
|
||||
@@ -41,6 +41,10 @@
|
||||
/* TUI dialog box maximum width */
|
||||
#define XTBL_TUI_MAX_DIALOG_WIDTH 100
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef D__XTOS_ASSEMBLER__
|
||||
|
||||
/* XTLDR Routine pointers */
|
||||
typedef LOADER_MEMORY_TYPE (XTCDECL *PBL_GET_MEMTYPE_ROUTINE)(IN EFI_MEMORY_TYPE EfiMemoryType);
|
||||
|
||||
@@ -520,4 +524,5 @@ typedef struct _XTBL_LOADER_PROTOCOL
|
||||
} WideString;
|
||||
} XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_BLTYPES_H */
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
#include <xttypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Kernel Executive routines forward references */
|
||||
XTCLINK
|
||||
XTFASTCALL
|
||||
@@ -44,4 +47,5 @@ XTFASTCALL
|
||||
VOID
|
||||
ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_EXFUNCS_H */
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
/* Rundown protection flags */
|
||||
#define EX_RUNDOWN_ACTIVE 0x1
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Executive rundown protection structure definition */
|
||||
typedef struct _EX_RUNDOWN_REFERENCE
|
||||
{
|
||||
@@ -34,4 +38,5 @@ typedef struct _EX_RUNDOWN_WAIT_BLOCK
|
||||
KEVENT WakeEvent;
|
||||
} EX_RUNDOWN_WAIT_BLOCK, *PEX_RUNDOWN_WAIT_BLOCK;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_EXTYPES_H */
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
#include <xttypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Hardware layer routines forward references */
|
||||
XTCLINK
|
||||
XTAPI
|
||||
@@ -48,4 +51,5 @@ VOID
|
||||
HlWriteRegister32(IN PVOID Register,
|
||||
IN ULONG Value);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_HLFUNCS_H */
|
||||
|
||||
@@ -101,6 +101,12 @@
|
||||
#define ACPI_MADT_PLACE_ENABLED 0 /* Processor Local APIC CPU Enabled */
|
||||
#define ACPI_MADT_PLAOC_ENABLED 1 /* Processor Local APIC Online Capable */
|
||||
|
||||
/* ACPI address space definitions */
|
||||
#define ACPI_ADDRESS_SPACE_MEMORY 0x00
|
||||
|
||||
/* Maximum number of cached ACPI tables */
|
||||
#define ACPI_MAX_CACHED_TABLES 32
|
||||
|
||||
/* Default serial port settings */
|
||||
#define COMPORT_CLOCK_RATE 0x1C200
|
||||
#define COMPORT_WAIT_TIMEOUT 204800
|
||||
@@ -179,6 +185,14 @@
|
||||
#define COMPORT_REG_MSR 0x06 /* Modem Status Register */
|
||||
#define COMPORT_REG_SR 0x07 /* Scratch Register */
|
||||
|
||||
/* Minimum and maximum profile intervals */
|
||||
#define MIN_PROFILE_INTERVAL 1000
|
||||
#define MAX_PROFILE_INTERVAL 10000000
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Generic Address structure */
|
||||
typedef struct _GENERIC_ADDRESS
|
||||
{
|
||||
@@ -214,7 +228,7 @@ typedef struct _ACPI_SUBTABLE_HEADER
|
||||
typedef struct _ACPI_CACHE_LIST
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
ACPI_DESCRIPTION_HEADER Header;
|
||||
PACPI_DESCRIPTION_HEADER Table;
|
||||
} ACPI_CACHE_LIST, *PACPI_CACHE_LIST;
|
||||
|
||||
/* ACPI Root System Description Table Pointer (RSDP) structure */
|
||||
@@ -450,4 +464,5 @@ typedef struct _SMBIOS3_TABLE_HEADER
|
||||
ULONGLONG TableAddress;
|
||||
} SMBIOS3_TABLE_HEADER, *PSMBIOS3_TABLE_HEADER;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_HLTYPES_H */
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <xtdefs.h>
|
||||
#include <xtstruct.h>
|
||||
#include <xttypes.h>
|
||||
#include ARCH_HEADER(xtstruct.h)
|
||||
|
||||
|
||||
/* Control Register 0 constants */
|
||||
@@ -92,6 +93,10 @@
|
||||
#define X86_EFLAGS_VIP_MASK 0x00100000 /* Virtual Interrupt Pending */
|
||||
#define X86_EFLAGS_ID_MASK 0x00200000 /* Identification */
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* CPU vendor enumeration list */
|
||||
typedef enum _CPU_VENDOR
|
||||
{
|
||||
@@ -100,6 +105,18 @@ typedef enum _CPU_VENDOR
|
||||
CPU_VENDOR_UNKNOWN = 0xFFFFFFFF
|
||||
} CPU_VENDOR, *PCPU_VENDOR;
|
||||
|
||||
/* CPUID advanced power management features (0x80000007) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT
|
||||
{
|
||||
CPUID_FEATURES_EDX_TS = 1 << 0, /* Temperature Sensor */
|
||||
CPUID_FEATURES_EDX_FIS = 1 << 1, /* Frequency ID Selection */
|
||||
CPUID_FEATURES_EDX_VIS = 1 << 2, /* Voltage ID Selection */
|
||||
CPUID_FEATURES_EDX_TTS = 1 << 3, /* ThermaTrip Support */
|
||||
CPUID_FEATURES_EDX_HTC = 1 << 4, /* Hardware Thermal Throttling */
|
||||
CPUID_FEATURES_EDX_STC = 1 << 5, /* Software Thermal Throttling */
|
||||
CPUID_FEATURES_EDX_TSCI = 1 << 8 /* TSC Invariant */
|
||||
} CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT, *PCPUID_FEATURES_ADVANCED_POWER_MANAGEMENT;
|
||||
|
||||
/* CPUID extended features (0x80000001) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_EXTENDED
|
||||
{
|
||||
@@ -141,6 +158,23 @@ typedef enum _CPUID_FEATURES_EXTENDED
|
||||
CPUID_FEATURES_EDX_3DNOW = 1 << 31
|
||||
} CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
|
||||
|
||||
/* CPUID Thermal and Power Management features (0x00000006) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_POWER_MANAGEMENT
|
||||
{
|
||||
CPUID_FEATURES_EAX_DTHERM = 1 << 0,
|
||||
CPUID_FEATURES_EAX_IDA = 1 << 1,
|
||||
CPUID_FEATURES_EAX_ARAT = 1 << 2,
|
||||
CPUID_FEATURES_EAX_PLN = 1 << 4,
|
||||
CPUID_FEATURES_EAX_PTS = 1 << 6,
|
||||
CPUID_FEATURES_EAX_HWP = 1 << 7,
|
||||
CPUID_FEATURES_EAX_HWP_NOTIFY = 1 << 8,
|
||||
CPUID_FEATURES_EAX_HWP_ACT_WINDOW = 1 << 9,
|
||||
CPUID_FEATURES_EAX_HWP_EPP = 1 << 10,
|
||||
CPUID_FEATURES_EAX_HWP_PKG_REQ = 1 << 11,
|
||||
CPUID_FEATURES_EAX_HWP_HIGHEST_PERF_CHANGE = 1 << 15,
|
||||
CPUID_FEATURES_EAX_HFI = 1 << 19
|
||||
} CPUID_FEATURES_LEAF6, *PCPUID_FEATURES_LEAF6;
|
||||
|
||||
/* CPUID STD1 features (0x00000001) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_STANDARD1
|
||||
{
|
||||
@@ -167,7 +201,7 @@ typedef enum _CPUID_FEATURES_STANDARD1
|
||||
CPUID_FEATURES_ECX_X2APIC = 1 << 21,
|
||||
CPUID_FEATURES_ECX_MOVBE = 1 << 22,
|
||||
CPUID_FEATURES_ECX_POPCNT = 1 << 23,
|
||||
CPUID_FEATURES_ECX_TSC = 1 << 24,
|
||||
CPUID_FEATURES_ECX_TSC_DEADLINE = 1 << 24,
|
||||
CPUID_FEATURES_ECX_AES = 1 << 25,
|
||||
CPUID_FEATURES_ECX_XSAVE = 1 << 26,
|
||||
CPUID_FEATURES_ECX_OSXSAVE = 1 << 27,
|
||||
@@ -341,16 +375,23 @@ typedef enum _CPUID_FEATURES_STANDARD7_LEAF1
|
||||
/* CPUID requests */
|
||||
typedef enum _CPUID_REQUESTS
|
||||
{
|
||||
CPUID_GET_VENDOR_STRING,
|
||||
CPUID_GET_STANDARD1_FEATURES,
|
||||
CPUID_GET_TLB_CACHE,
|
||||
CPUID_GET_SERIAL,
|
||||
CPUID_GET_CACHE_TOPOLOGY,
|
||||
CPUID_GET_MONITOR_MWAIT,
|
||||
CPUID_GET_POWER_MANAGEMENT,
|
||||
CPUID_GET_STANDARD7_FEATURES
|
||||
CPUID_GET_VENDOR_STRING = 0x00000000,
|
||||
CPUID_GET_STANDARD1_FEATURES = 0x00000001,
|
||||
CPUID_GET_TLB_CACHE = 0x00000002,
|
||||
CPUID_GET_SERIAL = 0x00000003,
|
||||
CPUID_GET_CACHE_TOPOLOGY = 0x00000004,
|
||||
CPUID_GET_MONITOR_MWAIT = 0x00000005,
|
||||
CPUID_GET_POWER_MANAGEMENT = 0x00000006,
|
||||
CPUID_GET_STANDARD7_FEATURES = 0x00000007,
|
||||
CPUID_GET_TSC_CRYSTAL_CLOCK = 0x00000015,
|
||||
CPUID_GET_EXTENDED_MAX = 0x80000000,
|
||||
CPUID_GET_EXTENDED_FEATURES = 0x80000001,
|
||||
CPUID_GET_ADVANCED_POWER_MANAGEMENT = 0x80000007
|
||||
} CPUID_REQUESTS, *PCPUID_REQUESTS;
|
||||
|
||||
/* Interrupt handler */
|
||||
typedef VOID (*PINTERRUPT_HANDLER)(PKTRAP_FRAME TrapFrame);
|
||||
|
||||
/* Processor identification information */
|
||||
typedef struct _CPU_IDENTIFICATION
|
||||
{
|
||||
@@ -390,4 +431,5 @@ typedef enum _TRAMPOLINE_TYPE
|
||||
TrampolineApStartup
|
||||
} TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_I686_ARTYPES_H */
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
#include <i686/xtstruct.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Hardware layer routines forward references */
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
@@ -49,4 +52,5 @@ VOID
|
||||
HlWritePort32(IN USHORT Port,
|
||||
IN ULONG Value);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_I686_HLFUNCS_H */
|
||||
|
||||
@@ -69,6 +69,10 @@
|
||||
/* PIC vector definitions */
|
||||
#define PIC1_VECTOR_SPURIOUS 0x37
|
||||
|
||||
/* PIT ports definitions */
|
||||
#define PIT_COMMAND_PORT 0x43
|
||||
#define PIT_DATA_PORT0 0x40
|
||||
|
||||
/* Serial ports information */
|
||||
#define COMPORT_ADDRESS {0x3F8, 0x2F8, 0x3E8, 0x2E8, 0x5F8, 0x4F8, 0x5E8, 0x4E8}
|
||||
#define COMPORT_COUNT 8
|
||||
@@ -76,6 +80,10 @@
|
||||
/* Initial stall factor */
|
||||
#define INITIAL_STALL_FACTOR 100
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* APIC delivery mode enumeration list */
|
||||
typedef enum _APIC_DM
|
||||
{
|
||||
@@ -133,6 +141,7 @@ typedef enum _APIC_REGISTER
|
||||
APIC_TICR = 0x38, /* Initial Count Register for Timer */
|
||||
APIC_TCCR = 0x39, /* Current Count Register for Timer */
|
||||
APIC_TDCR = 0x3E, /* Timer Divide Configuration Register */
|
||||
APIC_SIPI = 0x3F, /* Self-IPI Register */
|
||||
APIC_EAFR = 0x40, /* extended APIC Feature register */
|
||||
APIC_EACR = 0x41, /* Extended APIC Control Register */
|
||||
APIC_SEOI = 0x42, /* Specific End Of Interrupt Register */
|
||||
@@ -142,6 +151,19 @@ typedef enum _APIC_REGISTER
|
||||
APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */
|
||||
} APIC_REGISTER, *PAPIC_REGISTER;
|
||||
|
||||
/* APIC Timer Divide enumeration list */
|
||||
typedef enum _APIC_TIMER_DIVISOR
|
||||
{
|
||||
TIMER_DivideBy2 = 0,
|
||||
TIMER_DivideBy4 = 1,
|
||||
TIMER_DivideBy8 = 2,
|
||||
TIMER_DivideBy16 = 3,
|
||||
TIMER_DivideBy32 = 8,
|
||||
TIMER_DivideBy64 = 9,
|
||||
TIMER_DivideBy128 = 10,
|
||||
TIMER_DivideBy1 = 11,
|
||||
} APIC_TIMER_DIVISOR, *PAPIC_TIMER_DIVISOR;
|
||||
|
||||
/* I8259 PIC interrupt mode enumeration list */
|
||||
typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE
|
||||
{
|
||||
@@ -324,4 +346,18 @@ typedef union _PIC_I8259_ICW4
|
||||
UCHAR Bits;
|
||||
} PIC_I8259_ICW4, *PPIC_I8259_ICW4;
|
||||
|
||||
/* Timer Capabilities */
|
||||
typedef struct _TIMER_CAPABILITIES
|
||||
{
|
||||
BOOLEAN Arat;
|
||||
BOOLEAN Art;
|
||||
BOOLEAN InvariantTsc;
|
||||
BOOLEAN RDTSCP;
|
||||
ULONG TimerFrequency;
|
||||
BOOLEAN TscDeadline;
|
||||
ULONG TscDenominator;
|
||||
ULONG TscNumerator;
|
||||
} TIMER_CAPABILITIES, *PTIMER_CAPABILITIES;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_I686_HLTYPES_H */
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
#define KGDT_DESCRIPTOR_CODE 0x08
|
||||
|
||||
/* GDT descriptor type codes */
|
||||
#define KGDT_TYPE_NONE 0x0
|
||||
#define KGDT_TYPE_NONE 0x00
|
||||
#define KGDT_TYPE_CODE (0x10 | KGDT_DESCRIPTOR_CODE | KGDT_DESCRIPTOR_EXECUTE_READ)
|
||||
#define KGDT_TYPE_DATA (0x10 | KGDT_DESCRIPTOR_READ_WRITE)
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
#define KTSS_IO_MAPS 0x68
|
||||
|
||||
/* I686 Segment Types */
|
||||
#define I686_LDT 0x2
|
||||
#define I686_TASK_GATE 0x5
|
||||
#define I686_TSS 0x9
|
||||
#define I686_ACTIVE_TSS 0xB
|
||||
@@ -130,6 +131,7 @@
|
||||
|
||||
/* XTOS Kernel stack size */
|
||||
#define KERNEL_STACK_SIZE 0x4000
|
||||
#define KERNEL_STACKS 3
|
||||
|
||||
/* XTOS Kernel stack guard pages */
|
||||
#define KERNEL_STACK_GUARD_PAGES 1
|
||||
@@ -157,6 +159,10 @@
|
||||
#define NPX_STATE_LOADED 0x0
|
||||
#define NPX_STATE_UNLOADED 0xA
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Floating point state storing structure */
|
||||
typedef struct _FN_SAVE_FORMAT
|
||||
{
|
||||
@@ -472,6 +478,7 @@ typedef struct _KPROCESSOR_BLOCK
|
||||
KAFFINITY SetMember;
|
||||
ULONG StallScaleFactor;
|
||||
UCHAR CpuNumber;
|
||||
PINTERRUPT_HANDLER InterruptDispatchTable[256];
|
||||
} KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK;
|
||||
|
||||
/* Thread Environment Block (TEB) structure definition */
|
||||
@@ -480,4 +487,5 @@ typedef struct _THREAD_ENVIRONMENT_BLOCK
|
||||
THREAD_INFORMATION_BLOCK InformationBlock;
|
||||
} THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_I686_KETYPES_H */
|
||||
|
||||
@@ -117,6 +117,10 @@
|
||||
/* Number of pool tracking tables */
|
||||
#define MM_POOL_TRACKING_TABLES 32
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Page size enumeration list */
|
||||
typedef enum _PAGE_SIZE
|
||||
{
|
||||
@@ -437,4 +441,5 @@ typedef struct _POOL_DESCRIPTOR
|
||||
SIZE_T Reserved;
|
||||
} POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_I686_MMTYPES_H */
|
||||
|
||||
@@ -12,13 +12,19 @@
|
||||
#include <xtdefs.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Architecture-specific enumeration lists forward references */
|
||||
typedef enum _APIC_DM APIC_DM, *PAPIC_DM;
|
||||
typedef enum _APIC_DSH APIC_DSH, *PAPIC_DSH;
|
||||
typedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE;
|
||||
typedef enum _APIC_REGISTER APIC_REGISTER, *PAPIC_REGISTER;
|
||||
typedef enum _APIC_TIMER_DIVISOR APIC_TIMER_DIVISOR, *PAPIC_TIMER_DIVISOR;
|
||||
typedef enum _CPU_VENDOR CPU_VENDOR, *PCPU_VENDOR;
|
||||
typedef enum _CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT, *PCPUID_FEATURES_ADVANCED_POWER_MANAGEMENT;
|
||||
typedef enum _CPUID_FEATURES_EXTENDED CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
|
||||
typedef enum _CPUID_FEATURES_POWER_MANAGEMENT CPUID_FEATURES_POWER_MANAGEMENT, *PCPUID_FEATURES_POWER_MANAGEMENT;
|
||||
typedef enum _CPUID_FEATURES_STANDARD1 CPUID_FEATURES_STANDARD1, *PCPUID_FEATURES_STANDARD1;
|
||||
typedef enum _CPUID_FEATURES_STANDARD7_LEAF0 CPUID_FEATURES_STANDARD7_LEAF0, *PCPUID_FEATURES_STANDARD7_LEAF0;
|
||||
typedef enum _CPUID_FEATURES_STANDARD7_LEAF1 CPUID_FEATURES_STANDARD7_LEAF1, *PCPUID_FEATURES_STANDARD7_LEAF1;
|
||||
@@ -72,6 +78,7 @@ typedef struct _MMPML3_PTE_SUBSECTION MMPML3_PTE_SUBSECTION, *PMMPML3_PTE_SUBSEC
|
||||
typedef struct _MMPML3_PTE_TRANSITION MMPML3_PTE_TRANSITION, *PMMPML3_PTE_TRANSITION;
|
||||
typedef struct _POOL_DESCRIPTOR POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
||||
typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
||||
typedef struct _TIMER_CAPABILITIES TIMER_CAPABILITIES, *PTIMER_CAPABILITIES;
|
||||
|
||||
/* Unions forward references */
|
||||
typedef union _APIC_BASE_REGISTER APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER;
|
||||
@@ -89,4 +96,5 @@ typedef union _PIC_I8259_ICW2 PIC_I8259_ICW2, *PPIC_I8259_ICW2;
|
||||
typedef union _PIC_I8259_ICW3 PIC_I8259_ICW3, *PPIC_I8259_ICW3;
|
||||
typedef union _PIC_I8259_ICW4 PIC_I8259_ICW4, *PPIC_I8259_ICW4;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_I686_XTSTRUCT_H */
|
||||
|
||||
@@ -58,6 +58,10 @@
|
||||
#define PCI_STATUS_SIGNALED_SYSTEM_ERROR 0x4000
|
||||
#define PCI_STATUS_DETECTED_PARITY_ERROR 0x8000
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* PCI bridge control registers */
|
||||
typedef struct _PCI_BRIDGE_CONTROL_REGISTER
|
||||
{
|
||||
@@ -214,4 +218,5 @@ typedef struct _PCI_TYPE1_DEVICE
|
||||
PCI_BRIDGE_CONTROL_REGISTER Bridge;
|
||||
} PCI_TYPE1_DEVICE, *PPCI_TYPE1_DEVICE;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_IOTYPES_H */
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
#include <xttypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Kernel debugger routines forward references */
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
@@ -20,4 +23,5 @@ VOID
|
||||
DbgPrint(PCWSTR Format,
|
||||
...);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_KDFUNCS_H */
|
||||
|
||||
@@ -21,6 +21,10 @@
|
||||
#define DEBUG_PROVIDER_COMPORT 0x00000001
|
||||
#define DEBUG_PROVIDER_FRAMEBUFFER 0x00000002
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Kernel routine callbacks */
|
||||
typedef XTSTATUS (XTAPI *PKD_INIT_ROUTINE)();
|
||||
typedef VOID (*PKD_PRINT_ROUTINE)(IN PCWSTR Format, IN ...);
|
||||
@@ -42,4 +46,5 @@ typedef struct _KD_DISPATCH_TABLE
|
||||
RTL_PRINT_CONTEXT PrintContext;
|
||||
} KD_DISPATCH_TABLE, *PKD_DISPATCH_TABLE;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_KDTYPES_H */
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
#include <ketypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Kernel services routines forward references */
|
||||
XTCLINK
|
||||
XTFASTCALL
|
||||
@@ -159,4 +162,5 @@ XTAPI
|
||||
BOOLEAN
|
||||
KeSignalCallDpcSynchronize(IN PVOID SystemArgument);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_KEFUNCS_H */
|
||||
|
||||
@@ -49,6 +49,10 @@
|
||||
#define THREAD_HIGH_PRIORITY 31
|
||||
#define THREAD_MAXIMUM_PRIORITY 32
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Adjust reason */
|
||||
typedef enum _ADJUST_REASON
|
||||
{
|
||||
@@ -133,6 +137,37 @@ typedef enum _KPROCESS_STATE
|
||||
ProcessOutSwap
|
||||
} KPROCESS_STATE, *PKPROCESS_STATE;
|
||||
|
||||
/* Kernel profiling sources */
|
||||
typedef enum _KPROFILE_SOURCE
|
||||
{
|
||||
ProfileTime,
|
||||
ProfileAlignmentFixup,
|
||||
ProfileTotalIssues,
|
||||
ProfilePipelineDry,
|
||||
ProfileLoadInstructions,
|
||||
ProfilePipelineFrozen,
|
||||
ProfileBranchInstructions,
|
||||
ProfileTotalNonissues,
|
||||
ProfileDcacheMisses,
|
||||
ProfileIcacheMisses,
|
||||
ProfileCacheMisses,
|
||||
ProfileBranchMispredictions,
|
||||
ProfileStoreInstructions,
|
||||
ProfileFpInstructions,
|
||||
ProfileIntegerInstructions,
|
||||
Profile2Issue,
|
||||
Profile3Issue,
|
||||
Profile4Issue,
|
||||
ProfileSpecialInstructions,
|
||||
ProfileTotalCycles,
|
||||
ProfileIcacheIssues,
|
||||
ProfileDcacheAccesses,
|
||||
ProfileMemoryBarrierCycles,
|
||||
ProfileLoadLinkedIssues,
|
||||
ProfileXtKernel,
|
||||
ProfileMaximum
|
||||
} KPROFILE_SOURCE, *PKPROFILE_SOURCE;
|
||||
|
||||
/* Thread state */
|
||||
typedef enum _KTHREAD_STATE
|
||||
{
|
||||
@@ -647,4 +682,5 @@ typedef struct _KUBSAN_TYPE_MISMATCH_DATA_V1
|
||||
UCHAR TypeCheckKind;
|
||||
} KUBSAN_TYPE_MISMATCH_DATA_V1, *PKUBSAN_TYPE_MISMATCH_DATA_V1;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_KEFUNCS_H */
|
||||
|
||||
@@ -38,6 +38,10 @@
|
||||
#define LDR_DTE_MM_LOADED 0x40000000
|
||||
#define LDR_DTE_COMPAT_DATABASE_PROCESSED 0x80000000
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Loader data table entry */
|
||||
typedef struct _LDR_DATA_TABLE_ENTRY
|
||||
{
|
||||
@@ -70,4 +74,5 @@ typedef struct _LDR_DATA_TABLE_ENTRY
|
||||
PVOID PatchInformation;
|
||||
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_LDRTYPES_H */
|
||||
|
||||
44
sdk/xtdk/mmfuncs.h
Normal file
44
sdk/xtdk/mmfuncs.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: sdk/xtdk/mmfuncs.h
|
||||
* DESCRIPTION: XTOS memory manager routine definitions
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTDK_MMFUNCS_H
|
||||
#define __XTDK_MMFUNCS_H
|
||||
|
||||
#include <xtdefs.h>
|
||||
#include <xtstruct.h>
|
||||
#include <xttypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Memory manager routines forward references */
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
MmAllocatePool(IN MMPOOL_TYPE PoolType,
|
||||
IN SIZE_T Bytes,
|
||||
OUT PVOID *Memory);
|
||||
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
MmAllocatePoolWithTag(IN MMPOOL_TYPE PoolType,
|
||||
IN SIZE_T Bytes,
|
||||
OUT PVOID *Memory,
|
||||
IN ULONG Tag);
|
||||
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
MmFreePool(IN PVOID VirtualAddress);
|
||||
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
MmFreePoolWithTag(IN PVOID VirtualAddress,
|
||||
IN ULONG Tag);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_MMFUNCS_H */
|
||||
@@ -55,6 +55,10 @@
|
||||
/* Protection field shift */
|
||||
#define MM_PROTECT_FIELD_SHIFT 5
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Memory manager page lists */
|
||||
typedef enum _MMPAGELISTS
|
||||
{
|
||||
@@ -258,4 +262,5 @@ typedef struct _POOL_TRACKING_TABLE
|
||||
ULONG Tag;
|
||||
} POOL_TRACKING_TABLE, *PPOOL_TRACKING_TABLE;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_MMTYPES_H */
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
#include <ketypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Power Manager routine callbacks */
|
||||
typedef VOID (XTFASTCALL *PPROCESSOR_IDLE_FUNCTION)(IN PPROCESSOR_POWER_STATE PowerState);
|
||||
typedef XTSTATUS (XTFASTCALL *PSET_PROCESSOR_THROTTLE)(IN UCHAR Throttle);
|
||||
@@ -88,4 +91,5 @@ typedef struct _PROCESSOR_POWER_STATE
|
||||
ULONG LastC3UserTime;
|
||||
} PROCESSOR_POWER_STATE, *PPROCESSOR_POWER_STATE;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_POTYPES_H */
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
#include <ketypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Kernel's representation of a process object */
|
||||
typedef struct _EPROCESS
|
||||
{
|
||||
@@ -27,4 +30,5 @@ typedef struct _ETHREAD
|
||||
UINT Reserved0;
|
||||
} ETHREAD, *PETHREAD;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_PSTYPES_H */
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
#include <rtltypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Runtime Library routines forward references */
|
||||
XTCLINK
|
||||
XTAPI
|
||||
@@ -370,4 +373,5 @@ VOID
|
||||
RtlZeroMemory(OUT PVOID Destination,
|
||||
IN SIZE_T Length);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_RTLFUNCS_H */
|
||||
|
||||
@@ -53,6 +53,10 @@
|
||||
#define SHA1_BLOCK_SIZE 64
|
||||
#define SHA1_DIGEST_SIZE 20
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Runtime Library routine callbacks */
|
||||
typedef XTSTATUS (*PWRITE_CHARACTER)(IN CHAR Character);
|
||||
typedef XTSTATUS (*PWRITE_WIDE_CHARACTER)(IN WCHAR Character);
|
||||
@@ -107,4 +111,5 @@ typedef struct _RTL_SHA1_CONTEXT
|
||||
UCHAR Buffer[SHA1_BLOCK_SIZE];
|
||||
} RTL_SHA1_CONTEXT, *PRTL_SHA1_CONTEXT;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_RTLTYPES_H */
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
#include <xttypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Kernel affinity */
|
||||
typedef ULONG_PTR KAFFINITY, *PKAFFINITY;
|
||||
|
||||
@@ -108,4 +111,5 @@ typedef struct _DISPATCHER_HEADER
|
||||
LIST_ENTRY WaitListHead;
|
||||
} DISPATCHER_HEADER, *PDISPATCHER_HEADER;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER_ */
|
||||
#endif /* __XTDK_XTBASE_H */
|
||||
|
||||
@@ -10,11 +10,15 @@
|
||||
#define __XTDK_XTCOMPAT_H
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* C++ definitions */
|
||||
#define NULLPTR nullptr
|
||||
#define VIRTUAL virtual
|
||||
#define XTCLINK extern "C"
|
||||
#define XTSYMBOL(Name) __asm__(Name)
|
||||
|
||||
/* C++ boolean type */
|
||||
typedef bool BOOLEAN, *PBOOLEAN;
|
||||
@@ -28,6 +32,7 @@
|
||||
#define NULLPTR ((void *)0)
|
||||
#define VIRTUAL
|
||||
#define XTCLINK
|
||||
#define XTSYMBOL(Name)
|
||||
|
||||
/* C boolean type */
|
||||
typedef enum _BOOLEAN
|
||||
@@ -40,4 +45,5 @@
|
||||
typedef unsigned short wchar;
|
||||
#endif
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_XTCOMPAT_H */
|
||||
|
||||
@@ -111,7 +111,6 @@
|
||||
#define UNIQUE(Prefix) CONCATENATE(CONCATENATE(__UNIQUE_ID_, Prefix), __COUNTER__)
|
||||
|
||||
/* Variadic ABI functions */
|
||||
typedef __builtin_va_list VA_LIST, *PVA_LIST;
|
||||
#define VA_ARG(Marker, Type) ((sizeof(Type) < sizeof(UINT_PTR)) ? \
|
||||
(Type)(__builtin_va_arg(Marker, UINT_PTR)) : \
|
||||
(Type)(__builtin_va_arg(Marker, Type)))
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
#include <xtdefs.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef D__XTOS_ASSEMBLER__
|
||||
|
||||
/* SSF2 font header */
|
||||
typedef struct _SSFN_FONT_HEADER
|
||||
{
|
||||
@@ -3980,4 +3983,5 @@ UCHAR XtFbDefaultFont[] = {0x78, 0x74, 0x66, 0x6E, 0x3B, 0xE7, 0x00, 0x00, 0x03,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x82, 0x32, 0x4E, 0x46, 0x53};
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_XTFONT_H */
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
/* Version number of the current XTOS loader protocol */
|
||||
#define BOOT_PROTOCOL_VERSION 1
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Memory allocation structures */
|
||||
typedef enum _LOADER_MEMORY_TYPE
|
||||
{
|
||||
@@ -116,4 +120,5 @@ typedef struct _KERNEL_INITIALIZATION_BLOCK
|
||||
FIRMWARE_INFORMATION_BLOCK FirmwareInformation;
|
||||
} KERNEL_INITIALIZATION_BLOCK, *PKERNEL_INITIALIZATION_BLOCK;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER_ */
|
||||
#endif /* __XTDK_XTFW_H */
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
#include <xttypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef D__XTOS_ASSEMBLER__
|
||||
|
||||
CHAR XTGLYPH_EXECTOS_LOGO[] =
|
||||
{
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x25, 0x23,
|
||||
@@ -61,4 +64,5 @@ CHAR XTGLYPH_EXECTOS_LOGO[] =
|
||||
0x28, 0x0d, 0x0a
|
||||
};
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_XTGLYPH_H */
|
||||
|
||||
@@ -202,6 +202,10 @@
|
||||
#define PECOFF_IMAGE_SCN_MEM_READ 0x40000000
|
||||
#define PECOFF_IMAGE_SCN_MEM_WRITE 0x80000000
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* PE/COFF image representation structure */
|
||||
typedef struct _PECOFF_IMAGE_CONTEXT
|
||||
{
|
||||
@@ -638,4 +642,5 @@ typedef struct _PECOFF_IMAGE_RESOURCE_DATA_ENTRY
|
||||
ULONG Reserved;
|
||||
} PECOFF_IMAGE_RESOURCE_DATA_ENTRY, *PPECOFF_IMAGE_RESOURCE_DATA_ENTRY;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_XTIMAGE_H */
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include <hlfuncs.h>
|
||||
#include <kdfuncs.h>
|
||||
#include <kefuncs.h>
|
||||
#include <mmfuncs.h>
|
||||
#include <rtlfuncs.h>
|
||||
|
||||
/* Architecture specific XT routines */
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
#include <xtdefs.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Enumeration lists forward references */
|
||||
typedef enum _ADJUST_REASON ADJUST_REASON, *PADJUST_REASON;
|
||||
typedef enum _EXCEPTION_DISPOSITION EXCEPTION_DISPOSITION, *PEXCEPTION_DISPOSITION;
|
||||
@@ -44,6 +47,7 @@ typedef enum _KDPC_IMPORTANCE KDPC_IMPORTANCE, *PKDPC_IMPORTANCE;
|
||||
typedef enum _KEVENT_TYPE KEVENT_TYPE, *PKEVENT_TYPE;
|
||||
typedef enum _KOBJECTS KOBJECTS, *PKOBJECTS;
|
||||
typedef enum _KPROCESS_STATE KPROCESS_STATE, *PKPROCESS_STATE;
|
||||
typedef enum _KPROFILE_SOURCE KPROFILE_SOURCE, *PKPROFILE_SOURCE;
|
||||
typedef enum _KTHREAD_STATE KTHREAD_STATE, *PKTHREAD_STATE;
|
||||
typedef enum _KTIMER_TYPE KTIMER_TYPE, *PKTIMER_TYPE;
|
||||
typedef enum _KUBSAN_DATA_TYPE KUBSAN_DATA_TYPE, *PKUBSAN_DATA_TYPE;
|
||||
@@ -363,4 +367,5 @@ typedef union _LARGE_INTEGER LARGE_INTEGER, *PLARGE_INTEGER;
|
||||
typedef union _SINGLE_LIST_HEADER SINGLE_LIST_HEADER, *PSINGLE_LIST_HEADER;
|
||||
typedef union _ULARGE_INTEGER ULARGE_INTEGER, *PULARGE_INTEGER;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_XTSTRUCT_H */
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
#include <xtcompat.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Standard C types */
|
||||
typedef unsigned char BYTE, *PBYTE, *LPBYTE;
|
||||
typedef char CHAR, *PCHAR, *LPCHAR;
|
||||
@@ -150,6 +153,9 @@ typedef LPCWSTR PCTSTR, LPCTSTR;
|
||||
typedef LPUWSTR PUTSTR, LPUTSTR;
|
||||
typedef LPCUWSTR PCUTSTR, LPCUTSTR;
|
||||
|
||||
/* Variadic ABI types */
|
||||
typedef __builtin_va_list VA_LIST, *PVA_LIST;
|
||||
|
||||
/* 128-bit floats structure */
|
||||
typedef struct _FLOAT128
|
||||
{
|
||||
@@ -287,4 +293,5 @@ typedef struct _UNICODE_STRING64
|
||||
} UNICODE_STRING64, *PUNICODE_STRING64;
|
||||
typedef const UNICODE_STRING64 *PCUNICODE_STRING64;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_XTTYPES_H */
|
||||
|
||||
@@ -373,6 +373,10 @@
|
||||
#define EFI_CONFIG_TABLE_SMBIOS_TABLE_GUID {0xEB9D2D31, 0x2D88, 0x11D3, {0x9A, 0x16, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}}
|
||||
#define EFI_CONFIG_TABLE_SMBIOS3_TABLE_GUID {0xF2FD1544, 0x9794, 0x4A2C, {0x99, 0x2E, 0xE5, 0xBB, 0xCf, 0x20, 0xE3, 0x94}}
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Basic UEFI types */
|
||||
typedef PVOID EFI_EVENT, *PEFI_EVENT;
|
||||
typedef PVOID EFI_HANDLE, *PEFI_HANDLE;
|
||||
@@ -2723,4 +2727,5 @@ typedef struct _EFI_PROCESSOR_INFORMATION
|
||||
EFI_PROCESSOR_PHYSICAL_LOCATION Location;
|
||||
} EFI_PROCESSOR_INFORMATION, *PEFI_PROCESSOR_INFORMATION;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_XTUEFI_H */
|
||||
|
||||
@@ -10,7 +10,6 @@ include_directories(
|
||||
# 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.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/data.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/procsup.cc
|
||||
@@ -20,7 +19,9 @@ list(APPEND XTOSKRNL_SOURCE
|
||||
${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}/irq.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/runlevel.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/timer.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/hl/acpi.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/hl/cport.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/hl/data.cc
|
||||
@@ -31,7 +32,6 @@ list(APPEND XTOSKRNL_SOURCE
|
||||
${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
|
||||
@@ -61,6 +61,7 @@ list(APPEND XTOSKRNL_SOURCE
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/alloc.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/colors.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/data.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/exports.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/hlpool.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/kpool.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/mmgr.cc
|
||||
@@ -90,15 +91,13 @@ set_specfile(xtoskrnl.spec xtoskrnl.exe)
|
||||
|
||||
# Link static XTOS library
|
||||
add_library(libxtos ${XTOSKRNL_SOURCE})
|
||||
target_link_libraries(libxtos PRIVATE xtadk)
|
||||
|
||||
# Link kernel executable
|
||||
add_executable(xtoskrnl
|
||||
${CMAKE_CURRENT_BINARY_DIR}/xtoskrnl.def)
|
||||
add_executable(xtoskrnl ${CMAKE_CURRENT_BINARY_DIR}/xtoskrnl.def)
|
||||
|
||||
# Add linker libraries
|
||||
target_link_libraries(xtoskrnl
|
||||
PRIVATE
|
||||
libxtos)
|
||||
target_link_libraries(xtoskrnl PRIVATE libxtos)
|
||||
|
||||
# Set proper binary name and install target
|
||||
set_target_properties(xtoskrnl PROPERTIES SUFFIX .exe)
|
||||
|
||||
@@ -4,31 +4,42 @@
|
||||
* FILE: xtoskrnl/ar/amd64/archsup.S
|
||||
* DESCRIPTION: Provides AMD64 architecture features not implementable in C
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <ar/amd64/asmsup.h>
|
||||
#include <xtkmapi.h>
|
||||
#include <xtadk.h>
|
||||
|
||||
.altmacro
|
||||
.text
|
||||
|
||||
|
||||
/**
|
||||
* Creates a trap handler for the specified vector.
|
||||
* Creates a trap or interrupt handler for the specified vector.
|
||||
*
|
||||
* @param Vector
|
||||
* Supplies a trap vector number.
|
||||
* Supplies a trap/interrupt vector number.
|
||||
*
|
||||
* @param Type
|
||||
* Specifies whether the handler is designed to handle an interrupt or a trap.
|
||||
*
|
||||
* @return This macro does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.macro ArCreateTrapHandler Vector
|
||||
.global ArTrap\Vector
|
||||
ArTrap\Vector:
|
||||
/* Push fake error code for non-error vectors */
|
||||
.macro ArCreateHandler Vector Type
|
||||
.global Ar\Type\Vector
|
||||
Ar\Type\Vector:
|
||||
/* Check handler type */
|
||||
.ifc \Type,Trap
|
||||
/* Push fake error code for non-error vector traps */
|
||||
.if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
|
||||
push $0
|
||||
.endif
|
||||
.else
|
||||
/* Push fake error code for interrupts */
|
||||
push $0
|
||||
.endif
|
||||
|
||||
/* Push vector number */
|
||||
push $\Vector
|
||||
@@ -51,113 +62,122 @@ ArTrap\Vector:
|
||||
push %rax
|
||||
|
||||
/* Reserve space for other registers and point RBP to the trap frame */
|
||||
sub $(TRAP_FRAME_SIZE - TRAP_REGISTERS_SIZE), %rsp
|
||||
sub $(KTRAP_FRAME_SIZE - KTRAP_FRAME_REGISTERS_SIZE), %rsp
|
||||
lea (%rsp), %rbp
|
||||
|
||||
/* Store segment selectors */
|
||||
mov %gs, TrapSegGs(%rbp)
|
||||
mov %fs, TrapSegFs(%rbp)
|
||||
mov %es, TrapSegEs(%rbp)
|
||||
mov %ds, TrapSegDs(%rbp)
|
||||
mov %gs, KTRAP_FRAME_SegGs(%rbp)
|
||||
mov %fs, KTRAP_FRAME_SegFs(%rbp)
|
||||
mov %es, KTRAP_FRAME_SegEs(%rbp)
|
||||
mov %ds, KTRAP_FRAME_SegDs(%rbp)
|
||||
|
||||
/* Store debug registers */
|
||||
mov %dr7, %rax
|
||||
mov %rax, TrapDr7(%rbp)
|
||||
mov %rax, KTRAP_FRAME_Dr7(%rbp)
|
||||
mov %dr6, %rax
|
||||
mov %rax, TrapDr6(%rbp)
|
||||
mov %rax, KTRAP_FRAME_Dr6(%rbp)
|
||||
mov %dr3, %rax
|
||||
mov %rax, TrapDr3(%rbp)
|
||||
mov %rax, KTRAP_FRAME_Dr3(%rbp)
|
||||
mov %dr2, %rax
|
||||
mov %rax, TrapDr2(%rbp)
|
||||
mov %rax, KTRAP_FRAME_Dr2(%rbp)
|
||||
mov %dr1, %rax
|
||||
mov %rax, TrapDr1(%rbp)
|
||||
mov %rax, KTRAP_FRAME_Dr1(%rbp)
|
||||
mov %dr0, %rax
|
||||
mov %rax, TrapDr0(%rbp)
|
||||
mov %rax, KTRAP_FRAME_Dr0(%rbp)
|
||||
|
||||
/* Store CR2 and CR3 */
|
||||
mov %cr3, %rax
|
||||
mov %rax, TrapCr3(%rbp)
|
||||
mov %rax, KTRAP_FRAME_Cr3(%rbp)
|
||||
mov %cr2, %rax
|
||||
mov %rax, TrapCr2(%rbp)
|
||||
mov %rax, KTRAP_FRAME_Cr2(%rbp)
|
||||
|
||||
/* Store MxCsr register */
|
||||
stmxcsr TrapMxCsr(%rbp)
|
||||
stmxcsr KTRAP_FRAME_MxCsr(%rbp)
|
||||
|
||||
/* Store XMM registers */
|
||||
movdqa %xmm15, TrapXmm15(%rbp)
|
||||
movdqa %xmm14, TrapXmm14(%rbp)
|
||||
movdqa %xmm13, TrapXmm13(%rbp)
|
||||
movdqa %xmm12, TrapXmm12(%rbp)
|
||||
movdqa %xmm11, TrapXmm11(%rbp)
|
||||
movdqa %xmm10, TrapXmm10(%rbp)
|
||||
movdqa %xmm9, TrapXmm9(%rbp)
|
||||
movdqa %xmm8, TrapXmm8(%rbp)
|
||||
movdqa %xmm7, TrapXmm7(%rbp)
|
||||
movdqa %xmm6, TrapXmm6(%rbp)
|
||||
movdqa %xmm5, TrapXmm5(%rbp)
|
||||
movdqa %xmm4, TrapXmm4(%rbp)
|
||||
movdqa %xmm3, TrapXmm3(%rbp)
|
||||
movdqa %xmm2, TrapXmm2(%rbp)
|
||||
movdqa %xmm1, TrapXmm1(%rbp)
|
||||
movdqa %xmm0, TrapXmm0(%rbp)
|
||||
movdqa %xmm15, KTRAP_FRAME_Xmm15(%rbp)
|
||||
movdqa %xmm14, KTRAP_FRAME_Xmm14(%rbp)
|
||||
movdqa %xmm13, KTRAP_FRAME_Xmm13(%rbp)
|
||||
movdqa %xmm12, KTRAP_FRAME_Xmm12(%rbp)
|
||||
movdqa %xmm11, KTRAP_FRAME_Xmm11(%rbp)
|
||||
movdqa %xmm10, KTRAP_FRAME_Xmm10(%rbp)
|
||||
movdqa %xmm9, KTRAP_FRAME_Xmm9(%rbp)
|
||||
movdqa %xmm8, KTRAP_FRAME_Xmm8(%rbp)
|
||||
movdqa %xmm7, KTRAP_FRAME_Xmm7(%rbp)
|
||||
movdqa %xmm6, KTRAP_FRAME_Xmm6(%rbp)
|
||||
movdqa %xmm5, KTRAP_FRAME_Xmm5(%rbp)
|
||||
movdqa %xmm4, KTRAP_FRAME_Xmm4(%rbp)
|
||||
movdqa %xmm3, KTRAP_FRAME_Xmm3(%rbp)
|
||||
movdqa %xmm2, KTRAP_FRAME_Xmm2(%rbp)
|
||||
movdqa %xmm1, KTRAP_FRAME_Xmm1(%rbp)
|
||||
movdqa %xmm0, KTRAP_FRAME_Xmm0(%rbp)
|
||||
|
||||
/* Test previous mode and swap GS if needed */
|
||||
movl $0, TrapPreviousMode(%rbp)
|
||||
mov %cs, %ax
|
||||
movl $0, KTRAP_FRAME_PreviousMode(%rbp)
|
||||
mov KTRAP_FRAME_SegCs(%rbp), %ax
|
||||
and $3, %al
|
||||
mov %al, TrapPreviousMode(%rbp)
|
||||
jz KernelMode$\Vector
|
||||
mov %al, KTRAP_FRAME_PreviousMode(%rbp)
|
||||
|
||||
/* Skip swapgs as the interrupt originated from kernel mode */
|
||||
jz Dispatch\Type\Vector
|
||||
|
||||
swapgs
|
||||
jmp UserMode$\Vector
|
||||
|
||||
KernelMode$\Vector:
|
||||
/* Save kernel stack pointer (SS:RSP) */
|
||||
movl %ss, %eax
|
||||
mov %eax, TrapSegSs(%rbp)
|
||||
lea TRAP_FRAME_SIZE(%rbp), %rax
|
||||
mov %rax, TrapRsp(%rbp)
|
||||
|
||||
UserMode$\Vector:
|
||||
/* Push Frame Pointer, clear direction flag and pass to trap dispatcher */
|
||||
Dispatch\Type\Vector:
|
||||
/* Set up trap frame pointer for the dispatcher and clear the direction flag */
|
||||
mov %rsp, %rcx
|
||||
cld
|
||||
|
||||
/* Preserve the original stack pointer */
|
||||
mov %rsp, %rbx
|
||||
|
||||
/* Force stack alignment */
|
||||
and $-16, %rsp
|
||||
|
||||
/* Allocate 32 bytes of shadow space */
|
||||
sub $32, %rsp
|
||||
|
||||
.ifc \Type,Trap
|
||||
/* Pass to the trap dispatcher */
|
||||
call ArDispatchTrap
|
||||
.else
|
||||
/* Pass to the interrupt dispatcher */
|
||||
call ArDispatchInterrupt
|
||||
.endif
|
||||
|
||||
/* Restore the original trap frame stack pointer */
|
||||
mov %rbx, %rsp
|
||||
|
||||
/* Test previous mode and swapgs if needed */
|
||||
testb $1, TrapPreviousMode(%rbp)
|
||||
jz KernelModeReturn$\Vector
|
||||
testb $1, KTRAP_FRAME_PreviousMode(%rbp)
|
||||
jz RestoreState\Type\Vector
|
||||
cli
|
||||
swapgs
|
||||
|
||||
KernelModeReturn$\Vector:
|
||||
RestoreState\Type\Vector:
|
||||
/* Restore XMM registers */
|
||||
movdqa TrapXmm0(%rbp), %xmm0
|
||||
movdqa TrapXmm1(%rbp), %xmm1
|
||||
movdqa TrapXmm2(%rbp), %xmm2
|
||||
movdqa TrapXmm3(%rbp), %xmm3
|
||||
movdqa TrapXmm4(%rbp), %xmm4
|
||||
movdqa TrapXmm5(%rbp), %xmm5
|
||||
movdqa TrapXmm6(%rbp), %xmm6
|
||||
movdqa TrapXmm7(%rbp), %xmm7
|
||||
movdqa TrapXmm8(%rbp), %xmm8
|
||||
movdqa TrapXmm9(%rbp), %xmm9
|
||||
movdqa TrapXmm10(%rbp), %xmm10
|
||||
movdqa TrapXmm11(%rbp), %xmm11
|
||||
movdqa TrapXmm12(%rbp), %xmm12
|
||||
movdqa TrapXmm13(%rbp), %xmm13
|
||||
movdqa TrapXmm14(%rbp), %xmm14
|
||||
movdqa TrapXmm15(%rbp), %xmm15
|
||||
movdqa KTRAP_FRAME_Xmm0(%rbp), %xmm0
|
||||
movdqa KTRAP_FRAME_Xmm1(%rbp), %xmm1
|
||||
movdqa KTRAP_FRAME_Xmm2(%rbp), %xmm2
|
||||
movdqa KTRAP_FRAME_Xmm3(%rbp), %xmm3
|
||||
movdqa KTRAP_FRAME_Xmm4(%rbp), %xmm4
|
||||
movdqa KTRAP_FRAME_Xmm5(%rbp), %xmm5
|
||||
movdqa KTRAP_FRAME_Xmm6(%rbp), %xmm6
|
||||
movdqa KTRAP_FRAME_Xmm7(%rbp), %xmm7
|
||||
movdqa KTRAP_FRAME_Xmm8(%rbp), %xmm8
|
||||
movdqa KTRAP_FRAME_Xmm9(%rbp), %xmm9
|
||||
movdqa KTRAP_FRAME_Xmm10(%rbp), %xmm10
|
||||
movdqa KTRAP_FRAME_Xmm11(%rbp), %xmm11
|
||||
movdqa KTRAP_FRAME_Xmm12(%rbp), %xmm12
|
||||
movdqa KTRAP_FRAME_Xmm13(%rbp), %xmm13
|
||||
movdqa KTRAP_FRAME_Xmm14(%rbp), %xmm14
|
||||
movdqa KTRAP_FRAME_Xmm15(%rbp), %xmm15
|
||||
|
||||
/* Load MxCsr register */
|
||||
ldmxcsr TrapMxCsr(%rbp)
|
||||
|
||||
/* Restore segment selectors */
|
||||
mov TrapSegDs(%rbp), %ds
|
||||
mov TrapSegEs(%rbp), %es
|
||||
mov TrapSegFs(%rbp), %fs
|
||||
ldmxcsr KTRAP_FRAME_MxCsr(%rbp)
|
||||
|
||||
/* Free stack space */
|
||||
add $(TRAP_FRAME_SIZE - TRAP_REGISTERS_SIZE), %rsp
|
||||
add $(KTRAP_FRAME_SIZE - KTRAP_FRAME_REGISTERS_SIZE), %rsp
|
||||
|
||||
/* Pop General Purpose Registers */
|
||||
pop %rax
|
||||
@@ -181,9 +201,172 @@ KernelModeReturn$\Vector:
|
||||
iretq
|
||||
.endm
|
||||
|
||||
/* Populate common trap handlers */
|
||||
/* Populate common interrupt and 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
|
||||
ArCreateTrapHandler 0x\i\j
|
||||
ArCreateHandler 0x\i\j Interrupt
|
||||
ArCreateHandler 0x\i\j Trap
|
||||
.endr
|
||||
.endr
|
||||
|
||||
/* Define array of pointers to the interrupt handlers */
|
||||
.global ArInterruptEntry
|
||||
ArInterruptEntry:
|
||||
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.quad ArInterrupt0x\i\j
|
||||
.endr
|
||||
.endr
|
||||
|
||||
/* Define array of pointers to the trap handlers */
|
||||
.global ArTrapEntry
|
||||
ArTrapEntry:
|
||||
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.quad ArTrap0x\i\j
|
||||
.endr
|
||||
.endr
|
||||
|
||||
/**
|
||||
* Enables eXtended Physical Addressing (XPA).
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page map to be used.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.global ArEnableExtendedPhysicalAddressing
|
||||
ArEnableExtendedPhysicalAddressing:
|
||||
/* Save the original CR4 register */
|
||||
movq %cr4, %rax
|
||||
|
||||
/* Save the state of stack pointer and non-volatile registers */
|
||||
movq %rsp, XpaRegisterSaveArea(%rip)
|
||||
movq %rbp, XpaRegisterSaveArea+0x08(%rip)
|
||||
movq %rax, XpaRegisterSaveArea+0x10(%rip)
|
||||
movq %rbx, XpaRegisterSaveArea+0x18(%rip)
|
||||
|
||||
/* Save the original CR0 register */
|
||||
movq %cr0, %rbp
|
||||
|
||||
/* Load temporary GDT required for mode transitions */
|
||||
leaq XpaTemporaryGdtDesc(%rip), %rax
|
||||
movq %rax, XpaTemporaryGdtBase(%rip)
|
||||
lgdtq XpaTemporaryGdtSize(%rip)
|
||||
|
||||
/* Load addresses for entering compatibility mode and re-entering long mode */
|
||||
leaq XpaEnterCompatMode(%rip), %rax
|
||||
leaq XpaEnterLongMode(%rip), %rbx
|
||||
|
||||
/* Push the 32-bit code segment selector and the target address for a far jump */
|
||||
pushq $KGDT_R0_CMCODE
|
||||
pushq %rax
|
||||
|
||||
/* Perform a far return to switch to 32-bit compatibility mode */
|
||||
lretq
|
||||
|
||||
XpaEnterCompatMode:
|
||||
/* Enter 32-bit compatibility mode */
|
||||
.code32
|
||||
|
||||
/* Store the PageMap pointer on the stack for future use */
|
||||
pushl %ecx
|
||||
|
||||
/* Set the stack segment to the 32-bit data segment selector */
|
||||
movl $KGDT_R0_DATA, %eax
|
||||
movl %eax, %ss
|
||||
|
||||
/* Disable PGE and PCIDE to ensure all TLB entries will be flushed */
|
||||
movl %cr4, %eax
|
||||
andl $~(CR4_PGE | CR4_PCIDE), %eax
|
||||
movl %eax, %cr4
|
||||
|
||||
/* Temporarily disable paging */
|
||||
movl %ebp, %eax
|
||||
andl $~CR0_PG, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
/* Disable Long Mode as prerequisite for enabling 5-level paging */
|
||||
movl $X86_MSR_EFER, %ecx
|
||||
rdmsr
|
||||
andl $~X86_MSR_EFER_LME, %eax
|
||||
wrmsr
|
||||
|
||||
/* Transition to 5-level paging (PML5/LA57) */
|
||||
movl %cr4, %eax
|
||||
orl $CR4_LA57, %eax
|
||||
movl %eax, %cr4
|
||||
|
||||
/* Restore the PageMap pointer from the stack and load it into CR3 */
|
||||
popl %ecx
|
||||
movl %ecx, %cr3
|
||||
|
||||
/* Re-enable Long Mode */
|
||||
movl $X86_MSR_EFER, %ecx
|
||||
rdmsr
|
||||
orl $X86_MSR_EFER_LME, %eax
|
||||
wrmsr
|
||||
|
||||
/* Restore CR0 with paging enabled and flush the instruction pipeline */
|
||||
movl %ebp, %cr0
|
||||
call XpaFlushInstructions
|
||||
|
||||
XpaFlushInstructions:
|
||||
/* Push the 64-bit code segment selector and the target address for a far jump */
|
||||
pushl $KGDT_R0_CODE
|
||||
pushl %ebx
|
||||
|
||||
/* Perform a far return to switch to 64-bit long mode */
|
||||
lretl
|
||||
|
||||
XpaEnterLongMode:
|
||||
/* Enter 64-bit long mode */
|
||||
.code64
|
||||
|
||||
/* Restore the stack pointer and non-volatile registers */
|
||||
movq XpaRegisterSaveArea(%rip), %rsp
|
||||
movq XpaRegisterSaveArea+8(%rip), %rbp
|
||||
movq XpaRegisterSaveArea+0x10(%rip), %rax
|
||||
movq XpaRegisterSaveArea+0x18(%rip), %rbx
|
||||
|
||||
/* Restore the original CR4 register with LA57 bit set */
|
||||
orq $CR4_LA57, %rax
|
||||
movq %rax, %cr4
|
||||
|
||||
/* Return to the caller */
|
||||
retq
|
||||
|
||||
/* Data section for saving registers and temporary GDT */
|
||||
XpaRegisterSaveArea: .quad 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000
|
||||
XpaTemporaryGdtSize: .short ArEnableExtendedPhysicalAddressingEnd - XpaTemporaryGdtDesc - 1
|
||||
XpaTemporaryGdtBase: .quad 0x0000000000000000
|
||||
XpaTemporaryGdtDesc: .quad 0x0000000000000000, 0x00CF9A000000FFFF, 0x00AF9A000000FFFF, 0x00CF92000000FFFF
|
||||
|
||||
.global ArEnableExtendedPhysicalAddressingEnd
|
||||
ArEnableExtendedPhysicalAddressingEnd:
|
||||
|
||||
/**
|
||||
* Handles a spurious interrupt allowing it to end up.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.global ArHandleSpuriousInterrupt
|
||||
ArHandleSpuriousInterrupt:
|
||||
iretq
|
||||
|
||||
/**
|
||||
* Starts an application processor (AP). This is just a stub.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.global ArStartApplicationProcessor
|
||||
ArStartApplicationProcessor:
|
||||
|
||||
.global ArStartApplicationProcessorEnd
|
||||
ArStartApplicationProcessorEnd:
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ar/amd64/boot.S
|
||||
* DESCRIPTION: AMD64-specific boot code for setting up the low-level CPU environment
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <ar/amd64/asmsup.h>
|
||||
|
||||
.altmacro
|
||||
.text
|
||||
|
||||
|
||||
/**
|
||||
* Enables eXtended Physical Addressing (XPA).
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page map to be used.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.global ArEnableExtendedPhysicalAddressing
|
||||
ArEnableExtendedPhysicalAddressing:
|
||||
/* Save the original CR4 register */
|
||||
movq %cr4, %rax
|
||||
|
||||
/* Save the state of stack pointer and non-volatile registers */
|
||||
movq %rsp, XpaRegisterSaveArea(%rip)
|
||||
movq %rbp, XpaRegisterSaveArea+0x08(%rip)
|
||||
movq %rax, XpaRegisterSaveArea+0x10(%rip)
|
||||
movq %rbx, XpaRegisterSaveArea+0x18(%rip)
|
||||
|
||||
/* Save the original CR0 register */
|
||||
movq %cr0, %rbp
|
||||
|
||||
/* Load temporary GDT required for mode transitions */
|
||||
leaq XpaTemporaryGdtDesc(%rip), %rax
|
||||
movq %rax, XpaTemporaryGdtBase(%rip)
|
||||
lgdtq XpaTemporaryGdtSize(%rip)
|
||||
|
||||
/* Load addresses for entering compatibility mode and re-entering long mode */
|
||||
leaq XpaEnterCompatMode(%rip), %rax
|
||||
leaq XpaEnterLongMode(%rip), %rbx
|
||||
|
||||
/* Push the 32-bit code segment selector and the target address for a far jump */
|
||||
pushq $GDT_R0_CMCODE
|
||||
pushq %rax
|
||||
|
||||
/* Perform a far return to switch to 32-bit compatibility mode */
|
||||
lretq
|
||||
|
||||
XpaEnterCompatMode:
|
||||
/* Enter 32-bit compatibility mode */
|
||||
.code32
|
||||
|
||||
/* Store the PageMap pointer on the stack for future use */
|
||||
pushl %ecx
|
||||
|
||||
/* Set the stack segment to the 32-bit data segment selector */
|
||||
movl $GDT_R0_DATA, %eax
|
||||
movl %eax, %ss
|
||||
|
||||
/* Disable PGE and PCIDE to ensure all TLB entries will be flushed */
|
||||
movl %cr4, %eax
|
||||
andl $~(CR4_PGE | CR4_PCIDE), %eax
|
||||
movl %eax, %cr4
|
||||
|
||||
/* Temporarily disable paging */
|
||||
movl %ebp, %eax
|
||||
andl $~CR0_PG, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
/* Disable Long Mode as prerequisite for enabling 5-level paging */
|
||||
movl $X86_MSR_EFER, %ecx
|
||||
rdmsr
|
||||
andl $~X86_MSR_EFER_LME, %eax
|
||||
wrmsr
|
||||
|
||||
/* Transition to 5-level paging (PML5/LA57) */
|
||||
movl %cr4, %eax
|
||||
orl $CR4_LA57, %eax
|
||||
movl %eax, %cr4
|
||||
|
||||
/* Restore the PageMap pointer from the stack and load it into CR3 */
|
||||
popl %ecx
|
||||
movl %ecx, %cr3
|
||||
|
||||
/* Re-enable Long Mode */
|
||||
movl $X86_MSR_EFER, %ecx
|
||||
rdmsr
|
||||
orl $X86_MSR_EFER_LME, %eax
|
||||
wrmsr
|
||||
|
||||
/* Restore CR0 with paging enabled and flush the instruction pipeline */
|
||||
movl %ebp, %cr0
|
||||
call XpaFlushInstructions
|
||||
|
||||
XpaFlushInstructions:
|
||||
/* Push the 64-bit code segment selector and the target address for a far jump */
|
||||
pushl $GDT_R0_CODE
|
||||
pushl %ebx
|
||||
|
||||
/* Perform a far return to switch to 64-bit long mode */
|
||||
lretl
|
||||
|
||||
XpaEnterLongMode:
|
||||
/* Enter 64-bit long mode */
|
||||
.code64
|
||||
|
||||
/* Restore the stack pointer and non-volatile registers */
|
||||
movq XpaRegisterSaveArea(%rip), %rsp
|
||||
movq XpaRegisterSaveArea+8(%rip), %rbp
|
||||
movq XpaRegisterSaveArea+0x10(%rip), %rax
|
||||
movq XpaRegisterSaveArea+0x18(%rip), %rbx
|
||||
|
||||
/* Restore the original CR4 register with LA57 bit set */
|
||||
orq $CR4_LA57, %rax
|
||||
movq %rax, %cr4
|
||||
|
||||
/* Return to the caller */
|
||||
retq
|
||||
|
||||
/* Data section for saving registers and temporary GDT */
|
||||
XpaRegisterSaveArea: .quad 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000
|
||||
XpaTemporaryGdtSize: .short ArEnableExtendedPhysicalAddressingEnd - XpaTemporaryGdtDesc - 1
|
||||
XpaTemporaryGdtBase: .quad 0x0000000000000000
|
||||
XpaTemporaryGdtDesc: .quad 0x0000000000000000, 0x00CF9A000000FFFF, 0x00AF9A000000FFFF, 0x00CF92000000FFFF
|
||||
|
||||
.global ArEnableExtendedPhysicalAddressingEnd
|
||||
ArEnableExtendedPhysicalAddressingEnd:
|
||||
|
||||
|
||||
/**
|
||||
* Starts an application processor (AP). This is just a stub.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.global ArStartApplicationProcessor
|
||||
ArStartApplicationProcessor:
|
||||
|
||||
.global ArStartApplicationProcessorEnd
|
||||
ArStartApplicationProcessorEnd:
|
||||
@@ -26,3 +26,9 @@ KPROCESSOR_BLOCK AR::ProcSup::InitialProcessorBlock;
|
||||
|
||||
/* Initial TSS */
|
||||
KTSS AR::ProcSup::InitialTss;
|
||||
|
||||
/* Initial kernel NMI stack */
|
||||
UCHAR AR::ProcSup::NmiStack[KERNEL_STACK_SIZE] = {};
|
||||
|
||||
/* Unhandled interrupt routine */
|
||||
PINTERRUPT_HANDLER AR::Traps::UnhandledInterruptRoutine = NULLPTR;
|
||||
|
||||
@@ -73,7 +73,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
/* Get CPU vendor by issueing CPUID instruction */
|
||||
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
|
||||
CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU vendor in processor control block */
|
||||
Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx;
|
||||
@@ -85,7 +85,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
/* Get CPU standard features */
|
||||
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||
CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU signature in processor control block */
|
||||
CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax;
|
||||
@@ -97,23 +97,23 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
if(Prcb->CpuId.Vendor == CPU_VENDOR_AMD)
|
||||
{
|
||||
/* AMD CPU */
|
||||
if(Prcb->CpuId.Family >= 0xF)
|
||||
if(CpuSignature.Family == 0xF)
|
||||
{
|
||||
Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
|
||||
Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
|
||||
Prcb->CpuId.Family += CpuSignature.ExtendedFamily;
|
||||
Prcb->CpuId.Model += (CpuSignature.ExtendedModel << 4);
|
||||
}
|
||||
}
|
||||
else if(Prcb->CpuId.Vendor == CPU_VENDOR_INTEL)
|
||||
{
|
||||
/* Intel CPU */
|
||||
if(Prcb->CpuId.Family == 0xF)
|
||||
if(CpuSignature.Family == 0xF)
|
||||
{
|
||||
Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
|
||||
Prcb->CpuId.Family += CpuSignature.ExtendedFamily;
|
||||
}
|
||||
|
||||
if((Prcb->CpuId.Family == 0x6) || (Prcb->CpuId.Family == 0xF))
|
||||
if((CpuSignature.Family == 0x6) || (CpuSignature.Family == 0xF))
|
||||
{
|
||||
Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
|
||||
Prcb->CpuId.Model += (CpuSignature.ExtendedModel << 4);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -136,8 +136,8 @@ XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
{
|
||||
PVOID KernelBootStack, KernelFaultStack, KernelNmiStack;
|
||||
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
|
||||
PVOID KernelBootStack, KernelFaultStack;
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
PKGDTENTRY Gdt;
|
||||
PKIDTENTRY Idt;
|
||||
@@ -148,7 +148,7 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
{
|
||||
/* Assign CPU structures from provided buffer */
|
||||
InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
|
||||
&KernelBootStack, &KernelFaultStack);
|
||||
&KernelBootStack, &KernelFaultStack, &KernelNmiStack);
|
||||
|
||||
/* Use global IDT */
|
||||
Idt = InitialIdt;
|
||||
@@ -159,8 +159,9 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
Gdt = InitialGdt;
|
||||
Idt = InitialIdt;
|
||||
Tss = &InitialTss;
|
||||
KernelBootStack = &BootStack;
|
||||
KernelFaultStack = &FaultStack;
|
||||
KernelBootStack = (PVOID)((ULONG_PTR)&BootStack + KERNEL_STACK_SIZE);
|
||||
KernelFaultStack = (PVOID)((ULONG_PTR)&FaultStack + KERNEL_STACK_SIZE);
|
||||
KernelNmiStack = (PVOID)((ULONG_PTR)&NmiStack + KERNEL_STACK_SIZE);
|
||||
ProcessorBlock = &InitialProcessorBlock;
|
||||
}
|
||||
|
||||
@@ -170,7 +171,7 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
/* Initialize GDT, IDT and TSS */
|
||||
InitializeGdt(ProcessorBlock);
|
||||
InitializeIdt(ProcessorBlock);
|
||||
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack);
|
||||
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack, KernelNmiStack);
|
||||
|
||||
/* Set GDT and IDT descriptors */
|
||||
GdtDescriptor.Base = Gdt;
|
||||
@@ -179,9 +180,9 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
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);
|
||||
AR::CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
|
||||
AR::CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
|
||||
AR::CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS);
|
||||
|
||||
/* Enter passive IRQ level */
|
||||
HL::RunLevel::SetRunLevel(PASSIVE_LEVEL);
|
||||
@@ -190,8 +191,8 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
InitializeSegments();
|
||||
|
||||
/* Set GS base */
|
||||
CpuFunc::WriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock);
|
||||
CpuFunc::WriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock);
|
||||
AR::CpuFunc::WriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock);
|
||||
AR::CpuFunc::WriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock);
|
||||
|
||||
/* Initialize processor registers */
|
||||
InitializeProcessorRegisters();
|
||||
@@ -249,34 +250,35 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
|
||||
{
|
||||
/* Set the IDT to handle unexpected interrupts */
|
||||
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArInterruptEntry[Vector], KGDT_R0_CODE,
|
||||
KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
}
|
||||
|
||||
/* Setup IDT handlers for known interrupts and traps */
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x1F, (PVOID)ArTrap0x1F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrap0x2F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArTrap0xE1, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrapEntry[0x00], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrapEntry[0x01], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrapEntry[0x02], KGDT_R0_CODE, KIDT_IST_NMI, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrapEntry[0x03], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrapEntry[0x04], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrapEntry[0x05], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrapEntry[0x06], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrapEntry[0x07], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrapEntry[0x08], KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrapEntry[0x09], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrapEntry[0x0A], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrapEntry[0x0B], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrapEntry[0x0C], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrapEntry[0x0D], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrapEntry[0x0E], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrapEntry[0x10], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrapEntry[0x11], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrapEntry[0x12], KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrapEntry[0x13], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x1F, (PVOID)ArTrapEntry[0x1F], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrapEntry[0x2C], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrapEntry[0x2D], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrapEntry[0x2F], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArInterruptEntry[0xE1], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -355,45 +357,45 @@ AR::ProcSup::InitializeProcessorRegisters(VOID)
|
||||
ULONGLONG PatAttributes;
|
||||
|
||||
/* Enable FXSAVE restore */
|
||||
CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_FXSR);
|
||||
AR::CpuFunc::WriteControlRegister(4, AR::CpuFunc::ReadControlRegister(4) | CR4_FXSR);
|
||||
|
||||
/* Enable XMMI exceptions */
|
||||
CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_XMMEXCPT);
|
||||
AR::CpuFunc::WriteControlRegister(4, AR::CpuFunc::ReadControlRegister(4) | CR4_XMMEXCPT);
|
||||
|
||||
/* Set debugger extension */
|
||||
CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_DE);
|
||||
AR::CpuFunc::WriteControlRegister(4, AR::CpuFunc::ReadControlRegister(4) | CR4_DE);
|
||||
|
||||
/* Enable large pages */
|
||||
CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_PSE);
|
||||
AR::CpuFunc::WriteControlRegister(4, AR::CpuFunc::ReadControlRegister(4) | CR4_PSE);
|
||||
|
||||
/* Enable write-protection */
|
||||
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_WP);
|
||||
AR::CpuFunc::WriteControlRegister(0, AR::CpuFunc::ReadControlRegister(0) | CR0_WP);
|
||||
|
||||
/* Set alignment mask */
|
||||
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_AM);
|
||||
AR::CpuFunc::WriteControlRegister(0, AR::CpuFunc::ReadControlRegister(0) | CR0_AM);
|
||||
|
||||
/* Disable FPU monitoring */
|
||||
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) & ~CR0_MP);
|
||||
AR::CpuFunc::WriteControlRegister(0, AR::CpuFunc::ReadControlRegister(0) & ~CR0_MP);
|
||||
|
||||
/* Disable x87 FPU exceptions */
|
||||
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) & ~CR0_NE);
|
||||
AR::CpuFunc::WriteControlRegister(0, AR::CpuFunc::ReadControlRegister(0) & ~CR0_NE);
|
||||
|
||||
/* Flush the TLB */
|
||||
CpuFunc::FlushTlb();
|
||||
AR::CpuFunc::FlushTlb();
|
||||
|
||||
/* Initialize system call MSRs */
|
||||
Traps::InitializeSystemCallMsrs();
|
||||
AR::Traps::InitializeSystemCallMsrs();
|
||||
|
||||
/* Enable No-Execute (NXE) in EFER MSR */
|
||||
CpuFunc::WriteModelSpecificRegister(X86_MSR_EFER, CpuFunc::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_NXE);
|
||||
AR::CpuFunc::WriteModelSpecificRegister(X86_MSR_EFER, CpuFunc::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_NXE);
|
||||
|
||||
/* Initialize Page Attribute Table */
|
||||
PatAttributes = (PAT_TYPE_WB << 0) | (PAT_TYPE_USWC << 8) | (PAT_TYPE_WEAK_UC << 16) | (PAT_TYPE_STRONG_UC << 24) |
|
||||
(PAT_TYPE_WB << 32) | (PAT_TYPE_USWC << 40) | (PAT_TYPE_WEAK_UC << 48) | (PAT_TYPE_STRONG_UC << 56);
|
||||
CpuFunc::WriteModelSpecificRegister(X86_MSR_PAT, PatAttributes);
|
||||
AR::CpuFunc::WriteModelSpecificRegister(X86_MSR_PAT, PatAttributes);
|
||||
|
||||
/* Initialize MXCSR register */
|
||||
CpuFunc::LoadMxcsrRegister(INITIAL_MXCSR);
|
||||
AR::CpuFunc::LoadMxcsrRegister(INITIAL_MXCSR);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -428,7 +430,8 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
||||
OUT PKTSS *Tss,
|
||||
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
||||
OUT PVOID *KernelBootStack,
|
||||
OUT PVOID *KernelFaultStack)
|
||||
OUT PVOID *KernelFaultStack,
|
||||
OUT PVOID *KernelNmiStack)
|
||||
{
|
||||
UINT_PTR Address;
|
||||
|
||||
@@ -439,8 +442,12 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
||||
*KernelBootStack = (PVOID)Address;
|
||||
Address += KERNEL_STACK_SIZE;
|
||||
|
||||
/* Assign a space for kernel fault stack, no advance needed as stack grows down */
|
||||
/* Assign a space for kernel fault stack and advance */
|
||||
*KernelFaultStack = (PVOID)Address;
|
||||
Address += KERNEL_STACK_SIZE;
|
||||
|
||||
/* Assign a space for kernel NMI stack, no advance needed as stack grows down */
|
||||
*KernelNmiStack = (PVOID)Address;
|
||||
|
||||
/* Assign a space for GDT and advance */
|
||||
*Gdt = (PKGDTENTRY)(PVOID)Address;
|
||||
@@ -466,12 +473,12 @@ VOID
|
||||
AR::ProcSup::InitializeSegments(VOID)
|
||||
{
|
||||
/* Initialize segments */
|
||||
CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
|
||||
CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
|
||||
CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
|
||||
CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK);
|
||||
CpuFunc::LoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK);
|
||||
CpuFunc::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -491,7 +498,8 @@ XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelBootStack,
|
||||
IN PVOID KernelFaultStack)
|
||||
IN PVOID KernelFaultStack,
|
||||
IN PVOID KernelNmiStack)
|
||||
{
|
||||
/* Fill TSS with zeroes */
|
||||
RtlZeroMemory(ProcessorBlock->TssBase, sizeof(KTSS));
|
||||
@@ -501,6 +509,7 @@ AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
ProcessorBlock->TssBase->Rsp0 = (ULONG_PTR)KernelBootStack;
|
||||
ProcessorBlock->TssBase->Ist[KIDT_IST_PANIC] = (ULONG_PTR)KernelFaultStack;
|
||||
ProcessorBlock->TssBase->Ist[KIDT_IST_MCA] = (ULONG_PTR)KernelFaultStack;
|
||||
ProcessorBlock->TssBase->Ist[KIDT_IST_NMI] = (ULONG_PTR)KernelNmiStack;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,6 +9,44 @@
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Dispatches the interrupt provided by common interrupt handler.
|
||||
*
|
||||
* @param TrapFrame
|
||||
* Supplies a kernel trap frame pushed by common interrupt handler on the stack.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::Traps::DispatchInterrupt(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
PINTERRUPT_HANDLER Handler;
|
||||
|
||||
/* Read the handler pointer from the CPU's interrupt dispatch table */
|
||||
Handler = (PINTERRUPT_HANDLER)AR::CpuFunc::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, InterruptDispatchTable) +
|
||||
(TrapFrame->Vector * sizeof(PINTERRUPT_HANDLER)));
|
||||
|
||||
/* Check if the interrupt has a handler registered */
|
||||
if(Handler != NULLPTR)
|
||||
{
|
||||
/* Call the handler */
|
||||
Handler(TrapFrame);
|
||||
}
|
||||
else if(UnhandledInterruptRoutine != NULLPTR)
|
||||
{
|
||||
/* Call the unhandled interrupt routine */
|
||||
UnhandledInterruptRoutine(TrapFrame);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Dispatcher not initialized, print a debug message */
|
||||
DebugPrint(L"ERROR: Caught unhandled interrupt: 0x%.2llX\n", TrapFrame->Vector);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches the trap provided by common trap handler.
|
||||
*
|
||||
@@ -227,7 +265,6 @@ VOID
|
||||
AR::Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n");
|
||||
KE::Crash::Panic(0x02);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -645,19 +682,19 @@ AR::Traps::InitializeSystemCallMsrs(VOID)
|
||||
}
|
||||
|
||||
/**
|
||||
* C-linkage wrapper for dispatching the trap provided by common trap handler.
|
||||
* Sets the unhandled interrupt routine used for vectors that have no handler registered.
|
||||
*
|
||||
* @param TrapFrame
|
||||
* Supplies a kernel trap frame pushed by common trap handler on the stack.
|
||||
* @param Handler
|
||||
* Supplies the pointer to the interrupt handler routine.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
XTAPI
|
||||
VOID
|
||||
ArDispatchTrap(IN PKTRAP_FRAME TrapFrame)
|
||||
AR::Traps::SetUnhandledInterruptRoutine(PINTERRUPT_HANDLER Handler)
|
||||
{
|
||||
AR::Traps::DispatchTrap(TrapFrame);
|
||||
/* Set the unhandled interrupt routine */
|
||||
UnhandledInterruptRoutine = Handler;
|
||||
}
|
||||
|
||||
@@ -4,31 +4,69 @@
|
||||
* FILE: xtoskrnl/ar/i686/archsup.S
|
||||
* DESCRIPTION: Provides i686 architecture features not implementable in C.
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <ar/i686/asmsup.h>
|
||||
#include <xtkmapi.h>
|
||||
#include <xtadk.h>
|
||||
|
||||
.altmacro
|
||||
.text
|
||||
|
||||
|
||||
/**
|
||||
* This macro creates a trap handler for the specified vector.
|
||||
* Creates a task, trap or interrupt handler for the specified vector.
|
||||
*
|
||||
* @param Vector
|
||||
* Supplies a trap vector number.
|
||||
* Supplies a vector number.
|
||||
*
|
||||
* @param Type
|
||||
* Specifies whether the handler is designed to handle an interrupt, a task or a trap.
|
||||
*
|
||||
* @return This macro does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.macro ArCreateTrapHandler Vector
|
||||
.global _ArTrap\Vector
|
||||
_ArTrap\Vector:
|
||||
/* Push fake error code for non-error vectors */
|
||||
.macro ArCreateHandler Vector Type
|
||||
.global _Ar\Type\Vector
|
||||
_Ar\Type\Vector:
|
||||
/* Check handler type */
|
||||
.ifc \Type,Task
|
||||
_Ar\Type\Vector\()Start:
|
||||
/* Clear the Task Switch flag */
|
||||
clts
|
||||
|
||||
/* Allocate the trap frame and inject the hardware vector for the dispatcher */
|
||||
sub $KTRAP_FRAME_SIZE, %esp
|
||||
movl $\Vector, KTRAP_FRAME_Vector(%esp)
|
||||
|
||||
/* Pass the trap frame pointer as an argument and clear the direction flag */
|
||||
push %esp
|
||||
cld
|
||||
|
||||
/* Pass control to the trap dispatcher */
|
||||
call _ArDispatchTrap
|
||||
|
||||
/* Discard the argument and deallocate the trap frame */
|
||||
add $4, %esp
|
||||
add $KTRAP_FRAME_SIZE, %esp
|
||||
|
||||
/* Hardware task return */
|
||||
iretl
|
||||
|
||||
/* Spin back to the entry point to rearm the task gate */
|
||||
jmp _Ar\Type\Vector\()Start
|
||||
.else
|
||||
/* Check handler type */
|
||||
.ifc \Type,Trap
|
||||
/* Push fake error code for non-error vector traps */
|
||||
.if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
|
||||
push $0
|
||||
.endif
|
||||
.else
|
||||
/* Push fake error code for interrupts */
|
||||
push $0
|
||||
.endif
|
||||
|
||||
/* Push vector number */
|
||||
push $\Vector
|
||||
@@ -43,75 +81,81 @@ _ArTrap\Vector:
|
||||
push %eax
|
||||
|
||||
/* Reserve space for other registers and point RBP to the trap frame */
|
||||
sub $(TRAP_FRAME_SIZE - TRAP_REGISTERS_SIZE), %esp
|
||||
sub $(KTRAP_FRAME_SIZE - KTRAP_FRAME_REGISTERS_SIZE), %esp
|
||||
lea (%esp), %ebp
|
||||
|
||||
/* Store segment selectors */
|
||||
mov %gs, TrapSegGs(%ebp)
|
||||
mov %fs, TrapSegFs(%ebp)
|
||||
mov %es, TrapSegEs(%ebp)
|
||||
mov %ds, TrapSegDs(%ebp)
|
||||
mov %gs, KTRAP_FRAME_SegGs(%ebp)
|
||||
mov %fs, KTRAP_FRAME_SegFs(%ebp)
|
||||
mov %es, KTRAP_FRAME_SegEs(%ebp)
|
||||
mov %ds, KTRAP_FRAME_SegDs(%ebp)
|
||||
|
||||
/* Store debug registers */
|
||||
mov %dr7, %eax
|
||||
mov %eax, TrapDr7(%ebp)
|
||||
mov %eax, KTRAP_FRAME_Dr7(%ebp)
|
||||
mov %dr6, %eax
|
||||
mov %eax, TrapDr6(%ebp)
|
||||
mov %eax, KTRAP_FRAME_Dr6(%ebp)
|
||||
mov %dr3, %eax
|
||||
mov %eax, TrapDr3(%ebp)
|
||||
mov %eax, KTRAP_FRAME_Dr3(%ebp)
|
||||
mov %dr2, %eax
|
||||
mov %eax, TrapDr2(%ebp)
|
||||
mov %eax, KTRAP_FRAME_Dr2(%ebp)
|
||||
mov %dr1, %eax
|
||||
mov %eax, TrapDr1(%ebp)
|
||||
mov %eax, KTRAP_FRAME_Dr1(%ebp)
|
||||
mov %dr0, %eax
|
||||
mov %eax, TrapDr0(%ebp)
|
||||
mov %eax, KTRAP_FRAME_Dr0(%ebp)
|
||||
|
||||
/* Store CR2 and CR3 */
|
||||
mov %cr3, %eax
|
||||
mov %eax, TrapCr3(%ebp)
|
||||
mov %eax, KTRAP_FRAME_Cr3(%ebp)
|
||||
mov %cr2, %eax
|
||||
mov %eax, TrapCr2(%ebp)
|
||||
mov %eax, KTRAP_FRAME_Cr2(%ebp)
|
||||
|
||||
/* Test previous mode and swap GS if needed */
|
||||
movl $0, TrapPreviousMode(%ebp)
|
||||
mov %cs, %ax
|
||||
/* Test previous mode */
|
||||
movl $0, KTRAP_FRAME_PreviousMode(%ebp)
|
||||
mov KTRAP_FRAME_SegCs(%ebp), %ax
|
||||
and $3, %al
|
||||
mov %al, TrapPreviousMode(%ebp)
|
||||
jz KernelMode$\Vector
|
||||
swapgs
|
||||
jmp UserMode$\Vector
|
||||
mov %al, KTRAP_FRAME_PreviousMode(%ebp)
|
||||
jz Dispatch\Type\Vector
|
||||
|
||||
KernelMode$\Vector:
|
||||
/* Save kernel stack pointer (SS:ESP) as CPU did not push them */
|
||||
movl %ss, %eax
|
||||
mov %eax, TrapSegSs(%ebp)
|
||||
lea TrapEsp(%ebp), %eax
|
||||
mov %eax, TrapEsp(%ebp)
|
||||
/* Load Kernel PB selector into FS */
|
||||
mov $KGDT_R0_PB, %ax
|
||||
mov %ax, %fs
|
||||
|
||||
UserMode$\Vector:
|
||||
/* Push Frame Pointer, clear direction flag and pass to trap dispatcher */
|
||||
/* Set sane data segment selectors */
|
||||
mov $(KGDT_R3_DATA | RPL_MASK), %ax
|
||||
mov %ax, %ds
|
||||
mov %ax, %es
|
||||
|
||||
Dispatch\Type\Vector:
|
||||
/* Push Frame Pointer and clear direction flag */
|
||||
push %esp
|
||||
cld
|
||||
|
||||
.ifc \Type,Trap
|
||||
/* Pass to the trap dispatcher */
|
||||
call _ArDispatchTrap
|
||||
.else
|
||||
/* Pass to the interrupt dispatcher */
|
||||
call _ArDispatchInterrupt
|
||||
.endif
|
||||
|
||||
/* Clean up the stack */
|
||||
add $4, %esp
|
||||
|
||||
/* Test previous mode and swapgs if needed */
|
||||
testb $1, TrapPreviousMode(%ebp)
|
||||
jz KernelModeReturn$\Vector
|
||||
/* Test previous mode and disable interrupts before user mode return */
|
||||
testb $1, KTRAP_FRAME_PreviousMode(%ebp)
|
||||
jz RestoreState\Type\Vector
|
||||
cli
|
||||
swapgs
|
||||
|
||||
KernelModeReturn$\Vector:
|
||||
RestoreState\Type\Vector:
|
||||
/* Restore segment selectors */
|
||||
mov TrapSegDs(%ebp), %ds
|
||||
mov TrapSegEs(%ebp), %es
|
||||
mov TrapSegFs(%ebp), %fs
|
||||
mov TrapSegGs(%ebp), %gs
|
||||
mov KTRAP_FRAME_SegDs(%ebp), %ds
|
||||
mov KTRAP_FRAME_SegEs(%ebp), %es
|
||||
mov KTRAP_FRAME_SegFs(%ebp), %fs
|
||||
mov KTRAP_FRAME_SegGs(%ebp), %gs
|
||||
|
||||
/* Free stack space */
|
||||
add $(TRAP_FRAME_SIZE - TRAP_REGISTERS_SIZE), %esp
|
||||
add $(KTRAP_FRAME_SIZE - KTRAP_FRAME_REGISTERS_SIZE), %esp
|
||||
|
||||
/* Pop General Purpose Registers */
|
||||
pop %eax
|
||||
@@ -125,11 +169,79 @@ KernelModeReturn$\Vector:
|
||||
/* Skip error code and vector number, then return */
|
||||
add $(2 * 4), %esp
|
||||
iretl
|
||||
.endif
|
||||
.endm
|
||||
|
||||
/* Populate common trap handlers */
|
||||
/* Populate common interrupt, task and 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
|
||||
ArCreateTrapHandler 0x\i\j
|
||||
ArCreateHandler 0x\i\j Interrupt
|
||||
.if 0x\i\j == 0x02 || 0x\i\j == 0x08
|
||||
ArCreateHandler 0x\i\j Task
|
||||
.else
|
||||
ArCreateHandler 0x\i\j Trap
|
||||
.endif
|
||||
.endr
|
||||
.endr
|
||||
|
||||
/* Define array of pointers to the interrupt handlers */
|
||||
.global _ArInterruptEntry
|
||||
_ArInterruptEntry:
|
||||
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.long _ArInterrupt0x\i\j
|
||||
.endr
|
||||
.endr
|
||||
|
||||
/* Define array of pointers to the trap handlers */
|
||||
.global _ArTrapEntry
|
||||
_ArTrapEntry:
|
||||
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.if 0x\i\j == 0x02 || 0x\i\j == 0x08
|
||||
.long _ArTask0x\i\j
|
||||
.else
|
||||
.long _ArTrap0x\i\j
|
||||
.endif
|
||||
.endr
|
||||
.endr
|
||||
|
||||
/**
|
||||
* Enables eXtended Physical Addressing (XPA). On i386, this is just a stub.
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page map to be used.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.global ArEnableExtendedPhysicalAddressing
|
||||
ArEnableExtendedPhysicalAddressing:
|
||||
|
||||
.global ArEnableExtendedPhysicalAddressingEnd
|
||||
ArEnableExtendedPhysicalAddressingEnd:
|
||||
|
||||
/**
|
||||
* Handles a spurious interrupt allowing it to end up.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.global _ArHandleSpuriousInterrupt
|
||||
_ArHandleSpuriousInterrupt:
|
||||
iret
|
||||
|
||||
/**
|
||||
* Starts an application processor (AP). This is just a stub.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.global _ArStartApplicationProcessor
|
||||
_ArStartApplicationProcessor:
|
||||
|
||||
.global _ArStartApplicationProcessorEnd
|
||||
_ArStartApplicationProcessorEnd:
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ar/i686/boot.S
|
||||
* DESCRIPTION: i686-specific boot code for setting up the low-level CPU environment
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <ar/amd64/asmsup.h>
|
||||
|
||||
.altmacro
|
||||
.text
|
||||
|
||||
|
||||
/**
|
||||
* Starts an application processor (AP). This is just a stub.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.global _ArStartApplicationProcessor
|
||||
_ArStartApplicationProcessor:
|
||||
|
||||
.global _ArStartApplicationProcessorEnd
|
||||
_ArStartApplicationProcessorEnd:
|
||||
@@ -30,5 +30,11 @@ KPROCESSOR_BLOCK AR::ProcSup::InitialProcessorBlock;
|
||||
/* Initial TSS */
|
||||
KTSS AR::ProcSup::InitialTss;
|
||||
|
||||
/* Initial kernel NMI stack */
|
||||
UCHAR AR::ProcSup::NmiStack[KERNEL_STACK_SIZE] = {};
|
||||
|
||||
/* NMI task gate */
|
||||
UCHAR AR::ProcSup::NonMaskableInterruptTss[KTSS_IO_MAPS];
|
||||
|
||||
/* Unhandled interrupt routine */
|
||||
PINTERRUPT_HANDLER AR::Traps::UnhandledInterruptRoutine = NULLPTR;
|
||||
|
||||
@@ -68,7 +68,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
/* Get CPU vendor by issueing CPUID instruction */
|
||||
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
|
||||
CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU vendor in processor control block */
|
||||
Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx;
|
||||
@@ -80,7 +80,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
/* Get CPU standard features */
|
||||
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||
CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU signature in processor control block */
|
||||
CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax;
|
||||
@@ -92,23 +92,23 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
if(Prcb->CpuId.Vendor == CPU_VENDOR_AMD)
|
||||
{
|
||||
/* AMD CPU */
|
||||
if(Prcb->CpuId.Family >= 0xF)
|
||||
if(CpuSignature.Family == 0xF)
|
||||
{
|
||||
Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
|
||||
Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
|
||||
Prcb->CpuId.Family += CpuSignature.ExtendedFamily;
|
||||
Prcb->CpuId.Model += (CpuSignature.ExtendedModel << 4);
|
||||
}
|
||||
}
|
||||
else if(Prcb->CpuId.Vendor == CPU_VENDOR_INTEL)
|
||||
{
|
||||
/* Intel CPU */
|
||||
if(Prcb->CpuId.Family == 0xF)
|
||||
if(CpuSignature.Family == 0xF)
|
||||
{
|
||||
Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
|
||||
Prcb->CpuId.Family += CpuSignature.ExtendedFamily;
|
||||
}
|
||||
|
||||
if((Prcb->CpuId.Family == 0x6) || (Prcb->CpuId.Family == 0xF))
|
||||
if((CpuSignature.Family == 0x6) || (CpuSignature.Family == 0xF))
|
||||
{
|
||||
Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
|
||||
Prcb->CpuId.Model += (CpuSignature.ExtendedModel << 4);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -132,7 +132,7 @@ VOID
|
||||
AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
{
|
||||
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
|
||||
PVOID KernelBootStack, KernelFaultStack;
|
||||
PVOID KernelBootStack, KernelFaultStack, KernelNmiStack;
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
PKGDTENTRY Gdt;
|
||||
PKIDTENTRY Idt;
|
||||
@@ -143,7 +143,7 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
{
|
||||
/* Assign CPU structures from provided buffer */
|
||||
InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
|
||||
&KernelBootStack, &KernelFaultStack);
|
||||
&KernelBootStack, &KernelFaultStack, &KernelNmiStack);
|
||||
|
||||
/* Use global IDT */
|
||||
Idt = InitialIdt;
|
||||
@@ -154,8 +154,9 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
Gdt = InitialGdt;
|
||||
Idt = InitialIdt;
|
||||
Tss = &InitialTss;
|
||||
KernelBootStack = &BootStack;
|
||||
KernelFaultStack = &FaultStack;
|
||||
KernelBootStack = (PVOID)((ULONG_PTR)&BootStack + KERNEL_STACK_SIZE);
|
||||
KernelFaultStack = (PVOID)((ULONG_PTR)&FaultStack + KERNEL_STACK_SIZE);
|
||||
KernelNmiStack = (PVOID)((ULONG_PTR)&NmiStack + KERNEL_STACK_SIZE);
|
||||
ProcessorBlock = &InitialProcessorBlock;
|
||||
}
|
||||
|
||||
@@ -165,7 +166,7 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
/* Initialize GDT, IDT and TSS */
|
||||
InitializeGdt(ProcessorBlock);
|
||||
InitializeIdt(ProcessorBlock);
|
||||
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack);
|
||||
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack, KernelNmiStack);
|
||||
|
||||
/* Set GDT and IDT descriptors */
|
||||
GdtDescriptor.Base = Gdt;
|
||||
@@ -174,9 +175,9 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
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);
|
||||
AR::CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
|
||||
AR::CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
|
||||
AR::CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS);
|
||||
|
||||
/* Enter passive IRQ level */
|
||||
HL::RunLevel::SetRunLevel(PASSIVE_LEVEL);
|
||||
@@ -215,9 +216,9 @@ AR::ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_PB, (ULONG_PTR)ProcessorBlock, sizeof(KPROCESSOR_BLOCK), KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2);
|
||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_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_R0_LDT, 0x0, 0x0, I686_LDT, 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_NMI_TSS, 0x20000, 0xFFFF, I686_TSS, 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);
|
||||
}
|
||||
@@ -242,34 +243,35 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
|
||||
{
|
||||
/* Set the IDT to handle unexpected interrupts */
|
||||
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArInterruptEntry[Vector],
|
||||
KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
}
|
||||
|
||||
/* Setup IDT handlers for known interrupts and traps */
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrap0x2A, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrap0x2B, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrap0x2E, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrapEntry[0x00], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrapEntry[0x01], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrapEntry[0x02], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TASK_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrapEntry[0x03], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrapEntry[0x04], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrapEntry[0x05], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrapEntry[0x06], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrapEntry[0x07], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrapEntry[0x08], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TASK_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrapEntry[0x09], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrapEntry[0x0A], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrapEntry[0x0B], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrapEntry[0x0C], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrapEntry[0x0D], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrapEntry[0x0E], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrapEntry[0x10], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrapEntry[0x11], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrapEntry[0x12], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrapEntry[0x13], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrapEntry[0x2A], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrapEntry[0x2B], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrapEntry[0x2C], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrapEntry[0x2D], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrapEntry[0x2E], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -342,10 +344,10 @@ VOID
|
||||
AR::ProcSup::InitializeProcessorRegisters(VOID)
|
||||
{
|
||||
/* Clear EFLAGS register */
|
||||
CpuFunc::WriteEflagsRegister(0);
|
||||
AR::CpuFunc::WriteEflagsRegister(0);
|
||||
|
||||
/* Enable write-protection */
|
||||
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_WP);
|
||||
AR::CpuFunc::WriteControlRegister(0, AR::CpuFunc::ReadControlRegister(0) | CR0_WP);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -380,7 +382,8 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
||||
OUT PKTSS *Tss,
|
||||
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
||||
OUT PVOID *KernelBootStack,
|
||||
OUT PVOID *KernelFaultStack)
|
||||
OUT PVOID *KernelFaultStack,
|
||||
OUT PVOID *KernelNmiStack)
|
||||
{
|
||||
UINT_PTR Address;
|
||||
|
||||
@@ -391,8 +394,12 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
||||
*KernelBootStack = (PVOID)Address;
|
||||
Address += KERNEL_STACK_SIZE;
|
||||
|
||||
/* Assign a space for kernel fault stack, no advance needed as stack grows down */
|
||||
/* Assign a space for kernel fault stack and advance */
|
||||
*KernelFaultStack = (PVOID)Address;
|
||||
Address += KERNEL_STACK_SIZE;
|
||||
|
||||
/* Assign a space for kernel NMI stack, no advance needed as stack grows down */
|
||||
*KernelNmiStack = (PVOID)Address;
|
||||
|
||||
/* Assign a space for GDT and advance */
|
||||
*Gdt = (PKGDTENTRY)(PVOID)Address;
|
||||
@@ -418,10 +425,12 @@ VOID
|
||||
AR::ProcSup::InitializeSegments(VOID)
|
||||
{
|
||||
/* Initialize segments */
|
||||
CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
|
||||
CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
|
||||
CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
|
||||
CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R0_PB);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R0_PB);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_GS, 0);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -438,8 +447,19 @@ XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelBootStack,
|
||||
IN PVOID KernelFaultStack)
|
||||
IN PVOID KernelFaultStack,
|
||||
IN PVOID KernelNmiStack)
|
||||
{
|
||||
PKGDTENTRY TssEntry;
|
||||
|
||||
/* Setup System TSS entry in Global Descriptor Table */
|
||||
TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_SYS_TSS / sizeof(KGDTENTRY)]));
|
||||
TssEntry->LimitLow = sizeof(KTSS) - 1;
|
||||
TssEntry->Bits.LimitHigh = 0;
|
||||
TssEntry->Bits.Dpl = 0;
|
||||
TssEntry->Bits.Present = 1;
|
||||
TssEntry->Bits.Type = I686_TSS;
|
||||
|
||||
/* Clear I/O map */
|
||||
RtlSetMemory(ProcessorBlock->TssBase->IoMaps[0].IoMap, 0xFF, IOPM_FULL_SIZE);
|
||||
|
||||
@@ -461,16 +481,16 @@ AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
|
||||
/* Set I/O map base and disable traps */
|
||||
ProcessorBlock->TssBase->IoMapBase = sizeof(KTSS);
|
||||
ProcessorBlock->TssBase->Esp0 = (ULONG_PTR)KernelBootStack;
|
||||
ProcessorBlock->TssBase->Flags = 0;
|
||||
|
||||
/* Set LDT and SS */
|
||||
ProcessorBlock->TssBase->LDT = KGDT_R0_LDT;
|
||||
/* Set CR3, LDT and SS */
|
||||
ProcessorBlock->TssBase->CR3 = AR::CpuFunc::ReadControlRegister(3);
|
||||
ProcessorBlock->TssBase->LDT = 0;
|
||||
ProcessorBlock->TssBase->Ss0 = KGDT_R0_DATA;
|
||||
|
||||
/* Initialize task gates for DoubleFault and NMI traps */
|
||||
SetDoubleFaultTssEntry(ProcessorBlock, KernelFaultStack);
|
||||
SetNonMaskableInterruptTssEntry(ProcessorBlock, KernelFaultStack);
|
||||
SetNonMaskableInterruptTssEntry(ProcessorBlock, KernelNmiStack);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -502,24 +522,24 @@ AR::ProcSup::SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
Tss = (PKTSS)DoubleFaultTss;
|
||||
Tss->IoMapBase = sizeof(KTSS);
|
||||
Tss->Flags = 0;
|
||||
Tss->LDT = KGDT_R0_LDT;
|
||||
Tss->CR3 = CpuFunc::ReadControlRegister(3);
|
||||
Tss->LDT = 0;
|
||||
Tss->CR3 = AR::CpuFunc::ReadControlRegister(3);
|
||||
Tss->Esp = (ULONG_PTR)KernelFaultStack;
|
||||
Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
|
||||
Tss->Eip = PtrToUlong(ArTrap0x08);
|
||||
Tss->Eip = (ULONG)(ULONG_PTR)ArTrapEntry[0x08];
|
||||
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->Ss = KGDT_R0_DATA;
|
||||
Tss->Ss0 = KGDT_R0_DATA;
|
||||
CpuFunc::StoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss);
|
||||
|
||||
/* Setup DoubleFault TSS entry in Global Descriptor Table */
|
||||
TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_DF_TSS / sizeof(KGDTENTRY)]));
|
||||
TssEntry->BaseLow = ((ULONG_PTR)Tss & 0xFFFF);
|
||||
TssEntry->Bytes.BaseMiddle = ((ULONG_PTR)Tss >> 16);
|
||||
TssEntry->Bytes.BaseHigh = ((ULONG_PTR)Tss >> 24);
|
||||
TssEntry->LimitLow = sizeof(KTSS) - 1;
|
||||
TssEntry->LimitLow = 0x68;
|
||||
TssEntry->Bits.LimitHigh = 0;
|
||||
TssEntry->Bits.Dpl = 0;
|
||||
TssEntry->Bits.Present = 1;
|
||||
@@ -700,7 +720,7 @@ AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelFaultStack)
|
||||
IN PVOID KernelNmiStack)
|
||||
{
|
||||
PKGDTENTRY TaskGateEntry, TssEntry;
|
||||
PKTSS Tss;
|
||||
@@ -716,23 +736,24 @@ AR::ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock
|
||||
Tss = (PKTSS)NonMaskableInterruptTss;
|
||||
Tss->IoMapBase = sizeof(KTSS);
|
||||
Tss->Flags = 0;
|
||||
Tss->LDT = KGDT_R0_LDT;
|
||||
Tss->CR3 = CpuFunc::ReadControlRegister(3);
|
||||
Tss->Esp = (ULONG_PTR)KernelFaultStack;
|
||||
Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
|
||||
Tss->Eip = PtrToUlong(ArTrap0x02);
|
||||
Tss->LDT = 0;
|
||||
Tss->CR3 = AR::CpuFunc::ReadControlRegister(3);
|
||||
Tss->Esp = (ULONG_PTR)KernelNmiStack;
|
||||
Tss->Esp0 = (ULONG_PTR)KernelNmiStack;
|
||||
Tss->Eip = (ULONG)(ULONG_PTR)ArTrapEntry[0x02];
|
||||
Tss->Cs = KGDT_R0_CODE;
|
||||
Tss->Ds = KGDT_R3_DATA | RPL_MASK;
|
||||
Tss->Es = KGDT_R3_DATA | RPL_MASK;
|
||||
Tss->Fs = KGDT_R0_PB;
|
||||
CpuFunc::StoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss);
|
||||
Tss->Ss = KGDT_R0_DATA;
|
||||
Tss->Ss0 = KGDT_R0_DATA;
|
||||
|
||||
/* Setup NMI TSS entry in Global Descriptor Table */
|
||||
TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_NMI_TSS / sizeof(KGDTENTRY)]));
|
||||
TssEntry->BaseLow = ((ULONG_PTR)Tss & 0xFFFF);
|
||||
TssEntry->Bytes.BaseMiddle = ((ULONG_PTR)Tss >> 16);
|
||||
TssEntry->Bytes.BaseHigh = ((ULONG_PTR)Tss >> 24);
|
||||
TssEntry->LimitLow = sizeof(KTSS) - 1;
|
||||
TssEntry->LimitLow = 0x68;
|
||||
TssEntry->Bits.LimitHigh = 0;
|
||||
TssEntry->Bits.Dpl = 0;
|
||||
TssEntry->Bits.Present = 1;
|
||||
|
||||
@@ -9,6 +9,44 @@
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Dispatches the interrupt provided by common interrupt handler.
|
||||
*
|
||||
* @param TrapFrame
|
||||
* Supplies a kernel trap frame pushed by common interrupt handler on the stack.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::Traps::DispatchInterrupt(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
PINTERRUPT_HANDLER Handler;
|
||||
|
||||
/* Read the handler pointer from the CPU's interrupt dispatch table */
|
||||
Handler = (PINTERRUPT_HANDLER)AR::CpuFunc::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, InterruptDispatchTable) +
|
||||
(TrapFrame->Vector * sizeof(PINTERRUPT_HANDLER)));
|
||||
|
||||
/* Check if the interrupt has a handler registered */
|
||||
if(Handler != NULLPTR)
|
||||
{
|
||||
/* Call the handler */
|
||||
Handler(TrapFrame);
|
||||
}
|
||||
else if(UnhandledInterruptRoutine != NULLPTR)
|
||||
{
|
||||
/* Call the unhandled interrupt routine */
|
||||
UnhandledInterruptRoutine(TrapFrame);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Dispatcher not initialized, print a debug message */
|
||||
DebugPrint(L"ERROR: Caught unhandled interrupt: 0x%.2lX\n", TrapFrame->Vector);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches the trap provided by common trap handler.
|
||||
*
|
||||
@@ -195,7 +233,6 @@ VOID
|
||||
AR::Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n");
|
||||
KE::Crash::Panic(0x02);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -592,19 +629,19 @@ AR::Traps::HandleTrapFF(IN PKTRAP_FRAME TrapFrame)
|
||||
}
|
||||
|
||||
/**
|
||||
* C-linkage wrapper for dispatching the trap provided by common trap handler.
|
||||
* Sets the unhandled interrupt routine used for vectors that have no handler registered.
|
||||
*
|
||||
* @param TrapFrame
|
||||
* Supplies a kernel trap frame pushed by common trap handler on the stack.
|
||||
* @param Handler
|
||||
* Supplies the pointer to the interrupt handler routine.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArDispatchTrap(IN PKTRAP_FRAME TrapFrame)
|
||||
AR::Traps::SetUnhandledInterruptRoutine(PINTERRUPT_HANDLER Handler)
|
||||
{
|
||||
AR::Traps::DispatchTrap(TrapFrame);
|
||||
/* Set the unhandled interrupt routine */
|
||||
UnhandledInterruptRoutine = Handler;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* FILE: xtoskrnl/hl/x86/acpi.cc
|
||||
* DESCRIPTION: Advanced Configuration and Power Interface (ACPI) support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
@@ -25,8 +26,21 @@ 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);
|
||||
/* Check if there are free slots in static early-boot cache array */
|
||||
if(CacheCount >= ACPI_MAX_CACHED_TABLES)
|
||||
{
|
||||
/* Cache is full, the table is mapped but not cached */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the next available static cache entry */
|
||||
AcpiCache = &CacheEntries[CacheCount];
|
||||
CacheCount++;
|
||||
|
||||
/* Store the pointer to the mapped ACPI table */
|
||||
AcpiCache->Table = AcpiTable;
|
||||
|
||||
/* Insert entry into the global ACPI cache list */
|
||||
RTL::LinkedList::InsertTailList(&CacheList, &AcpiCache->ListEntry);
|
||||
}
|
||||
|
||||
@@ -196,14 +210,23 @@ HL::Acpi::InitializeAcpiSystemDescriptionTable(OUT PACPI_DESCRIPTION_HEADER *Acp
|
||||
AcpiResource = (PSYSTEM_RESOURCE_ACPI)ResourceHeader;
|
||||
RsdpAddress.QuadPart = (LONGLONG)AcpiResource->Header.PhysicalAddress;
|
||||
|
||||
/* Map RSDP and mark it as CD/WT to avoid delays in write-back cache */
|
||||
/* Map RSDP using hardware memory pool */
|
||||
Status = MM::HardwarePool::MapHardwareMemory(RsdpAddress, 1, TRUE, (PVOID *)&RsdpStructure);
|
||||
if(Status != STATUS_SUCCESS)
|
||||
{
|
||||
/* Failed to map RSDP, return error */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Mark RSDP as CD/WT to avoid delays in write-back cache */
|
||||
MM::HardwarePool::MarkHardwareMemoryWriteThrough(RsdpStructure, 1);
|
||||
|
||||
/* Validate RSDP signature */
|
||||
if(Status != STATUS_SUCCESS || RsdpStructure->Signature != ACPI_RSDP_SIGNATURE)
|
||||
if(RsdpStructure->Signature != ACPI_RSDP_SIGNATURE)
|
||||
{
|
||||
/* Not mapped correctly or invalid RSDP signature, return error */
|
||||
/* Invalid RSDP signature, unmap and return error */
|
||||
MM::HardwarePool::UnmapHardwareMemory(RsdpStructure, 1, TRUE);
|
||||
RsdpStructure = NULLPTR;
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
@@ -219,34 +242,40 @@ HL::Acpi::InitializeAcpiSystemDescriptionTable(OUT PACPI_DESCRIPTION_HEADER *Acp
|
||||
RsdtAddress.QuadPart = (LONGLONG)RsdpStructure->RsdtAddress;
|
||||
}
|
||||
|
||||
/* Map RSDT/XSDT as CD/WT */
|
||||
/* Map RSDT/XSDT using hardware memory pool */
|
||||
Status = MM::HardwarePool::MapHardwareMemory(RsdtAddress, 2, TRUE, (PVOID *)&Rsdt);
|
||||
if(Status != STATUS_SUCCESS)
|
||||
{
|
||||
/* Failed to map RSDT/XSDT, return error */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Mark RSDT/XSDT as CD/WT */
|
||||
MM::HardwarePool::MarkHardwareMemoryWriteThrough(Rsdt, 2);
|
||||
|
||||
/* Validate RSDT/XSDT signature */
|
||||
if((Status != STATUS_SUCCESS) ||
|
||||
(Rsdt->Header.Signature != ACPI_RSDT_SIGNATURE &&
|
||||
Rsdt->Header.Signature != ACPI_XSDT_SIGNATURE))
|
||||
if(Rsdt->Header.Signature != ACPI_RSDT_SIGNATURE && Rsdt->Header.Signature != ACPI_XSDT_SIGNATURE)
|
||||
{
|
||||
/* Not mapped correctly or invalid RSDT/XSDT signature, return error */
|
||||
/* Not mapped correctly or invalid RSDT/XSDT signature, unmap and return error */
|
||||
MM::HardwarePool::UnmapHardwareMemory(Rsdt, 2, TRUE);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Calculate the length of all available ACPI tables and remap it if needed */
|
||||
RsdtPages = ((RsdtAddress.LowPart & (MM_PAGE_SIZE - 1)) + Rsdt->Header.Length + (MM_PAGE_SIZE - 1)) >> MM_PAGE_SHIFT;
|
||||
RsdtPages = (((RsdtAddress.LowPart & (MM_PAGE_SIZE - 1)) + Rsdt->Header.Length + (MM_PAGE_SIZE - 1)) >> MM_PAGE_SHIFT);
|
||||
if(RsdtPages != 2)
|
||||
{
|
||||
/* RSDT/XSDT needs less or more than 2 pages, remap it */
|
||||
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)
|
||||
{
|
||||
/* Remapping failed, return error */
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* Mark remapped RSDT/XSDT as CD/WT */
|
||||
MM::HardwarePool::MarkHardwareMemoryWriteThrough(Rsdt, RsdtPages);
|
||||
}
|
||||
|
||||
/* Get ACPI table header and return success */
|
||||
@@ -267,6 +296,7 @@ HL::Acpi::InitializeAcpiSystemInformation(VOID)
|
||||
{
|
||||
PACPI_MADT_LOCAL_X2APIC LocalX2Apic;
|
||||
PACPI_MADT_LOCAL_APIC LocalApic;
|
||||
PACPI_SUBTABLE_HEADER SubTable;
|
||||
ULONG_PTR MadtTable;
|
||||
PACPI_MADT Madt;
|
||||
XTSTATUS Status;
|
||||
@@ -293,11 +323,20 @@ HL::Acpi::InitializeAcpiSystemInformation(VOID)
|
||||
CpuCount = 0;
|
||||
|
||||
/* Traverse all MADT tables to get system information */
|
||||
while(MadtTable <= ((ULONG_PTR)Madt + Madt->Header.Length))
|
||||
while(MadtTable < ((ULONG_PTR)Madt + Madt->Header.Length))
|
||||
{
|
||||
/* Get current MADT subtable header */
|
||||
SubTable = (PACPI_SUBTABLE_HEADER)MadtTable;
|
||||
|
||||
/* Prevent infinite loops if BIOS provides 0 length */
|
||||
if(SubTable->Length == 0)
|
||||
{
|
||||
/* Broken ACPI table, abort traversal */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if this is a local APIC subtable */
|
||||
if((((PACPI_SUBTABLE_HEADER)MadtTable)->Type == ACPI_MADT_TYPE_LOCAL_APIC) &&
|
||||
(((PACPI_SUBTABLE_HEADER)MadtTable)->Length == sizeof(ACPI_MADT_LOCAL_APIC)))
|
||||
if(SubTable->Type == ACPI_MADT_TYPE_LOCAL_APIC && SubTable->Length >= sizeof(ACPI_MADT_LOCAL_APIC))
|
||||
{
|
||||
/* Get local APIC subtable */
|
||||
LocalApic = (PACPI_MADT_LOCAL_APIC)MadtTable;
|
||||
@@ -313,12 +352,8 @@ HL::Acpi::InitializeAcpiSystemInformation(VOID)
|
||||
/* Increment number of CPUs */
|
||||
CpuCount++;
|
||||
}
|
||||
|
||||
/* Go to the next MADT table */
|
||||
MadtTable += ((PACPI_SUBTABLE_HEADER)MadtTable)->Length;
|
||||
}
|
||||
else if((((PACPI_SUBTABLE_HEADER)MadtTable)->Type == ACPI_MADT_TYPE_LOCAL_X2APIC) &&
|
||||
(((PACPI_SUBTABLE_HEADER)MadtTable)->Length == sizeof(ACPI_MADT_LOCAL_X2APIC)))
|
||||
else if(SubTable->Type == ACPI_MADT_TYPE_LOCAL_X2APIC && SubTable->Length >= sizeof(ACPI_MADT_LOCAL_X2APIC))
|
||||
{
|
||||
/* Get local X2APIC subtable */
|
||||
LocalX2Apic = (PACPI_MADT_LOCAL_X2APIC)MadtTable;
|
||||
@@ -334,15 +369,10 @@ HL::Acpi::InitializeAcpiSystemInformation(VOID)
|
||||
/* Increment number of CPUs */
|
||||
CpuCount++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Go to the next MADT table */
|
||||
MadtTable += ((PACPI_SUBTABLE_HEADER)MadtTable)->Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Any other MADT table, try to go to the next one byte-by-byte */
|
||||
MadtTable += 1;
|
||||
}
|
||||
/* Safely advance pointer using proper subtable length */
|
||||
MadtTable += SubTable->Length;
|
||||
}
|
||||
|
||||
/* Store number of CPUs */
|
||||
@@ -522,10 +552,10 @@ HL::Acpi::QueryAcpiCache(IN ULONG Signature,
|
||||
AcpiCache = CONTAIN_RECORD(ListEntry, ACPI_CACHE_LIST, ListEntry);
|
||||
|
||||
/* Check if ACPI table signature matches */
|
||||
if(AcpiCache->Header.Signature == Signature)
|
||||
if(AcpiCache->Table->Signature == Signature)
|
||||
{
|
||||
/* ACPI table found in cache, return it */
|
||||
TableHeader = &AcpiCache->Header;
|
||||
TableHeader = AcpiCache->Table;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -596,17 +626,30 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
|
||||
/* Check if DSDT or FACS table requested */
|
||||
if(Signature == ACPI_DSDT_SIGNATURE)
|
||||
{
|
||||
/* Get DSDT address */
|
||||
TableAddress.LowPart = Fadt->Dsdt;
|
||||
/* Prefer 64-bit address on ACPI 2.0+ */
|
||||
if(Fadt->Header.Revision >= 2 && Fadt->XDsdt.QuadPart != 0)
|
||||
{
|
||||
TableAddress.QuadPart = Fadt->XDsdt.QuadPart;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get FACS address */
|
||||
TableAddress.LowPart = Fadt->FirmwareCtrl;
|
||||
}
|
||||
|
||||
/* Fill in high part of ACPI table address */
|
||||
TableAddress.LowPart = Fadt->Dsdt;
|
||||
TableAddress.HighPart = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Prefer 64-bit address on ACPI 2.0+ */
|
||||
if(Fadt->Header.Revision >= 2 && Fadt->XFirmwareCtrl.QuadPart != 0)
|
||||
{
|
||||
TableAddress.QuadPart = Fadt->XFirmwareCtrl.QuadPart;
|
||||
}
|
||||
else
|
||||
{
|
||||
TableAddress.LowPart = Fadt->FirmwareCtrl;
|
||||
TableAddress.HighPart = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Map table using hardware memory pool */
|
||||
Status = MM::HardwarePool::MapHardwareMemory(TableAddress, 2, TRUE, (PVOID*)&TableHeader);
|
||||
@@ -618,11 +661,12 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Query cache for XSDP table */
|
||||
/* Query cache for XSDT table */
|
||||
Status = QueryAcpiCache(ACPI_XSDT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Xsdt);
|
||||
if(Status != STATUS_SUCCESS)
|
||||
{
|
||||
/* XSDP not found, query cache for RSDP table */
|
||||
/* XSDT not found, query cache for RSDT table */
|
||||
Xsdt = NULLPTR;
|
||||
Status = QueryAcpiCache(ACPI_RSDT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Rsdt);
|
||||
}
|
||||
|
||||
@@ -633,22 +677,22 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Get table count depending on root table type */
|
||||
/* Get table count depending on root table type securely */
|
||||
if(Xsdt != NULLPTR)
|
||||
{
|
||||
/* Get table count from XSDT */
|
||||
if(Xsdt->Header.Length < sizeof(ACPI_DESCRIPTION_HEADER)) return STATUS_INVALID_PARAMETER;
|
||||
TableCount = (Xsdt->Header.Length - sizeof(ACPI_DESCRIPTION_HEADER)) / 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get table count from RSDT */
|
||||
if(Rsdt->Header.Length < sizeof(ACPI_DESCRIPTION_HEADER)) return STATUS_INVALID_PARAMETER;
|
||||
TableCount = (Rsdt->Header.Length - sizeof(ACPI_DESCRIPTION_HEADER)) / 4;
|
||||
}
|
||||
|
||||
/* Iterate over all ACPI tables */
|
||||
for(TableIndex = 0; TableIndex < TableCount; TableIndex++)
|
||||
{
|
||||
/* Check if XSDP or RSDT is used */
|
||||
/* Check if XSDT or RSDT is used */
|
||||
if(Xsdt != NULLPTR)
|
||||
{
|
||||
/* Get table header physical address from XSDT */
|
||||
@@ -661,13 +705,6 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
|
||||
TableAddress.HighPart = 0;
|
||||
}
|
||||
|
||||
/* Check whether some table is already mapped */
|
||||
if(TableHeader != NULLPTR)
|
||||
{
|
||||
/* Unmap previous table */
|
||||
MM::HardwarePool::UnmapHardwareMemory(TableHeader, 2, TRUE);
|
||||
}
|
||||
|
||||
/* Map table using hardware memory pool */
|
||||
Status = MM::HardwarePool::MapHardwareMemory(TableAddress, 2, TRUE, (PVOID*)&TableHeader);
|
||||
if(Status != STATUS_SUCCESS)
|
||||
@@ -682,25 +719,31 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
|
||||
/* Found requested ACPI table */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure table was found */
|
||||
if(TableHeader->Signature != Signature)
|
||||
{
|
||||
/* ACPI table not found, check if cleanup is needed */
|
||||
if(TableHeader != NULLPTR)
|
||||
{
|
||||
/* Unmap non-matching ACPI table */
|
||||
/* Unmap non-matching table and try next one */
|
||||
MM::HardwarePool::UnmapHardwareMemory(TableHeader, 2, TRUE);
|
||||
TableHeader = NULLPTR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return error */
|
||||
/* Ensure the table was actually found and mapped */
|
||||
if(TableHeader == NULLPTR)
|
||||
{
|
||||
/* ACPI table not found, return error */
|
||||
return STATUS_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* Don't validate FADT on old, broken firmwares with ACPI 2.0 or older */
|
||||
if(TableHeader->Signature != ACPI_FADT_SIGNATURE || TableHeader->Revision > 2)
|
||||
/* Check if we broke out of the loop with the wrong table (safety check) */
|
||||
if(TableHeader->Signature != Signature)
|
||||
{
|
||||
/* Unmap non-matching ACPI table and return error */
|
||||
MM::HardwarePool::UnmapHardwareMemory(TableHeader, 2, TRUE);
|
||||
return STATUS_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* Don't validate FACS and FADT on old, broken firmwares with ACPI 2.0 or older */
|
||||
if((TableHeader->Signature != ACPI_FADT_SIGNATURE || TableHeader->Revision > 2) &&
|
||||
(TableHeader->Signature != ACPI_FACS_SIGNATURE))
|
||||
{
|
||||
/* Validate table checksum */
|
||||
if(!ValidateAcpiTable(TableHeader, TableHeader->Length))
|
||||
@@ -712,7 +755,7 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
|
||||
}
|
||||
|
||||
/* Calculate the length of ACPI table and remap it if needed */
|
||||
TablePages = (((ULONG_PTR)TableHeader & (MM_PAGE_SIZE - 1)) + TableHeader->Length + (MM_PAGE_SIZE - 1)) >> MM_PAGE_SHIFT;
|
||||
TablePages = (((TableAddress.LowPart & (MM_PAGE_SIZE - 1)) + TableHeader->Length + (MM_PAGE_SIZE - 1)) >> MM_PAGE_SHIFT);
|
||||
if(TablePages != 2)
|
||||
{
|
||||
/* ACPI table needs less or more than 2 pages, remap it */
|
||||
|
||||
162
xtoskrnl/hl/amd64/irq.cc
Normal file
162
xtoskrnl/hl/amd64/irq.cc
Normal file
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/hl/amd64/irq.cc
|
||||
* DESCRIPTION: Interrupts support for AMD64 architecture
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Handles profiling interrupt.
|
||||
*
|
||||
* @param TrapFrame
|
||||
* Supplies a kernel trap frame pushed by common interrupt handler.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
HL::Irq::HandleProfileInterrupt(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
/* Send EOI*/
|
||||
HL::Pic::SendEoi();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles unexpected or unmapped system interrupts.
|
||||
*
|
||||
* @param TrapFrame
|
||||
* Supplies a kernel trap frame pushed by common interrupt handler.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
HL::Irq::HandleUnexpectedInterrupt(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
|
||||
/* Disable interrupts */
|
||||
AR::CpuFunc::ClearInterruptFlag();
|
||||
|
||||
/* Print debug message and raise kernel panic */
|
||||
DebugPrint(L"ERROR: Caught unexpected interrupt (0x%.2llX)!\n", TrapFrame->Vector);
|
||||
KE::Crash::Panic(0x47, TrapFrame->Vector, 0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the registered interrupt handler for the specified IDT vector.
|
||||
*
|
||||
* @param Vector
|
||||
* Supplies the interrupt vector number.
|
||||
*
|
||||
* @return This routine returns the pointer to the IDT interrupt handler routine.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PVOID
|
||||
HL::Irq::QueryInterruptHandler(IN ULONG Vector)
|
||||
{
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
PKIDTENTRY IdtEntry;
|
||||
|
||||
/* Get current processor block and IDT entry */
|
||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
||||
IdtEntry = &ProcessorBlock->IdtBase[Vector];
|
||||
|
||||
/* Return address of the interrupt handler */
|
||||
return (PVOID)((ULONGLONG)IdtEntry->OffsetHigh << 32 |
|
||||
(ULONGLONG)IdtEntry->OffsetMiddle << 16 |
|
||||
(ULONGLONG)IdtEntry->OffsetLow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the registered interrupt handler for the specified vector.
|
||||
*
|
||||
* @param Vector
|
||||
* Supplies the interrupt vector number.
|
||||
*
|
||||
* @return This routine returns the pointer to the interrupt handler routine.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PVOID
|
||||
HL::Irq::QuerySystemInterruptHandler(IN ULONG Vector)
|
||||
{
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
|
||||
/* Get current processor block */
|
||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
||||
|
||||
return (PVOID)ProcessorBlock->InterruptDispatchTable[Vector];
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers new interrupt handler for the existing IDT entry.
|
||||
*
|
||||
* @param HalVector
|
||||
* Supplies the interrupt vector number.
|
||||
*
|
||||
* @param Handler
|
||||
* Supplies the pointer to the interrupt handler routine.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Irq::RegisterInterruptHandler(IN ULONG Vector,
|
||||
IN PVOID Handler)
|
||||
{
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
|
||||
/* Get current processor block */
|
||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
||||
|
||||
/* Update interrupt handler */
|
||||
AR::ProcSup::SetIdtGate(ProcessorBlock->IdtBase,
|
||||
Vector,
|
||||
Handler,
|
||||
KGDT_R0_CODE,
|
||||
0,
|
||||
KIDT_ACCESS_RING0,
|
||||
AMD64_INTERRUPT_GATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the interrupt handler for the specified vector.
|
||||
*
|
||||
* @param HalVector
|
||||
* Supplies the interrupt vector number.
|
||||
*
|
||||
* @param Handler
|
||||
* Supplies the pointer to the interrupt handler routine.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Irq::RegisterSystemInterruptHandler(IN ULONG Vector,
|
||||
IN PINTERRUPT_HANDLER Handler)
|
||||
{
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
|
||||
/* Get current processor block */
|
||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
||||
|
||||
/* Update interrupt handler in the processor's interrupt dispatch table */
|
||||
ProcessorBlock->InterruptDispatchTable[Vector] = Handler;
|
||||
}
|
||||
13
xtoskrnl/hl/amd64/timer.cc
Normal file
13
xtoskrnl/hl/amd64/timer.cc
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/hl/amd64/timer.cc
|
||||
* DESCRIPTION: APIC Timer for AMD64 support
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Include common Timer interface */
|
||||
#include ARCH_COMMON(timer.cc)
|
||||
@@ -9,6 +9,12 @@
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* ACPI tables cache count */
|
||||
ULONG HL::Acpi::CacheCount = 0;
|
||||
|
||||
/* ACPI tables cache entries */
|
||||
ACPI_CACHE_LIST HL::Acpi::CacheEntries[ACPI_MAX_CACHED_TABLES];
|
||||
|
||||
/* ACPI tables cache list */
|
||||
LIST_ENTRY HL::Acpi::CacheList;
|
||||
|
||||
@@ -32,3 +38,12 @@ HL_SCROLL_REGION_DATA HL::FrameBuffer::ScrollRegionData;
|
||||
|
||||
/* APIC mode */
|
||||
APIC_MODE HL::Pic::ApicMode;
|
||||
|
||||
/* Kernel profiling interval */
|
||||
ULONG HL::Timer::ProfilingInterval;
|
||||
|
||||
/* Timer capabilities */
|
||||
TIMER_CAPABILITIES HL::Timer::TimerCapabilities = {0};
|
||||
|
||||
/* APIC timer frequency */
|
||||
ULONG HL::Timer::TimerFrequency;
|
||||
|
||||
160
xtoskrnl/hl/i686/irq.cc
Normal file
160
xtoskrnl/hl/i686/irq.cc
Normal file
@@ -0,0 +1,160 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/hl/i686/irq.cc
|
||||
* DESCRIPTION: Interrupts support for i686 architecture
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Handles profiling interrupt.
|
||||
*
|
||||
* @param TrapFrame
|
||||
* Supplies a kernel trap frame pushed by common interrupt handler.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
HL::Irq::HandleProfileInterrupt(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
/* Send EOI*/
|
||||
HL::Pic::SendEoi();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles unexpected or unmapped system interrupts.
|
||||
*
|
||||
* @param TrapFrame
|
||||
* Supplies a kernel trap frame pushed by common interrupt handler.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
HL::Irq::HandleUnexpectedInterrupt(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
|
||||
/* Disable interrupts */
|
||||
AR::CpuFunc::ClearInterruptFlag();
|
||||
|
||||
/* Print debug message and raise kernel panic */
|
||||
DebugPrint(L"ERROR: Caught unexpected interrupt (0x%.2lX)!\n", TrapFrame->Vector);
|
||||
KE::Crash::Panic(0x47, TrapFrame->Vector, 0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the registered interrupt handler for the specified IDT vector.
|
||||
*
|
||||
* @param Vector
|
||||
* Supplies the interrupt vector number.
|
||||
*
|
||||
* @return This routine returns the pointer to the IDT interrupt handler routine.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PVOID
|
||||
HL::Irq::QueryInterruptHandler(IN ULONG Vector)
|
||||
{
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
PKIDTENTRY IdtEntry;
|
||||
|
||||
/* Get current processor block and IDT entry */
|
||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
||||
IdtEntry = &ProcessorBlock->IdtBase[Vector];
|
||||
|
||||
/* Return address of the interrupt handler */
|
||||
return (PVOID)(((IdtEntry->ExtendedOffset << 16) & 0xFFFF0000) | (IdtEntry->Offset & 0xFFFF));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the registered interrupt handler for the specified vector.
|
||||
*
|
||||
* @param Vector
|
||||
* Supplies the interrupt vector number.
|
||||
*
|
||||
* @return This routine returns the pointer to the interrupt handler routine.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PVOID
|
||||
HL::Irq::QuerySystemInterruptHandler(IN ULONG Vector)
|
||||
{
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
|
||||
/* Get current processor block */
|
||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
||||
|
||||
return (PVOID)ProcessorBlock->InterruptDispatchTable[Vector];
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers new interrupt handler for the existing IDT entry.
|
||||
*
|
||||
* @param HalVector
|
||||
* Supplies the interrupt vector number.
|
||||
*
|
||||
* @param Handler
|
||||
* Supplies the pointer to the interrupt handler routine.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Irq::RegisterInterruptHandler(IN ULONG Vector,
|
||||
IN PVOID Handler)
|
||||
{
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
|
||||
/* Get current processor block */
|
||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
||||
|
||||
/* Update interrupt handler */
|
||||
AR::ProcSup::SetIdtGate(ProcessorBlock->IdtBase,
|
||||
Vector,
|
||||
Handler,
|
||||
KGDT_R0_CODE,
|
||||
0,
|
||||
KIDT_ACCESS_RING0,
|
||||
I686_INTERRUPT_GATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the interrupt handler for the specified vector.
|
||||
*
|
||||
* @param HalVector
|
||||
* Supplies the interrupt vector number.
|
||||
*
|
||||
* @param Handler
|
||||
* Supplies the pointer to the interrupt handler routine.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Irq::RegisterSystemInterruptHandler(IN ULONG Vector,
|
||||
IN PINTERRUPT_HANDLER Handler)
|
||||
{
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
|
||||
/* Get current processor block */
|
||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
||||
|
||||
/* Update interrupt handler in the processor's interrupt dispatch table */
|
||||
ProcessorBlock->InterruptDispatchTable[Vector] = Handler;
|
||||
}
|
||||
13
xtoskrnl/hl/i686/timer.cc
Normal file
13
xtoskrnl/hl/i686/timer.cc
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/hl/i686/timer.cc
|
||||
* DESCRIPTION: APIC Timer for i686 support
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Include common Timer interface */
|
||||
#include ARCH_COMMON(timer.cc)
|
||||
@@ -23,14 +23,14 @@ HL::Init::InitializeSystem(VOID)
|
||||
XTSTATUS Status;
|
||||
|
||||
/* Initialize ACPI */
|
||||
Status = Acpi::InitializeAcpi();
|
||||
Status = HL::Acpi::InitializeAcpi();
|
||||
if(Status != STATUS_SUCCESS)
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Get system information from ACPI */
|
||||
Status = Acpi::InitializeAcpiSystemInformation();
|
||||
Status = HL::Acpi::InitializeAcpiSystemInformation();
|
||||
if(Status != STATUS_SUCCESS)
|
||||
{
|
||||
return Status;
|
||||
|
||||
@@ -40,8 +40,11 @@ HL::Cpu::InitializeProcessor(VOID)
|
||||
ActiveProcessors |= Affinity;
|
||||
|
||||
/* Initialize APIC for this processor */
|
||||
Pic::InitializePic();
|
||||
HL::Pic::InitializePic();
|
||||
|
||||
/* Set the APIC running level */
|
||||
HL::RunLevel::SetRunLevel(KE::Processor::GetCurrentProcessorBlock()->RunLevel);
|
||||
|
||||
/* Initialize timer */
|
||||
HL::Timer::InitializeTimer();
|
||||
}
|
||||
|
||||
@@ -9,6 +9,41 @@
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether the APIC is supported by the processor.
|
||||
*
|
||||
* @return This routine returns TRUE if APIC is supported, or FALSE otherwise.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
BOOLEAN
|
||||
HL::Pic::CheckApicSupport(VOID)
|
||||
{
|
||||
CPUID_REGISTERS CpuRegisters;
|
||||
|
||||
/* Prepare CPUID registers */
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||
CpuRegisters.SubLeaf = 0;
|
||||
CpuRegisters.Eax = 0;
|
||||
CpuRegisters.Ebx = 0;
|
||||
CpuRegisters.Ecx = 0;
|
||||
CpuRegisters.Edx = 0;
|
||||
|
||||
/* Get CPUID */
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
|
||||
/* Check APIC status from the CPUID results */
|
||||
if(!(CpuRegisters.Edx & CPUID_FEATURES_EDX_APIC))
|
||||
{
|
||||
/* APIC is not supported */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* APIC is supported */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the x2APIC extension is supported by the processor.
|
||||
*
|
||||
@@ -82,32 +117,6 @@ HL::Pic::GetCpuApicId(VOID)
|
||||
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.
|
||||
*
|
||||
@@ -124,6 +133,14 @@ HL::Pic::InitializeApic(VOID)
|
||||
APIC_LVT_REGISTER LvtRegister;
|
||||
ULONG CpuNumber;
|
||||
|
||||
/* Check APIC support */
|
||||
if(!CheckApicSupport())
|
||||
{
|
||||
/* APIC is not supported, raise kernel panic */
|
||||
DebugPrint(L"FATAL ERROR: Local APIC not present.\n");
|
||||
KE::Crash::Panic(0x5D, CPUID_GET_STANDARD1_FEATURES, 0x0, 0x0, CPUID_FEATURES_EDX_APIC);
|
||||
}
|
||||
|
||||
/* Determine APIC mode (xAPIC compatibility or x2APIC) */
|
||||
if(CheckX2ApicSupport())
|
||||
{
|
||||
@@ -206,8 +223,8 @@ HL::Pic::InitializeApic(VOID)
|
||||
WriteApicRegister(APIC_LINT1, LvtRegister.Long);
|
||||
|
||||
/* Register interrupt handlers */
|
||||
KE::Irq::SetInterruptHandler(APIC_VECTOR_SPURIOUS, (PVOID)HandleApicSpuriousService);
|
||||
KE::Irq::SetInterruptHandler(PIC1_VECTOR_SPURIOUS, (PVOID)HandlePicSpuriousService);
|
||||
HL::Irq::RegisterInterruptHandler(APIC_VECTOR_SPURIOUS, (PVOID)ArHandleSpuriousInterrupt);
|
||||
HL::Irq::RegisterSystemInterruptHandler(APIC_VECTOR_PROFILE, HL::Irq::HandleProfileInterrupt);
|
||||
|
||||
/* Clear any pre-existing errors */
|
||||
WriteApicRegister(APIC_ESR, 0);
|
||||
@@ -289,6 +306,9 @@ HL::Pic::InitializeLegacyPic(VOID)
|
||||
|
||||
/* Mask all interrupts on PIC2 port */
|
||||
HL::IoPort::WritePort8(PIC2_DATA_PORT, 0xFF);
|
||||
|
||||
/* Register interrupt handler */
|
||||
HL::Irq::RegisterInterruptHandler(PIC1_VECTOR_SPURIOUS, (PVOID)ArHandleSpuriousInterrupt);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -333,7 +353,7 @@ HL::Pic::ReadApicRegister(IN APIC_REGISTER Register)
|
||||
else
|
||||
{
|
||||
/* Read from xAPIC */
|
||||
return IoRegister::ReadRegister32((PULONG)(APIC_BASE + (Register << 4)));
|
||||
return HL::IoRegister::ReadRegister32((PULONG)(APIC_BASE + (Register << 4)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,6 +404,62 @@ HL::Pic::SendIpi(ULONG ApicId,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a Self-IPI (Inter-Processor Interrupt) to the current CPU.
|
||||
*
|
||||
* @param Vector
|
||||
* Supplies the IPI vector to send.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Pic::SendSelfIpi(ULONG Vector)
|
||||
{
|
||||
BOOLEAN Interrupts;
|
||||
|
||||
/* Check whether interrupts are enabled */
|
||||
Interrupts = AR::CpuFunc::InterruptsEnabled();
|
||||
|
||||
/* Disable interrupts */
|
||||
AR::CpuFunc::ClearInterruptFlag();
|
||||
|
||||
/* Check current APIC mode */
|
||||
if(ApicMode == APIC_MODE_X2APIC)
|
||||
{
|
||||
/* In x2APIC mode, a dedicated Self-IPI register is used */
|
||||
WriteApicRegister(APIC_SIPI, Vector);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Wait for the APIC to clear the delivery status */
|
||||
while((ReadApicRegister(APIC_ICR0) & 0x1000) != 0)
|
||||
{
|
||||
/* Yield the processor */
|
||||
AR::CpuFunc::YieldProcessor();
|
||||
}
|
||||
|
||||
/* In xAPIC compatibility mode, ICR0 is used */
|
||||
WriteApicRegister(APIC_ICR0, Vector | (1 << 18));
|
||||
}
|
||||
|
||||
/* Wait for the APIC to complete delivery of the IPI */
|
||||
while((ReadApicRegister(APIC_ICR0) & 0x1000) != 0)
|
||||
{
|
||||
/* Yield the processor */
|
||||
AR::CpuFunc::YieldProcessor();
|
||||
}
|
||||
|
||||
/* Check whether interrupts need to be re-enabled */
|
||||
if(Interrupts)
|
||||
{
|
||||
/* Re-enable interrupts */
|
||||
AR::CpuFunc::SetInterruptFlag();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes to the APIC register.
|
||||
*
|
||||
@@ -410,6 +486,6 @@ HL::Pic::WriteApicRegister(IN APIC_REGISTER Register,
|
||||
else
|
||||
{
|
||||
/* Write to xAPIC */
|
||||
IoRegister::WriteRegister32((PULONG)(APIC_BASE + (Register << 4)), Value);
|
||||
HL::IoRegister::WriteRegister32((PULONG)(APIC_BASE + (Register << 4)), Value);
|
||||
}
|
||||
}
|
||||
|
||||
439
xtoskrnl/hl/x86/timer.cc
Normal file
439
xtoskrnl/hl/x86/timer.cc
Normal file
@@ -0,0 +1,439 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/hl/x86/timer.cc
|
||||
* DESCRIPTION: APIC Timer support for x86 (i686/AMD64) support
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Calibrates the Local APIC timer frequency.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
HL::Timer::CalibrateApicTimer()
|
||||
{
|
||||
ULONG CurrentCount, Frequency, InitialCount;
|
||||
|
||||
/* Get APIC timer frequency from the Core Crystal Clock */
|
||||
if(TimerCapabilities.Art && TimerCapabilities.TimerFrequency != 0)
|
||||
{
|
||||
/* CCC available, use it as the source of APIC timer frequency */
|
||||
Frequency = TimerCapabilities.TimerFrequency;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* CCC unavailable, fallback to PIT calibration */
|
||||
InitialCount = 0xFFFFFFFF;
|
||||
|
||||
/* Load the initial count into the APIC Timer and begin the countdown */
|
||||
HL::Pic::WriteApicRegister(APIC_TICR, InitialCount);
|
||||
|
||||
/* Wait for 10ms */
|
||||
StallExecution(10000);
|
||||
|
||||
/* Read current tick count from APIC timer and clear APIC timer */
|
||||
CurrentCount = HL::Pic::ReadApicRegister(APIC_TCCR);
|
||||
HL::Pic::WriteApicRegister(APIC_TICR, 0);
|
||||
|
||||
/* Calculate APIC timer frequency based on ticks passed */
|
||||
Frequency = (InitialCount - CurrentCount) * 100;
|
||||
|
||||
/* Verify APIC timer frequency */
|
||||
if(Frequency == 0)
|
||||
{
|
||||
/* Unable to calibrate APIC timer, return error */
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Save APIC timer frequency */
|
||||
TimerFrequency = Frequency;
|
||||
|
||||
/* Print APIC timer frequency and return success */
|
||||
DebugPrint(L"APIC Timer calibrated: %u Ticks/s\n", TimerFrequency);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes and calibrates the Local APIC Timer.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Timer::InitializeApicTimer(VOID)
|
||||
{
|
||||
XTSTATUS Status;
|
||||
|
||||
/* Set APIC timer to divide by 1 */
|
||||
HL::Pic::WriteApicRegister(APIC_TDCR, TIMER_DivideBy1);
|
||||
|
||||
/* Calibrate the APIC timer */
|
||||
Status = CalibrateApicTimer();
|
||||
if(Status != STATUS_SUCCESS)
|
||||
{
|
||||
/* System cannot operate without a calibrated system timer, raise kernel panic */
|
||||
KE::Crash::Panic(0);
|
||||
}
|
||||
|
||||
/* Set the default system profile interval */
|
||||
HL::Timer::SetProfileInterval(1000);
|
||||
|
||||
/* Program the APIC timer for periodic mode */
|
||||
StopProfileInterrupt(ProfileXtKernel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a basic Timer initialization.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Timer::InitializeTimer(VOID)
|
||||
{
|
||||
/* Query timer capabilities */
|
||||
QueryTimerCapabilities();
|
||||
|
||||
/* Initialize the APIC timer */
|
||||
InitializeApicTimer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stalls the CPU execution for a specified duration (maximum 3 seconds) using the legacy PIT timer.
|
||||
*
|
||||
* @param MicroSeconds
|
||||
* Specifies the number of microseconds to stall execution.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Timer::PitStallExecution(IN ULONG MicroSeconds)
|
||||
{
|
||||
USHORT CurrentCount, PreviousCount;
|
||||
ULONG TargetTicks, TickCounter;
|
||||
|
||||
/* Validate input parameter */
|
||||
if(MicroSeconds == 0)
|
||||
{
|
||||
/* Nothing to do */
|
||||
return;
|
||||
}
|
||||
else if(MicroSeconds > 3000000)
|
||||
{
|
||||
/* Cap execution stall to 3 seconds */
|
||||
MicroSeconds = 3000000;
|
||||
}
|
||||
|
||||
/* Convert us to PIT ticks and initialize tick counter */
|
||||
TargetTicks = (MicroSeconds * 1193) / 1000;
|
||||
TickCounter = 0;
|
||||
|
||||
/* Configure PIT Channel 0: Read/Write LSB then MSB, Mode 0 (Interrupt on Terminal Count) */
|
||||
HL::IoPort::WritePort8(PIT_COMMAND_PORT, 0x30);
|
||||
|
||||
/* Initialize the PIT counter with the maximum possible value (0xFFFF) */
|
||||
HL::IoPort::WritePort8(PIT_DATA_PORT0, 0xFF);
|
||||
HL::IoPort::WritePort8(PIT_DATA_PORT0, 0xFF);
|
||||
|
||||
/* Latch and read the initial counter value */
|
||||
HL::IoPort::WritePort8(PIT_COMMAND_PORT, 0x00);
|
||||
PreviousCount = HL::IoPort::ReadPort8(PIT_DATA_PORT0);
|
||||
PreviousCount |= (HL::IoPort::ReadPort8(PIT_DATA_PORT0) << 8);
|
||||
|
||||
/* Poll the PIT */
|
||||
while(TickCounter < TargetTicks)
|
||||
{
|
||||
/* Latch the current counter value without stopping the timer */
|
||||
HL::IoPort::WritePort8(PIT_COMMAND_PORT, 0x00);
|
||||
CurrentCount = HL::IoPort::ReadPort8(PIT_DATA_PORT0);
|
||||
CurrentCount |= (HL::IoPort::ReadPort8(PIT_DATA_PORT0) << 8);
|
||||
|
||||
/* Calculate elapsed ticks since the last read */
|
||||
TickCounter += (PreviousCount - CurrentCount) & 0xFFFF;
|
||||
|
||||
/* Update the tracking variable */
|
||||
PreviousCount = CurrentCount;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Probes the processor via CPUID to detect available modern timing and clock generation features.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Timer::QueryTimerCapabilities(VOID)
|
||||
{
|
||||
CPUID_REGISTERS CpuRegisters;
|
||||
ULONG MaxStandardLeaf;
|
||||
ULONG MaxExtendedLeaf;
|
||||
|
||||
/* Query maximum standard CPUID leaf */
|
||||
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
|
||||
CpuRegisters.SubLeaf = 0;
|
||||
CpuRegisters.Eax = 0;
|
||||
CpuRegisters.Ebx = 0;
|
||||
CpuRegisters.Ecx = 0;
|
||||
CpuRegisters.Edx = 0;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
|
||||
/* Save maximum supported standard CPUID leaf */
|
||||
MaxStandardLeaf = CpuRegisters.Eax;
|
||||
|
||||
/* Query maximum extended CPUID leaf */
|
||||
CpuRegisters.Leaf = CPUID_GET_EXTENDED_MAX;
|
||||
CpuRegisters.SubLeaf = 0;
|
||||
CpuRegisters.Eax = 0;
|
||||
CpuRegisters.Ebx = 0;
|
||||
CpuRegisters.Ecx = 0;
|
||||
CpuRegisters.Edx = 0;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
|
||||
/* Save maximum supported extended CPUID leaf */
|
||||
MaxExtendedLeaf = CpuRegisters.Eax;
|
||||
|
||||
/* Check TSC-Deadline mode if leaf supported */
|
||||
if(MaxStandardLeaf >= CPUID_GET_STANDARD1_FEATURES)
|
||||
{
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||
CpuRegisters.SubLeaf = 0;
|
||||
CpuRegisters.Eax = 0;
|
||||
CpuRegisters.Ebx = 0;
|
||||
CpuRegisters.Ecx = 0;
|
||||
CpuRegisters.Edx = 0;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
|
||||
/* Verify TSC-Deadline support */
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_TSC_DEADLINE)
|
||||
{
|
||||
TimerCapabilities.TscDeadline = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check Always Running APIC Timer - ARAT if leaf supported */
|
||||
if(MaxStandardLeaf >= CPUID_GET_POWER_MANAGEMENT)
|
||||
{
|
||||
CpuRegisters.Leaf = CPUID_GET_POWER_MANAGEMENT;
|
||||
CpuRegisters.SubLeaf = 0;
|
||||
CpuRegisters.Eax = 0;
|
||||
CpuRegisters.Ebx = 0;
|
||||
CpuRegisters.Ecx = 0;
|
||||
CpuRegisters.Edx = 0;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
|
||||
/* Verify ARAT support */
|
||||
if(CpuRegisters.Eax & CPUID_FEATURES_EAX_ARAT)
|
||||
{
|
||||
TimerCapabilities.Arat = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check Always Running Timer - ART if leaf supported */
|
||||
if(MaxStandardLeaf >= CPUID_GET_TSC_CRYSTAL_CLOCK)
|
||||
{
|
||||
CpuRegisters.Leaf = CPUID_GET_TSC_CRYSTAL_CLOCK;
|
||||
CpuRegisters.SubLeaf = 0;
|
||||
CpuRegisters.Eax = 0;
|
||||
CpuRegisters.Ebx = 0;
|
||||
CpuRegisters.Ecx = 0;
|
||||
CpuRegisters.Edx = 0;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
|
||||
/* Verify ART support */
|
||||
if(CpuRegisters.Eax != 0 && CpuRegisters.Ebx != 0)
|
||||
{
|
||||
TimerCapabilities.Art = TRUE;
|
||||
|
||||
/* Save the TSC scaling ratios */
|
||||
TimerCapabilities.TscDenominator = CpuRegisters.Eax;
|
||||
TimerCapabilities.TscNumerator = CpuRegisters.Ebx;
|
||||
|
||||
/* Check if ECX contains the nominal frequency of the core crystal clock */
|
||||
if(CpuRegisters.Ecx != 0)
|
||||
{
|
||||
/* Save the base frequency for the APIC Timer */
|
||||
TimerCapabilities.TimerFrequency = CpuRegisters.Ecx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check RDTSCP instruction support if leaf supported */
|
||||
if(MaxExtendedLeaf >= CPUID_GET_EXTENDED_FEATURES)
|
||||
{
|
||||
CpuRegisters.Leaf = CPUID_GET_EXTENDED_FEATURES;
|
||||
CpuRegisters.SubLeaf = 0;
|
||||
CpuRegisters.Eax = 0;
|
||||
CpuRegisters.Ebx = 0;
|
||||
CpuRegisters.Ecx = 0;
|
||||
CpuRegisters.Edx = 0;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
|
||||
/* Verify RDTSCP support */
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_RDTSCP)
|
||||
{
|
||||
TimerCapabilities.RDTSCP = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check Invariant TSC if leaf supported */
|
||||
if(MaxExtendedLeaf >= CPUID_GET_ADVANCED_POWER_MANAGEMENT)
|
||||
{
|
||||
CpuRegisters.Leaf = CPUID_GET_ADVANCED_POWER_MANAGEMENT;
|
||||
CpuRegisters.SubLeaf = 0;
|
||||
CpuRegisters.Eax = 0;
|
||||
CpuRegisters.Ebx = 0;
|
||||
CpuRegisters.Ecx = 0;
|
||||
CpuRegisters.Edx = 0;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
|
||||
/* Verify Invariant TSC support */
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSCI)
|
||||
{
|
||||
TimerCapabilities.InvariantTsc = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the profile interrupt interval. The interval may be bounded by hardware capabilities.
|
||||
*
|
||||
* @param Interval
|
||||
* Supplies the requested profile interval in 100-nanosecond units.
|
||||
*
|
||||
* @return This routine returns the actual profile interval that was set.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
ULONG_PTR
|
||||
HL::Timer::SetProfileInterval(IN ULONG_PTR Interval)
|
||||
{
|
||||
/* Validate and bound the requested profile interval against hardware limits */
|
||||
if(Interval < MIN_PROFILE_INTERVAL)
|
||||
{
|
||||
/* Enforce the minimum profile interval limit */
|
||||
Interval = MIN_PROFILE_INTERVAL;
|
||||
}
|
||||
else if(Interval > MAX_PROFILE_INTERVAL)
|
||||
{
|
||||
/* Enforce the maximum profile interval limit */
|
||||
Interval = MAX_PROFILE_INTERVAL;
|
||||
}
|
||||
|
||||
/* Calculate the number of APIC timer ticks required for the requested interval */
|
||||
ProfilingInterval = (TimerFrequency / 10000) * (Interval / 1000);
|
||||
|
||||
/* Update the APIC Timer Initial Count Register (TICR) to apply the new interval immediately */
|
||||
HL::Pic::WriteApicRegister(APIC_TICR, ProfilingInterval);
|
||||
|
||||
/* Return the actual interval */
|
||||
return Interval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stalls the CPU execution for a specified duration.
|
||||
*
|
||||
* @param MicroSeconds
|
||||
* Supplies the number of microseconds to stall execution.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Timer::StallExecution(IN ULONG MicroSeconds)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
|
||||
/* ACPI PM Timer not supported, fall back to PIT */
|
||||
PitStallExecution(MicroSeconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the profile interrupt for the specified profile source.
|
||||
*
|
||||
* @param ProfileSource
|
||||
* Supplies the source of the profile interrupt to start.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Timer::StartProfileInterrupt(IN KPROFILE_SOURCE ProfileSource)
|
||||
{
|
||||
APIC_LVT_REGISTER LvtRegister;
|
||||
|
||||
/* Handle only ProfileTime and ProfileXtKernel */
|
||||
if(ProfileSource != ProfileTime && ProfileSource != ProfileXtKernel)
|
||||
{
|
||||
/* Invalid profile source, do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the interval */
|
||||
HL::Pic::WriteApicRegister(APIC_TICR, ProfilingInterval);
|
||||
|
||||
/* Unmask interrupt */
|
||||
LvtRegister.Long = 0;
|
||||
LvtRegister.Mask = 0;
|
||||
LvtRegister.DeliveryMode = APIC_DM_FIXED;
|
||||
LvtRegister.TimerMode = 1;
|
||||
LvtRegister.TriggerMode = APIC_TGM_EDGE;
|
||||
LvtRegister.Vector = APIC_VECTOR_PROFILE;
|
||||
HL::Pic::WriteApicRegister(APIC_TMRLVTR, LvtRegister.Long);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the profile interrupt for the specified profile source.
|
||||
*
|
||||
* @param ProfileSource
|
||||
* Supplies the source of the profile interrupt to stop.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Timer::StopProfileInterrupt(IN KPROFILE_SOURCE ProfileSource)
|
||||
{
|
||||
APIC_LVT_REGISTER LvtRegister;
|
||||
|
||||
/* Handle only ProfileTime and ProfileXtKernel */
|
||||
if(ProfileSource != ProfileTime && ProfileSource != ProfileXtKernel)
|
||||
{
|
||||
/* Invalid profile source, do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Mask interrupt */
|
||||
LvtRegister.Long = 0;
|
||||
LvtRegister.Mask = 1;
|
||||
LvtRegister.DeliveryMode = APIC_DM_FIXED;
|
||||
LvtRegister.TimerMode = 1;
|
||||
LvtRegister.TriggerMode = APIC_TGM_EDGE;
|
||||
LvtRegister.Vector = APIC_VECTOR_PROFILE;
|
||||
HL::Pic::WriteApicRegister(APIC_TMRLVTR, LvtRegister.Long);
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
#include XTOS_ARCH_HEADER(ar, assembly.hh)
|
||||
#include XTOS_ARCH_HEADER(ar, asmsup.hh)
|
||||
#include XTOS_ARCH_HEADER(ar, cpufunc.hh)
|
||||
#include XTOS_ARCH_HEADER(ar, procsup.hh)
|
||||
#include XTOS_ARCH_HEADER(ar, traps.hh)
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/includes/amd64/asm.h
|
||||
* DESCRIPTION: AMD64 architecture assembly definitions
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#ifndef __XTOSKRNL_AMD64_ASMSUP_H
|
||||
#define __XTOSKRNL_AMD64_ASMSUP_H
|
||||
|
||||
|
||||
/* Control Register bit definitions */
|
||||
#define CR0_PG 0x80000000
|
||||
#define CR4_PGE 0x00000080
|
||||
#define CR4_LA57 0x00001000
|
||||
#define CR4_PCIDE 0x00020000
|
||||
|
||||
/* GDT selectors */
|
||||
#define GDT_R0_CMCODE 0x08
|
||||
#define GDT_R0_CODE 0x10
|
||||
#define GDT_R0_DATA 0x18
|
||||
|
||||
/* MSR registers */
|
||||
#define X86_MSR_EFER 0xC0000080
|
||||
#define X86_MSR_EFER_LME (1 << 8)
|
||||
|
||||
/* KTRAP_FRAME structure offsets */
|
||||
#define TrapXmm0 0
|
||||
#define TrapXmm1 16
|
||||
#define TrapXmm2 32
|
||||
#define TrapXmm3 48
|
||||
#define TrapXmm4 64
|
||||
#define TrapXmm5 80
|
||||
#define TrapXmm6 96
|
||||
#define TrapXmm7 112
|
||||
#define TrapXmm8 128
|
||||
#define TrapXmm9 144
|
||||
#define TrapXmm10 160
|
||||
#define TrapXmm11 176
|
||||
#define TrapXmm12 192
|
||||
#define TrapXmm13 208
|
||||
#define TrapXmm14 224
|
||||
#define TrapXmm15 240
|
||||
#define TrapMxCsr 256
|
||||
#define TrapPreviousMode 260
|
||||
#define TrapCr2 264
|
||||
#define TrapCr3 272
|
||||
#define TrapDr0 280
|
||||
#define TrapDr1 288
|
||||
#define TrapDr2 296
|
||||
#define TrapDr3 304
|
||||
#define TrapDr6 312
|
||||
#define TrapDr7 320
|
||||
#define TrapSegDs 328
|
||||
#define TrapSegEs 330
|
||||
#define TrapSegFs 332
|
||||
#define TrapSegGs 334
|
||||
#define TrapRsp 496
|
||||
#define TrapSegSs 504
|
||||
|
||||
/* KTRAP_FRAME length related definitions */
|
||||
#define TRAP_FRAME_SIZE 512
|
||||
#define TRAP_REGISTERS_SIZE 176
|
||||
|
||||
#endif /* __XTOSKRNL_AMD64_ASMSUP_H */
|
||||
43
xtoskrnl/includes/ar/amd64/asmsup.hh
Normal file
43
xtoskrnl/includes/ar/amd64/asmsup.hh
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/includes/ar/amd64/asmsup.hh
|
||||
* DESCRIPTION: Architecture-specific assembler prototypes
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTOSKRNL_AR_ASMSUP_HH
|
||||
#define __XTOSKRNL_AR_ASMSUP_HH
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* TrampolineEnableXpa end address to calculate trampoline size */
|
||||
XTCLINK PVOID ArEnableExtendedPhysicalAddressingEnd[];
|
||||
|
||||
/* External array of pointers to the interrupt handlers */
|
||||
XTCLINK ULONG_PTR ArInterruptEntry[256];
|
||||
|
||||
/* TrampolineApStartup end address to calculate trampoline size */
|
||||
XTCLINK PVOID ArStartApplicationProcessorEnd[];
|
||||
|
||||
/* External array of pointers to the trap handlers */
|
||||
XTCLINK ULONG_PTR ArTrapEntry[256];
|
||||
|
||||
/* Forward reference for assembler code */
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArEnableExtendedPhysicalAddressing(IN ULONG_PTR PageMap);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArHandleSpuriousInterrupt(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArStartApplicationProcessor(VOID);
|
||||
|
||||
#endif /* __XTOSKRNL_AR_ASMSUP_HH */
|
||||
@@ -1,158 +0,0 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/includes/ar/amd64/assembly.hh
|
||||
* DESCRIPTION: Architecture-specific assembler prototypes
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTOSKRNL_AR_ASSEMBLY_HH
|
||||
#define __XTOSKRNL_AR_ASSEMBLY_HH
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* TrampolineEnableXpa end address to calculate trampoline size */
|
||||
XTCLINK PVOID ArEnableExtendedPhysicalAddressingEnd[];
|
||||
|
||||
/* TrampolineApStartup end address to calculate trampoline size */
|
||||
XTCLINK PVOID ArStartApplicationProcessorEnd[];
|
||||
|
||||
|
||||
/* Forward reference for assembler code */
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArEnableExtendedPhysicalAddressing(IN ULONG_PTR PageMap);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArStartApplicationProcessor(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x00(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x01(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x02(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x03(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x04(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x05(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x06(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x07(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x08(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x09(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x0A(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x0B(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x0C(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x0D(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x0E(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x10(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x11(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x12(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x13(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x1F(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x2C(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x2D(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x2F(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0xE1(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0xFF(VOID);
|
||||
|
||||
#endif /* __XTOSKRNL_AR_ASSEMBLY_HH */
|
||||
@@ -24,6 +24,7 @@ namespace AR
|
||||
STATIC KIDTENTRY InitialIdt[IDT_ENTRIES];
|
||||
STATIC KPROCESSOR_BLOCK InitialProcessorBlock;
|
||||
STATIC KTSS InitialTss;
|
||||
STATIC UCHAR NmiStack[KERNEL_STACK_SIZE];
|
||||
|
||||
public:
|
||||
STATIC XTAPI PVOID GetBootStack(VOID);
|
||||
@@ -31,6 +32,13 @@ namespace AR
|
||||
OUT PVOID *TrampolineCode,
|
||||
OUT PULONG_PTR TrampolineSize);
|
||||
STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures);
|
||||
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
|
||||
IN USHORT Vector,
|
||||
IN PVOID Handler,
|
||||
IN USHORT Selector,
|
||||
IN USHORT Ist,
|
||||
IN USHORT Dpl,
|
||||
IN USHORT Type);
|
||||
|
||||
private:
|
||||
STATIC XTAPI VOID IdentifyProcessor(VOID);
|
||||
@@ -47,11 +55,13 @@ namespace AR
|
||||
OUT PKTSS *Tss,
|
||||
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
||||
OUT PVOID *KernelBootStack,
|
||||
OUT PVOID *KernelFaultStack);
|
||||
OUT PVOID *KernelFaultStack,
|
||||
OUT PVOID *KernelNmiStack);
|
||||
STATIC XTAPI VOID InitializeSegments(VOID);
|
||||
STATIC XTAPI VOID InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelBootStack,
|
||||
IN PVOID KernelFaultStack);
|
||||
IN PVOID KernelFaultStack,
|
||||
IN PVOID KernelNmiStack);
|
||||
STATIC XTAPI VOID SetGdtEntry(IN PKGDTENTRY Gdt,
|
||||
IN USHORT Selector,
|
||||
IN ULONG_PTR Base,
|
||||
@@ -62,13 +72,6 @@ namespace AR
|
||||
STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
||||
IN USHORT Selector,
|
||||
IN ULONG_PTR Base);
|
||||
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
|
||||
IN USHORT Vector,
|
||||
IN PVOID Handler,
|
||||
IN USHORT Selector,
|
||||
IN USHORT Ist,
|
||||
IN USHORT Dpl,
|
||||
IN USHORT Type);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,14 @@ namespace AR
|
||||
{
|
||||
class Traps
|
||||
{
|
||||
private:
|
||||
STATIC PINTERRUPT_HANDLER UnhandledInterruptRoutine;
|
||||
|
||||
public:
|
||||
STATIC XTCDECL VOID DispatchTrap(IN PKTRAP_FRAME TrapFrame);
|
||||
STATIC XTCDECL VOID DispatchInterrupt(IN PKTRAP_FRAME TrapFrame) XTSYMBOL("ArDispatchInterrupt");
|
||||
STATIC XTCDECL VOID DispatchTrap(IN PKTRAP_FRAME TrapFrame) XTSYMBOL("ArDispatchTrap");
|
||||
STATIC XTCDECL VOID InitializeSystemCallMsrs(VOID);
|
||||
STATIC XTCDECL VOID SetUnhandledInterruptRoutine(PINTERRUPT_HANDLER Handler);
|
||||
|
||||
private:
|
||||
STATIC XTCDECL VOID HandleSystemCall32(VOID);
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/includes/i686/asm.h
|
||||
* DESCRIPTION: i686 architecture assembly definitions
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#ifndef __XTOSKRNL_I686_ASMSUP_H
|
||||
#define __XTOSKRNL_I686_ASMSUP_H
|
||||
|
||||
|
||||
/* KTRAP_FRAME structure offsets */
|
||||
#define TrapPreviousMode 0
|
||||
#define TrapCr2 4
|
||||
#define TrapCr3 8
|
||||
#define TrapDr0 12
|
||||
#define TrapDr1 16
|
||||
#define TrapDr2 20
|
||||
#define TrapDr3 24
|
||||
#define TrapDr6 28
|
||||
#define TrapDr7 32
|
||||
#define TrapSegDs 36
|
||||
#define TrapSegEs 38
|
||||
#define TrapSegFs 40
|
||||
#define TrapSegGs 42
|
||||
#define TrapEsp 92
|
||||
#define TrapSegSs 96
|
||||
|
||||
/* KTRAP_FRAME length related definitions */
|
||||
#define TRAP_FRAME_SIZE 100
|
||||
#define TRAP_REGISTERS_SIZE 56
|
||||
|
||||
#endif /* __XTOSKRNL_I686_ASMSUP_H */
|
||||
43
xtoskrnl/includes/ar/i686/asmsup.hh
Normal file
43
xtoskrnl/includes/ar/i686/asmsup.hh
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/includes/ar/i686/asmsup.hh
|
||||
* DESCRIPTION: Architecture-specific assembler prototypes
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTOSKRNL_AR_ASMSUP_HH
|
||||
#define __XTOSKRNL_AR_ASMSUP_HH
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* TrampolineEnableXpa end address to calculate trampoline size */
|
||||
XTCLINK PVOID ArEnableExtendedPhysicalAddressingEnd[];
|
||||
|
||||
/* External array of pointers to the interrupt handlers */
|
||||
XTCLINK ULONG_PTR ArInterruptEntry[256];
|
||||
|
||||
/* TrampolineApStartup end address to calculate trampoline size */
|
||||
XTCLINK PVOID ArStartApplicationProcessorEnd[];
|
||||
|
||||
/* External array of pointers to the trap handlers */
|
||||
XTCLINK ULONG_PTR ArTrapEntry[256];
|
||||
|
||||
/* Forward reference for assembler code */
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArEnableExtendedPhysicalAddressing(IN ULONG_PTR PageMap);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArHandleSpuriousInterrupt(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArStartApplicationProcessor(VOID);
|
||||
|
||||
#endif /* __XTOSKRNL_AR_ASMSUP_HH */
|
||||
@@ -1,151 +0,0 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/includes/ar/i686/assembly.hh
|
||||
* DESCRIPTION: Architecture-specific assembler prototypes
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTOSKRNL_AR_ASSEMBLY_HH
|
||||
#define __XTOSKRNL_AR_ASSEMBLY_HH
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* TrampolineApStartup end address to calculate trampoline size */
|
||||
XTCLINK PVOID ArStartApplicationProcessorEnd[];
|
||||
|
||||
|
||||
/* Forward reference for assembler code */
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArStartApplicationProcessor(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x00(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x01(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x02(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x03(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x04(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x05(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x06(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x07(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x08(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x09(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x0A(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x0B(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x0C(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x0D(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x0E(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x10(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x11(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x12(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x13(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x2A(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x2B(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x2C(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x2D(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0x2E(VOID);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArTrap0xFF(VOID);
|
||||
|
||||
|
||||
#endif /* __XTOSKRNL_AR_ASSEMBLY_HH */
|
||||
@@ -25,6 +25,7 @@ namespace AR
|
||||
STATIC KIDTENTRY InitialIdt[IDT_ENTRIES];
|
||||
STATIC KPROCESSOR_BLOCK InitialProcessorBlock;
|
||||
STATIC KTSS InitialTss;
|
||||
STATIC UCHAR NmiStack[KERNEL_STACK_SIZE];
|
||||
STATIC UCHAR NonMaskableInterruptTss[KTSS_IO_MAPS];
|
||||
|
||||
|
||||
@@ -34,6 +35,13 @@ namespace AR
|
||||
OUT PVOID *TrampolineCode,
|
||||
OUT PULONG_PTR TrampolineSize);
|
||||
STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures);
|
||||
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
|
||||
IN USHORT Vector,
|
||||
IN PVOID Handler,
|
||||
IN USHORT Selector,
|
||||
IN USHORT Ist,
|
||||
IN USHORT Dpl,
|
||||
IN USHORT Type);
|
||||
|
||||
private:
|
||||
STATIC XTAPI VOID IdentifyProcessor(VOID);
|
||||
@@ -50,11 +58,13 @@ namespace AR
|
||||
OUT PKTSS *Tss,
|
||||
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
||||
OUT PVOID *KernelBootStack,
|
||||
OUT PVOID *KernelFaultStack);
|
||||
OUT PVOID *KernelFaultStack,
|
||||
OUT PVOID *KernelNmiStack);
|
||||
STATIC XTAPI VOID InitializeSegments(VOID);
|
||||
STATIC XTAPI VOID InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelBootStack,
|
||||
IN PVOID KernelFaultStack);
|
||||
IN PVOID KernelFaultStack,
|
||||
IN PVOID KernelNmiStack);
|
||||
STATIC XTAPI VOID SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelFaultStack);
|
||||
STATIC XTAPI VOID SetGdtEntry(IN PKGDTENTRY Gdt,
|
||||
@@ -67,15 +77,8 @@ namespace AR
|
||||
STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
||||
IN USHORT Selector,
|
||||
IN ULONG_PTR Base);
|
||||
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
|
||||
IN USHORT Vector,
|
||||
IN PVOID Handler,
|
||||
IN USHORT Selector,
|
||||
IN USHORT Ist,
|
||||
IN USHORT Dpl,
|
||||
IN USHORT Type);
|
||||
STATIC XTAPI VOID SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelFaultStack);
|
||||
IN PVOID KernelNmiStack);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/**@s
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/includes/ar/i686/traps.hh
|
||||
@@ -17,8 +17,13 @@ namespace AR
|
||||
{
|
||||
class Traps
|
||||
{
|
||||
private:
|
||||
STATIC PINTERRUPT_HANDLER UnhandledInterruptRoutine;
|
||||
|
||||
public:
|
||||
STATIC XTCDECL VOID DispatchTrap(IN PKTRAP_FRAME TrapFrame);
|
||||
STATIC XTCDECL VOID DispatchInterrupt(IN PKTRAP_FRAME TrapFrame) XTSYMBOL("_ArDispatchInterrupt");
|
||||
STATIC XTCDECL VOID DispatchTrap(IN PKTRAP_FRAME TrapFrame) XTSYMBOL("_ArDispatchTrap");
|
||||
STATIC XTCDECL VOID SetUnhandledInterruptRoutine(PINTERRUPT_HANDLER Handler);
|
||||
|
||||
private:
|
||||
STATIC XTCDECL VOID HandleTrap00(IN PKTRAP_FRAME TrapFrame);
|
||||
|
||||
@@ -18,8 +18,10 @@
|
||||
#include <hl/init.hh>
|
||||
#include <hl/ioport.hh>
|
||||
#include <hl/ioreg.hh>
|
||||
#include <hl/irq.hh>
|
||||
#include <hl/pic.hh>
|
||||
#include <hl/runlevel.hh>
|
||||
#include <hl/timer.hh>
|
||||
|
||||
|
||||
#endif /* __XTOSKRNL_HL_HH */
|
||||
|
||||
@@ -18,6 +18,8 @@ namespace HL
|
||||
class Acpi
|
||||
{
|
||||
private:
|
||||
STATIC ULONG CacheCount;
|
||||
STATIC ACPI_CACHE_LIST CacheEntries[ACPI_MAX_CACHED_TABLES];
|
||||
STATIC LIST_ENTRY CacheList;
|
||||
STATIC PACPI_RSDP RsdpStructure;
|
||||
STATIC ACPI_SYSTEM_INFO SystemInfo;
|
||||
|
||||
32
xtoskrnl/includes/hl/irq.hh
Normal file
32
xtoskrnl/includes/hl/irq.hh
Normal file
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/includes/hl/irq.hh
|
||||
* DESCRIPTION: Interrupts support
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTOSKRNL_HL_IRQ_HH
|
||||
#define __XTOSKRNL_HL_IRQ_HH
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Hardware Layer */
|
||||
namespace HL
|
||||
{
|
||||
class Irq
|
||||
{
|
||||
public:
|
||||
STATIC XTCDECL VOID HandleProfileInterrupt(IN PKTRAP_FRAME TrapFrame);
|
||||
STATIC XTCDECL VOID HandleUnexpectedInterrupt(IN PKTRAP_FRAME TrapFrame);
|
||||
STATIC XTAPI PVOID QueryInterruptHandler(IN ULONG Vector);
|
||||
STATIC XTAPI PVOID QuerySystemInterruptHandler(IN ULONG Vector);
|
||||
STATIC XTAPI VOID RegisterInterruptHandler(IN ULONG Vector,
|
||||
IN PVOID Handler);
|
||||
STATIC XTAPI VOID RegisterSystemInterruptHandler(IN ULONG Vector,
|
||||
IN PINTERRUPT_HANDLER Handler);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* __XTOSKRNL_HL_IRQ_HH */
|
||||
@@ -28,13 +28,13 @@ namespace HL
|
||||
STATIC XTAPI VOID SendEoi(VOID);
|
||||
STATIC XTAPI VOID SendIpi(ULONG ApicId,
|
||||
ULONG Vector);
|
||||
STATIC XTAPI VOID SendSelfIpi(ULONG Vector);
|
||||
STATIC XTFASTCALL VOID WriteApicRegister(IN APIC_REGISTER Register,
|
||||
IN ULONGLONG Value);
|
||||
|
||||
private:
|
||||
STATIC XTAPI BOOLEAN CheckApicSupport(VOID);
|
||||
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);
|
||||
};
|
||||
|
||||
40
xtoskrnl/includes/hl/timer.hh
Normal file
40
xtoskrnl/includes/hl/timer.hh
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/includes/hl/timer.hh
|
||||
* DESCRIPTION: ACPI Timer support
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTOSKRNL_HL_TIMER_HH
|
||||
#define __XTOSKRNL_HL_TIMER_HH
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Hardware Layer */
|
||||
namespace HL
|
||||
{
|
||||
class Timer
|
||||
{
|
||||
private:
|
||||
STATIC ULONG ProfilingInterval;
|
||||
STATIC TIMER_CAPABILITIES TimerCapabilities;
|
||||
STATIC ULONG TimerFrequency;
|
||||
|
||||
public:
|
||||
STATIC XTAPI VOID InitializeTimer(VOID);
|
||||
STATIC XTAPI ULONG_PTR SetProfileInterval(IN ULONG_PTR Interval);
|
||||
STATIC XTAPI VOID StartProfileInterrupt(IN KPROFILE_SOURCE ProfileSource);
|
||||
STATIC XTAPI VOID StopProfileInterrupt(IN KPROFILE_SOURCE ProfileSource);
|
||||
|
||||
private:
|
||||
STATIC XTAPI XTSTATUS CalibrateApicTimer();
|
||||
STATIC XTAPI VOID InitializeApicTimer(VOID);
|
||||
STATIC XTAPI VOID PitStallExecution(IN ULONG MicroSeconds);
|
||||
STATIC XTAPI VOID QueryTimerCapabilities(VOID);
|
||||
STATIC XTAPI VOID StallExecution(IN ULONG MicroSeconds);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* __XTOSKRNL_HL_TIMER_HH */
|
||||
@@ -17,7 +17,6 @@
|
||||
#include <ke/dpc.hh>
|
||||
#include <ke/event.hh>
|
||||
#include <ke/guard.hh>
|
||||
#include <ke/irq.hh>
|
||||
#include <ke/kprocess.hh>
|
||||
#include <ke/krnlinit.hh>
|
||||
#include <ke/kthread.hh>
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
/**
|
||||
* 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 <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTOSKRNL_KE_INFO_HH
|
||||
#define __XTOSKRNL_KE_INFO_HH
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* 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 */
|
||||
@@ -1,26 +0,0 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/includes/ke/irq.hh
|
||||
* DESCRIPTION: Kernel interrupts support
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTOSKRNL_KE_IRQ_HH
|
||||
#define __XTOSKRNL_KE_IRQ_HH
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Kernel Library */
|
||||
namespace KE
|
||||
{
|
||||
class Irq
|
||||
{
|
||||
public:
|
||||
STATIC XTAPI VOID SetInterruptHandler(IN ULONG Vector,
|
||||
IN PVOID Handler);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* __XTOSKRNL_KE_IRQ_HH */
|
||||
@@ -1,39 +0,0 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ke/amd64/irq.cc
|
||||
* DESCRIPTION: Kernel interrupts support for amd64 architecture
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Sets new interrupt handler for the existing IDT entry.
|
||||
*
|
||||
* @param HalVector
|
||||
* Supplies the HAL vector number.
|
||||
*
|
||||
* @param Handler
|
||||
* Supplies the new interrupt handler.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KE::Irq::SetInterruptHandler(IN ULONG Vector,
|
||||
IN PVOID Handler)
|
||||
{
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
|
||||
/* Get current processor block */
|
||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
||||
|
||||
/* Update interrupt handler */
|
||||
ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF);
|
||||
ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetMiddle = (((ULONG_PTR)Handler >> 16) & 0xFFFF);
|
||||
ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetHigh = (ULONG_PTR)Handler >> 32;
|
||||
}
|
||||
@@ -28,7 +28,7 @@ KE::KernelInit::InitializeKernel(VOID)
|
||||
{
|
||||
/* Hardware layer initialization failed, kernel panic */
|
||||
DebugPrint(L"Failed to initialize hardware layer subsystem!\n");
|
||||
Crash::Panic(0);
|
||||
KE::Crash::Panic(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,8 +74,8 @@ KE::KernelInit::StartKernel(VOID)
|
||||
PKTHREAD CurrentThread;
|
||||
|
||||
/* Get processor control block and current thread */
|
||||
Prcb = Processor::GetCurrentProcessorControlBlock();
|
||||
CurrentThread = Processor::GetCurrentThread();
|
||||
Prcb = KE::Processor::GetCurrentProcessorControlBlock();
|
||||
CurrentThread = KE::Processor::GetCurrentThread();
|
||||
|
||||
/* Get current process */
|
||||
CurrentProcess = CurrentThread->ApcState.Process;
|
||||
@@ -84,14 +84,14 @@ KE::KernelInit::StartKernel(VOID)
|
||||
PO::Idle::InitializeProcessorIdleState(Prcb);
|
||||
|
||||
/* Save processor state */
|
||||
Processor::SaveProcessorState(&Prcb->ProcessorState);
|
||||
KE::Processor::SaveProcessorState(&Prcb->ProcessorState);
|
||||
|
||||
/* Initialize spin locks */
|
||||
SpinLock::InitializeAllLocks();
|
||||
SpinLock::InitializeLockQueues();
|
||||
KE::SpinLock::InitializeAllLocks();
|
||||
KE::SpinLock::InitializeLockQueues();
|
||||
|
||||
/* Lower to APC runlevel */
|
||||
RunLevel::LowerRunLevel(APC_LEVEL);
|
||||
KE::RunLevel::LowerRunLevel(APC_LEVEL);
|
||||
|
||||
/* Initialize XTOS kernel */
|
||||
InitializeKernel();
|
||||
@@ -99,11 +99,11 @@ KE::KernelInit::StartKernel(VOID)
|
||||
/* Initialize Idle process */
|
||||
PageDirectory[0] = 0;
|
||||
PageDirectory[1] = 0;
|
||||
KProcess::InitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE);
|
||||
KE::KProcess::InitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE);
|
||||
CurrentProcess->Quantum = MAXCHAR;
|
||||
|
||||
/* Initialize Idle thread */
|
||||
KThread::InitializeThread(CurrentProcess, CurrentThread, NULLPTR, NULLPTR, NULLPTR,
|
||||
KE::KThread::InitializeThread(CurrentProcess, CurrentThread, NULLPTR, NULLPTR, NULLPTR,
|
||||
NULLPTR, NULLPTR, AR::ProcSup::GetBootStack(), TRUE);
|
||||
CurrentThread->NextProcessor = Prcb->CpuNumber;
|
||||
CurrentThread->Priority = THREAD_HIGH_PRIORITY;
|
||||
@@ -117,7 +117,7 @@ KE::KernelInit::StartKernel(VOID)
|
||||
|
||||
/* Enter infinite loop */
|
||||
DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n");
|
||||
Crash::HaltSystem();
|
||||
KE::Crash::HaltSystem();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -138,7 +138,7 @@ KE::KernelInit::SwitchBootStack(VOID)
|
||||
Stack = ((ULONG_PTR)AR::ProcSup::GetBootStack() + KERNEL_STACK_SIZE) & ~(STACK_ALIGNMENT - 1);
|
||||
|
||||
/* Get address of KernelInit::StartKernel() */
|
||||
StartKernel = (PVOID)KernelInit::StartKernel;
|
||||
StartKernel = (PVOID)KE::KernelInit::StartKernel;
|
||||
|
||||
/* Discard old stack frame, switch stack and jump to KernelInit::StartKernel() */
|
||||
__asm__ volatile("mov %0, %%rdx\n"
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ke/i686/irq.cc
|
||||
* DESCRIPTION: Kernel interrupts support for i686 architecture
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Sets new interrupt handler for the existing IDT entry.
|
||||
*
|
||||
* @param HalVector
|
||||
* Supplies the HAL vector number.
|
||||
*
|
||||
* @param Handler
|
||||
* Supplies the new interrupt handler.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KE::Irq::SetInterruptHandler(IN ULONG Vector,
|
||||
IN PVOID Handler)
|
||||
{
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
|
||||
/* Get current processor block */
|
||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
||||
|
||||
/* Update interrupt handler */
|
||||
ProcessorBlock->IdtBase[(UCHAR) Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF);
|
||||
ProcessorBlock->IdtBase[(UCHAR) Vector].ExtendedOffset = (USHORT)((ULONG)Handler >> 16);
|
||||
}
|
||||
@@ -28,7 +28,7 @@ KE::KernelInit::InitializeKernel(VOID)
|
||||
{
|
||||
/* Hardware layer initialization failed, kernel panic */
|
||||
DebugPrint(L"Failed to initialize hardware layer subsystem!\n");
|
||||
Crash::Panic(0);
|
||||
KE::Crash::Panic(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,8 +74,8 @@ KE::KernelInit::StartKernel(VOID)
|
||||
PKTHREAD CurrentThread;
|
||||
|
||||
/* Get processor control block and current thread */
|
||||
Prcb = Processor::GetCurrentProcessorControlBlock();
|
||||
CurrentThread = Processor::GetCurrentThread();
|
||||
Prcb = KE::Processor::GetCurrentProcessorControlBlock();
|
||||
CurrentThread = KE::Processor::GetCurrentThread();
|
||||
|
||||
/* Get current process */
|
||||
CurrentProcess = CurrentThread->ApcState.Process;
|
||||
@@ -84,14 +84,14 @@ KE::KernelInit::StartKernel(VOID)
|
||||
PO::Idle::InitializeProcessorIdleState(Prcb);
|
||||
|
||||
/* Save processor state */
|
||||
Processor::SaveProcessorState(&Prcb->ProcessorState);
|
||||
KE::Processor::SaveProcessorState(&Prcb->ProcessorState);
|
||||
|
||||
/* Initialize spin locks */
|
||||
SpinLock::InitializeAllLocks();
|
||||
SpinLock::InitializeLockQueues();
|
||||
KE::SpinLock::InitializeAllLocks();
|
||||
KE::SpinLock::InitializeLockQueues();
|
||||
|
||||
/* Lower to APC runlevel */
|
||||
RunLevel::LowerRunLevel(APC_LEVEL);
|
||||
KE::RunLevel::LowerRunLevel(APC_LEVEL);
|
||||
|
||||
/* Initialize XTOS kernel */
|
||||
InitializeKernel();
|
||||
@@ -99,11 +99,11 @@ KE::KernelInit::StartKernel(VOID)
|
||||
/* Initialize Idle process */
|
||||
PageDirectory[0] = 0;
|
||||
PageDirectory[1] = 0;
|
||||
KProcess::InitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE);
|
||||
KE::KProcess::InitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE);
|
||||
CurrentProcess->Quantum = MAXCHAR;
|
||||
|
||||
/* Initialize Idle thread */
|
||||
KThread::InitializeThread(CurrentProcess, CurrentThread, NULLPTR, NULLPTR, NULLPTR,
|
||||
KE::KThread::InitializeThread(CurrentProcess, CurrentThread, NULLPTR, NULLPTR, NULLPTR,
|
||||
NULLPTR, NULLPTR, AR::ProcSup::GetBootStack(), TRUE);
|
||||
CurrentThread->NextProcessor = Prcb->CpuNumber;
|
||||
CurrentThread->Priority = THREAD_HIGH_PRIORITY;
|
||||
@@ -117,7 +117,7 @@ KE::KernelInit::StartKernel(VOID)
|
||||
|
||||
/* Enter infinite loop */
|
||||
DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n");
|
||||
Crash::HaltSystem();
|
||||
KE::Crash::HaltSystem();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -138,7 +138,7 @@ KE::KernelInit::SwitchBootStack(VOID)
|
||||
Stack = ((ULONG_PTR)AR::ProcSup::GetBootStack() + KERNEL_STACK_SIZE) & ~(STACK_ALIGNMENT - 1);
|
||||
|
||||
/* Get address of KernelInit::StartKernel() */
|
||||
StartKernel = (PVOID)KernelInit::StartKernel;
|
||||
StartKernel = (PVOID)KE::KernelInit::StartKernel;
|
||||
|
||||
/* Discard old stack frame, switch stack, make space for NPX and jump to KernelInit::StartKernel() */
|
||||
__asm__ volatile("mov %0, %%edx\n"
|
||||
|
||||
@@ -32,25 +32,26 @@ KeStartXtSystem(IN PKERNEL_INITIALIZATION_BLOCK Parameters)
|
||||
Parameters->ProtocolVersion != BOOT_PROTOCOL_VERSION)
|
||||
{
|
||||
/* Kernel and boot loader version mismatch */
|
||||
Crash::HaltSystem();
|
||||
KE::Crash::HaltSystem();
|
||||
}
|
||||
|
||||
/* Save the kernel initialization block */
|
||||
BootInformation::InitializeInitializationBlock(Parameters);
|
||||
KE::BootInformation::InitializeInitializationBlock(Parameters);
|
||||
|
||||
/* Check if debugging enabled and if boot loader provided routine for debug printing */
|
||||
if(DEBUG && BootInformation::GetDebugPrint())
|
||||
if(DEBUG && KE::BootInformation::GetDebugPrint())
|
||||
{
|
||||
/* Use loader's provided DbgPrint() routine for early printing to serial console */
|
||||
KD::DebugIo::SetPrintRoutine(BootInformation::GetDebugPrint());
|
||||
KD::DebugIo::SetPrintRoutine(KE::BootInformation::GetDebugPrint());
|
||||
DebugPrint(L"Initializing ExectOS v%d.%d for %s\n", XTOS_VERSION_MAJOR, XTOS_VERSION_MINOR, _ARCH_NAME);
|
||||
}
|
||||
|
||||
/* Initialize boot CPU */
|
||||
/* Initialize boot CPU and set the unhandled interrupt routine */
|
||||
AR::ProcSup::InitializeProcessor(NULLPTR);
|
||||
AR::Traps::SetUnhandledInterruptRoutine(HL::Irq::HandleUnexpectedInterrupt);
|
||||
|
||||
/* Initialize system resources */
|
||||
SystemResources::InitializeResources();
|
||||
KE::SystemResources::InitializeResources();
|
||||
|
||||
/* Check if debugging enabled */
|
||||
if(DEBUG)
|
||||
@@ -66,11 +67,11 @@ KeStartXtSystem(IN PKERNEL_INITIALIZATION_BLOCK Parameters)
|
||||
XTOS_COMPILER_NAME, XTOS_COMPILER_VERSION);
|
||||
|
||||
/* Architecture specific kernel initialization */
|
||||
KernelInit::InitializeMachine();
|
||||
KE::KernelInit::InitializeMachine();
|
||||
|
||||
/* Raise to HIGH runlevel */
|
||||
RunLevel::RaiseRunLevel(HIGH_LEVEL);
|
||||
KE::RunLevel::RaiseRunLevel(HIGH_LEVEL);
|
||||
|
||||
/* Switch the boot stack and transfer control to the KepStartKernel() routine */
|
||||
KernelInit::SwitchBootStack();
|
||||
KE::KernelInit::SwitchBootStack();
|
||||
}
|
||||
|
||||
@@ -92,10 +92,10 @@ KE::KThread::InitializeThread(IN PKPROCESS Process,
|
||||
Thread->Header.SignalState = 0;
|
||||
|
||||
/* Initialize thread wait list */
|
||||
RtlInitializeListHead(&Thread->Header.WaitListHead);
|
||||
RTL::LinkedList::InitializeListHead(&Thread->Header.WaitListHead);
|
||||
|
||||
/* Initialize thread mutant list head */
|
||||
RtlInitializeListHead(&Thread->MutantListHead);
|
||||
RTL::LinkedList::InitializeListHead(&Thread->MutantListHead);
|
||||
|
||||
/* Initialize the builtin wait blocks */
|
||||
for(Index = 0; Index <= KTHREAD_WAIT_BLOCK; Index++)
|
||||
@@ -113,7 +113,7 @@ KE::KThread::InitializeThread(IN PKPROCESS Process,
|
||||
Thread->AdjustReason = AdjustNone;
|
||||
|
||||
/* Initialize thread lock */
|
||||
SpinLock::InitializeSpinLock(&Thread->ThreadLock);
|
||||
KE::SpinLock::InitializeSpinLock(&Thread->ThreadLock);
|
||||
|
||||
/* Initialize thread APC */
|
||||
Thread->ApcStatePointer[0] = &Thread->ApcState;
|
||||
@@ -123,21 +123,21 @@ KE::KThread::InitializeThread(IN PKPROCESS Process,
|
||||
Thread->Process = Process;
|
||||
|
||||
/* Initialize APC list heads */
|
||||
RtlInitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]);
|
||||
RtlInitializeListHead(&Thread->ApcState.ApcListHead[UserMode]);
|
||||
RTL::LinkedList::InitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]);
|
||||
RTL::LinkedList::InitializeListHead(&Thread->ApcState.ApcListHead[UserMode]);
|
||||
|
||||
/* Initialize APC queue lock */
|
||||
SpinLock::InitializeSpinLock(&Thread->ApcQueueLock);
|
||||
KE::SpinLock::InitializeSpinLock(&Thread->ApcQueueLock);
|
||||
|
||||
/* Initialize kernel-mode suspend APC */
|
||||
Apc::InitializeApc(&Thread->SuspendApc, Thread, OriginalApcEnvironment, SuspendNop,
|
||||
KE::Apc::InitializeApc(&Thread->SuspendApc, Thread, OriginalApcEnvironment, SuspendNop,
|
||||
SuspendRundown, SuspendThread, KernelMode, NULLPTR);
|
||||
|
||||
/* Initialize suspend semaphore */
|
||||
Semaphore::InitializeSemaphore(&Thread->SuspendSemaphore, 0, 2);
|
||||
KE::Semaphore::InitializeSemaphore(&Thread->SuspendSemaphore, 0, 2);
|
||||
|
||||
/* Initialize the builtin timer */
|
||||
Timer::InitializeTimer(&Thread->Timer, NotificationTimer);
|
||||
KE::Timer::InitializeTimer(&Thread->Timer, NotificationTimer);
|
||||
TimerWaitBlock = &Thread->WaitBlock[KTIMER_WAIT_BLOCK];
|
||||
TimerWaitBlock->Object = &Thread->Timer;
|
||||
TimerWaitBlock->WaitKey = STATUS_TIMEOUT;
|
||||
|
||||
@@ -66,7 +66,7 @@ KE::SystemResources::GetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
|
||||
|
||||
/* Disable interrupts and acquire a spinlock */
|
||||
AR::CpuFunc::ClearInterruptFlag();
|
||||
SpinLock::AcquireSpinLock(&ResourcesLock);
|
||||
KE::SpinLock::AcquireSpinLock(&ResourcesLock);
|
||||
|
||||
/* Iterate through system resources list */
|
||||
ListEntry = ResourcesListHead.Flink;
|
||||
@@ -110,7 +110,7 @@ KE::SystemResources::GetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
|
||||
}
|
||||
|
||||
/* Release spinlock and re-enable interrupts if necessary */
|
||||
SpinLock::ReleaseSpinLock(&ResourcesLock);
|
||||
KE::SpinLock::ReleaseSpinLock(&ResourcesLock);
|
||||
if(Interrupts)
|
||||
{
|
||||
/* Re-enable interrupts */
|
||||
@@ -160,15 +160,15 @@ KE::SystemResources::InitializeResources(VOID)
|
||||
ULONG ResourceSize;
|
||||
|
||||
/* Initialize system resources spin lock and resource list */
|
||||
SpinLock::InitializeSpinLock(&ResourcesLock);
|
||||
KE::SpinLock::InitializeSpinLock(&ResourcesLock);
|
||||
RTL::LinkedList::InitializeListHead(&ResourcesListHead);
|
||||
|
||||
/* Make sure there are some system resources available */
|
||||
if(!RTL::LinkedList::ListEmpty(BootInformation::GetSystemResources()))
|
||||
if(!RTL::LinkedList::ListEmpty(KE::BootInformation::GetSystemResources()))
|
||||
{
|
||||
/* Iterate through system resources list */
|
||||
ListEntry = BootInformation::GetSystemResources()->Flink;
|
||||
while(ListEntry != BootInformation::GetSystemResources())
|
||||
ListEntry = KE::BootInformation::GetSystemResources()->Flink;
|
||||
while(ListEntry != KE::BootInformation::GetSystemResources())
|
||||
{
|
||||
/* Get resource header and next list entry */
|
||||
ResourceHeader = CONTAIN_RECORD(ListEntry, SYSTEM_RESOURCE_HEADER, ListEntry);
|
||||
@@ -221,12 +221,12 @@ KE::SystemResources::ReleaseResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader)
|
||||
{
|
||||
/* Disable interrupts and acquire a spinlock */
|
||||
AR::CpuFunc::ClearInterruptFlag();
|
||||
SpinLock::AcquireSpinLock(&ResourcesLock);
|
||||
KE::SpinLock::AcquireSpinLock(&ResourcesLock);
|
||||
|
||||
/* Release resource lock */
|
||||
ResourceHeader->ResourceLocked = FALSE;
|
||||
|
||||
/* Release spinlock and enable interrupts */
|
||||
SpinLock::ReleaseSpinLock(&ResourcesLock);
|
||||
KE::SpinLock::ReleaseSpinLock(&ResourcesLock);
|
||||
AR::CpuFunc::SetInterruptFlag();
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ KE::Timer::CancelTimer(IN PKTIMER Timer)
|
||||
|
||||
/* Raise run level and acquire dispatcher lock */
|
||||
RunLevel = KE::RunLevel::RaiseRunLevel(SYNC_LEVEL);
|
||||
SpinLock::AcquireQueuedSpinLock(DispatcherLock);
|
||||
KE::SpinLock::AcquireQueuedSpinLock(DispatcherLock);
|
||||
|
||||
/* Check timer status */
|
||||
if(Timer->Header.Inserted)
|
||||
@@ -42,8 +42,8 @@ KE::Timer::CancelTimer(IN PKTIMER Timer)
|
||||
}
|
||||
|
||||
/* Release dispatcher lock and process the deferred ready list */
|
||||
SpinLock::ReleaseQueuedSpinLock(DispatcherLock);
|
||||
KThread::ExitDispatcher(RunLevel);
|
||||
KE::SpinLock::ReleaseQueuedSpinLock(DispatcherLock);
|
||||
KE::KThread::ExitDispatcher(RunLevel);
|
||||
|
||||
/* Return result */
|
||||
return Result;
|
||||
@@ -139,7 +139,7 @@ KE::Timer::QueryTimer(IN PKTIMER Timer)
|
||||
|
||||
/* Raise run level and acquire dispatcher lock */
|
||||
RunLevel = KE::RunLevel::RaiseRunLevel(SYNC_LEVEL);
|
||||
SpinLock::AcquireQueuedSpinLock(DispatcherLock);
|
||||
KE::SpinLock::AcquireQueuedSpinLock(DispatcherLock);
|
||||
|
||||
/* Check timer status */
|
||||
if(Timer->Header.Inserted)
|
||||
@@ -149,8 +149,8 @@ KE::Timer::QueryTimer(IN PKTIMER Timer)
|
||||
}
|
||||
|
||||
/* Release dispatcher lock and process the deferred ready list */
|
||||
SpinLock::ReleaseQueuedSpinLock(DispatcherLock);
|
||||
KThread::ExitDispatcher(RunLevel);
|
||||
KE::SpinLock::ReleaseQueuedSpinLock(DispatcherLock);
|
||||
KE::KThread::ExitDispatcher(RunLevel);
|
||||
|
||||
/* Return timer's due time */
|
||||
return DueTime;
|
||||
|
||||
102
xtoskrnl/mm/exports.cc
Normal file
102
xtoskrnl/mm/exports.cc
Normal file
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/mm/exports.cc
|
||||
* DESCRIPTION: C-compatible API wrappers for exported kernel functions
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Allocates a block of memory from the specified pool type.
|
||||
*
|
||||
* @param PoolType
|
||||
* Specifies the type of pool to allocate from.
|
||||
*
|
||||
* @param Bytes
|
||||
* Specifies the number of bytes to allocate.
|
||||
*
|
||||
* @param Memory
|
||||
* Supplies a pointer to the allocated memory.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
MmAllocatePool(IN MMPOOL_TYPE PoolType,
|
||||
IN SIZE_T Bytes,
|
||||
OUT PVOID *Memory)
|
||||
{
|
||||
return MM::Allocator::AllocatePool(PoolType, Bytes, Memory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates a block of memory from the specified pool type.
|
||||
*
|
||||
* @param PoolType
|
||||
* Specifies the type of pool to allocate from.
|
||||
*
|
||||
* @param Bytes
|
||||
* Specifies the number of bytes to allocate.
|
||||
*
|
||||
* @param Memory
|
||||
* Supplies a pointer to the allocated memory.
|
||||
*
|
||||
* @param Tag
|
||||
* Specifies the allocation identifying tag.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
MmAllocatePoolWithTag(IN MMPOOL_TYPE PoolType,
|
||||
IN SIZE_T Bytes,
|
||||
OUT PVOID *Memory,
|
||||
IN ULONG Tag)
|
||||
{
|
||||
return MM::Allocator::AllocatePool(PoolType, Bytes, Memory, Tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees a previously allocated memory pool.
|
||||
*
|
||||
* @param VirtualAddress
|
||||
* Supplies the base virtual address of the pool allocation to free.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
MmFreePool(IN PVOID VirtualAddress)
|
||||
{
|
||||
return MM::Allocator::FreePool(VirtualAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees a previously allocated memory pool.
|
||||
*
|
||||
* @param VirtualAddress
|
||||
* Supplies the base virtual address of the pool allocation to free.
|
||||
*
|
||||
* @param Tag
|
||||
* Specifies the allocation identifying tag.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
MmFreePoolWithTag(IN PVOID VirtualAddress,
|
||||
IN ULONG Tag)
|
||||
{
|
||||
return MM::Allocator::FreePool(VirtualAddress, Tag);
|
||||
}
|
||||
@@ -128,7 +128,9 @@ MM::KernelPool::AllocateProcessorStructures(IN ULONG CpuNumber,
|
||||
|
||||
/* 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) + (GDT_ENTRIES * sizeof(KGDTENTRY)));
|
||||
ProcessorBlock = (PKPROCESSOR_BLOCK)((PUCHAR)Address +
|
||||
(KERNEL_STACKS * KERNEL_STACK_SIZE) +
|
||||
(GDT_ENTRIES * sizeof(KGDTENTRY)));
|
||||
|
||||
/* Store processor number in the processor block */
|
||||
ProcessorBlock->CpuNumber = CpuNumber;
|
||||
|
||||
@@ -24,7 +24,7 @@ VOID
|
||||
PO::Idle::InitializeProcessorIdleState(IN OUT PKPROCESSOR_CONTROL_BLOCK Prcb)
|
||||
{
|
||||
/* Zero memory */
|
||||
RtlZeroMemory(&Prcb->PowerState, sizeof(Prcb->PowerState));
|
||||
RTL::Memory::ZeroMemory(&Prcb->PowerState, sizeof(Prcb->PowerState));
|
||||
|
||||
/* Initialize default power state */
|
||||
Prcb->PowerState.Idle0TimeLimit = 0xFFFFFFFF;
|
||||
@@ -33,9 +33,9 @@ PO::Idle::InitializeProcessorIdleState(IN OUT PKPROCESSOR_CONTROL_BLOCK Prcb)
|
||||
Prcb->PowerState.IdleFunction = Idle0Function;
|
||||
|
||||
/* Initialize DPC and Timer */
|
||||
KeInitializeDpc(&Prcb->PowerState.PerfDpc, PerfIdleDpc, Prcb);
|
||||
KeSetTargetProcessorDpc(&Prcb->PowerState.PerfDpc, Prcb->CpuNumber);
|
||||
KeInitializeTimer(&Prcb->PowerState.PerfTimer, SynchronizationTimer);
|
||||
KE::Dpc::InitializeDpc(&Prcb->PowerState.PerfDpc, PerfIdleDpc, Prcb);
|
||||
KE::Dpc::SetTargetProcessor(&Prcb->PowerState.PerfDpc, Prcb->CpuNumber);
|
||||
KE::Timer::InitializeTimer(&Prcb->PowerState.PerfTimer, SynchronizationTimer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user