Compare commits
211 Commits
smp
...
1339943473
| Author | SHA1 | Date | |
|---|---|---|---|
| 1339943473 | |||
| 160222fd3b | |||
| 7e4b425702 | |||
| bbdbdc7bcd | |||
| 28dd16fb94 | |||
| 6ac0fd0a1c | |||
| 202b98a3fd | |||
| b323956f4b | |||
| 6e992f3005 | |||
| d1a4b378b1 | |||
| 3ca3a86c0f | |||
| 8ee50255bb | |||
| f1b9d57bf7 | |||
| f18c9ca5b4 | |||
| 5fa948d57e | |||
| 6577876285 | |||
| caf0287135 | |||
| 95a3b5d7e2 | |||
| 579ac1d90e | |||
| 4015b4b2f3 | |||
| 0375a08ca5 | |||
| d55a8219e3 | |||
| 8a35727e43 | |||
| 322fea763b | |||
| 77e487495b | |||
| 7b3f4bb35a | |||
| 427c7ae810 | |||
| c575352f90 | |||
| d8a430ee42 | |||
| 2e5c259a5a | |||
| 66df8fddda | |||
| 4f16957016 | |||
| e1b9664ec0 | |||
| 60d8844afe | |||
| d39ddabd04 | |||
| 6044dbaac9 | |||
| 3d2be65545 | |||
| caff02383c | |||
| 58bc1839f5 | |||
| 72b3fe8209 | |||
| a1899fd1fa | |||
| 5748e73853 | |||
| 792157eab1 | |||
| 14276179a7 | |||
| 71684314c7 | |||
| b959e1908f | |||
| 5cca5970b1 | |||
| 6c6b1f6a52 | |||
| 706aca6e20 | |||
| cd60cd7b1a | |||
| a6b050ddf2 | |||
| 398de5cb5b | |||
| 37d70c449c | |||
| 50654a28b5 | |||
| 1f8d2a0370 | |||
| bd9af3bb5c | |||
| c303694384 | |||
| 4de76886ee | |||
| 52355698a9 | |||
| 420a66629b | |||
| 59f851f22c | |||
| 58ed35b0e4 | |||
| dc2c24e83e | |||
| 932e951d4b | |||
| b7f85909cb | |||
| ca661d1201 | |||
| 1be5732789 | |||
| e08af6bfd3 | |||
| 78fac504b7 | |||
| 157c48ce7f | |||
| 3b397aca92 | |||
| 755c3fe1bf | |||
| 75484e8c58 | |||
| 3799dbae65 | |||
| aa7d9bb417 | |||
| 21fb192790 | |||
| a4f5211a96 | |||
| 9da11d827e | |||
| bcd3032fe3 | |||
| d8792cc9db | |||
| a2335900ad | |||
| 94320928bc | |||
| 17e096f18c | |||
| 66300103e1 | |||
| 8d05099d7b | |||
| 488736512f | |||
| a326fea9af | |||
| bd7129ce13 | |||
| af9cc43b1d | |||
| d272d2cb78 | |||
| b435752cbf | |||
| 2e0a32ca1d | |||
| 8554c634df | |||
| 8577d23e47 | |||
| bc85eb3c12 | |||
| 52c119885c | |||
| efe7f28675 | |||
| c29afe477c | |||
| ae43f7c723 | |||
| c8792a013a | |||
| edfae7ec6a | |||
| 31002b27be | |||
| 44a217ea14 | |||
| 4a26507228 | |||
| 33d41a9442 | |||
| d2374799eb | |||
| 0ee46924a7 | |||
| 3384556543 | |||
| 3b8359042b | |||
| c8fa998e38 | |||
| 807b0a736f | |||
| cb61566e8b | |||
| 41eed4c7ad | |||
| 042d0fa03a | |||
| 6accbfd2ae | |||
| ec27cb7f76 | |||
| bfa5cddb57 | |||
| f8cdcc3f75 | |||
| 602e837e11 | |||
| 0ca04a7dfe | |||
| 3270f920dd | |||
| 4f6e8bc07a | |||
| 4aa841650a | |||
| c5ea9e4489 | |||
| c6041b02ae | |||
| 0153b2fb33 | |||
| e0bcac3722 | |||
| 466b0c8eab | |||
| 374f404324 | |||
| 6308fd048b | |||
| 4963ff5367 | |||
| e0e3482326 | |||
| 896803e248 | |||
| b5ebd24f24 | |||
| e1144da195 | |||
| 0c9ea2ed20 | |||
| 43d0e8932d | |||
| d88fa93df9 | |||
| 9cfc22e1f3 | |||
| d9a95527f3 | |||
| 47606faded | |||
| b6c5bae289 | |||
| 330c9e3eaf | |||
| 2854f77159 | |||
| 75dfcec5a6 | |||
| f33fa0fdaf | |||
| cdad8ffe2c | |||
| 425780de69 | |||
| 446d9af325 | |||
| 536d59c3a8 | |||
| 4192e93157 | |||
| b32c66110b | |||
| cdb3c1a8da | |||
| 5e54aca398 | |||
| 68604e1bc0 | |||
| a4b36827e4 | |||
| e8512e9f45 | |||
| 0448217c06 | |||
| f9b27b48b0 | |||
| eb621e0264 | |||
| ed769e023f | |||
| 08b095d47c | |||
| 87aa3494f9 | |||
| 244af13500 | |||
| e6d2574bf9 | |||
| 6f9e537e86 | |||
| be6ad1658f | |||
| a45cd95b6f | |||
| 3c5bb52152 | |||
| 3a311a0497 | |||
| 140b25ff76 | |||
| c760016ee5 | |||
| 6a55b1a42c | |||
| d8b2af8f1e | |||
| 28fc0ab435 | |||
| 329c22ae82 | |||
| d27954091a | |||
| df9028d425 | |||
| 540c4df13e | |||
| 0a2fb7ae38 | |||
| 6f824c55bb | |||
| f371b305ad | |||
| 24e20f3d8f | |||
| c7bfc028b6 | |||
| 9492ba09a6 | |||
| 4e7ab3585e | |||
| 9d27778e4c | |||
| 0796164cf8 | |||
| 2f4d26b432 | |||
| 48fafd4a9a | |||
| 1996024e96 | |||
| 42a96ae5c3 | |||
| f9a057db2d | |||
| f210c9e334 | |||
| 117d174e6e | |||
| 8334fe5a48 | |||
| 7b7426738a | |||
| 8d4455de88 | |||
| b7f0f07f8b | |||
| e831902363 | |||
| f247726ee9 | |||
| 9449ee6eb1 | |||
| 34586d8fa1 | |||
| 05b9bb75a7 | |||
| d752de20f6 | |||
| fd7cc019ee | |||
| 8e48153852 | |||
| bf98860ff2 | |||
| c2d3f2e6f4 | |||
| 779726c4d6 | |||
| 4cf2c0c9e8 |
@@ -55,9 +55,6 @@ add_definitions(-D__XTOS__)
|
|||||||
add_definitions(-DXTOS_SOURCE_DIR="${EXECTOS_SOURCE_DIR}")
|
add_definitions(-DXTOS_SOURCE_DIR="${EXECTOS_SOURCE_DIR}")
|
||||||
add_definitions(-DXTOS_BINARY_DIR="${EXECTOS_BINARY_DIR}")
|
add_definitions(-DXTOS_BINARY_DIR="${EXECTOS_BINARY_DIR}")
|
||||||
|
|
||||||
# Add assembler flags
|
|
||||||
add_compiler_asmflags(-D__XTOS_ASSEMBLER__)
|
|
||||||
|
|
||||||
# Compute __FILE__ definition
|
# Compute __FILE__ definition
|
||||||
file(RELATIVE_PATH _PATH_PREFIX ${EXECTOS_BINARY_DIR} ${EXECTOS_SOURCE_DIR})
|
file(RELATIVE_PATH _PATH_PREFIX ${EXECTOS_BINARY_DIR} ${EXECTOS_SOURCE_DIR})
|
||||||
add_compiler_flags(-D__RELFILE__="&__FILE__[__FILE__[0] == '.' ? sizeof \\\"${_PATH_PREFIX}\\\" - 1 : sizeof XTOS_SOURCE_DIR]")
|
add_compiler_flags(-D__RELFILE__="&__FILE__[__FILE__[0] == '.' ? sizeof \\\"${_PATH_PREFIX}\\\" - 1 : sizeof XTOS_SOURCE_DIR]")
|
||||||
|
|||||||
@@ -221,15 +221,10 @@ Console::QueryMode(OUT PUINT_PTR ResX,
|
|||||||
* @since XT 1.0
|
* @since XT 1.0
|
||||||
*/
|
*/
|
||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
VOID
|
||||||
Console::ReadKeyStroke(OUT PEFI_INPUT_KEY Key)
|
Console::ReadKeyStroke(OUT PEFI_INPUT_KEY Key)
|
||||||
{
|
{
|
||||||
/* Clear the key structure to prevent ghost keystrokes */
|
XtLoader::GetEfiSystemTable()->ConIn->ReadKeyStroke(XtLoader::GetEfiSystemTable()->ConIn, Key);
|
||||||
Key->ScanCode = 0;
|
|
||||||
Key->UnicodeChar = 0;
|
|
||||||
|
|
||||||
/* Read the keystroke from the EFI input console */
|
|
||||||
return XtLoader::GetEfiSystemTable()->ConIn->ReadKeyStroke(XtLoader::GetEfiSystemTable()->ConIn, Key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -56,21 +56,6 @@ XTBL_LOADER_PROTOCOL Protocol::LoaderProtocol;
|
|||||||
/* XT Boot Loader loaded modules list */
|
/* XT Boot Loader loaded modules list */
|
||||||
LIST_ENTRY Protocol::LoadedModules;
|
LIST_ENTRY Protocol::LoadedModules;
|
||||||
|
|
||||||
/* XT Boot Loader shell exit flag */
|
|
||||||
BOOLEAN Shell::ExitRequest;
|
|
||||||
|
|
||||||
/* XT Boot Loader shell history buffer */
|
|
||||||
WCHAR Shell::History[XTBL_SH_HISTORY_ENTRIES][XTBL_SH_MAX_LINE_LENGTH];
|
|
||||||
|
|
||||||
/* XT Boot Loader shell history count */
|
|
||||||
ULONG Shell::HistoryCount = 0;
|
|
||||||
|
|
||||||
/* XT Boot Loader shell history index */
|
|
||||||
ULONG Shell::HistoryIndex = 0;
|
|
||||||
|
|
||||||
/* XT Boot Loader shell commands list */
|
|
||||||
LIST_ENTRY Shell::ShellCommands;
|
|
||||||
|
|
||||||
/* List of available block devices */
|
/* List of available block devices */
|
||||||
LIST_ENTRY Volume::EfiBlockDevices;
|
LIST_ENTRY Volume::EfiBlockDevices;
|
||||||
|
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ class Console
|
|||||||
STATIC XTCDECL XTSTATUS PutChar(IN WCHAR Character);
|
STATIC XTCDECL XTSTATUS PutChar(IN WCHAR Character);
|
||||||
STATIC XTCDECL VOID QueryMode(OUT PUINT_PTR ResX,
|
STATIC XTCDECL VOID QueryMode(OUT PUINT_PTR ResX,
|
||||||
OUT PUINT_PTR ResY);
|
OUT PUINT_PTR ResY);
|
||||||
STATIC XTCDECL EFI_STATUS ReadKeyStroke(OUT PEFI_INPUT_KEY Key);
|
STATIC XTCDECL VOID ReadKeyStroke(OUT PEFI_INPUT_KEY Key);
|
||||||
STATIC XTCDECL VOID ResetInputBuffer();
|
STATIC XTCDECL VOID ResetInputBuffer();
|
||||||
STATIC XTCDECL VOID SetAttributes(IN ULONGLONG Attributes);
|
STATIC XTCDECL VOID SetAttributes(IN ULONGLONG Attributes);
|
||||||
STATIC XTCDECL VOID SetCursorPosition(IN ULONGLONG PosX,
|
STATIC XTCDECL VOID SetCursorPosition(IN ULONGLONG PosX,
|
||||||
@@ -253,47 +253,11 @@ class Protocol
|
|||||||
|
|
||||||
class Shell
|
class Shell
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
STATIC BOOLEAN ExitRequest;
|
|
||||||
STATIC WCHAR History[XTBL_SH_HISTORY_ENTRIES][XTBL_SH_MAX_LINE_LENGTH];
|
|
||||||
STATIC ULONG HistoryCount;
|
|
||||||
STATIC ULONG HistoryIndex;
|
|
||||||
STATIC LIST_ENTRY ShellCommands;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
STATIC XTCDECL EFI_STATUS RegisterCommand(IN PCWSTR Command,
|
|
||||||
IN PCWSTR Description,
|
|
||||||
IN PBL_SHELL_COMMAND Handler);
|
|
||||||
STATIC XTCDECL VOID StartLoaderShell();
|
STATIC XTCDECL VOID StartLoaderShell();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
STATIC XTCDECL VOID CommandExit(IN ULONG Argc,
|
|
||||||
IN PWCHAR *Argv);
|
|
||||||
STATIC XTCDECL VOID CommandHelp(IN ULONG Argc,
|
|
||||||
IN PWCHAR *Argv);
|
|
||||||
STATIC XTCDECL VOID CommandInsmod(IN ULONG Argc,
|
|
||||||
IN PWCHAR *Argv);
|
|
||||||
STATIC XTCDECL VOID CommandLsmod(IN ULONG Argc,
|
|
||||||
IN PWCHAR *Argv);
|
|
||||||
STATIC XTCDECL VOID CommandPoweroff(IN ULONG Argc,
|
|
||||||
IN PWCHAR *Argv);
|
|
||||||
STATIC XTCDECL VOID CommandReboot(IN ULONG Argc,
|
|
||||||
IN PWCHAR *Argv);
|
|
||||||
STATIC XTCDECL VOID CommandVersion(IN ULONG Argc,
|
|
||||||
IN PWCHAR *Argv);
|
|
||||||
STATIC XTCDECL VOID ExecuteCommand(IN ULONG Argc,
|
|
||||||
IN PWCHAR *Argv);
|
|
||||||
STATIC XTCDECL EFI_STATUS ParseCommand(IN PWCHAR CommandLine,
|
|
||||||
OUT PULONG Argc,
|
|
||||||
OUT PWCHAR **Argv);
|
|
||||||
STATIC XTCDECL VOID PrintPrompt();
|
STATIC XTCDECL VOID PrintPrompt();
|
||||||
STATIC XTCDECL VOID PrintPromptLine(IN PWCHAR Buffer,
|
|
||||||
IN ULONG BufferLength,
|
|
||||||
IN ULONG CursorPosition,
|
|
||||||
IN ULONG PreviousBufferLength);
|
|
||||||
STATIC XTCDECL VOID ReadCommand(OUT PWCHAR Buffer,
|
|
||||||
IN ULONG BufferSize);
|
|
||||||
STATIC XTCDECL VOID RegisterBuiltinCommands();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class TextUi
|
class TextUi
|
||||||
|
|||||||
@@ -302,7 +302,6 @@ Protocol::LoadModule(IN PWCHAR ModuleName)
|
|||||||
PXTBL_MODULE_DEPS ModuleDependency;
|
PXTBL_MODULE_DEPS ModuleDependency;
|
||||||
PXTBL_MODULE_INFO ModuleInfo;
|
PXTBL_MODULE_INFO ModuleInfo;
|
||||||
WCHAR ModuleFileName[24];
|
WCHAR ModuleFileName[24];
|
||||||
ULONG ModuleNameLength;
|
|
||||||
USHORT SectionIndex;
|
USHORT SectionIndex;
|
||||||
PWCHAR SectionData;
|
PWCHAR SectionData;
|
||||||
SIZE_T ModuleSize;
|
SIZE_T ModuleSize;
|
||||||
@@ -329,11 +328,8 @@ Protocol::LoadModule(IN PWCHAR ModuleName)
|
|||||||
/* Print debug message */
|
/* Print debug message */
|
||||||
Debug::Print(L"Loading module '%S' ...\n", ModuleName);
|
Debug::Print(L"Loading module '%S' ...\n", ModuleName);
|
||||||
|
|
||||||
/* Calculate module name length */
|
|
||||||
ModuleNameLength = RTL::WideString::WideStringLength(ModuleName, 0) + 1;
|
|
||||||
|
|
||||||
/* Set module path */
|
/* Set module path */
|
||||||
RTL::Memory::CopyMemory(ModuleFileName, ModuleName, ModuleNameLength * sizeof(WCHAR));
|
RTL::Memory::CopyMemory(ModuleFileName, ModuleName, (RTL::WideString::WideStringLength(ModuleName, 0) + 1) * sizeof(WCHAR));
|
||||||
RTL::WideString::ConcatenateWideString(ModuleFileName, (PWCHAR)L".EFI", 0);
|
RTL::WideString::ConcatenateWideString(ModuleFileName, (PWCHAR)L".EFI", 0);
|
||||||
|
|
||||||
/* Open EFI volume */
|
/* Open EFI volume */
|
||||||
@@ -442,8 +438,7 @@ Protocol::LoadModule(IN PWCHAR ModuleName)
|
|||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Failed to load module, print error message and return status code */
|
/* Failed to load module, print error message and return status code */
|
||||||
Debug::Print(L"Failed to load dependency module '%S' (Status Code: 0x%zX)\n",
|
Debug::Print(L"Failed to load dependency module '%S' (Status Code: 0x%zX)\n", ModuleDependency->ModuleName, Status);
|
||||||
ModuleDependency->ModuleName, Status);
|
|
||||||
return STATUS_EFI_UNSUPPORTED;
|
return STATUS_EFI_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -506,19 +501,8 @@ Protocol::LoadModule(IN PWCHAR ModuleName)
|
|||||||
XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULLPTR);
|
XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULLPTR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate memory for module name */
|
|
||||||
Status = Memory::AllocatePool(ModuleNameLength * sizeof(WCHAR), (PVOID *)&ModuleInfo->ModuleName);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to allocate memory for module name, return error */
|
|
||||||
Debug::Print(L"ERROR: Failed to allocate memory (Status Code: 0x%zX)\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy module name */
|
|
||||||
RTL::Memory::CopyMemory(ModuleInfo->ModuleName, ModuleName, ModuleNameLength * sizeof(WCHAR));
|
|
||||||
|
|
||||||
/* Save additional module information, not found in '.modinfo' section */
|
/* Save additional module information, not found in '.modinfo' section */
|
||||||
|
ModuleInfo->ModuleName = ModuleName;
|
||||||
ModuleInfo->ModuleBase = LoadedImage->ImageBase;
|
ModuleInfo->ModuleBase = LoadedImage->ImageBase;
|
||||||
ModuleInfo->ModuleSize = LoadedImage->ImageSize;
|
ModuleInfo->ModuleSize = LoadedImage->ImageSize;
|
||||||
ModuleInfo->Revision = LoadedImage->Revision;
|
ModuleInfo->Revision = LoadedImage->Revision;
|
||||||
@@ -1093,7 +1077,6 @@ Protocol::InstallXtLoaderProtocol()
|
|||||||
LoaderProtocol.Protocol.LocateHandles = LocateProtocolHandles;
|
LoaderProtocol.Protocol.LocateHandles = LocateProtocolHandles;
|
||||||
LoaderProtocol.Protocol.Open = OpenProtocol;
|
LoaderProtocol.Protocol.Open = OpenProtocol;
|
||||||
LoaderProtocol.Protocol.OpenHandle = OpenProtocolHandle;
|
LoaderProtocol.Protocol.OpenHandle = OpenProtocolHandle;
|
||||||
LoaderProtocol.Shell.RegisterCommand = Shell::RegisterCommand;
|
|
||||||
LoaderProtocol.String.Compare = RTL::String::CompareString;
|
LoaderProtocol.String.Compare = RTL::String::CompareString;
|
||||||
LoaderProtocol.String.Length = RTL::String::StringLength;
|
LoaderProtocol.String.Length = RTL::String::StringLength;
|
||||||
LoaderProtocol.String.ToWideString = RTL::String::StringToWideString;
|
LoaderProtocol.String.ToWideString = RTL::String::StringToWideString;
|
||||||
|
|||||||
@@ -4,21 +4,13 @@
|
|||||||
* FILE: xtldr/shell.cc
|
* FILE: xtldr/shell.cc
|
||||||
* DESCRIPTION: XT Boot Loader shell
|
* DESCRIPTION: XT Boot Loader shell
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
* Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xtldr.hh>
|
#include <xtldr.hh>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements the built-in `exit` command. Sets the exit flag to signal the main
|
* Starts XTLDR shell.
|
||||||
* shell loop to terminate and return control to the boot menu.
|
|
||||||
*
|
|
||||||
* @param Argc
|
|
||||||
* Supplies the number of arguments provided by the user.
|
|
||||||
*
|
|
||||||
* @param Argv
|
|
||||||
* Supplies a list of arguments provided by the user.
|
|
||||||
*
|
*
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
@@ -26,410 +18,14 @@
|
|||||||
*/
|
*/
|
||||||
XTCDECL
|
XTCDECL
|
||||||
VOID
|
VOID
|
||||||
Shell::CommandExit(IN ULONG Argc,
|
Shell::StartLoaderShell()
|
||||||
IN PWCHAR *Argv)
|
|
||||||
{
|
{
|
||||||
/* Signal the main shell loop to stop and return to the boot menu */
|
/* Initialize console */
|
||||||
ExitRequest = TRUE;
|
Console::InitializeConsole();
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/* Print prompt */
|
||||||
* Implements the built-in `help` command. Prints a list of available commands alongside their descriptions.
|
PrintPrompt();
|
||||||
*
|
for(;;);
|
||||||
* @param Argc
|
|
||||||
* Supplies the number of arguments provided by the user.
|
|
||||||
*
|
|
||||||
* @param Argv
|
|
||||||
* Supplies a list of arguments provided by the user.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
Shell::CommandHelp(IN ULONG Argc,
|
|
||||||
IN PWCHAR *Argv)
|
|
||||||
{
|
|
||||||
PXTBL_SHELL_COMMAND CommandEntry;
|
|
||||||
PLIST_ENTRY ListEntry;
|
|
||||||
|
|
||||||
/* Print a header line */
|
|
||||||
Console::Print(L"Available commands:\n\n");
|
|
||||||
|
|
||||||
/* Walk the registered commands list */
|
|
||||||
ListEntry = ShellCommands.Flink;
|
|
||||||
while(ListEntry != &ShellCommands)
|
|
||||||
{
|
|
||||||
/* Retrieve the current command entry */
|
|
||||||
CommandEntry = CONTAIN_RECORD(ListEntry, XTBL_SHELL_COMMAND, Flink);
|
|
||||||
|
|
||||||
/* Print the command name in a highlighted color */
|
|
||||||
Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_WHITE);
|
|
||||||
Console::Print(L" %-12S", CommandEntry->Command);
|
|
||||||
|
|
||||||
/* Print the description in the default color */
|
|
||||||
Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
|
|
||||||
Console::Print(L" %S\n", CommandEntry->Description);
|
|
||||||
|
|
||||||
/* Advance to the next entry */
|
|
||||||
ListEntry = ListEntry->Flink;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements the built-in `insmod` command. Loads an XTLDR module by its name.
|
|
||||||
*
|
|
||||||
* @param Argc
|
|
||||||
* Supplies the number of arguments provided by the user.
|
|
||||||
*
|
|
||||||
* @param Argv
|
|
||||||
* Supplies a list of arguments provided by the user.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
Shell::CommandInsmod(IN ULONG Argc,
|
|
||||||
IN PWCHAR *Argv)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
/* Check if the module name was provided */
|
|
||||||
if(Argc != 2)
|
|
||||||
{
|
|
||||||
/* Print usage message and return */
|
|
||||||
Console::Print(L"Usage: insmod <module_name>\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load the module */
|
|
||||||
Status = Protocol::LoadModule(Argv[1]);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to load module, print error message */
|
|
||||||
Console::Print(L"ERROR: Failed to load module '%S' (Status: 0x%llx).\n", Argv[1], Status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements the built-in `lsmod` command. Lists all loaded XTLDR modules.
|
|
||||||
*
|
|
||||||
* @param Argc
|
|
||||||
* Supplies the number of arguments provided by the user.
|
|
||||||
*
|
|
||||||
* @param Argv
|
|
||||||
* Supplies a list of arguments provided by the user.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
Shell::CommandLsmod(IN ULONG Argc,
|
|
||||||
IN PWCHAR *Argv)
|
|
||||||
{
|
|
||||||
PXTBL_MODULE_INFO ModuleInfo;
|
|
||||||
PLIST_ENTRY ModulesList;
|
|
||||||
PLIST_ENTRY ListEntry;
|
|
||||||
|
|
||||||
/* Print header */
|
|
||||||
Console::Print(L"Module Name Version Base Address Size\n");
|
|
||||||
Console::Print(L"----------------------------------------------------------------------\n");
|
|
||||||
|
|
||||||
/* Get modules list */
|
|
||||||
ModulesList = Protocol::GetModulesList();
|
|
||||||
if(ModulesList == NULLPTR)
|
|
||||||
{
|
|
||||||
/* No modules loaded */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Iterate over all loaded modules */
|
|
||||||
ListEntry = ModulesList->Flink;
|
|
||||||
while(ListEntry != ModulesList)
|
|
||||||
{
|
|
||||||
/* Retrieve the module information */
|
|
||||||
ModuleInfo = CONTAIN_RECORD(ListEntry, XTBL_MODULE_INFO, Flink);
|
|
||||||
|
|
||||||
/* Print module information */
|
|
||||||
Console::Print(L"%-16S %-16S 0x%016llx %llu\n",
|
|
||||||
ModuleInfo->ModuleName, ModuleInfo->Version,
|
|
||||||
(ULONGLONG)ModuleInfo->ModuleBase, ModuleInfo->ModuleSize);
|
|
||||||
|
|
||||||
/* Advance to the next entry */
|
|
||||||
ListEntry = ListEntry->Flink;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements the built-in `poweroff` command. Shuts down the machine.
|
|
||||||
*
|
|
||||||
* @param Argc
|
|
||||||
* Supplies the number of arguments provided by the user.
|
|
||||||
*
|
|
||||||
* @param Argv
|
|
||||||
* Supplies a list of arguments provided by the user.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
Shell::CommandPoweroff(IN ULONG Argc,
|
|
||||||
IN PWCHAR *Argv)
|
|
||||||
{
|
|
||||||
/* Attempt to power off the machine */
|
|
||||||
Console::Print(L"Powering off...\n");
|
|
||||||
EfiUtils::ShutdownSystem();
|
|
||||||
|
|
||||||
/* The poweroff call failed, print error message */
|
|
||||||
Console::Print(L"ERROR: Failed to power off the machine\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements the built-in `reboot` command. Performs a normal system restart via the EFI runtime services.
|
|
||||||
* When the '/EFI' parameter is supplied, the routine instead schedules a reboot into the UEFI firmware setup interface.
|
|
||||||
*
|
|
||||||
* @param Argc
|
|
||||||
* Supplies the number of arguments provided by the user.
|
|
||||||
*
|
|
||||||
* @param Argv
|
|
||||||
* Supplies a list of arguments provided by the user.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
Shell::CommandReboot(IN ULONG Argc,
|
|
||||||
IN PWCHAR *Argv)
|
|
||||||
{
|
|
||||||
/* Check if the /EFI flag was specified */
|
|
||||||
if(Argc > 1 && RTL::WideString::CompareWideStringInsensitive(Argv[1], L"/EFI", 0) == 0)
|
|
||||||
{
|
|
||||||
/* Attempt to reboot into firmware setup */
|
|
||||||
Console::Print(L"Rebooting into UEFI firmware setup...\n");
|
|
||||||
EfiUtils::EnterFirmwareSetup();
|
|
||||||
|
|
||||||
/* The firmware does not support this feature, print error message */
|
|
||||||
Console::Print(L"ERROR: Reboot into firmware setup interface not supported.\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Perform a standard system reboot */
|
|
||||||
Console::Print(L"Rebooting...\n");
|
|
||||||
EfiUtils::RebootSystem();
|
|
||||||
|
|
||||||
/* The reboot call failed, print error message */
|
|
||||||
Console::Print(L"ERROR: Failed to reboot the machine\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements the built-in `ver` command. Prints the bootloader identification string.
|
|
||||||
*
|
|
||||||
* @param Argc
|
|
||||||
* Supplies the number of arguments provided by the user.
|
|
||||||
*
|
|
||||||
* @param Argv
|
|
||||||
* Supplies a list of arguments provided by the user.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
Shell::CommandVersion(IN ULONG Argc,
|
|
||||||
IN PWCHAR *Argv)
|
|
||||||
{
|
|
||||||
/* Check if debugging enabled */
|
|
||||||
if(DEBUG)
|
|
||||||
{
|
|
||||||
/* Print debug version of XTLDR version string */
|
|
||||||
Console::Print(L"XTLDR Boot Loader v%d.%d (%s-%s)\n",
|
|
||||||
XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR, XTOS_VERSION_DATE, XTOS_VERSION_HASH);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Print standard XTLDR version string */
|
|
||||||
Console::Print(L"XTLDR Boot Loader v%d.%d\n", XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Looks up the given command name in the registered shell commands list and invokes the corresponding handler.
|
|
||||||
*
|
|
||||||
* @param Argc
|
|
||||||
* Supplies the number of arguments in the argument vector, including the command name itself.
|
|
||||||
*
|
|
||||||
* @param Argv
|
|
||||||
* Supplies a pointer to the argument vector. First argument is the command name.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
Shell::ExecuteCommand(IN ULONG Argc,
|
|
||||||
IN PWCHAR *Argv)
|
|
||||||
{
|
|
||||||
PXTBL_SHELL_COMMAND CommandEntry;
|
|
||||||
PLIST_ENTRY ListEntry;
|
|
||||||
|
|
||||||
/* Walk through the list of registered shell commands */
|
|
||||||
ListEntry = ShellCommands.Flink;
|
|
||||||
while(ListEntry != &ShellCommands)
|
|
||||||
{
|
|
||||||
/* Retrieve the shell command entry from the list node */
|
|
||||||
CommandEntry = CONTAIN_RECORD(ListEntry, XTBL_SHELL_COMMAND, Flink);
|
|
||||||
|
|
||||||
/* Perform a case-insensitive comparison against the command name */
|
|
||||||
if(RTL::WideString::CompareWideStringInsensitive(CommandEntry->Command, Argv[0], 0) == 0)
|
|
||||||
{
|
|
||||||
/* Command matches, invoke its handler and return */
|
|
||||||
CommandEntry->Handler(Argc, Argv);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Advance to the next registered command */
|
|
||||||
ListEntry = ListEntry->Flink;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No matching command was found, print error message */
|
|
||||||
Console::Print(L"ERROR: '%S' is not recognized as a valid command.\n", Argv[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Splits the supplied raw command line string into an argument count and an argument vector suitable
|
|
||||||
* for command dispatch. The input string is tokenized by whitespace.
|
|
||||||
*
|
|
||||||
* @param CommandLine
|
|
||||||
* Supplies a mutable wide-character string containing the raw command line.
|
|
||||||
*
|
|
||||||
* @param Argc
|
|
||||||
* Receives the number of arguments found in the command line.
|
|
||||||
*
|
|
||||||
* @param Argv
|
|
||||||
* Receives a pointer to an allocated array of wide-character string pointers, one for each argument.
|
|
||||||
*
|
|
||||||
* @return This routine returns a status code.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
EFI_STATUS
|
|
||||||
Shell::ParseCommand(IN PWCHAR CommandLine,
|
|
||||||
OUT PULONG Argc,
|
|
||||||
OUT PWCHAR **Argv)
|
|
||||||
{
|
|
||||||
PWCHAR *ArgumentVector, TempLine;
|
|
||||||
ULONG ArgumentCount;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
/* Initialize argument count */
|
|
||||||
ArgumentCount = 0;
|
|
||||||
|
|
||||||
/* Count the tokens to determine the size of the argument vector */
|
|
||||||
TempLine = CommandLine;
|
|
||||||
while(*TempLine != L'\0')
|
|
||||||
{
|
|
||||||
/* Skip leading spaces */
|
|
||||||
while(*TempLine == L' ')
|
|
||||||
{
|
|
||||||
/* Move to the next character */
|
|
||||||
TempLine++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if the end of the string was reached */
|
|
||||||
if(*TempLine == L'\0')
|
|
||||||
{
|
|
||||||
/* End of the string, break the loop */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* One more argument found */
|
|
||||||
ArgumentCount++;
|
|
||||||
|
|
||||||
/* Skip the characters of the token */
|
|
||||||
while(*TempLine != L'\0' && *TempLine != L' ')
|
|
||||||
{
|
|
||||||
/* Move to the next character */
|
|
||||||
TempLine++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if the command line was empty */
|
|
||||||
if(ArgumentCount == 0)
|
|
||||||
{
|
|
||||||
/* Set argument count and vector to zero and NULL */
|
|
||||||
*Argc = 0;
|
|
||||||
*Argv = NULLPTR;
|
|
||||||
|
|
||||||
/* Return success */
|
|
||||||
return STATUS_EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate memory for the argument vector */
|
|
||||||
Status = Memory::AllocatePool(ArgumentCount * sizeof(PWCHAR), (PVOID *)&ArgumentVector);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Memory allocation failure, return status code */
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset argument count and temp line */
|
|
||||||
ArgumentCount = 0;
|
|
||||||
TempLine = CommandLine;
|
|
||||||
|
|
||||||
/* Walk through the command line */
|
|
||||||
while(*TempLine != L'\0')
|
|
||||||
{
|
|
||||||
/* Skip leading whitespace */
|
|
||||||
while(*TempLine == L' ')
|
|
||||||
{
|
|
||||||
/* Move to the next character */
|
|
||||||
TempLine++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if the end of the string was reached */
|
|
||||||
if(*TempLine == L'\0')
|
|
||||||
{
|
|
||||||
/* End of string reached, break the loop */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Record token */
|
|
||||||
ArgumentVector[ArgumentCount] = TempLine;
|
|
||||||
ArgumentCount++;
|
|
||||||
|
|
||||||
/* Advance past the token characters */
|
|
||||||
while(*TempLine != L'\0' && *TempLine != L' ')
|
|
||||||
{
|
|
||||||
/* Move to the next character */
|
|
||||||
TempLine++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if token was NULL-terminated */
|
|
||||||
if(*TempLine != L'\0')
|
|
||||||
{
|
|
||||||
/* NULL-terminate the token and move to the next character */
|
|
||||||
*TempLine = L'\0';
|
|
||||||
TempLine++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return results to the caller */
|
|
||||||
*Argc = ArgumentCount;
|
|
||||||
*Argv = ArgumentVector;
|
|
||||||
return STATUS_EFI_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -446,486 +42,9 @@ Shell::PrintPrompt()
|
|||||||
/* Set prompt color */
|
/* Set prompt color */
|
||||||
Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_YELLOW);
|
Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_YELLOW);
|
||||||
|
|
||||||
/* Print prompt at the start of the line */
|
/* Print prompt */
|
||||||
Console::Print(L"\rXTLDR> ");
|
Console::Print(L"XTLDR> ");
|
||||||
|
|
||||||
/* Reset standard shell colors */
|
/* Reset standard shell colors */
|
||||||
Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
|
Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Prints the whole prompt line, including the current command line and the cursor position.
|
|
||||||
*
|
|
||||||
* @param Buffer
|
|
||||||
* Supplies a pointer to the buffer containing the command line.
|
|
||||||
*
|
|
||||||
* @param BufferLength
|
|
||||||
* Supplies the buffer text length.
|
|
||||||
*
|
|
||||||
* @param CursorPosition
|
|
||||||
* Supplies the current cursor position.
|
|
||||||
*
|
|
||||||
* @param PreviousBufferLength
|
|
||||||
* Supplies the previous buffer text length to clear artifacts.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
Shell::PrintPromptLine(IN PWCHAR Buffer,
|
|
||||||
IN ULONG BufferLength,
|
|
||||||
IN ULONG CursorPosition,
|
|
||||||
IN ULONG PreviousBufferLength)
|
|
||||||
{
|
|
||||||
INT32 TargetX, TargetY;
|
|
||||||
WCHAR SavedChar;
|
|
||||||
ULONG Index;
|
|
||||||
|
|
||||||
/* Print the prompt */
|
|
||||||
PrintPrompt();
|
|
||||||
|
|
||||||
/* Temporarily truncate the string to capture cursor position */
|
|
||||||
SavedChar = Buffer[CursorPosition];
|
|
||||||
Buffer[CursorPosition] = L'\0';
|
|
||||||
|
|
||||||
/* Print up to the cursor position */
|
|
||||||
Console::Print(L"%S", Buffer);
|
|
||||||
|
|
||||||
/* Capture target cursor coordinates from the EFI text mode structure */
|
|
||||||
TargetX = XtLoader::GetEfiSystemTable()->ConOut->Mode->CursorColumn;
|
|
||||||
TargetY = XtLoader::GetEfiSystemTable()->ConOut->Mode->CursorRow;
|
|
||||||
|
|
||||||
/* Restore the character and print the remainder of the buffer */
|
|
||||||
Buffer[CursorPosition] = SavedChar;
|
|
||||||
Console::Print(L"%S", Buffer + CursorPosition);
|
|
||||||
|
|
||||||
/* Check if the previous buffer was longer than the current one */
|
|
||||||
if(PreviousBufferLength > BufferLength)
|
|
||||||
{
|
|
||||||
/* Clear artifacts from the previous longer line */
|
|
||||||
for(Index = 0; Index < (PreviousBufferLength - BufferLength); Index++)
|
|
||||||
{
|
|
||||||
/* Print a white space */
|
|
||||||
Console::Print(L" ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Move the cursor back to the correct target position */
|
|
||||||
Console::SetCursorPosition(TargetX, TargetY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads a complete line of input from the shell console into the supplied buffer.
|
|
||||||
*
|
|
||||||
* @param Buffer
|
|
||||||
* Supplies a pointer to a wide-character buffer that receives the entered command line.
|
|
||||||
*
|
|
||||||
* @param BufferSize
|
|
||||||
* Supplies the capacity of the buffer, in wide characters.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
Shell::ReadCommand(OUT PWCHAR Buffer,
|
|
||||||
IN ULONG BufferSize)
|
|
||||||
{
|
|
||||||
ULONG BufferLength, CursorPosition, OldBufferLength;
|
|
||||||
UINT_PTR EventIndex;
|
|
||||||
EFI_INPUT_KEY Key;
|
|
||||||
|
|
||||||
/* Start with an empty buffer */
|
|
||||||
CursorPosition = 0;
|
|
||||||
BufferLength = 0;
|
|
||||||
Buffer[0] = L'\0';
|
|
||||||
|
|
||||||
/* Reset history index */
|
|
||||||
HistoryIndex = HistoryCount;
|
|
||||||
|
|
||||||
/* Read characters until the user submits the command line */
|
|
||||||
while(TRUE)
|
|
||||||
{
|
|
||||||
/* Wait until a key event is available */
|
|
||||||
EfiUtils::WaitForEfiEvent(1, &(XtLoader::GetEfiSystemTable()->ConIn->WaitForKey), &EventIndex);
|
|
||||||
|
|
||||||
/* Read the keystroke from the input device */
|
|
||||||
Console::ReadKeyStroke(&Key);
|
|
||||||
|
|
||||||
/* Capture the previous line length to wipe possible artifacts */
|
|
||||||
OldBufferLength = BufferLength;
|
|
||||||
|
|
||||||
/* Check the keystroke */
|
|
||||||
if(Key.UnicodeChar == 0x0D)
|
|
||||||
{
|
|
||||||
/* ENTER key pressed, terminate the buffer and move to a new line */
|
|
||||||
Buffer[BufferLength] = L'\0';
|
|
||||||
Console::Print(L"\n");
|
|
||||||
|
|
||||||
/* Check if the buffer is not empty */
|
|
||||||
if(BufferLength > 0)
|
|
||||||
{
|
|
||||||
/* Check if the history is not full */
|
|
||||||
if(HistoryCount < XTBL_SH_HISTORY_ENTRIES)
|
|
||||||
{
|
|
||||||
/* Store command in history and increment history count */
|
|
||||||
RTL::Memory::CopyMemory(History[HistoryCount], Buffer, (BufferLength + 1) * sizeof(WCHAR));
|
|
||||||
HistoryCount++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Shift history entries to fit new command */
|
|
||||||
RTL::Memory::MoveMemory(History[0],
|
|
||||||
History[1],
|
|
||||||
(XTBL_SH_HISTORY_ENTRIES - 1) * XTBL_SH_MAX_LINE_LENGTH * sizeof(WCHAR));
|
|
||||||
RTL::Memory::CopyMemory(History[XTBL_SH_HISTORY_ENTRIES - 1],
|
|
||||||
Buffer,
|
|
||||||
(BufferLength + 1) * sizeof(WCHAR));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the command line to the caller */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if(Key.ScanCode == 0x01)
|
|
||||||
{
|
|
||||||
/* UP key pressed, go back in history */
|
|
||||||
if(HistoryIndex > 0)
|
|
||||||
{
|
|
||||||
/* Decrement history index */
|
|
||||||
HistoryIndex--;
|
|
||||||
|
|
||||||
/* Copy history entry to buffer and update cursor position */
|
|
||||||
BufferLength = RTL::WideString::WideStringLength(History[HistoryIndex], XTBL_SH_MAX_LINE_LENGTH - 1);
|
|
||||||
RTL::Memory::CopyMemory(Buffer, History[HistoryIndex], (BufferLength + 1) * sizeof(WCHAR));
|
|
||||||
CursorPosition = BufferLength;
|
|
||||||
|
|
||||||
/* Reprint the prompt line */
|
|
||||||
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Continue to the next iteration */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if(Key.ScanCode == 0x02)
|
|
||||||
{
|
|
||||||
/* DOWN key pressed, go forward in history */
|
|
||||||
if(HistoryIndex < HistoryCount)
|
|
||||||
{
|
|
||||||
/* Increment history index */
|
|
||||||
HistoryIndex++;
|
|
||||||
|
|
||||||
/* Check if we are at the end of history */
|
|
||||||
if(HistoryIndex == HistoryCount)
|
|
||||||
{
|
|
||||||
/* End of history, show empty prompt */
|
|
||||||
Buffer[0] = L'\0';
|
|
||||||
BufferLength = 0;
|
|
||||||
CursorPosition = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Copy history entry to buffer and update cursor position */
|
|
||||||
BufferLength = RTL::WideString::WideStringLength(History[HistoryIndex],
|
|
||||||
XTBL_SH_MAX_LINE_LENGTH - 1);
|
|
||||||
RTL::Memory::CopyMemory(Buffer, History[HistoryIndex], (BufferLength + 1) * sizeof(WCHAR));
|
|
||||||
CursorPosition = BufferLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reprint the prompt line */
|
|
||||||
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Continue to the next iteration */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if(Key.ScanCode == 0x03)
|
|
||||||
{
|
|
||||||
/* RIGHT key pressed, move cursor right */
|
|
||||||
if(CursorPosition < BufferLength)
|
|
||||||
{
|
|
||||||
/* Increment cursor position */
|
|
||||||
CursorPosition++;
|
|
||||||
|
|
||||||
/* Reprint the prompt line */
|
|
||||||
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Continue to the next iteration */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if(Key.ScanCode == 0x04)
|
|
||||||
{
|
|
||||||
/* LEFT key pressed, move cursor left */
|
|
||||||
if(CursorPosition > 0)
|
|
||||||
{
|
|
||||||
/* Decrement cursor position */
|
|
||||||
CursorPosition--;
|
|
||||||
|
|
||||||
/* Reprint the prompt line */
|
|
||||||
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Continue to the next iteration */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if(Key.ScanCode == 0x05)
|
|
||||||
{
|
|
||||||
/* HOME key pressed, move cursor to beginning */
|
|
||||||
if (CursorPosition > 0)
|
|
||||||
{
|
|
||||||
/* Set cursor position to beginning of the line and reprint the prompt line */
|
|
||||||
CursorPosition = 0;
|
|
||||||
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Continue to the next iteration */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if(Key.ScanCode == 0x06)
|
|
||||||
{
|
|
||||||
/* END key pressed, move cursor to end */
|
|
||||||
if (CursorPosition < BufferLength)
|
|
||||||
{
|
|
||||||
/* Set cursor position to end of the line and reprint the prompt line */
|
|
||||||
CursorPosition = BufferLength;
|
|
||||||
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Continue to the next iteration */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if(Key.ScanCode == 0x17)
|
|
||||||
{
|
|
||||||
/* ESC key pressed, discard the current input, move to a new line and reprint the prompt */
|
|
||||||
Buffer[0] = L'\0';
|
|
||||||
Console::Print(L"\n");
|
|
||||||
PrintPrompt();
|
|
||||||
|
|
||||||
/* Reset cursor position, buffer length and history index */
|
|
||||||
CursorPosition = 0;
|
|
||||||
BufferLength = 0;
|
|
||||||
HistoryIndex = HistoryCount;
|
|
||||||
|
|
||||||
/* Continue reading the command line */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if(Key.ScanCode == 0x08)
|
|
||||||
{
|
|
||||||
/* DELETE key pressed, remove character at cursor */
|
|
||||||
if(CursorPosition < BufferLength)
|
|
||||||
{
|
|
||||||
/* Move memory to remove the character at cursor */
|
|
||||||
RTL::Memory::MoveMemory(Buffer + CursorPosition,
|
|
||||||
Buffer + CursorPosition + 1,
|
|
||||||
(BufferLength - CursorPosition) * sizeof(WCHAR));
|
|
||||||
|
|
||||||
/* Decrement buffer length and reprint the prompt line */
|
|
||||||
BufferLength--;
|
|
||||||
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Continue to the next iteration */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if(Key.UnicodeChar == 0x08)
|
|
||||||
{
|
|
||||||
/* BACKSPACE key pressed, delete character before cursor */
|
|
||||||
if(CursorPosition > 0)
|
|
||||||
{
|
|
||||||
/* Move memory to remove the character before cursor */
|
|
||||||
RTL::Memory::MoveMemory(Buffer + CursorPosition - 1,
|
|
||||||
Buffer + CursorPosition,
|
|
||||||
(BufferLength - CursorPosition + 1) * sizeof(WCHAR));
|
|
||||||
|
|
||||||
/* Decrement cursor position and buffer length */
|
|
||||||
CursorPosition--;
|
|
||||||
BufferLength--;
|
|
||||||
|
|
||||||
/* Reprint the prompt line */
|
|
||||||
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Continue reading the command line */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if(Key.UnicodeChar == 0)
|
|
||||||
{
|
|
||||||
/* Ignore non-printable characters */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make sure there is room in the buffer (reserve one slot for NULL terminator) */
|
|
||||||
if(BufferLength < BufferSize - 1)
|
|
||||||
{
|
|
||||||
/* Insert character in the middle or end of the buffer */
|
|
||||||
RTL::Memory::MoveMemory(Buffer + CursorPosition + 1,
|
|
||||||
Buffer + CursorPosition,
|
|
||||||
(BufferLength - CursorPosition + 1) * sizeof(WCHAR));
|
|
||||||
Buffer[CursorPosition] = Key.UnicodeChar;
|
|
||||||
|
|
||||||
/* Increment cursor position and buffer length */
|
|
||||||
CursorPosition++;
|
|
||||||
BufferLength++;
|
|
||||||
|
|
||||||
/* Reprint the prompt line */
|
|
||||||
PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers a new command in the XTLDR shell.
|
|
||||||
*
|
|
||||||
* @param Command
|
|
||||||
* Supplies the command keyword that the user types at the shell prompt.
|
|
||||||
*
|
|
||||||
* @param Description
|
|
||||||
* Supplies a short help string displayed by the 'help' command.
|
|
||||||
*
|
|
||||||
* @param Handler
|
|
||||||
* Supplies a pointer to the function that implements the command.
|
|
||||||
*
|
|
||||||
* @return This routine returns a status code.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
EFI_STATUS
|
|
||||||
Shell::RegisterCommand(IN PCWSTR Command,
|
|
||||||
IN PCWSTR Description,
|
|
||||||
IN PBL_SHELL_COMMAND Handler)
|
|
||||||
{
|
|
||||||
PXTBL_SHELL_COMMAND CommandEntry;
|
|
||||||
PLIST_ENTRY ListEntry;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
/* Verify that a command with this name has not already been registered */
|
|
||||||
ListEntry = ShellCommands.Flink;
|
|
||||||
while(ListEntry != &ShellCommands)
|
|
||||||
{
|
|
||||||
/* Retrieve the existing shell command entry */
|
|
||||||
CommandEntry = CONTAIN_RECORD(ListEntry, XTBL_SHELL_COMMAND, Flink);
|
|
||||||
|
|
||||||
/* Compare command names case-insensitively */
|
|
||||||
if(RTL::WideString::CompareWideStringInsensitive(CommandEntry->Command, Command, 0) == 0)
|
|
||||||
{
|
|
||||||
/* Duplicate command name, return error */
|
|
||||||
return STATUS_EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Advance to the next entry */
|
|
||||||
ListEntry = ListEntry->Flink;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate memory for the new command entry */
|
|
||||||
Status = Memory::AllocatePool(sizeof(XTBL_SHELL_COMMAND), (PVOID *)&CommandEntry);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Memory allocation failure, return error */
|
|
||||||
return STATUS_EFI_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Populate the new command entry */
|
|
||||||
CommandEntry->Command = (PWCHAR)Command;
|
|
||||||
CommandEntry->Description = (PWCHAR)Description;
|
|
||||||
CommandEntry->Handler = Handler;
|
|
||||||
|
|
||||||
/* Append the command to the global shell commands list */
|
|
||||||
RTL::LinkedList::InsertTailList(&ShellCommands, &CommandEntry->Flink);
|
|
||||||
|
|
||||||
/* Return success */
|
|
||||||
return STATUS_EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers all built-in shell commands that are provided by the XTLDR.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
Shell::RegisterBuiltinCommands()
|
|
||||||
{
|
|
||||||
/* Register all built-in shell commands */
|
|
||||||
RegisterCommand(L"exit", L"Exits the shell and returns to the boot menu", CommandExit);
|
|
||||||
RegisterCommand(L"help", L"Displays a list of all available shell commands", CommandHelp);
|
|
||||||
RegisterCommand(L"insmod", L"Loads a specific XTLDR module", CommandInsmod);
|
|
||||||
RegisterCommand(L"lsmod", L"Displays a list of loaded modules", CommandLsmod);
|
|
||||||
RegisterCommand(L"poweroff", L"Shuts down the machine", CommandPoweroff);
|
|
||||||
RegisterCommand(L"reboot", L"Reboots the machine (/EFI to enter firmware setup)", CommandReboot);
|
|
||||||
RegisterCommand(L"ver", L"Displays the boot loader version information", CommandVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the command list, registers the built-in commands and enters an interactive XTLDR shell loop.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
Shell::StartLoaderShell()
|
|
||||||
{
|
|
||||||
WCHAR CommandLine[XTBL_SH_MAX_LINE_LENGTH];
|
|
||||||
PWCHAR *ArgumentVector;
|
|
||||||
ULONG ArgumentCount;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
/* Initialize console */
|
|
||||||
Console::InitializeConsole();
|
|
||||||
|
|
||||||
/* Initialize the shell commands list */
|
|
||||||
RTL::LinkedList::InitializeListHead(&ShellCommands);
|
|
||||||
|
|
||||||
/* Register all built-in commands */
|
|
||||||
RegisterBuiltinCommands();
|
|
||||||
|
|
||||||
/* Clear the shell exit request flag */
|
|
||||||
ExitRequest = FALSE;
|
|
||||||
|
|
||||||
/* Main XTLDR shell loop */
|
|
||||||
while(!ExitRequest)
|
|
||||||
{
|
|
||||||
/* Display the shell prompt */
|
|
||||||
PrintPrompt();
|
|
||||||
|
|
||||||
/* Read a command line */
|
|
||||||
ReadCommand(CommandLine, XTBL_SH_MAX_LINE_LENGTH);
|
|
||||||
|
|
||||||
/* Parse the command line into a list of arguments */
|
|
||||||
Status = ParseCommand(CommandLine, &ArgumentCount, &ArgumentVector);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Parsing failed, print error and continue */
|
|
||||||
Console::Print(L"ERROR: Failed to parse command line (Status: 0x%llx).\n\n", Status);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if command line is empty */
|
|
||||||
if(ArgumentCount == 0)
|
|
||||||
{
|
|
||||||
/* Skip empty command line */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if command line starts with a comment symbol (#) */
|
|
||||||
if(ArgumentVector[0][0] != L'#')
|
|
||||||
{
|
|
||||||
/* Dispatch the command */
|
|
||||||
ExecuteCommand(ArgumentCount, ArgumentVector);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free the argument vector */
|
|
||||||
Memory::FreePool(ArgumentVector);
|
|
||||||
|
|
||||||
/* Print a trailing blank line for visual separation */
|
|
||||||
Console::Print(L"\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -717,9 +717,9 @@ TextUi::DisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry)
|
|||||||
RedrawEntries = TRUE;
|
RedrawEntries = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(Key.ScanCode == 0x14)
|
else if(Key.UnicodeChar == 0x02)
|
||||||
{
|
{
|
||||||
/* F10 key pressed, boot the OS */
|
/* CTRL-B key pressed, boot the OS */
|
||||||
Console::SetAttributes(Handle.DialogColor | Handle.TextColor);
|
Console::SetAttributes(Handle.DialogColor | Handle.TextColor);
|
||||||
Console::ClearLine(Handle.PosY + Handle.Height + 4);
|
Console::ClearLine(Handle.PosY + Handle.Height + 4);
|
||||||
Console::SetCursorPosition(4, Handle.PosY + Handle.Height + 4);
|
Console::SetCursorPosition(4, Handle.PosY + Handle.Height + 4);
|
||||||
@@ -1673,7 +1673,7 @@ TextUi::DrawEditMenu(OUT PXTBL_DIALOG_HANDLE Handle)
|
|||||||
Console::SetCursorPosition(0, Handle->PosY + Handle->Height);
|
Console::SetCursorPosition(0, Handle->PosY + Handle->Height);
|
||||||
Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
|
Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
|
||||||
Console::Print(L" Use cursors to change the selection. Press ENTER key to edit the chosen\n"
|
Console::Print(L" Use cursors to change the selection. Press ENTER key to edit the chosen\n"
|
||||||
L" option, ESC to return to the main boot menu or F10 to boot.\n");
|
L" option, ESC to return to the main boot menu or CTRL-B to boot.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,3 +1 @@
|
|||||||
add_subdirectory("xtadk")
|
|
||||||
|
|
||||||
set_sdk_target("xtdk/" "include")
|
set_sdk_target("xtdk/" "include")
|
||||||
|
|||||||
@@ -59,86 +59,6 @@ function(add_module_linker_flags MODULE FLAGS)
|
|||||||
set_module_property(${MODULE} LINK_FLAGS ${FLAGS})
|
set_module_property(${MODULE} LINK_FLAGS ${FLAGS})
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# This function compiles XT Assembly Development Kit
|
|
||||||
function(generate_xtadk TARGET_NAME SOURCE_FILES)
|
|
||||||
# Define the absolute destination path for the generated header file
|
|
||||||
set(HEADER_OUTPUT "${EXECTOS_BINARY_DIR}/sdk/includes/${TARGET_NAME}.h")
|
|
||||||
get_filename_component(HEADER_OUTPUT_DIRECTORY "${HEADER_OUTPUT}" DIRECTORY)
|
|
||||||
|
|
||||||
# Tokenize global CXX flags into a list to ensure correct argument expansion
|
|
||||||
separate_arguments(COMPILER_FLAGS NATIVE_COMMAND "${CMAKE_CXX_FLAGS}")
|
|
||||||
|
|
||||||
# Resolve and tokenize build-configuration specific flags
|
|
||||||
string(TOUPPER "${CMAKE_BUILD_TYPE}" BUILD_TYPE)
|
|
||||||
if(BUILD_TYPE)
|
|
||||||
separate_arguments(BUILD_TYPE_SPECIFIC_FLAGS NATIVE_COMMAND "${CMAKE_CXX_FLAGS_${BUILD_TYPE}}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Retrieve compiler definitions, include paths, and options
|
|
||||||
get_directory_property(COMPILE_DEFINITIONS COMPILE_DEFINITIONS)
|
|
||||||
get_directory_property(INCLUDE_DIRECTORIES INCLUDE_DIRECTORIES)
|
|
||||||
get_directory_property(COMPILE_OPTIONS COMPILE_OPTIONS)
|
|
||||||
|
|
||||||
# Initialize the final compiler argument list
|
|
||||||
set(COMPILER_ARGUMENTS "")
|
|
||||||
list(APPEND COMPILER_ARGUMENTS ${COMPILER_FLAGS} ${BUILD_TYPE_SPECIFIC_FLAGS})
|
|
||||||
|
|
||||||
# Transform definitions into MSVC-style
|
|
||||||
foreach(DEFINITION ${COMPILE_DEFINITIONS})
|
|
||||||
list(APPEND COMPILER_ARGUMENTS "/D${DEFINITION}")
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
# Transform include paths into MSVC-style
|
|
||||||
foreach(INCLUDE_PATH ${INCLUDE_DIRECTORIES})
|
|
||||||
list(APPEND COMPILER_ARGUMENTS "/I${INCLUDE_PATH}")
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
# Append all supplemental compiler options
|
|
||||||
list(APPEND COMPILER_ARGUMENTS ${COMPILE_OPTIONS})
|
|
||||||
set(COLLECTED_ASSEMBLY_OUTPUTS "")
|
|
||||||
|
|
||||||
# Iterate through each source file to create individual assembly generation rules
|
|
||||||
foreach(SOURCE_FILE_PATH ${SOURCE_FILES})
|
|
||||||
# Extract the base filename
|
|
||||||
get_filename_component(FILENAME_WITHOUT_EXTENSION "${SOURCE_FILE_PATH}" NAME_WE)
|
|
||||||
|
|
||||||
# Define the unique output path for the intermediate assembly file
|
|
||||||
set(CURRENT_ASSEMBLY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FILENAME_WITHOUT_EXTENSION}.S")
|
|
||||||
list(APPEND COLLECTED_ASSEMBLY_OUTPUTS "${CURRENT_ASSEMBLY_OUTPUT}")
|
|
||||||
get_filename_component(CURRENT_ASSEMBLY_DIRECTORY "${CURRENT_ASSEMBLY_OUTPUT}" DIRECTORY)
|
|
||||||
|
|
||||||
# Execute the compiler to generate assembly code
|
|
||||||
add_custom_command(
|
|
||||||
OUTPUT "${CURRENT_ASSEMBLY_OUTPUT}"
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${CURRENT_ASSEMBLY_DIRECTORY}"
|
|
||||||
COMMAND ${CMAKE_CXX_COMPILER}
|
|
||||||
${COMPILER_ARGUMENTS}
|
|
||||||
/c /FAs /Fa${CURRENT_ASSEMBLY_OUTPUT}
|
|
||||||
-- ${SOURCE_FILE_PATH}
|
|
||||||
DEPENDS "${SOURCE_FILE_PATH}"
|
|
||||||
COMMENT "Generating XTADK Assembly: ${FILENAME_WITHOUT_EXTENSION}"
|
|
||||||
VERBATIM
|
|
||||||
COMMAND_EXPAND_LISTS
|
|
||||||
)
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
# Aggregate all generated assembly units into a single consolidated XTADK header
|
|
||||||
add_custom_command(
|
|
||||||
OUTPUT "${HEADER_OUTPUT}"
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${HEADER_OUTPUT_DIRECTORY}"
|
|
||||||
COMMAND xtadkgen ${COLLECTED_ASSEMBLY_OUTPUTS} -O "${HEADER_OUTPUT}"
|
|
||||||
DEPENDS ${COLLECTED_ASSEMBLY_OUTPUTS}
|
|
||||||
COMMENT "Generating XTADK header: ${TARGET_NAME}"
|
|
||||||
VERBATIM
|
|
||||||
)
|
|
||||||
|
|
||||||
# Establish the generation target and expose the header directory via an interface library
|
|
||||||
add_custom_target(${TARGET_NAME}_gen DEPENDS "${HEADER_OUTPUT}")
|
|
||||||
add_library(${TARGET_NAME} INTERFACE)
|
|
||||||
add_dependencies(${TARGET_NAME} ${TARGET_NAME}_gen)
|
|
||||||
target_include_directories(${TARGET_NAME} INTERFACE "${EXECTOS_BINARY_DIR}/sdk/includes")
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# This function compiles an assembly bootsector file into a flat binary
|
# This function compiles an assembly bootsector file into a flat binary
|
||||||
function(compile_bootsector NAME SOURCE BASEADDR ENTRYPOINT)
|
function(compile_bootsector NAME SOURCE BASEADDR ENTRYPOINT)
|
||||||
set(BINARY_NAME "${NAME}.bin")
|
set(BINARY_NAME "${NAME}.bin")
|
||||||
|
|||||||
@@ -13,10 +13,6 @@ The ovmf_vars files, store UEFI variables, which are used to store and retrieve
|
|||||||
boot options, device settings, and system preferences. The ovmf_vars file contains the persistent variables specific to
|
boot options, device settings, and system preferences. The ovmf_vars file contains the persistent variables specific to
|
||||||
a virtual machine, allowing it to maintain its configuration across multiple boot sessions.
|
a virtual machine, allowing it to maintain its configuration across multiple boot sessions.
|
||||||
|
|
||||||
## BOCHS ROM BIOS
|
|
||||||
The rombios.bin file contains the ROM BIOS image for Bochs. This image is distributed under the GNU Lesser General Public
|
|
||||||
License (LGPL).
|
|
||||||
|
|
||||||
## Video BIOS (LGPL'd VGABios)
|
## Video BIOS (LGPL'd VGABios)
|
||||||
The vgabios.bin file contains the Video Bios for Bochs and QEMU. This VGA Bios is very specific to the emulated VGA card.
|
The vgabios.bin file contains the Video Bios for Bochs and QEMU. This VGA Bios is very specific to the emulated VGA card.
|
||||||
It is NOT meant to drive a physical vga card. It also implements support for VBE version 2.0.
|
It is NOT meant to drive a physical vga card. It also implements support for VBE version 2.0.
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
# XT Assembly Development Kit
|
|
||||||
PROJECT(XTADK)
|
|
||||||
|
|
||||||
# Specify include directories
|
|
||||||
include_directories(
|
|
||||||
${EXECTOS_SOURCE_DIR}/sdk/xtdk
|
|
||||||
${XTADK_SOURCE_DIR}/includes)
|
|
||||||
|
|
||||||
# Specify list of XTADK source code files
|
|
||||||
list(APPEND XTADK_SOURCE
|
|
||||||
${XTADK_SOURCE_DIR}/${ARCH}/ke.cc)
|
|
||||||
|
|
||||||
# Generate assembly header from XTADK sources
|
|
||||||
generate_xtadk(xtadk "${XTADK_SOURCE}")
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: sdk/xtadk/amd64/ke.cc
|
|
||||||
* DESCRIPTION: ADK generator for AMD64 version of Kernel Library
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtkmapi.h>
|
|
||||||
#include <adkdefs.h>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a definitions file for the Kernel Library used by the XTOS kernel assembly code
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCLINK
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
GenerateAssemblyDefinitions(VOID)
|
|
||||||
{
|
|
||||||
/* Generate KTRAP_FRAME offsets */
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Xmm0);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Xmm1);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Xmm2);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Xmm3);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Xmm4);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Xmm5);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Xmm6);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Xmm7);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Xmm8);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Xmm9);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Xmm10);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Xmm11);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Xmm12);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Xmm13);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Xmm14);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Xmm15);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, MxCsr);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, PreviousMode);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Cr2);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Cr3);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Dr0);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Dr1);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Dr2);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Dr3);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Dr6);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Dr7);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, SegDs);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, SegEs);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, SegFs);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, SegGs);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Rax);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Rbx);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Rcx);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Rdx);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, R8);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, R9);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, R10);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, R11);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, R12);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, R13);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, R14);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, R15);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Rsi);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Rdi);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Rbp);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Vector);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, ErrorCode);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, ExceptionFrame);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Rip);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, SegCs);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Flags);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Rsp);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, SegSs);
|
|
||||||
|
|
||||||
/* Generate KTRAP_FRAME size and REGISTERS_SIZE */
|
|
||||||
ADK_SIZE(KTRAP_FRAME);
|
|
||||||
ADK_SIZE_FROM(REGISTERS_SIZE, KTRAP_FRAME, Rax);
|
|
||||||
|
|
||||||
/* Generate PROCESSOR_START_BLOCK offsets */
|
|
||||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr3);
|
|
||||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr4);
|
|
||||||
ADK_OFFSET(PROCESSOR_START_BLOCK, EntryPoint);
|
|
||||||
ADK_OFFSET(PROCESSOR_START_BLOCK, ProcessorStructures);
|
|
||||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Stack);
|
|
||||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Started);
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: sdk/xtadk/i686/ke.cc
|
|
||||||
* DESCRIPTION: ADK generator for i686 version of Kernel Library
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtkmapi.h>
|
|
||||||
#include <adkdefs.h>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a definitions file for the Kernel Library used by the XTOS kernel assembly code
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCLINK
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
GenerateAssemblyDefinitions(VOID)
|
|
||||||
{
|
|
||||||
/* Generate KTRAP_FRAME offsets */
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, PreviousMode);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Cr2);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Cr3);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Dr0);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Dr1);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Dr2);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Dr3);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Dr6);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Dr7);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, SegDs);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, SegEs);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, SegFs);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, SegGs);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Eax);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Ebx);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Ecx);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Edx);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Esi);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Edi);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Ebp);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Vector);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, ErrorCode);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Eip);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, SegCs);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Flags);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, Esp);
|
|
||||||
ADK_OFFSET(KTRAP_FRAME, SegSs);
|
|
||||||
|
|
||||||
/* Generate KTRAP_FRAME size and REGISTERS_SIZE */
|
|
||||||
ADK_SIZE(KTRAP_FRAME);
|
|
||||||
ADK_SIZE_FROM(REGISTERS_SIZE, KTRAP_FRAME, Eax);
|
|
||||||
|
|
||||||
/* Generate PROCESSOR_START_BLOCK offsets */
|
|
||||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr3);
|
|
||||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr4);
|
|
||||||
ADK_OFFSET(PROCESSOR_START_BLOCK, EntryPoint);
|
|
||||||
ADK_OFFSET(PROCESSOR_START_BLOCK, ProcessorStructures);
|
|
||||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Stack);
|
|
||||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Started);
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: sdk/xtadk/adkdefs.h
|
|
||||||
* DESCRIPTION: Definitions for XTADK
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __XTADK_ADKDEFS_H
|
|
||||||
#define __XTADK_ADKDEFS_H
|
|
||||||
|
|
||||||
|
|
||||||
/* Macros for calculating structure size and offsets for assembler code */
|
|
||||||
#define ADK_DEFINE(Symbol, Value) __asm__ volatile("\n\t# ==> " #Symbol " %c0" : : "i" ((SIZE_T)(Value)))
|
|
||||||
#define ADK_OFFSET(Structure, Member) ADK_DEFINE(Structure ## _ ## Member, FIELD_OFFSET(Structure, Member))
|
|
||||||
#define ADK_SIZE(Structure) ADK_DEFINE(Structure ## _SIZE, sizeof(Structure))
|
|
||||||
#define ADK_SIZE_FROM(Name, Structure, Member) ADK_DEFINE(Structure ## _ ## Name, sizeof(Structure) - FIELD_OFFSET(Structure, Member))
|
|
||||||
|
|
||||||
#endif /* __XTADK_ADKDEFS_H */
|
|
||||||
@@ -12,7 +12,6 @@
|
|||||||
#include <xtdefs.h>
|
#include <xtdefs.h>
|
||||||
#include <xtstruct.h>
|
#include <xtstruct.h>
|
||||||
#include <xttypes.h>
|
#include <xttypes.h>
|
||||||
#include ARCH_HEADER(xtstruct.h)
|
|
||||||
|
|
||||||
|
|
||||||
/* Control Register 0 constants */
|
/* Control Register 0 constants */
|
||||||
@@ -128,10 +127,6 @@
|
|||||||
#define X86_EFLAGS_VIP_MASK 0x00100000 /* Virtual Interrupt Pending */
|
#define X86_EFLAGS_VIP_MASK 0x00100000 /* Virtual Interrupt Pending */
|
||||||
#define X86_EFLAGS_ID_MASK 0x00200000 /* Identification */
|
#define X86_EFLAGS_ID_MASK 0x00200000 /* Identification */
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* CPU vendor enumeration list */
|
/* CPU vendor enumeration list */
|
||||||
typedef enum _CPU_VENDOR
|
typedef enum _CPU_VENDOR
|
||||||
{
|
{
|
||||||
@@ -140,18 +135,6 @@ typedef enum _CPU_VENDOR
|
|||||||
CPU_VENDOR_UNKNOWN = 0xFFFFFFFF
|
CPU_VENDOR_UNKNOWN = 0xFFFFFFFF
|
||||||
} CPU_VENDOR, *PCPU_VENDOR;
|
} CPU_VENDOR, *PCPU_VENDOR;
|
||||||
|
|
||||||
/* CPUID advanced power management features (0x80000007) enumeration list */
|
|
||||||
typedef enum _CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT
|
|
||||||
{
|
|
||||||
CPUID_FEATURES_EDX_TS = 1 << 0, /* Temperature Sensor */
|
|
||||||
CPUID_FEATURES_EDX_FIS = 1 << 1, /* Frequency ID Selection */
|
|
||||||
CPUID_FEATURES_EDX_VIS = 1 << 2, /* Voltage ID Selection */
|
|
||||||
CPUID_FEATURES_EDX_TTS = 1 << 3, /* ThermaTrip Support */
|
|
||||||
CPUID_FEATURES_EDX_HTC = 1 << 4, /* Hardware Thermal Throttling */
|
|
||||||
CPUID_FEATURES_EDX_STC = 1 << 5, /* Software Thermal Throttling */
|
|
||||||
CPUID_FEATURES_EDX_TSCI = 1 << 8 /* TSC Invariant */
|
|
||||||
} CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT, *PCPUID_FEATURES_ADVANCED_POWER_MANAGEMENT;
|
|
||||||
|
|
||||||
/* CPUID extended features (0x80000001) enumeration list */
|
/* CPUID extended features (0x80000001) enumeration list */
|
||||||
typedef enum _CPUID_FEATURES_EXTENDED
|
typedef enum _CPUID_FEATURES_EXTENDED
|
||||||
{
|
{
|
||||||
@@ -193,23 +176,6 @@ typedef enum _CPUID_FEATURES_EXTENDED
|
|||||||
CPUID_FEATURES_EDX_3DNOW = 1 << 31
|
CPUID_FEATURES_EDX_3DNOW = 1 << 31
|
||||||
} CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
|
} CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
|
||||||
|
|
||||||
/* CPUID Thermal and Power Management features (0x00000006) enumeration list */
|
|
||||||
typedef enum _CPUID_FEATURES_POWER_MANAGEMENT
|
|
||||||
{
|
|
||||||
CPUID_FEATURES_EAX_DTHERM = 1 << 0,
|
|
||||||
CPUID_FEATURES_EAX_IDA = 1 << 1,
|
|
||||||
CPUID_FEATURES_EAX_ARAT = 1 << 2,
|
|
||||||
CPUID_FEATURES_EAX_PLN = 1 << 4,
|
|
||||||
CPUID_FEATURES_EAX_PTS = 1 << 6,
|
|
||||||
CPUID_FEATURES_EAX_HWP = 1 << 7,
|
|
||||||
CPUID_FEATURES_EAX_HWP_NOTIFY = 1 << 8,
|
|
||||||
CPUID_FEATURES_EAX_HWP_ACT_WINDOW = 1 << 9,
|
|
||||||
CPUID_FEATURES_EAX_HWP_EPP = 1 << 10,
|
|
||||||
CPUID_FEATURES_EAX_HWP_PKG_REQ = 1 << 11,
|
|
||||||
CPUID_FEATURES_EAX_HWP_HIGHEST_PERF_CHANGE = 1 << 15,
|
|
||||||
CPUID_FEATURES_EAX_HFI = 1 << 19
|
|
||||||
} CPUID_FEATURES_LEAF6, *PCPUID_FEATURES_LEAF6;
|
|
||||||
|
|
||||||
/* CPUID STD1 features (0x00000001) enumeration list */
|
/* CPUID STD1 features (0x00000001) enumeration list */
|
||||||
typedef enum _CPUID_FEATURES_STANDARD1
|
typedef enum _CPUID_FEATURES_STANDARD1
|
||||||
{
|
{
|
||||||
@@ -236,7 +202,7 @@ typedef enum _CPUID_FEATURES_STANDARD1
|
|||||||
CPUID_FEATURES_ECX_X2APIC = 1 << 21,
|
CPUID_FEATURES_ECX_X2APIC = 1 << 21,
|
||||||
CPUID_FEATURES_ECX_MOVBE = 1 << 22,
|
CPUID_FEATURES_ECX_MOVBE = 1 << 22,
|
||||||
CPUID_FEATURES_ECX_POPCNT = 1 << 23,
|
CPUID_FEATURES_ECX_POPCNT = 1 << 23,
|
||||||
CPUID_FEATURES_ECX_TSC_DEADLINE = 1 << 24,
|
CPUID_FEATURES_ECX_TSC = 1 << 24,
|
||||||
CPUID_FEATURES_ECX_AES = 1 << 25,
|
CPUID_FEATURES_ECX_AES = 1 << 25,
|
||||||
CPUID_FEATURES_ECX_XSAVE = 1 << 26,
|
CPUID_FEATURES_ECX_XSAVE = 1 << 26,
|
||||||
CPUID_FEATURES_ECX_OSXSAVE = 1 << 27,
|
CPUID_FEATURES_ECX_OSXSAVE = 1 << 27,
|
||||||
@@ -410,29 +376,20 @@ typedef enum _CPUID_FEATURES_STANDARD7_LEAF1
|
|||||||
/* CPUID requests */
|
/* CPUID requests */
|
||||||
typedef enum _CPUID_REQUESTS
|
typedef enum _CPUID_REQUESTS
|
||||||
{
|
{
|
||||||
CPUID_GET_VENDOR_STRING = 0x00000000,
|
CPUID_GET_VENDOR_STRING,
|
||||||
CPUID_GET_STANDARD1_FEATURES = 0x00000001,
|
CPUID_GET_STANDARD1_FEATURES,
|
||||||
CPUID_GET_TLB_CACHE = 0x00000002,
|
CPUID_GET_TLB_CACHE,
|
||||||
CPUID_GET_SERIAL = 0x00000003,
|
CPUID_GET_SERIAL,
|
||||||
CPUID_GET_CACHE_TOPOLOGY = 0x00000004,
|
CPUID_GET_CACHE_TOPOLOGY,
|
||||||
CPUID_GET_MONITOR_MWAIT = 0x00000005,
|
CPUID_GET_MONITOR_MWAIT,
|
||||||
CPUID_GET_POWER_MANAGEMENT = 0x00000006,
|
CPUID_GET_POWER_MANAGEMENT,
|
||||||
CPUID_GET_STANDARD7_FEATURES = 0x00000007,
|
CPUID_GET_STANDARD7_FEATURES
|
||||||
CPUID_GET_TSC_CRYSTAL_CLOCK = 0x00000015,
|
|
||||||
CPUID_GET_EXTENDED_MAX = 0x80000000,
|
|
||||||
CPUID_GET_EXTENDED_FEATURES = 0x80000001,
|
|
||||||
CPUID_GET_ADVANCED_POWER_MANAGEMENT = 0x80000007
|
|
||||||
} CPUID_REQUESTS, *PCPUID_REQUESTS;
|
} CPUID_REQUESTS, *PCPUID_REQUESTS;
|
||||||
|
|
||||||
/* Interrupt handler */
|
|
||||||
typedef VOID (*PINTERRUPT_HANDLER)(PKTRAP_FRAME TrapFrame);
|
|
||||||
|
|
||||||
/* Processor identification information */
|
/* Processor identification information */
|
||||||
typedef struct _CPU_IDENTIFICATION
|
typedef struct _CPU_IDENTIFICATION
|
||||||
{
|
{
|
||||||
ULONGLONG ExtendedFeatureBits;
|
|
||||||
USHORT Family;
|
USHORT Family;
|
||||||
ULONGLONG FeatureBits;
|
|
||||||
USHORT Model;
|
USHORT Model;
|
||||||
USHORT Stepping;
|
USHORT Stepping;
|
||||||
CPU_VENDOR Vendor;
|
CPU_VENDOR Vendor;
|
||||||
@@ -469,5 +426,4 @@ typedef enum _TRAMPOLINE_TYPE
|
|||||||
TrampolineEnableXpa
|
TrampolineEnableXpa
|
||||||
} TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;
|
} TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_AMD64_ARTYPES_H */
|
#endif /* __XTDK_AMD64_ARTYPES_H */
|
||||||
|
|||||||
@@ -15,9 +15,6 @@
|
|||||||
#include <amd64/xtstruct.h>
|
#include <amd64/xtstruct.h>
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Hardware layer routines forward references */
|
/* Hardware layer routines forward references */
|
||||||
XTCLINK
|
XTCLINK
|
||||||
XTCDECL
|
XTCDECL
|
||||||
@@ -52,5 +49,4 @@ VOID
|
|||||||
HlWritePort32(IN USHORT Port,
|
HlWritePort32(IN USHORT Port,
|
||||||
IN ULONG Value);
|
IN ULONG Value);
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_AMD64_HLFUNCS_H */
|
#endif /* __XTDK_AMD64_HLFUNCS_H */
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
#ifndef __XTDK_AMD64_HLTYPES_H
|
#ifndef __XTDK_AMD64_HLTYPES_H
|
||||||
#define __XTDK_AMD64_HLTYPES_H
|
#define __XTDK_AMD64_HLTYPES_H
|
||||||
|
|
||||||
#include <xtbase.h>
|
|
||||||
#include <xtdefs.h>
|
#include <xtdefs.h>
|
||||||
#include <xtstruct.h>
|
#include <xtstruct.h>
|
||||||
#include <xttypes.h>
|
#include <xttypes.h>
|
||||||
@@ -54,27 +53,6 @@
|
|||||||
/* Maximum number of I/O APICs */
|
/* Maximum number of I/O APICs */
|
||||||
#define APIC_MAX_IOAPICS 64
|
#define APIC_MAX_IOAPICS 64
|
||||||
|
|
||||||
/* I/O APIC base address */
|
|
||||||
#define IOAPIC_DEFAULT_BASE 0xFEC00000
|
|
||||||
|
|
||||||
/* I/O APIC definitions */
|
|
||||||
#define IOAPIC_MAX_CONTROLLERS 128
|
|
||||||
#define IOAPIC_MAX_OVERRIDES 16
|
|
||||||
#define IOAPIC_RTE_MASKED 0x100FF
|
|
||||||
#define IOAPIC_RTE_SIZE 2
|
|
||||||
#define IOAPIC_VECTOR_FREE 0xFF
|
|
||||||
#define IOAPIC_VECTOR_RESERVED 0xFE
|
|
||||||
|
|
||||||
/* IOAPIC offsets */
|
|
||||||
#define IOAPIC_IOREGSEL 0x00
|
|
||||||
#define IOAPIC_IOWIN 0x10
|
|
||||||
|
|
||||||
/* IOAPIC registers */
|
|
||||||
#define IOAPIC_ID 0x00
|
|
||||||
#define IOAPIC_VER 0x01
|
|
||||||
#define IOAPIC_ARB 0x02
|
|
||||||
#define IOAPIC_REDTBL 0x10
|
|
||||||
|
|
||||||
/* 8259/ISP PIC ports definitions */
|
/* 8259/ISP PIC ports definitions */
|
||||||
#define PIC1_CONTROL_PORT 0x20
|
#define PIC1_CONTROL_PORT 0x20
|
||||||
#define PIC1_DATA_PORT 0x21
|
#define PIC1_DATA_PORT 0x21
|
||||||
@@ -84,87 +62,6 @@
|
|||||||
/* PIC vector definitions */
|
/* PIC vector definitions */
|
||||||
#define PIC1_VECTOR_SPURIOUS 0x37
|
#define PIC1_VECTOR_SPURIOUS 0x37
|
||||||
|
|
||||||
/* HPET General Capabilities definitions */
|
|
||||||
#define HPET_CAPABILITY_64BIT 0x2000ULL
|
|
||||||
#define HPET_CAPABILITY_LEGACY_REPLACEMENT 0x8000ULL
|
|
||||||
|
|
||||||
/* HPET General Configuration definitions */
|
|
||||||
#define HPET_CONFIG_ENABLE 0x0001ULL
|
|
||||||
#define HPET_CONFIG_LEGACY_REPLACEMENT 0x0002ULL
|
|
||||||
|
|
||||||
/* HPET Timer Configuration definitions */
|
|
||||||
#define HPET_TIMER_CONFIG_LEVEL_TRIGGERED 0x0002ULL
|
|
||||||
#define HPET_TIMER_CONFIG_ENABLED 0x0004ULL
|
|
||||||
#define HPET_TIMER_CONFIG_PERIODIC 0x0008ULL
|
|
||||||
#define HPET_TIMER_CONFIG_SUPPORTS_PERIODIC 0x0010ULL
|
|
||||||
#define HPET_TIMER_CONFIG_SUPPORTS_64BIT 0x0020ULL
|
|
||||||
#define HPET_TIMER_CONFIG_VALUE_ACCUMULATOR 0x0040ULL
|
|
||||||
#define HPET_TIMER_CONFIG_FORCE_32BIT 0x0100ULL
|
|
||||||
#define HPET_TIMER_CONFIG_FSB_ENABLED 0x4000ULL
|
|
||||||
#define HPET_TIMER_CONFIG_SUPPORTS_FSB 0x8000ULL
|
|
||||||
|
|
||||||
/* PIT ports definitions */
|
|
||||||
#define PIT_COMMAND_PORT 0x43
|
|
||||||
#define PIT_DATA_PORT0 0x40
|
|
||||||
#define PIT_DATA_PORT1 0x41
|
|
||||||
#define PIT_DATA_PORT2 0x42
|
|
||||||
|
|
||||||
/* PIT related definitions */
|
|
||||||
#define PIT_BASE_FREQUENCY 1193182
|
|
||||||
|
|
||||||
/* PIT Access Mode: Defines how the CPU reads or writes the counter value */
|
|
||||||
#define PIT_CMD_ACCESS_LATCH 0x00
|
|
||||||
#define PIT_CMD_ACCESS_LOWBYTE_ONLY 0x10
|
|
||||||
#define PIT_CMD_ACCESS_HIGHBYTE_ONLY 0x20
|
|
||||||
#define PIT_CMD_ACCESS_LOWBYTE_HIGHBYTE 0x30
|
|
||||||
|
|
||||||
/* PIT Channel Selection: Specifies the physical timer channel to configure */
|
|
||||||
#define PIT_CMD_CHANNEL0 0x00
|
|
||||||
#define PIT_CMD_CHANNEL1 0x40
|
|
||||||
#define PIT_CMD_CHANNEL2 0x80
|
|
||||||
|
|
||||||
/* PIT Operating Mode: Defines the hardware behavior and the generated waveform */
|
|
||||||
#define PIT_MODE0_INT_ON_TERMINAL_COUNT 0x00
|
|
||||||
#define PIT_MODE1_ONESHOT 0x02
|
|
||||||
#define PIT_MODE2_RATE_GENERATOR 0x04
|
|
||||||
#define PIT_MODE3_SQUARE_WAVE_GEN 0x06
|
|
||||||
#define PIT_MODE4_SOFTWARE_STROBE 0x08
|
|
||||||
#define PIT_MODE5_HARDWARE_STROBE 0x0A
|
|
||||||
|
|
||||||
/* CMOS controller access ports */
|
|
||||||
#define CMOS_SELECT_PORT 0x70
|
|
||||||
#define CMOS_DATA_PORT 0x71
|
|
||||||
|
|
||||||
/* CMOD Select port definitions */
|
|
||||||
#define CMOS_NMI_SELECT 0x80
|
|
||||||
#define CMOS_REGISTER_SECOND 0x00
|
|
||||||
#define CMOS_REGISTER_MINUTE 0x02
|
|
||||||
#define CMOS_REGISTER_HOUR 0x04
|
|
||||||
#define CMOS_REGISTER_WEEKDAY 0x06
|
|
||||||
#define CMOS_REGISTER_DAY 0x07
|
|
||||||
#define CMOS_REGISTER_MONTH 0x08
|
|
||||||
#define CMOS_REGISTER_YEAR 0x09
|
|
||||||
#define CMOS_REGISTER_A 0x0A
|
|
||||||
#define CMOS_REGISTER_B 0x0B
|
|
||||||
#define CMOS_REGISTER_C 0x0C
|
|
||||||
|
|
||||||
/* CMOS Register A definitions */
|
|
||||||
#define CMOS_REGISTER_A_RATE_MASK 0x0F
|
|
||||||
#define CMOS_REGISTER_A_UPDATE_IN_PROGRESS 0x80
|
|
||||||
|
|
||||||
/* CMOS Register B definitions */
|
|
||||||
#define CMOS_REGISTER_B_24_HOUR 0x02
|
|
||||||
#define CMOS_REGISTER_B_BINARY 0x04
|
|
||||||
#define CMOS_REGISTER_B_PERIODIC 0x40
|
|
||||||
#define CMOS_REGISTER_B_SET_CLOCK 0x80
|
|
||||||
|
|
||||||
/* CMOS Register C definitions */
|
|
||||||
#define CMOS_REGISTER_C_PERIODIC 0x40
|
|
||||||
#define CMOS_REGISTER_C_INTERRUPT 0x80
|
|
||||||
|
|
||||||
/* CMOS RTC 24-hour mode */
|
|
||||||
#define CMOS_RTC_POST_MERIDIEM 0x80
|
|
||||||
|
|
||||||
/* Serial ports information */
|
/* Serial ports information */
|
||||||
#define COMPORT_ADDRESS {0x3F8, 0x2F8, 0x3E8, 0x2E8, 0x5F8, 0x4F8, 0x5E8, 0x4E8}
|
#define COMPORT_ADDRESS {0x3F8, 0x2F8, 0x3E8, 0x2E8, 0x5F8, 0x4F8, 0x5E8, 0x4E8}
|
||||||
#define COMPORT_COUNT 8
|
#define COMPORT_COUNT 8
|
||||||
@@ -172,17 +69,6 @@
|
|||||||
/* Initial stall factor */
|
/* Initial stall factor */
|
||||||
#define INITIAL_STALL_FACTOR 100
|
#define INITIAL_STALL_FACTOR 100
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* APIC destination mode enumeration list */
|
|
||||||
typedef enum _APIC_DEST_MODE
|
|
||||||
{
|
|
||||||
APIC_DM_Physical,
|
|
||||||
APIC_DM_Logical
|
|
||||||
} APIC_DEST_MODE, *PAPIC_DEST_MODE;
|
|
||||||
|
|
||||||
/* APIC delivery mode enumeration list */
|
/* APIC delivery mode enumeration list */
|
||||||
typedef enum _APIC_DM
|
typedef enum _APIC_DM
|
||||||
{
|
{
|
||||||
@@ -240,7 +126,6 @@ typedef enum _APIC_REGISTER
|
|||||||
APIC_TICR = 0x38, /* Initial Count Register for Timer */
|
APIC_TICR = 0x38, /* Initial Count Register for Timer */
|
||||||
APIC_TCCR = 0x39, /* Current Count Register for Timer */
|
APIC_TCCR = 0x39, /* Current Count Register for Timer */
|
||||||
APIC_TDCR = 0x3E, /* Timer Divide Configuration Register */
|
APIC_TDCR = 0x3E, /* Timer Divide Configuration Register */
|
||||||
APIC_SIPI = 0x3F, /* Self-IPI Register */
|
|
||||||
APIC_EAFR = 0x40, /* extended APIC Feature register */
|
APIC_EAFR = 0x40, /* extended APIC Feature register */
|
||||||
APIC_EACR = 0x41, /* Extended APIC Control Register */
|
APIC_EACR = 0x41, /* Extended APIC Control Register */
|
||||||
APIC_SEOI = 0x42, /* Specific End Of Interrupt Register */
|
APIC_SEOI = 0x42, /* Specific End Of Interrupt Register */
|
||||||
@@ -250,19 +135,6 @@ typedef enum _APIC_REGISTER
|
|||||||
APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */
|
APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */
|
||||||
} APIC_REGISTER, *PAPIC_REGISTER;
|
} APIC_REGISTER, *PAPIC_REGISTER;
|
||||||
|
|
||||||
/* APIC Timer Divide enumeration list */
|
|
||||||
typedef enum _APIC_TIMER_DIVISOR
|
|
||||||
{
|
|
||||||
TIMER_DivideBy2 = 0,
|
|
||||||
TIMER_DivideBy4 = 1,
|
|
||||||
TIMER_DivideBy8 = 2,
|
|
||||||
TIMER_DivideBy16 = 3,
|
|
||||||
TIMER_DivideBy32 = 8,
|
|
||||||
TIMER_DivideBy64 = 9,
|
|
||||||
TIMER_DivideBy128 = 10,
|
|
||||||
TIMER_DivideBy1 = 11,
|
|
||||||
} APIC_TIMER_DIVISOR, *PAPIC_TIMER_DIVISOR;
|
|
||||||
|
|
||||||
/* I8259 PIC interrupt mode enumeration list */
|
/* I8259 PIC interrupt mode enumeration list */
|
||||||
typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE
|
typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE
|
||||||
{
|
{
|
||||||
@@ -307,17 +179,6 @@ typedef enum _PIC_I8259_ICW4_SYSTEM_MODE
|
|||||||
New8086Mode
|
New8086Mode
|
||||||
} PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;
|
} PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;
|
||||||
|
|
||||||
/* Supported hardware timer backends */
|
|
||||||
typedef enum _TIMER_TYPE
|
|
||||||
{
|
|
||||||
TimerNone,
|
|
||||||
TimerAcpiPm,
|
|
||||||
TimerHpet,
|
|
||||||
TimerLapic,
|
|
||||||
TimerPit,
|
|
||||||
TimerTsc
|
|
||||||
} TIMER_TYPE, *PTIMER_TYPE;
|
|
||||||
|
|
||||||
/* APIC Base Register */
|
/* APIC Base Register */
|
||||||
typedef union _APIC_BASE_REGISTER
|
typedef union _APIC_BASE_REGISTER
|
||||||
{
|
{
|
||||||
@@ -391,40 +252,6 @@ typedef union _APIC_SPURIOUS_REGISTER
|
|||||||
};
|
};
|
||||||
} APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
|
} APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
|
||||||
|
|
||||||
/* I/O APIC Controller information */
|
|
||||||
typedef struct _IOAPIC_DATA
|
|
||||||
{
|
|
||||||
ULONG GsiBase;
|
|
||||||
ULONG Identifier;
|
|
||||||
ULONG LineCount;
|
|
||||||
PHYSICAL_ADDRESS PhysicalAddress;
|
|
||||||
ULONG_PTR VirtualAddress;
|
|
||||||
} IOAPIC_DATA, *PIOAPIC_DATA;
|
|
||||||
|
|
||||||
/* I/O APIC Redirection Register */
|
|
||||||
typedef union _IOAPIC_REDIRECTION_REGISTER
|
|
||||||
{
|
|
||||||
ULONGLONG LongLong;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
UINT Base;
|
|
||||||
UINT Extended;
|
|
||||||
};
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
ULONGLONG Vector:8;
|
|
||||||
ULONGLONG DeliveryMode:3;
|
|
||||||
ULONGLONG DestinationMode:1;
|
|
||||||
ULONGLONG DeliveryStatus:1;
|
|
||||||
ULONGLONG PinPolarity:1;
|
|
||||||
ULONGLONG RemoteIRR:1;
|
|
||||||
ULONGLONG TriggerMode:1;
|
|
||||||
ULONGLONG Mask:1;
|
|
||||||
ULONGLONG Reserved:39;
|
|
||||||
ULONGLONG Destination:8;
|
|
||||||
};
|
|
||||||
} IOAPIC_REDIRECTION_REGISTER, *PIOAPIC_REDIRECTION_REGISTER;
|
|
||||||
|
|
||||||
/* I8259 PIC register structure */
|
/* I8259 PIC register structure */
|
||||||
typedef union _PIC_I8259_ICW1
|
typedef union _PIC_I8259_ICW1
|
||||||
{
|
{
|
||||||
@@ -490,39 +317,4 @@ typedef union _PIC_I8259_ICW4
|
|||||||
UCHAR Bits;
|
UCHAR Bits;
|
||||||
} PIC_I8259_ICW4, *PPIC_I8259_ICW4;
|
} PIC_I8259_ICW4, *PPIC_I8259_ICW4;
|
||||||
|
|
||||||
/* HPET Registers structure definition */
|
|
||||||
typedef struct _HPET_REGISTERS
|
|
||||||
{
|
|
||||||
VOLATILE ULONGLONG GeneralCapabilities;
|
|
||||||
VOLATILE ULONGLONG Reserved0;
|
|
||||||
VOLATILE ULONGLONG GeneralConfiguration;
|
|
||||||
VOLATILE ULONGLONG Reserved1;
|
|
||||||
VOLATILE ULONGLONG GeneralInterruptStatus;
|
|
||||||
VOLATILE ULONGLONG Reserved2;
|
|
||||||
VOLATILE ULONGLONG Reserved3[2][12];
|
|
||||||
VOLATILE ULONGLONG MainCounterValue;
|
|
||||||
VOLATILE ULONGLONG Reserved4;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
VOLATILE ULONGLONG Configuration;
|
|
||||||
VOLATILE ULONGLONG Comparator;
|
|
||||||
VOLATILE ULONGLONG FsbInterruptRoute;
|
|
||||||
VOLATILE ULONGLONG Reserved;
|
|
||||||
} Timers[];
|
|
||||||
} HPET_REGISTERS, *PHPET_REGISTERS;
|
|
||||||
|
|
||||||
/* Hardware timer capabilities and CPU clock features */
|
|
||||||
typedef struct _TIMER_CAPABILITIES
|
|
||||||
{
|
|
||||||
BOOLEAN Arat;
|
|
||||||
BOOLEAN Art;
|
|
||||||
BOOLEAN InvariantTsc;
|
|
||||||
BOOLEAN RDTSCP;
|
|
||||||
ULONG TimerFrequency;
|
|
||||||
BOOLEAN TscDeadline;
|
|
||||||
ULONG TscDenominator;
|
|
||||||
ULONG TscNumerator;
|
|
||||||
} TIMER_CAPABILITIES, *PTIMER_CAPABILITIES;
|
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_AMD64_HLTYPES_H */
|
#endif /* __XTDK_AMD64_HLTYPES_H */
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
|
|
||||||
/* GDT selector names */
|
/* GDT selector names */
|
||||||
#define KGDT_NULL 0x0000
|
#define KGDT_NULL 0x0000
|
||||||
#define KGDT_R0_CMCODE 0x0008
|
|
||||||
#define KGDT_R0_CODE 0x0010
|
#define KGDT_R0_CODE 0x0010
|
||||||
#define KGDT_R0_DATA 0x0018
|
#define KGDT_R0_DATA 0x0018
|
||||||
#define KGDT_R3_CMCODE 0x0020
|
#define KGDT_R3_CMCODE 0x0020
|
||||||
@@ -47,7 +46,7 @@
|
|||||||
#define KGDT_DESCRIPTOR_CODE 0x08
|
#define KGDT_DESCRIPTOR_CODE 0x08
|
||||||
|
|
||||||
/* GDT descriptor type codes */
|
/* GDT descriptor type codes */
|
||||||
#define KGDT_TYPE_NONE 0x00
|
#define KGDT_TYPE_NONE 0x0
|
||||||
#define KGDT_TYPE_CODE (0x10 | KGDT_DESCRIPTOR_CODE | KGDT_DESCRIPTOR_EXECUTE_READ)
|
#define KGDT_TYPE_CODE (0x10 | KGDT_DESCRIPTOR_CODE | KGDT_DESCRIPTOR_EXECUTE_READ)
|
||||||
#define KGDT_TYPE_DATA (0x10 | KGDT_DESCRIPTOR_READ_WRITE)
|
#define KGDT_TYPE_DATA (0x10 | KGDT_DESCRIPTOR_READ_WRITE)
|
||||||
|
|
||||||
@@ -59,7 +58,6 @@
|
|||||||
#define KIDT_IST_RESERVED 0
|
#define KIDT_IST_RESERVED 0
|
||||||
#define KIDT_IST_PANIC 1
|
#define KIDT_IST_PANIC 1
|
||||||
#define KIDT_IST_MCA 2
|
#define KIDT_IST_MCA 2
|
||||||
#define KIDT_IST_NMI 3
|
|
||||||
|
|
||||||
/* AMD64 Segment Types */
|
/* AMD64 Segment Types */
|
||||||
#define AMD64_TASK_GATE 0x5
|
#define AMD64_TASK_GATE 0x5
|
||||||
@@ -69,62 +67,6 @@
|
|||||||
#define AMD64_INTERRUPT_GATE 0xE
|
#define AMD64_INTERRUPT_GATE 0xE
|
||||||
#define AMD64_TRAP_GATE 0xF
|
#define AMD64_TRAP_GATE 0xF
|
||||||
|
|
||||||
/* Kernel CPU Standard Features */
|
|
||||||
#define KCF_VME (1ULL << 0) /* Virtual 8086 Mode Enhancements */
|
|
||||||
#define KCF_LARGE_PAGE (1ULL << 1) /* Page Size Extensions */
|
|
||||||
#define KCF_RDTSC (1ULL << 2) /* Time Stamp Counter */
|
|
||||||
#define KCF_PAE (1ULL << 3) /* Physical Address Extension */
|
|
||||||
#define KCF_MCE (1ULL << 4) /* Machine Check Exception */
|
|
||||||
#define KCF_CMPXCHG8B (1ULL << 5) /* CMPXCHG8B Instruction */
|
|
||||||
#define KCF_APIC (1ULL << 6) /* APIC On-Chip */
|
|
||||||
#define KCF_FAST_SYSCALL (1ULL << 7) /* SYSENTER/SYSEXIT Instructions */
|
|
||||||
#define KCF_MTRR (1ULL << 8) /* Memory Type Range Registers */
|
|
||||||
#define KCF_GLOBAL_PAGE (1ULL << 9) /* Page Global Enable */
|
|
||||||
#define KCF_MCA (1ULL << 10) /* Machine Check Architecture */
|
|
||||||
#define KCF_CMOV (1ULL << 11) /* Conditional Move Instructions */
|
|
||||||
#define KCF_PAT (1ULL << 12) /* Page Attribute Table */
|
|
||||||
#define KCF_PSE36 (1ULL << 13) /* 36-bit Page Size Extension */
|
|
||||||
#define KCF_CLFLUSH (1ULL << 14) /* CLFLUSH Instruction */
|
|
||||||
#define KCF_FXSR (1ULL << 15) /* FXSAVE/FXRSTOR Instructions */
|
|
||||||
#define KCF_ACPI (1ULL << 16) /* Thermal Monitor and Software Controlled Clock */
|
|
||||||
#define KCF_MMX (1ULL << 17) /* MMX Technology */
|
|
||||||
#define KCF_SSE (1ULL << 18) /* Streaming SIMD Extensions */
|
|
||||||
#define KCF_SSE2 (1ULL << 19) /* Streaming SIMD Extensions 2 */
|
|
||||||
#define KCF_SMT (1ULL << 20) /* Hyper-Threading Technology */
|
|
||||||
#define KCF_SSE3 (1ULL << 21) /* Streaming SIMD Extensions 3 */
|
|
||||||
#define KCF_VMX (1ULL << 22) /* Intel Virtual Machine Extensions */
|
|
||||||
#define KCF_SSSE3 (1ULL << 23) /* Supplemental SSE3 Instructions */
|
|
||||||
#define KCF_SSE41 (1ULL << 24) /* SSE4.1 Instructions */
|
|
||||||
#define KCF_SSE42 (1ULL << 25) /* SSE4.2 Instructions */
|
|
||||||
#define KCF_X2APIC (1ULL << 26) /* x2APIC Support */
|
|
||||||
#define KCF_POPCNT (1ULL << 27) /* POPCNT Instruction */
|
|
||||||
#define KCF_TSC_DEADLINE (1ULL << 28) /* TSC Deadline Timer */
|
|
||||||
#define KCF_AES (1ULL << 29) /* AES-NI Instruction Set */
|
|
||||||
#define KCF_XSAVE (1ULL << 30) /* XSAVE/XRSTOR Instructions */
|
|
||||||
#define KCF_AVX (1ULL << 31) /* Advanced Vector Extensions */
|
|
||||||
#define KCF_RDRAND (1ULL << 32) /* RDRAND Instruction */
|
|
||||||
#define KCF_FSGSBASE (1ULL << 33) /* RDFSBASE/WRFSBASE Instructions */
|
|
||||||
#define KCF_AVX2 (1ULL << 34) /* AVX2 Instructions */
|
|
||||||
#define KCF_SMEP (1ULL << 35) /* Supervisor Mode Execution Prevention */
|
|
||||||
#define KCF_RDSEED (1ULL << 36) /* RDSEED Instruction */
|
|
||||||
#define KCF_SMAP (1ULL << 37) /* Supervisor Mode Access Prevention */
|
|
||||||
#define KCF_SHA (1ULL << 38) /* SHA Extensions */
|
|
||||||
#define KCF_LA57 (1ULL << 39) /* 57-bit Linear Addresses */
|
|
||||||
#define KCF_ARAT (1ULL << 40) /* Always Running APIC Timer */
|
|
||||||
|
|
||||||
/* Kernel CPU Extended Features */
|
|
||||||
#define KCF_SVM (1ULL << 0) /* AMD Secure Virtual Machine */
|
|
||||||
#define KCF_SSE4A (1ULL << 1) /* SSE4A Instructions */
|
|
||||||
#define KCF_FMA4 (1ULL << 2) /* FMA4 Instructions */
|
|
||||||
#define KCF_TOPOEXT (1ULL << 3) /* AMD Topology Extensions */
|
|
||||||
#define KCF_SYSCALL (1ULL << 4) /* SYSCALL/SYSRET Instructions */
|
|
||||||
#define KCF_NX_BIT (1ULL << 5) /* No-Execute Page Protection */
|
|
||||||
#define KCF_RDTSCP (1ULL << 6) /* RDTSCP Instruction */
|
|
||||||
#define KCF_64BIT (1ULL << 7) /* Long Mode Support */
|
|
||||||
#define KCF_3DNOW_EXT (1ULL << 8) /* 3DNow! Extensions */
|
|
||||||
#define KCF_3DNOW (1ULL << 9) /* 3DNow! Instructions */
|
|
||||||
#define KCF_INVARIANT_TSC (1ULL << 10) /* Invariant Time Stamp Counter */
|
|
||||||
|
|
||||||
/* Context control flags */
|
/* Context control flags */
|
||||||
#define CONTEXT_ARCHITECTURE 0x00100000
|
#define CONTEXT_ARCHITECTURE 0x00100000
|
||||||
#define CONTEXT_CONTROL (CONTEXT_ARCHITECTURE | 0x01)
|
#define CONTEXT_CONTROL (CONTEXT_ARCHITECTURE | 0x01)
|
||||||
@@ -168,14 +110,13 @@
|
|||||||
|
|
||||||
/* XTOS Kernel stack size */
|
/* XTOS Kernel stack size */
|
||||||
#define KERNEL_STACK_SIZE 0x8000
|
#define KERNEL_STACK_SIZE 0x8000
|
||||||
#define KERNEL_STACKS 3
|
|
||||||
|
|
||||||
/* XTOS Kernel stack guard pages */
|
/* XTOS Kernel stack guard pages */
|
||||||
#define KERNEL_STACK_GUARD_PAGES 1
|
#define KERNEL_STACK_GUARD_PAGES 1
|
||||||
|
|
||||||
/* Processor structures size */
|
/* Processor structures size */
|
||||||
#define KPROCESSOR_STRUCTURES_SIZE ((KERNEL_STACKS * KERNEL_STACK_SIZE) + (GDT_ENTRIES * sizeof(KGDTENTRY)) + \
|
#define KPROCESSOR_STRUCTURES_SIZE ((2 * KERNEL_STACK_SIZE) + (GDT_ENTRIES * sizeof(KGDTENTRY)) + sizeof(KTSS) + \
|
||||||
sizeof(KTSS) + sizeof(KPROCESSOR_BLOCK) + MM_PAGE_SIZE)
|
sizeof(KPROCESSOR_BLOCK) + MM_PAGE_SIZE)
|
||||||
|
|
||||||
/* Kernel frames */
|
/* Kernel frames */
|
||||||
#define KEXCEPTION_FRAME_SIZE sizeof(KEXCEPTION_FRAME)
|
#define KEXCEPTION_FRAME_SIZE sizeof(KEXCEPTION_FRAME)
|
||||||
@@ -194,10 +135,6 @@
|
|||||||
#define NPX_STATE_SCRUB 0x1
|
#define NPX_STATE_SCRUB 0x1
|
||||||
#define NPX_STATE_SWITCH 0x2
|
#define NPX_STATE_SWITCH 0x2
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Floating point state storing structure */
|
/* Floating point state storing structure */
|
||||||
typedef struct _FLOATING_SAVE_AREA
|
typedef struct _FLOATING_SAVE_AREA
|
||||||
{
|
{
|
||||||
@@ -526,22 +463,11 @@ typedef struct _KSPECIAL_REGISTERS
|
|||||||
ULONG64 MsrSyscallMask;
|
ULONG64 MsrSyscallMask;
|
||||||
} KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS;
|
} KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS;
|
||||||
|
|
||||||
/* Processor start block structure definition */
|
|
||||||
typedef struct _PROCESSOR_START_BLOCK
|
|
||||||
{
|
|
||||||
ULONG_PTR Cr3;
|
|
||||||
ULONG_PTR Cr4;
|
|
||||||
PVOID EntryPoint;
|
|
||||||
PVOID ProcessorStructures;
|
|
||||||
PVOID Stack;
|
|
||||||
BOOLEAN Started;
|
|
||||||
} PROCESSOR_START_BLOCK, *PPROCESSOR_START_BLOCK;
|
|
||||||
|
|
||||||
/* Processor state frame structure definition */
|
/* Processor state frame structure definition */
|
||||||
typedef struct _KPROCESSOR_STATE
|
typedef struct _KPROCESSOR_STATE
|
||||||
{
|
{
|
||||||
CONTEXT ContextFrame;
|
|
||||||
KSPECIAL_REGISTERS SpecialRegisters;
|
KSPECIAL_REGISTERS SpecialRegisters;
|
||||||
|
CONTEXT ContextFrame;
|
||||||
} KPROCESSOR_STATE, *PKPROCESSOR_STATE;
|
} KPROCESSOR_STATE, *PKPROCESSOR_STATE;
|
||||||
|
|
||||||
/* Processor Control Block (PRCB) structure definition */
|
/* Processor Control Block (PRCB) structure definition */
|
||||||
@@ -564,7 +490,6 @@ typedef struct _KPROCESSOR_CONTROL_BLOCK
|
|||||||
ULONG_PTR MultiThreadProcessorSet;
|
ULONG_PTR MultiThreadProcessorSet;
|
||||||
SINGLE_LIST_ENTRY DeferredReadyListHead;
|
SINGLE_LIST_ENTRY DeferredReadyListHead;
|
||||||
PROCESSOR_POWER_STATE PowerState;
|
PROCESSOR_POWER_STATE PowerState;
|
||||||
ULONG ProfilingCountdown;
|
|
||||||
} KPROCESSOR_CONTROL_BLOCK, *PKPROCESSOR_CONTROL_BLOCK;
|
} KPROCESSOR_CONTROL_BLOCK, *PKPROCESSOR_CONTROL_BLOCK;
|
||||||
|
|
||||||
/* Processor Block structure definition */
|
/* Processor Block structure definition */
|
||||||
@@ -591,9 +516,6 @@ typedef struct _KPROCESSOR_BLOCK
|
|||||||
KAFFINITY SetMember;
|
KAFFINITY SetMember;
|
||||||
ULONG StallScaleFactor;
|
ULONG StallScaleFactor;
|
||||||
UCHAR CpuNumber;
|
UCHAR CpuNumber;
|
||||||
ULONG HardwareId;
|
|
||||||
VOLATILE BOOLEAN Started;
|
|
||||||
PINTERRUPT_HANDLER InterruptDispatchTable[256];
|
|
||||||
} KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK;
|
} KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK;
|
||||||
|
|
||||||
/* Thread Environment Block (TEB) structure definition */
|
/* Thread Environment Block (TEB) structure definition */
|
||||||
@@ -602,5 +524,4 @@ typedef struct _THREAD_ENVIRONMENT_BLOCK
|
|||||||
THREAD_INFORMATION_BLOCK InformationBlock;
|
THREAD_INFORMATION_BLOCK InformationBlock;
|
||||||
} THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
} THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_AMD64_KETYPES_H */
|
#endif /* __XTDK_AMD64_KETYPES_H */
|
||||||
|
|||||||
@@ -101,9 +101,6 @@
|
|||||||
/* HAL memory pool virtual address start */
|
/* HAL memory pool virtual address start */
|
||||||
#define MM_HARDWARE_VA_START 0xFFFFFFFFFFC00000ULL
|
#define MM_HARDWARE_VA_START 0xFFFFFFFFFFC00000ULL
|
||||||
|
|
||||||
/* Kernel shared data address */
|
|
||||||
#define MM_KERNEL_SHARED_DATA_ADDRESS 0xFFFFFFFFFFDF0000ULL
|
|
||||||
|
|
||||||
/* Maximum physical address used by HAL allocations */
|
/* Maximum physical address used by HAL allocations */
|
||||||
#define MM_MAXIMUM_PHYSICAL_ADDRESS 0x00000000FFFFFFFFULL
|
#define MM_MAXIMUM_PHYSICAL_ADDRESS 0x00000000FFFFFFFFULL
|
||||||
|
|
||||||
@@ -122,10 +119,6 @@
|
|||||||
/* Number of pool tracking tables */
|
/* Number of pool tracking tables */
|
||||||
#define MM_POOL_TRACKING_TABLES 64
|
#define MM_POOL_TRACKING_TABLES 64
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Page size enumeration list */
|
/* Page size enumeration list */
|
||||||
typedef enum _PAGE_SIZE
|
typedef enum _PAGE_SIZE
|
||||||
{
|
{
|
||||||
@@ -351,5 +344,4 @@ typedef struct _POOL_DESCRIPTOR
|
|||||||
SIZE_T Reserved;
|
SIZE_T Reserved;
|
||||||
} POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
} POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_AMD64_MMTYPES_H */
|
#endif /* __XTDK_AMD64_MMTYPES_H */
|
||||||
|
|||||||
@@ -12,20 +12,13 @@
|
|||||||
#include <xtdefs.h>
|
#include <xtdefs.h>
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Architecture-specific enumeration lists forward references */
|
/* Architecture-specific enumeration lists forward references */
|
||||||
typedef enum _APIC_DEST_MODE APIC_DEST_MODE, *PAPIC_DEST_MODE;
|
|
||||||
typedef enum _APIC_DM APIC_DM, *PAPIC_DM;
|
typedef enum _APIC_DM APIC_DM, *PAPIC_DM;
|
||||||
typedef enum _APIC_DSH APIC_DSH, *PAPIC_DSH;
|
typedef enum _APIC_DSH APIC_DSH, *PAPIC_DSH;
|
||||||
typedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE;
|
typedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE;
|
||||||
typedef enum _APIC_REGISTER APIC_REGISTER, *PAPIC_REGISTER;
|
typedef enum _APIC_REGISTER APIC_REGISTER, *PAPIC_REGISTER;
|
||||||
typedef enum _APIC_TIMER_DIVISOR APIC_TIMER_DIVISOR, *PAPIC_TIMER_DIVISOR;
|
|
||||||
typedef enum _CPU_VENDOR CPU_VENDOR, *PCPU_VENDOR;
|
typedef enum _CPU_VENDOR CPU_VENDOR, *PCPU_VENDOR;
|
||||||
typedef enum _CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT, *PCPUID_FEATURES_ADVANCED_POWER_MANAGEMENT;
|
|
||||||
typedef enum _CPUID_FEATURES_EXTENDED CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
|
typedef enum _CPUID_FEATURES_EXTENDED CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
|
||||||
typedef enum _CPUID_FEATURES_POWER_MANAGEMENT CPUID_FEATURES_POWER_MANAGEMENT, *PCPUID_FEATURES_POWER_MANAGEMENT;
|
|
||||||
typedef enum _CPUID_FEATURES_STANDARD1 CPUID_FEATURES_STANDARD1, *PCPUID_FEATURES_STANDARD1;
|
typedef enum _CPUID_FEATURES_STANDARD1 CPUID_FEATURES_STANDARD1, *PCPUID_FEATURES_STANDARD1;
|
||||||
typedef enum _CPUID_FEATURES_STANDARD7_LEAF0 CPUID_FEATURES_STANDARD7_LEAF0, *PCPUID_FEATURES_STANDARD7_LEAF0;
|
typedef enum _CPUID_FEATURES_STANDARD7_LEAF0 CPUID_FEATURES_STANDARD7_LEAF0, *PCPUID_FEATURES_STANDARD7_LEAF0;
|
||||||
typedef enum _CPUID_FEATURES_STANDARD7_LEAF1 CPUID_FEATURES_STANDARD7_LEAF1, *PCPUID_FEATURES_STANDARD7_LEAF1;
|
typedef enum _CPUID_FEATURES_STANDARD7_LEAF1 CPUID_FEATURES_STANDARD7_LEAF1, *PCPUID_FEATURES_STANDARD7_LEAF1;
|
||||||
@@ -37,7 +30,6 @@ typedef enum _PIC_I8259_ICW1_OPERATING_MODE PIC_I8259_ICW1_OPERATING_MODE, *PPIC
|
|||||||
typedef enum _PIC_I8259_ICW4_BUFFERED_MODE PIC_I8259_ICW4_BUFFERED_MODE, *PPIC_I8259_ICW4_BUFFERED_MODE;
|
typedef enum _PIC_I8259_ICW4_BUFFERED_MODE PIC_I8259_ICW4_BUFFERED_MODE, *PPIC_I8259_ICW4_BUFFERED_MODE;
|
||||||
typedef enum _PIC_I8259_ICW4_EOI_MODE PIC_I8259_ICW4_EOI_MODE, *PPIC_I8259_ICW4_EOI_MODE;
|
typedef enum _PIC_I8259_ICW4_EOI_MODE PIC_I8259_ICW4_EOI_MODE, *PPIC_I8259_ICW4_EOI_MODE;
|
||||||
typedef enum _PIC_I8259_ICW4_SYSTEM_MODE PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;
|
typedef enum _PIC_I8259_ICW4_SYSTEM_MODE PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;
|
||||||
typedef enum _TIMER_TYPE TIMER_TYPE, *PTIMER_TYPE;
|
|
||||||
typedef enum _TRAMPOLINE_TYPE TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;
|
typedef enum _TRAMPOLINE_TYPE TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;
|
||||||
|
|
||||||
/* Architecture-specific structures forward references */
|
/* Architecture-specific structures forward references */
|
||||||
@@ -47,8 +39,6 @@ typedef struct _CPUID_REGISTERS CPUID_REGISTERS, *PCPUID_REGISTERS;
|
|||||||
typedef struct _CPUID_SIGNATURE CPUID_SIGNATURE, *PCPUID_SIGNATURE;
|
typedef struct _CPUID_SIGNATURE CPUID_SIGNATURE, *PCPUID_SIGNATURE;
|
||||||
typedef struct _FLOATING_SAVE_AREA FLOATING_SAVE_AREA, *PFLOATING_SAVE_AREA;
|
typedef struct _FLOATING_SAVE_AREA FLOATING_SAVE_AREA, *PFLOATING_SAVE_AREA;
|
||||||
typedef struct _HARDWARE_PTE HARDWARE_PTE, *PHARDWARE_PTE;
|
typedef struct _HARDWARE_PTE HARDWARE_PTE, *PHARDWARE_PTE;
|
||||||
typedef struct _HPET_REGISTERS HPET_REGISTERS, *PHPET_REGISTERS;
|
|
||||||
typedef struct _IOAPIC_DATA IOAPIC_DATA, *PIOAPIC_DATA;
|
|
||||||
typedef struct _KDESCRIPTOR KDESCRIPTOR, *PKDESCRIPTOR;
|
typedef struct _KDESCRIPTOR KDESCRIPTOR, *PKDESCRIPTOR;
|
||||||
typedef struct _KEXCEPTION_FRAME KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;
|
typedef struct _KEXCEPTION_FRAME KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;
|
||||||
typedef struct _KGDTENTRY KGDTENTRY, *PKGDTENTRY;
|
typedef struct _KGDTENTRY KGDTENTRY, *PKGDTENTRY;
|
||||||
@@ -73,14 +63,12 @@ typedef struct _MMPTE_SUBSECTION MMPTE_SUBSECTION, *PMMPTE_SUBSECTION;
|
|||||||
typedef struct _MMPTE_TRANSITION MMPTE_TRANSITION, *PMMPTE_TRANSITION;
|
typedef struct _MMPTE_TRANSITION MMPTE_TRANSITION, *PMMPTE_TRANSITION;
|
||||||
typedef struct _POOL_DESCRIPTOR POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
typedef struct _POOL_DESCRIPTOR POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
||||||
typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
||||||
typedef struct _TIMER_CAPABILITIES TIMER_CAPABILITIES, *PTIMER_CAPABILITIES;
|
|
||||||
|
|
||||||
/* Unions forward references */
|
/* Unions forward references */
|
||||||
typedef union _APIC_BASE_REGISTER APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER;
|
typedef union _APIC_BASE_REGISTER APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER;
|
||||||
typedef union _APIC_COMMAND_REGISTER APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGISTER;
|
typedef union _APIC_COMMAND_REGISTER APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGISTER;
|
||||||
typedef union _APIC_LVT_REGISTER APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER;
|
typedef union _APIC_LVT_REGISTER APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER;
|
||||||
typedef union _APIC_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
|
typedef union _APIC_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
|
||||||
typedef union _IOAPIC_REDIRECTION_REGISTER IOAPIC_REDIRECTION_REGISTER, *PIOAPIC_REDIRECTION_REGISTER;
|
|
||||||
typedef union _MMPTE MMP5E, *PMMP5E;
|
typedef union _MMPTE MMP5E, *PMMP5E;
|
||||||
typedef union _MMPTE MMPDE, *PMMPDE;
|
typedef union _MMPTE MMPDE, *PMMPDE;
|
||||||
typedef union _MMPTE MMPPE, *PMMPPE;
|
typedef union _MMPTE MMPPE, *PMMPPE;
|
||||||
@@ -91,5 +79,4 @@ typedef union _PIC_I8259_ICW2 PIC_I8259_ICW2, *PPIC_I8259_ICW2;
|
|||||||
typedef union _PIC_I8259_ICW3 PIC_I8259_ICW3, *PPIC_I8259_ICW3;
|
typedef union _PIC_I8259_ICW3 PIC_I8259_ICW3, *PPIC_I8259_ICW3;
|
||||||
typedef union _PIC_I8259_ICW4 PIC_I8259_ICW4, *PPIC_I8259_ICW4;
|
typedef union _PIC_I8259_ICW4 PIC_I8259_ICW4, *PPIC_I8259_ICW4;
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_AMD64_XTSTRUCT_H */
|
#endif /* __XTDK_AMD64_XTSTRUCT_H */
|
||||||
|
|||||||
@@ -13,9 +13,6 @@
|
|||||||
#include <xtuefi.h>
|
#include <xtuefi.h>
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef D__XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* XT BootLoader routines forward references */
|
/* XT BootLoader routines forward references */
|
||||||
XTCLINK
|
XTCLINK
|
||||||
XTCDECL
|
XTCDECL
|
||||||
@@ -24,5 +21,4 @@ BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable,
|
|||||||
IN EFI_HANDLE ImageHandle,
|
IN EFI_HANDLE ImageHandle,
|
||||||
OUT PXTBL_LOADER_PROTOCOL *ProtocolHandler);
|
OUT PXTBL_LOADER_PROTOCOL *ProtocolHandler);
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_BLFUNCS_H */
|
#endif /* __XTDK_BLFUNCS_H */
|
||||||
|
|||||||
@@ -29,10 +29,6 @@
|
|||||||
#define XTBL_DEBUGPORT_SCREEN 1
|
#define XTBL_DEBUGPORT_SCREEN 1
|
||||||
#define XTBL_DEBUGPORT_SERIAL 2
|
#define XTBL_DEBUGPORT_SERIAL 2
|
||||||
|
|
||||||
/* XTLDR Shell definitions */
|
|
||||||
#define XTBL_SH_MAX_LINE_LENGTH 256
|
|
||||||
#define XTBL_SH_HISTORY_ENTRIES 20
|
|
||||||
|
|
||||||
/* TUI dialog box attributes */
|
/* TUI dialog box attributes */
|
||||||
#define XTBL_TUI_DIALOG_GENERIC_BOX 1
|
#define XTBL_TUI_DIALOG_GENERIC_BOX 1
|
||||||
#define XTBL_TUI_DIALOG_ERROR_BOX 2
|
#define XTBL_TUI_DIALOG_ERROR_BOX 2
|
||||||
@@ -45,10 +41,6 @@
|
|||||||
/* TUI dialog box maximum width */
|
/* TUI dialog box maximum width */
|
||||||
#define XTBL_TUI_MAX_DIALOG_WIDTH 100
|
#define XTBL_TUI_MAX_DIALOG_WIDTH 100
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef D__XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* XTLDR Routine pointers */
|
/* XTLDR Routine pointers */
|
||||||
typedef LOADER_MEMORY_TYPE (XTCDECL *PBL_GET_MEMTYPE_ROUTINE)(IN EFI_MEMORY_TYPE EfiMemoryType);
|
typedef LOADER_MEMORY_TYPE (XTCDECL *PBL_GET_MEMTYPE_ROUTINE)(IN EFI_MEMORY_TYPE EfiMemoryType);
|
||||||
|
|
||||||
@@ -77,7 +69,7 @@ typedef VOID (XTCDECL *PBL_CONSOLE_DISABLE_CURSOR)();
|
|||||||
typedef VOID (XTCDECL *PBL_CONSOLE_ENABLE_CURSOR)();
|
typedef VOID (XTCDECL *PBL_CONSOLE_ENABLE_CURSOR)();
|
||||||
typedef VOID (XTCDECL *PBL_CONSOLE_PRINT)(IN PCWSTR Format, IN ...);
|
typedef VOID (XTCDECL *PBL_CONSOLE_PRINT)(IN PCWSTR Format, IN ...);
|
||||||
typedef VOID (XTCDECL *PBL_CONSOLE_QUERY_MODE)(OUT PUINT_PTR ResX, OUT PUINT_PTR ResY);
|
typedef VOID (XTCDECL *PBL_CONSOLE_QUERY_MODE)(OUT PUINT_PTR ResX, OUT PUINT_PTR ResY);
|
||||||
typedef EFI_STATUS (XTCDECL *PBL_CONSOLE_READ_KEY_STROKE)(OUT PEFI_INPUT_KEY Key);
|
typedef VOID (XTCDECL *PBL_CONSOLE_READ_KEY_STROKE)(OUT PEFI_INPUT_KEY Key);
|
||||||
typedef VOID (XTCDECL *PBL_CONSOLE_RESET_INPUT_BUFFER)();
|
typedef VOID (XTCDECL *PBL_CONSOLE_RESET_INPUT_BUFFER)();
|
||||||
typedef VOID (XTCDECL *PBL_CONSOLE_SET_ATTRIBUTES)(IN ULONGLONG Attributes);
|
typedef VOID (XTCDECL *PBL_CONSOLE_SET_ATTRIBUTES)(IN ULONGLONG Attributes);
|
||||||
typedef VOID (XTCDECL *PBL_CONSOLE_SET_CURSOR_POSITION)(IN ULONGLONG PosX, IN ULONGLONG PosY);
|
typedef VOID (XTCDECL *PBL_CONSOLE_SET_CURSOR_POSITION)(IN ULONGLONG PosX, IN ULONGLONG PosY);
|
||||||
@@ -147,8 +139,6 @@ typedef XTSTATUS (XTAPI *PBL_WIDESTRING_FORMAT)(IN PRTL_PRINT_CONTEXT Context, I
|
|||||||
typedef SIZE_T (XTAPI *PBL_WIDESTRING_LENGTH)(IN PCWSTR String, IN SIZE_T MaxLength);
|
typedef SIZE_T (XTAPI *PBL_WIDESTRING_LENGTH)(IN PCWSTR String, IN SIZE_T MaxLength);
|
||||||
typedef PWCHAR (XTAPI *PBL_WIDESTRING_TOKENIZE)(IN PWCHAR String, IN PCWSTR Delimiter, IN OUT PWCHAR *SavePtr);
|
typedef PWCHAR (XTAPI *PBL_WIDESTRING_TOKENIZE)(IN PWCHAR String, IN PCWSTR Delimiter, IN OUT PWCHAR *SavePtr);
|
||||||
typedef EFI_STATUS (XTCDECL *PBL_WAIT_FOR_EFI_EVENT)(IN UINT_PTR NumberOfEvents, IN PEFI_EVENT Event, OUT PUINT_PTR Index);
|
typedef EFI_STATUS (XTCDECL *PBL_WAIT_FOR_EFI_EVENT)(IN UINT_PTR NumberOfEvents, IN PEFI_EVENT Event, OUT PUINT_PTR Index);
|
||||||
typedef VOID (XTCDECL *PBL_SHELL_COMMAND)(IN ULONG Argc, IN PWCHAR *Argv);
|
|
||||||
typedef EFI_STATUS (XTCDECL *PBL_REGISTER_SHELL_COMMAND)(IN PCWSTR Command, IN PCWSTR Description, IN PBL_SHELL_COMMAND Handler);
|
|
||||||
typedef VOID (XTCDECL *PBL_XT_BOOT_MENU)();
|
typedef VOID (XTCDECL *PBL_XT_BOOT_MENU)();
|
||||||
typedef VOID (XTAPI *PBL_ZERO_MEMORY)(OUT PVOID Destination, IN SIZE_T Length);
|
typedef VOID (XTAPI *PBL_ZERO_MEMORY)(OUT PVOID Destination, IN SIZE_T Length);
|
||||||
|
|
||||||
@@ -239,15 +229,6 @@ typedef struct _XTBL_KNOWN_BOOT_PROTOCOL
|
|||||||
EFI_GUID Guid;
|
EFI_GUID Guid;
|
||||||
} XTBL_KNOWN_BOOT_PROTOCOL, *PXTBL_KNOWN_BOOT_PROTOCOL;
|
} XTBL_KNOWN_BOOT_PROTOCOL, *PXTBL_KNOWN_BOOT_PROTOCOL;
|
||||||
|
|
||||||
/* XTLDR Shell command entry */
|
|
||||||
typedef struct _XTBL_SHELL_COMMAND
|
|
||||||
{
|
|
||||||
LIST_ENTRY Flink;
|
|
||||||
PWCHAR Command;
|
|
||||||
PWCHAR Description;
|
|
||||||
PBL_SHELL_COMMAND Handler;
|
|
||||||
} XTBL_SHELL_COMMAND, *PXTBL_SHELL_COMMAND;
|
|
||||||
|
|
||||||
/* Boot Loader memory mapping information */
|
/* Boot Loader memory mapping information */
|
||||||
typedef struct _XTBL_MEMORY_MAPPING
|
typedef struct _XTBL_MEMORY_MAPPING
|
||||||
{
|
{
|
||||||
@@ -497,10 +478,6 @@ typedef struct _XTBL_LOADER_PROTOCOL
|
|||||||
PBL_OPEN_PROTOCOL_HANDLE OpenHandle;
|
PBL_OPEN_PROTOCOL_HANDLE OpenHandle;
|
||||||
} Protocol;
|
} Protocol;
|
||||||
struct
|
struct
|
||||||
{
|
|
||||||
PBL_REGISTER_SHELL_COMMAND RegisterCommand;
|
|
||||||
} Shell;
|
|
||||||
struct
|
|
||||||
{
|
{
|
||||||
PBL_STRING_COMPARE Compare;
|
PBL_STRING_COMPARE Compare;
|
||||||
PBL_STRING_LENGTH Length;
|
PBL_STRING_LENGTH Length;
|
||||||
@@ -543,5 +520,4 @@ typedef struct _XTBL_LOADER_PROTOCOL
|
|||||||
} WideString;
|
} WideString;
|
||||||
} XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL;
|
} XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL;
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_BLTYPES_H */
|
#endif /* __XTDK_BLTYPES_H */
|
||||||
|
|||||||
@@ -13,9 +13,6 @@
|
|||||||
#include <xttypes.h>
|
#include <xttypes.h>
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Kernel Executive routines forward references */
|
/* Kernel Executive routines forward references */
|
||||||
XTCLINK
|
XTCLINK
|
||||||
XTFASTCALL
|
XTFASTCALL
|
||||||
@@ -47,5 +44,4 @@ XTFASTCALL
|
|||||||
VOID
|
VOID
|
||||||
ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor);
|
ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor);
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_EXFUNCS_H */
|
#endif /* __XTDK_EXFUNCS_H */
|
||||||
|
|||||||
@@ -17,10 +17,6 @@
|
|||||||
/* Rundown protection flags */
|
/* Rundown protection flags */
|
||||||
#define EX_RUNDOWN_ACTIVE 0x1
|
#define EX_RUNDOWN_ACTIVE 0x1
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Executive rundown protection structure definition */
|
/* Executive rundown protection structure definition */
|
||||||
typedef struct _EX_RUNDOWN_REFERENCE
|
typedef struct _EX_RUNDOWN_REFERENCE
|
||||||
{
|
{
|
||||||
@@ -38,5 +34,4 @@ typedef struct _EX_RUNDOWN_WAIT_BLOCK
|
|||||||
KEVENT WakeEvent;
|
KEVENT WakeEvent;
|
||||||
} EX_RUNDOWN_WAIT_BLOCK, *PEX_RUNDOWN_WAIT_BLOCK;
|
} EX_RUNDOWN_WAIT_BLOCK, *PEX_RUNDOWN_WAIT_BLOCK;
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_EXTYPES_H */
|
#endif /* __XTDK_EXTYPES_H */
|
||||||
|
|||||||
@@ -14,15 +14,7 @@
|
|||||||
#include <xttypes.h>
|
#include <xttypes.h>
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Hardware layer routines forward references */
|
/* Hardware layer routines forward references */
|
||||||
XTCLINK
|
|
||||||
XTAPI
|
|
||||||
LARGE_INTEGER
|
|
||||||
HlQueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceFrequency);
|
|
||||||
|
|
||||||
XTCLINK
|
XTCLINK
|
||||||
XTAPI
|
XTAPI
|
||||||
UCHAR
|
UCHAR
|
||||||
@@ -38,11 +30,6 @@ XTAPI
|
|||||||
ULONG
|
ULONG
|
||||||
HlReadRegister32(IN PVOID Register);
|
HlReadRegister32(IN PVOID Register);
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTAPI
|
|
||||||
ULONG
|
|
||||||
HlSetClockRate(IN ULONG Rate);
|
|
||||||
|
|
||||||
XTCLINK
|
XTCLINK
|
||||||
XTAPI
|
XTAPI
|
||||||
VOID
|
VOID
|
||||||
@@ -61,5 +48,4 @@ VOID
|
|||||||
HlWriteRegister32(IN PVOID Register,
|
HlWriteRegister32(IN PVOID Register,
|
||||||
IN ULONG Value);
|
IN ULONG Value);
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_HLFUNCS_H */
|
#endif /* __XTDK_HLFUNCS_H */
|
||||||
|
|||||||
@@ -64,8 +64,8 @@
|
|||||||
#define ACPI_FADT_32BIT_TIMER (1<<8)
|
#define ACPI_FADT_32BIT_TIMER (1<<8)
|
||||||
|
|
||||||
/* ACPI Timer bit masks */
|
/* ACPI Timer bit masks */
|
||||||
#define ACPI_FADT_TIMER_32BIT 0xFFFFFFFF
|
#define ACPI_FADT_TIMER_32BIT 0x80000000
|
||||||
#define ACPI_FADT_TIMER_24BIT 0x00FFFFFF
|
#define ACPI_FADT_TIMER_24BIT 0x00800000
|
||||||
|
|
||||||
/* ACPI MADT subtable type definitions */
|
/* ACPI MADT subtable type definitions */
|
||||||
#define ACPI_MADT_TYPE_LOCAL_APIC 0
|
#define ACPI_MADT_TYPE_LOCAL_APIC 0
|
||||||
@@ -101,15 +101,6 @@
|
|||||||
#define ACPI_MADT_PLACE_ENABLED 0 /* Processor Local APIC CPU Enabled */
|
#define ACPI_MADT_PLACE_ENABLED 0 /* Processor Local APIC CPU Enabled */
|
||||||
#define ACPI_MADT_PLAOC_ENABLED 1 /* Processor Local APIC Online Capable */
|
#define ACPI_MADT_PLAOC_ENABLED 1 /* Processor Local APIC Online Capable */
|
||||||
|
|
||||||
/* ACPI Timer frequency */
|
|
||||||
#define ACPI_PM_TIMER_FREQUENCY 3579545
|
|
||||||
|
|
||||||
/* ACPI address space definitions */
|
|
||||||
#define ACPI_ADDRESS_SPACE_MEMORY 0x00
|
|
||||||
|
|
||||||
/* Maximum number of cached ACPI tables */
|
|
||||||
#define ACPI_MAX_CACHED_TABLES 32
|
|
||||||
|
|
||||||
/* Default serial port settings */
|
/* Default serial port settings */
|
||||||
#define COMPORT_CLOCK_RATE 0x1C200
|
#define COMPORT_CLOCK_RATE 0x1C200
|
||||||
#define COMPORT_WAIT_TIMEOUT 204800
|
#define COMPORT_WAIT_TIMEOUT 204800
|
||||||
@@ -188,33 +179,6 @@
|
|||||||
#define COMPORT_REG_MSR 0x06 /* Modem Status Register */
|
#define COMPORT_REG_MSR 0x06 /* Modem Status Register */
|
||||||
#define COMPORT_REG_SR 0x07 /* Scratch Register */
|
#define COMPORT_REG_SR 0x07 /* Scratch Register */
|
||||||
|
|
||||||
/* Standard system clock rates (in 100-nanosecond units)*/
|
|
||||||
#define HL_CLOCK_RATE_1000HZ 10000 /* 1 ms (1000 Hz) - Best Performance */
|
|
||||||
#define HL_CLOCK_RATE_500HZ 20000 /* 2 ms (500 Hz) - High Responsiveness */
|
|
||||||
#define HL_CLOCK_RATE_300HZ 33333 /* 3.33ms (300 Hz) - Multimedia Sync */
|
|
||||||
#define HL_CLOCK_RATE_250HZ 40000 /* 4 ms (250 Hz) - Optimal Balance */
|
|
||||||
#define HL_CLOCK_RATE_100HZ 100000 /* 10 ms (100 Hz) - Power Saving */
|
|
||||||
#define HL_CLOCK_RATE_50HZ 200000 /* 20 ms (50 Hz) - Deep Power Saving */
|
|
||||||
|
|
||||||
/* Minimum and maximum system clock rate definitions */
|
|
||||||
#define HL_MINIMUM_CLOCK_RATE HL_CLOCK_RATE_1000HZ
|
|
||||||
#define HL_MAXIMUM_CLOCK_RATE HL_CLOCK_RATE_50HZ
|
|
||||||
|
|
||||||
/* Minimum and maximum profile intervals */
|
|
||||||
#define MIN_PROFILE_INTERVAL 10000
|
|
||||||
#define MAX_PROFILE_INTERVAL 10000000
|
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Hardware Layer routine callbacks */
|
|
||||||
typedef XTSTATUS (XTAPI *PHALP_INITIALIZE_CLOCK)(VOID);
|
|
||||||
typedef ULONGLONG (XTAPI *PHALP_QUERY_PERF_COUNTER)(VOID);
|
|
||||||
typedef ULONG (XTAPI *PHALP_QUERY_TIME_DELTA)(VOID);
|
|
||||||
typedef ULONG (XTAPI *PHALP_SET_CLOCK_RATE)(IN ULONG Increment);
|
|
||||||
typedef VOID (XTAPI *PHALP_STALL_EXECUTION)(IN ULONG MicroSeconds);
|
|
||||||
|
|
||||||
/* Generic Address structure */
|
/* Generic Address structure */
|
||||||
typedef struct _GENERIC_ADDRESS
|
typedef struct _GENERIC_ADDRESS
|
||||||
{
|
{
|
||||||
@@ -250,7 +214,7 @@ typedef struct _ACPI_SUBTABLE_HEADER
|
|||||||
typedef struct _ACPI_CACHE_LIST
|
typedef struct _ACPI_CACHE_LIST
|
||||||
{
|
{
|
||||||
LIST_ENTRY ListEntry;
|
LIST_ENTRY ListEntry;
|
||||||
PACPI_DESCRIPTION_HEADER Table;
|
ACPI_DESCRIPTION_HEADER Header;
|
||||||
} ACPI_CACHE_LIST, *PACPI_CACHE_LIST;
|
} ACPI_CACHE_LIST, *PACPI_CACHE_LIST;
|
||||||
|
|
||||||
/* ACPI Root System Description Table Pointer (RSDP) structure */
|
/* ACPI Root System Description Table Pointer (RSDP) structure */
|
||||||
@@ -341,17 +305,6 @@ typedef struct _ACPI_FADT
|
|||||||
GENERIC_ADDRESS SleepStatusReg;
|
GENERIC_ADDRESS SleepStatusReg;
|
||||||
} PACKED ACPI_FADT, *PACPI_FADT;
|
} PACKED ACPI_FADT, *PACPI_FADT;
|
||||||
|
|
||||||
/* ACPI High Precision Event Timer (HPET) table structure */
|
|
||||||
typedef struct _ACPI_HPET
|
|
||||||
{
|
|
||||||
ACPI_DESCRIPTION_HEADER Header;
|
|
||||||
ULONG EventTimerBlockId;
|
|
||||||
GENERIC_ADDRESS BaseAddress;
|
|
||||||
UCHAR HpetNumber;
|
|
||||||
USHORT MinimumTick;
|
|
||||||
UCHAR PageProtectionAndOem;
|
|
||||||
} PACKED ACPI_HPET, *PACPI_HPET;
|
|
||||||
|
|
||||||
/* ACPI Multiple APIC Description Table (MADT) structure */
|
/* ACPI Multiple APIC Description Table (MADT) structure */
|
||||||
typedef struct _ACPI_MADT
|
typedef struct _ACPI_MADT
|
||||||
{
|
{
|
||||||
@@ -361,26 +314,6 @@ typedef struct _ACPI_MADT
|
|||||||
ULONG ApicTables[];
|
ULONG ApicTables[];
|
||||||
} PACKED ACPI_MADT, *PACPI_MADT;
|
} PACKED ACPI_MADT, *PACPI_MADT;
|
||||||
|
|
||||||
/* ACPI Interrupt Override MADT subtable structure */
|
|
||||||
typedef struct _ACPI_MADT_INTERRUPT_OVERRIDE
|
|
||||||
{
|
|
||||||
ACPI_SUBTABLE_HEADER Header;
|
|
||||||
UCHAR Bus;
|
|
||||||
UCHAR SourceIrq;
|
|
||||||
ULONG GlobalSystemInterrupt;
|
|
||||||
USHORT Flags;
|
|
||||||
} PACKED ACPI_MADT_INTERRUPT_OVERRIDE, *PACPI_MADT_INTERRUPT_OVERRIDE;
|
|
||||||
|
|
||||||
/* ACPI IO APIC MADT subtable structure */
|
|
||||||
typedef struct _ACPI_MADT_IOAPIC
|
|
||||||
{
|
|
||||||
ACPI_SUBTABLE_HEADER Header;
|
|
||||||
UCHAR IoApicId;
|
|
||||||
UCHAR Reserved;
|
|
||||||
ULONG IoApicAddress;
|
|
||||||
ULONG GlobalIrqBase;
|
|
||||||
} PACKED ACPI_MADT_IOAPIC, *PACPI_MADT_IOAPIC;
|
|
||||||
|
|
||||||
/* ACPI Local APIC MADT subtable structure */
|
/* ACPI Local APIC MADT subtable structure */
|
||||||
typedef struct _ACPI_MADT_LOCAL_APIC
|
typedef struct _ACPI_MADT_LOCAL_APIC
|
||||||
{
|
{
|
||||||
@@ -517,15 +450,4 @@ typedef struct _SMBIOS3_TABLE_HEADER
|
|||||||
ULONGLONG TableAddress;
|
ULONGLONG TableAddress;
|
||||||
} SMBIOS3_TABLE_HEADER, *PSMBIOS3_TABLE_HEADER;
|
} SMBIOS3_TABLE_HEADER, *PSMBIOS3_TABLE_HEADER;
|
||||||
|
|
||||||
/* Timer dispatch table */
|
|
||||||
typedef struct _TIMER_ROUTINES
|
|
||||||
{
|
|
||||||
PHALP_INITIALIZE_CLOCK InitializeClock;
|
|
||||||
PHALP_QUERY_PERF_COUNTER QueryPerformanceCounter;
|
|
||||||
PHALP_QUERY_TIME_DELTA QueryTimeDelta;
|
|
||||||
PHALP_SET_CLOCK_RATE SetClockRate;
|
|
||||||
PHALP_STALL_EXECUTION StallExecution;
|
|
||||||
} TIMER_ROUTINES, *PTIMER_ROUTINES;
|
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_HLTYPES_H */
|
#endif /* __XTDK_HLTYPES_H */
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
#include <xtdefs.h>
|
#include <xtdefs.h>
|
||||||
#include <xtstruct.h>
|
#include <xtstruct.h>
|
||||||
#include <xttypes.h>
|
#include <xttypes.h>
|
||||||
#include ARCH_HEADER(xtstruct.h)
|
|
||||||
|
|
||||||
|
|
||||||
/* Control Register 0 constants */
|
/* Control Register 0 constants */
|
||||||
@@ -93,10 +92,6 @@
|
|||||||
#define X86_EFLAGS_VIP_MASK 0x00100000 /* Virtual Interrupt Pending */
|
#define X86_EFLAGS_VIP_MASK 0x00100000 /* Virtual Interrupt Pending */
|
||||||
#define X86_EFLAGS_ID_MASK 0x00200000 /* Identification */
|
#define X86_EFLAGS_ID_MASK 0x00200000 /* Identification */
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* CPU vendor enumeration list */
|
/* CPU vendor enumeration list */
|
||||||
typedef enum _CPU_VENDOR
|
typedef enum _CPU_VENDOR
|
||||||
{
|
{
|
||||||
@@ -105,18 +100,6 @@ typedef enum _CPU_VENDOR
|
|||||||
CPU_VENDOR_UNKNOWN = 0xFFFFFFFF
|
CPU_VENDOR_UNKNOWN = 0xFFFFFFFF
|
||||||
} CPU_VENDOR, *PCPU_VENDOR;
|
} CPU_VENDOR, *PCPU_VENDOR;
|
||||||
|
|
||||||
/* CPUID advanced power management features (0x80000007) enumeration list */
|
|
||||||
typedef enum _CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT
|
|
||||||
{
|
|
||||||
CPUID_FEATURES_EDX_TS = 1 << 0, /* Temperature Sensor */
|
|
||||||
CPUID_FEATURES_EDX_FIS = 1 << 1, /* Frequency ID Selection */
|
|
||||||
CPUID_FEATURES_EDX_VIS = 1 << 2, /* Voltage ID Selection */
|
|
||||||
CPUID_FEATURES_EDX_TTS = 1 << 3, /* ThermaTrip Support */
|
|
||||||
CPUID_FEATURES_EDX_HTC = 1 << 4, /* Hardware Thermal Throttling */
|
|
||||||
CPUID_FEATURES_EDX_STC = 1 << 5, /* Software Thermal Throttling */
|
|
||||||
CPUID_FEATURES_EDX_TSCI = 1 << 8 /* TSC Invariant */
|
|
||||||
} CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT, *PCPUID_FEATURES_ADVANCED_POWER_MANAGEMENT;
|
|
||||||
|
|
||||||
/* CPUID extended features (0x80000001) enumeration list */
|
/* CPUID extended features (0x80000001) enumeration list */
|
||||||
typedef enum _CPUID_FEATURES_EXTENDED
|
typedef enum _CPUID_FEATURES_EXTENDED
|
||||||
{
|
{
|
||||||
@@ -158,23 +141,6 @@ typedef enum _CPUID_FEATURES_EXTENDED
|
|||||||
CPUID_FEATURES_EDX_3DNOW = 1 << 31
|
CPUID_FEATURES_EDX_3DNOW = 1 << 31
|
||||||
} CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
|
} CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
|
||||||
|
|
||||||
/* CPUID Thermal and Power Management features (0x00000006) enumeration list */
|
|
||||||
typedef enum _CPUID_FEATURES_POWER_MANAGEMENT
|
|
||||||
{
|
|
||||||
CPUID_FEATURES_EAX_DTHERM = 1 << 0,
|
|
||||||
CPUID_FEATURES_EAX_IDA = 1 << 1,
|
|
||||||
CPUID_FEATURES_EAX_ARAT = 1 << 2,
|
|
||||||
CPUID_FEATURES_EAX_PLN = 1 << 4,
|
|
||||||
CPUID_FEATURES_EAX_PTS = 1 << 6,
|
|
||||||
CPUID_FEATURES_EAX_HWP = 1 << 7,
|
|
||||||
CPUID_FEATURES_EAX_HWP_NOTIFY = 1 << 8,
|
|
||||||
CPUID_FEATURES_EAX_HWP_ACT_WINDOW = 1 << 9,
|
|
||||||
CPUID_FEATURES_EAX_HWP_EPP = 1 << 10,
|
|
||||||
CPUID_FEATURES_EAX_HWP_PKG_REQ = 1 << 11,
|
|
||||||
CPUID_FEATURES_EAX_HWP_HIGHEST_PERF_CHANGE = 1 << 15,
|
|
||||||
CPUID_FEATURES_EAX_HFI = 1 << 19
|
|
||||||
} CPUID_FEATURES_LEAF6, *PCPUID_FEATURES_LEAF6;
|
|
||||||
|
|
||||||
/* CPUID STD1 features (0x00000001) enumeration list */
|
/* CPUID STD1 features (0x00000001) enumeration list */
|
||||||
typedef enum _CPUID_FEATURES_STANDARD1
|
typedef enum _CPUID_FEATURES_STANDARD1
|
||||||
{
|
{
|
||||||
@@ -201,7 +167,7 @@ typedef enum _CPUID_FEATURES_STANDARD1
|
|||||||
CPUID_FEATURES_ECX_X2APIC = 1 << 21,
|
CPUID_FEATURES_ECX_X2APIC = 1 << 21,
|
||||||
CPUID_FEATURES_ECX_MOVBE = 1 << 22,
|
CPUID_FEATURES_ECX_MOVBE = 1 << 22,
|
||||||
CPUID_FEATURES_ECX_POPCNT = 1 << 23,
|
CPUID_FEATURES_ECX_POPCNT = 1 << 23,
|
||||||
CPUID_FEATURES_ECX_TSC_DEADLINE = 1 << 24,
|
CPUID_FEATURES_ECX_TSC = 1 << 24,
|
||||||
CPUID_FEATURES_ECX_AES = 1 << 25,
|
CPUID_FEATURES_ECX_AES = 1 << 25,
|
||||||
CPUID_FEATURES_ECX_XSAVE = 1 << 26,
|
CPUID_FEATURES_ECX_XSAVE = 1 << 26,
|
||||||
CPUID_FEATURES_ECX_OSXSAVE = 1 << 27,
|
CPUID_FEATURES_ECX_OSXSAVE = 1 << 27,
|
||||||
@@ -375,29 +341,20 @@ typedef enum _CPUID_FEATURES_STANDARD7_LEAF1
|
|||||||
/* CPUID requests */
|
/* CPUID requests */
|
||||||
typedef enum _CPUID_REQUESTS
|
typedef enum _CPUID_REQUESTS
|
||||||
{
|
{
|
||||||
CPUID_GET_VENDOR_STRING = 0x00000000,
|
CPUID_GET_VENDOR_STRING,
|
||||||
CPUID_GET_STANDARD1_FEATURES = 0x00000001,
|
CPUID_GET_STANDARD1_FEATURES,
|
||||||
CPUID_GET_TLB_CACHE = 0x00000002,
|
CPUID_GET_TLB_CACHE,
|
||||||
CPUID_GET_SERIAL = 0x00000003,
|
CPUID_GET_SERIAL,
|
||||||
CPUID_GET_CACHE_TOPOLOGY = 0x00000004,
|
CPUID_GET_CACHE_TOPOLOGY,
|
||||||
CPUID_GET_MONITOR_MWAIT = 0x00000005,
|
CPUID_GET_MONITOR_MWAIT,
|
||||||
CPUID_GET_POWER_MANAGEMENT = 0x00000006,
|
CPUID_GET_POWER_MANAGEMENT,
|
||||||
CPUID_GET_STANDARD7_FEATURES = 0x00000007,
|
CPUID_GET_STANDARD7_FEATURES
|
||||||
CPUID_GET_TSC_CRYSTAL_CLOCK = 0x00000015,
|
|
||||||
CPUID_GET_EXTENDED_MAX = 0x80000000,
|
|
||||||
CPUID_GET_EXTENDED_FEATURES = 0x80000001,
|
|
||||||
CPUID_GET_ADVANCED_POWER_MANAGEMENT = 0x80000007
|
|
||||||
} CPUID_REQUESTS, *PCPUID_REQUESTS;
|
} CPUID_REQUESTS, *PCPUID_REQUESTS;
|
||||||
|
|
||||||
/* Interrupt handler */
|
|
||||||
typedef VOID (*PINTERRUPT_HANDLER)(PKTRAP_FRAME TrapFrame);
|
|
||||||
|
|
||||||
/* Processor identification information */
|
/* Processor identification information */
|
||||||
typedef struct _CPU_IDENTIFICATION
|
typedef struct _CPU_IDENTIFICATION
|
||||||
{
|
{
|
||||||
ULONGLONG ExtendedFeatureBits;
|
|
||||||
USHORT Family;
|
USHORT Family;
|
||||||
ULONGLONG FeatureBits;
|
|
||||||
USHORT Model;
|
USHORT Model;
|
||||||
USHORT Stepping;
|
USHORT Stepping;
|
||||||
CPU_VENDOR Vendor;
|
CPU_VENDOR Vendor;
|
||||||
@@ -433,5 +390,4 @@ typedef enum _TRAMPOLINE_TYPE
|
|||||||
TrampolineApStartup
|
TrampolineApStartup
|
||||||
} TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;
|
} TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_I686_ARTYPES_H */
|
#endif /* __XTDK_I686_ARTYPES_H */
|
||||||
|
|||||||
@@ -15,9 +15,6 @@
|
|||||||
#include <i686/xtstruct.h>
|
#include <i686/xtstruct.h>
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Hardware layer routines forward references */
|
/* Hardware layer routines forward references */
|
||||||
XTCLINK
|
XTCLINK
|
||||||
XTCDECL
|
XTCDECL
|
||||||
@@ -52,5 +49,4 @@ VOID
|
|||||||
HlWritePort32(IN USHORT Port,
|
HlWritePort32(IN USHORT Port,
|
||||||
IN ULONG Value);
|
IN ULONG Value);
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_I686_HLFUNCS_H */
|
#endif /* __XTDK_I686_HLFUNCS_H */
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
#ifndef __XTDK_I686_HLTYPES_H
|
#ifndef __XTDK_I686_HLTYPES_H
|
||||||
#define __XTDK_I686_HLTYPES_H
|
#define __XTDK_I686_HLTYPES_H
|
||||||
|
|
||||||
#include <xtbase.h>
|
|
||||||
#include <xtdefs.h>
|
#include <xtdefs.h>
|
||||||
#include <xtstruct.h>
|
#include <xtstruct.h>
|
||||||
#include <xttypes.h>
|
#include <xttypes.h>
|
||||||
@@ -37,7 +36,6 @@
|
|||||||
#define APIC_VECTOR_GENERIC 0xC1
|
#define APIC_VECTOR_GENERIC 0xC1
|
||||||
#define APIC_VECTOR_SYNC 0xC1
|
#define APIC_VECTOR_SYNC 0xC1
|
||||||
#define APIC_VECTOR_CLOCK 0xD1
|
#define APIC_VECTOR_CLOCK 0xD1
|
||||||
#define APIC_VECTOR_CLOCK_IPI 0xD2
|
|
||||||
#define APIC_VECTOR_IPI 0xE1
|
#define APIC_VECTOR_IPI 0xE1
|
||||||
#define APIC_VECTOR_ERROR 0xE3
|
#define APIC_VECTOR_ERROR 0xE3
|
||||||
#define APIC_VECTOR_POWERFAIL 0xEF
|
#define APIC_VECTOR_POWERFAIL 0xEF
|
||||||
@@ -60,27 +58,6 @@
|
|||||||
/* Maximum number of I/O APICs */
|
/* Maximum number of I/O APICs */
|
||||||
#define APIC_MAX_IOAPICS 64
|
#define APIC_MAX_IOAPICS 64
|
||||||
|
|
||||||
/* I/O APIC base address */
|
|
||||||
#define IOAPIC_DEFAULT_BASE 0xFEC00000
|
|
||||||
|
|
||||||
/* I/O APIC definitions */
|
|
||||||
#define IOAPIC_MAX_CONTROLLERS 64
|
|
||||||
#define IOAPIC_MAX_OVERRIDES 16
|
|
||||||
#define IOAPIC_RTE_MASKED 0x100FF
|
|
||||||
#define IOAPIC_RTE_SIZE 2
|
|
||||||
#define IOAPIC_VECTOR_FREE 0xFF
|
|
||||||
#define IOAPIC_VECTOR_RESERVED 0xFE
|
|
||||||
|
|
||||||
/* IOAPIC offsets */
|
|
||||||
#define IOAPIC_IOREGSEL 0x00
|
|
||||||
#define IOAPIC_IOWIN 0x10
|
|
||||||
|
|
||||||
/* IOAPIC registers */
|
|
||||||
#define IOAPIC_ID 0x00
|
|
||||||
#define IOAPIC_VER 0x01
|
|
||||||
#define IOAPIC_ARB 0x02
|
|
||||||
#define IOAPIC_REDTBL 0x10
|
|
||||||
|
|
||||||
/* 8259/ISP PIC ports definitions */
|
/* 8259/ISP PIC ports definitions */
|
||||||
#define PIC1_CONTROL_PORT 0x20
|
#define PIC1_CONTROL_PORT 0x20
|
||||||
#define PIC1_DATA_PORT 0x21
|
#define PIC1_DATA_PORT 0x21
|
||||||
@@ -92,87 +69,6 @@
|
|||||||
/* PIC vector definitions */
|
/* PIC vector definitions */
|
||||||
#define PIC1_VECTOR_SPURIOUS 0x37
|
#define PIC1_VECTOR_SPURIOUS 0x37
|
||||||
|
|
||||||
/* HPET General Capabilities definitions */
|
|
||||||
#define HPET_CAPABILITY_64BIT 0x2000ULL
|
|
||||||
#define HPET_CAPABILITY_LEGACY_REPLACEMENT 0x8000ULL
|
|
||||||
|
|
||||||
/* HPET General Configuration definitions */
|
|
||||||
#define HPET_CONFIG_ENABLE 0x0001ULL
|
|
||||||
#define HPET_CONFIG_LEGACY_REPLACEMENT 0x0002ULL
|
|
||||||
|
|
||||||
/* HPET Timer Configuration definitions */
|
|
||||||
#define HPET_TIMER_CONFIG_LEVEL_TRIGGERED 0x0002ULL
|
|
||||||
#define HPET_TIMER_CONFIG_ENABLED 0x0004ULL
|
|
||||||
#define HPET_TIMER_CONFIG_PERIODIC 0x0008ULL
|
|
||||||
#define HPET_TIMER_CONFIG_SUPPORTS_PERIODIC 0x0010ULL
|
|
||||||
#define HPET_TIMER_CONFIG_SUPPORTS_64BIT 0x0020ULL
|
|
||||||
#define HPET_TIMER_CONFIG_VALUE_ACCUMULATOR 0x0040ULL
|
|
||||||
#define HPET_TIMER_CONFIG_FORCE_32BIT 0x0100ULL
|
|
||||||
#define HPET_TIMER_CONFIG_FSB_ENABLED 0x4000ULL
|
|
||||||
#define HPET_TIMER_CONFIG_SUPPORTS_FSB 0x8000ULL
|
|
||||||
|
|
||||||
/* PIT ports definitions */
|
|
||||||
#define PIT_COMMAND_PORT 0x43
|
|
||||||
#define PIT_DATA_PORT0 0x40
|
|
||||||
#define PIT_DATA_PORT1 0x41
|
|
||||||
#define PIT_DATA_PORT2 0x42
|
|
||||||
|
|
||||||
/* PIT related definitions */
|
|
||||||
#define PIT_BASE_FREQUENCY 1193182
|
|
||||||
|
|
||||||
/* PIT Access Mode: Defines how the CPU reads or writes the counter value */
|
|
||||||
#define PIT_CMD_ACCESS_LATCH 0x00
|
|
||||||
#define PIT_CMD_ACCESS_LOWBYTE_ONLY 0x10
|
|
||||||
#define PIT_CMD_ACCESS_HIGHBYTE_ONLY 0x20
|
|
||||||
#define PIT_CMD_ACCESS_LOWBYTE_HIGHBYTE 0x30
|
|
||||||
|
|
||||||
/* PIT Channel Selection: Specifies the physical timer channel to configure */
|
|
||||||
#define PIT_CMD_CHANNEL0 0x00
|
|
||||||
#define PIT_CMD_CHANNEL1 0x40
|
|
||||||
#define PIT_CMD_CHANNEL2 0x80
|
|
||||||
|
|
||||||
/* PIT Operating Mode: Defines the hardware behavior and the generated waveform */
|
|
||||||
#define PIT_MODE0_INT_ON_TERMINAL_COUNT 0x00
|
|
||||||
#define PIT_MODE1_ONESHOT 0x02
|
|
||||||
#define PIT_MODE2_RATE_GENERATOR 0x04
|
|
||||||
#define PIT_MODE3_SQUARE_WAVE_GEN 0x06
|
|
||||||
#define PIT_MODE4_SOFTWARE_STROBE 0x08
|
|
||||||
#define PIT_MODE5_HARDWARE_STROBE 0x0A
|
|
||||||
|
|
||||||
/* CMOS controller access ports */
|
|
||||||
#define CMOS_SELECT_PORT 0x70
|
|
||||||
#define CMOS_DATA_PORT 0x71
|
|
||||||
|
|
||||||
/* CMOD Select port definitions */
|
|
||||||
#define CMOS_NMI_SELECT 0x80
|
|
||||||
#define CMOS_REGISTER_SECOND 0x00
|
|
||||||
#define CMOS_REGISTER_MINUTE 0x02
|
|
||||||
#define CMOS_REGISTER_HOUR 0x04
|
|
||||||
#define CMOS_REGISTER_WEEKDAY 0x06
|
|
||||||
#define CMOS_REGISTER_DAY 0x07
|
|
||||||
#define CMOS_REGISTER_MONTH 0x08
|
|
||||||
#define CMOS_REGISTER_YEAR 0x09
|
|
||||||
#define CMOS_REGISTER_A 0x0A
|
|
||||||
#define CMOS_REGISTER_B 0x0B
|
|
||||||
#define CMOS_REGISTER_C 0x0C
|
|
||||||
|
|
||||||
/* CMOS Register A definitions */
|
|
||||||
#define CMOS_REGISTER_A_RATE_MASK 0x0F
|
|
||||||
#define CMOS_REGISTER_A_UPDATE_IN_PROGRESS 0x80
|
|
||||||
|
|
||||||
/* CMOS Register B definitions */
|
|
||||||
#define CMOS_REGISTER_B_24_HOUR 0x02
|
|
||||||
#define CMOS_REGISTER_B_BINARY 0x04
|
|
||||||
#define CMOS_REGISTER_B_PERIODIC 0x40
|
|
||||||
#define CMOS_REGISTER_B_SET_CLOCK 0x80
|
|
||||||
|
|
||||||
/* CMOS Register C definitions */
|
|
||||||
#define CMOS_REGISTER_C_PERIODIC 0x40
|
|
||||||
#define CMOS_REGISTER_C_INTERRUPT 0x80
|
|
||||||
|
|
||||||
/* CMOS RTC 24-hour mode */
|
|
||||||
#define CMOS_RTC_POST_MERIDIEM 0x80
|
|
||||||
|
|
||||||
/* Serial ports information */
|
/* Serial ports information */
|
||||||
#define COMPORT_ADDRESS {0x3F8, 0x2F8, 0x3E8, 0x2E8, 0x5F8, 0x4F8, 0x5E8, 0x4E8}
|
#define COMPORT_ADDRESS {0x3F8, 0x2F8, 0x3E8, 0x2E8, 0x5F8, 0x4F8, 0x5E8, 0x4E8}
|
||||||
#define COMPORT_COUNT 8
|
#define COMPORT_COUNT 8
|
||||||
@@ -180,17 +76,6 @@
|
|||||||
/* Initial stall factor */
|
/* Initial stall factor */
|
||||||
#define INITIAL_STALL_FACTOR 100
|
#define INITIAL_STALL_FACTOR 100
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* APIC destination mode enumeration list */
|
|
||||||
typedef enum _APIC_DEST_MODE
|
|
||||||
{
|
|
||||||
APIC_DM_Physical,
|
|
||||||
APIC_DM_Logical
|
|
||||||
} APIC_DEST_MODE, *PAPIC_DEST_MODE;
|
|
||||||
|
|
||||||
/* APIC delivery mode enumeration list */
|
/* APIC delivery mode enumeration list */
|
||||||
typedef enum _APIC_DM
|
typedef enum _APIC_DM
|
||||||
{
|
{
|
||||||
@@ -248,7 +133,6 @@ typedef enum _APIC_REGISTER
|
|||||||
APIC_TICR = 0x38, /* Initial Count Register for Timer */
|
APIC_TICR = 0x38, /* Initial Count Register for Timer */
|
||||||
APIC_TCCR = 0x39, /* Current Count Register for Timer */
|
APIC_TCCR = 0x39, /* Current Count Register for Timer */
|
||||||
APIC_TDCR = 0x3E, /* Timer Divide Configuration Register */
|
APIC_TDCR = 0x3E, /* Timer Divide Configuration Register */
|
||||||
APIC_SIPI = 0x3F, /* Self-IPI Register */
|
|
||||||
APIC_EAFR = 0x40, /* extended APIC Feature register */
|
APIC_EAFR = 0x40, /* extended APIC Feature register */
|
||||||
APIC_EACR = 0x41, /* Extended APIC Control Register */
|
APIC_EACR = 0x41, /* Extended APIC Control Register */
|
||||||
APIC_SEOI = 0x42, /* Specific End Of Interrupt Register */
|
APIC_SEOI = 0x42, /* Specific End Of Interrupt Register */
|
||||||
@@ -258,19 +142,6 @@ typedef enum _APIC_REGISTER
|
|||||||
APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */
|
APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */
|
||||||
} APIC_REGISTER, *PAPIC_REGISTER;
|
} APIC_REGISTER, *PAPIC_REGISTER;
|
||||||
|
|
||||||
/* APIC Timer Divide enumeration list */
|
|
||||||
typedef enum _APIC_TIMER_DIVISOR
|
|
||||||
{
|
|
||||||
TIMER_DivideBy2 = 0,
|
|
||||||
TIMER_DivideBy4 = 1,
|
|
||||||
TIMER_DivideBy8 = 2,
|
|
||||||
TIMER_DivideBy16 = 3,
|
|
||||||
TIMER_DivideBy32 = 8,
|
|
||||||
TIMER_DivideBy64 = 9,
|
|
||||||
TIMER_DivideBy128 = 10,
|
|
||||||
TIMER_DivideBy1 = 11,
|
|
||||||
} APIC_TIMER_DIVISOR, *PAPIC_TIMER_DIVISOR;
|
|
||||||
|
|
||||||
/* I8259 PIC interrupt mode enumeration list */
|
/* I8259 PIC interrupt mode enumeration list */
|
||||||
typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE
|
typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE
|
||||||
{
|
{
|
||||||
@@ -315,17 +186,6 @@ typedef enum _PIC_I8259_ICW4_SYSTEM_MODE
|
|||||||
New8086Mode
|
New8086Mode
|
||||||
} PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;
|
} PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;
|
||||||
|
|
||||||
/* Supported hardware timer backends */
|
|
||||||
typedef enum _TIMER_TYPE
|
|
||||||
{
|
|
||||||
TimerNone,
|
|
||||||
TimerAcpiPm,
|
|
||||||
TimerHpet,
|
|
||||||
TimerLapic,
|
|
||||||
TimerPit,
|
|
||||||
TimerTsc
|
|
||||||
} TIMER_TYPE, *PTIMER_TYPE;
|
|
||||||
|
|
||||||
/* APIC Base Register */
|
/* APIC Base Register */
|
||||||
typedef union _APIC_BASE_REGISTER
|
typedef union _APIC_BASE_REGISTER
|
||||||
{
|
{
|
||||||
@@ -399,40 +259,6 @@ typedef union _APIC_SPURIOUS_REGISTER
|
|||||||
};
|
};
|
||||||
} APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
|
} APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
|
||||||
|
|
||||||
/* I/O APIC Controller information */
|
|
||||||
typedef struct _IOAPIC_DATA
|
|
||||||
{
|
|
||||||
ULONG GsiBase;
|
|
||||||
ULONG Identifier;
|
|
||||||
ULONG LineCount;
|
|
||||||
PHYSICAL_ADDRESS PhysicalAddress;
|
|
||||||
ULONG_PTR VirtualAddress;
|
|
||||||
} IOAPIC_DATA, *PIOAPIC_DATA;
|
|
||||||
|
|
||||||
/* I/O APIC Redirection Register */
|
|
||||||
typedef union _IOAPIC_REDIRECTION_REGISTER
|
|
||||||
{
|
|
||||||
ULONGLONG LongLong;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
UINT Base;
|
|
||||||
UINT Extended;
|
|
||||||
};
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
ULONGLONG Vector:8;
|
|
||||||
ULONGLONG DeliveryMode:3;
|
|
||||||
ULONGLONG DestinationMode:1;
|
|
||||||
ULONGLONG DeliveryStatus:1;
|
|
||||||
ULONGLONG PinPolarity:1;
|
|
||||||
ULONGLONG RemoteIRR:1;
|
|
||||||
ULONGLONG TriggerMode:1;
|
|
||||||
ULONGLONG Mask:1;
|
|
||||||
ULONGLONG Reserved:39;
|
|
||||||
ULONGLONG Destination:8;
|
|
||||||
};
|
|
||||||
} IOAPIC_REDIRECTION_REGISTER, *PIOAPIC_REDIRECTION_REGISTER;
|
|
||||||
|
|
||||||
/* I8259 PIC register structure */
|
/* I8259 PIC register structure */
|
||||||
typedef union _PIC_I8259_ICW1
|
typedef union _PIC_I8259_ICW1
|
||||||
{
|
{
|
||||||
@@ -498,39 +324,4 @@ typedef union _PIC_I8259_ICW4
|
|||||||
UCHAR Bits;
|
UCHAR Bits;
|
||||||
} PIC_I8259_ICW4, *PPIC_I8259_ICW4;
|
} PIC_I8259_ICW4, *PPIC_I8259_ICW4;
|
||||||
|
|
||||||
/* HPET Registers structure definition */
|
|
||||||
typedef struct _HPET_REGISTERS
|
|
||||||
{
|
|
||||||
VOLATILE ULONGLONG GeneralCapabilities;
|
|
||||||
VOLATILE ULONGLONG Reserved0;
|
|
||||||
VOLATILE ULONGLONG GeneralConfiguration;
|
|
||||||
VOLATILE ULONGLONG Reserved1;
|
|
||||||
VOLATILE ULONGLONG GeneralInterruptStatus;
|
|
||||||
VOLATILE ULONGLONG Reserved2;
|
|
||||||
VOLATILE ULONGLONG Reserved3[2][12];
|
|
||||||
VOLATILE ULONGLONG MainCounterValue;
|
|
||||||
VOLATILE ULONGLONG Reserved4;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
VOLATILE ULONGLONG Configuration;
|
|
||||||
VOLATILE ULONGLONG Comparator;
|
|
||||||
VOLATILE ULONGLONG FsbInterruptRoute;
|
|
||||||
VOLATILE ULONGLONG Reserved;
|
|
||||||
} Timers[];
|
|
||||||
} HPET_REGISTERS, *PHPET_REGISTERS;
|
|
||||||
|
|
||||||
/* Hardware timer capabilities and CPU clock features */
|
|
||||||
typedef struct _TIMER_CAPABILITIES
|
|
||||||
{
|
|
||||||
BOOLEAN Arat;
|
|
||||||
BOOLEAN Art;
|
|
||||||
BOOLEAN InvariantTsc;
|
|
||||||
BOOLEAN RDTSCP;
|
|
||||||
ULONG TimerFrequency;
|
|
||||||
BOOLEAN TscDeadline;
|
|
||||||
ULONG TscDenominator;
|
|
||||||
ULONG TscNumerator;
|
|
||||||
} TIMER_CAPABILITIES, *PTIMER_CAPABILITIES;
|
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_I686_HLTYPES_H */
|
#endif /* __XTDK_I686_HLTYPES_H */
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
#define KGDT_DESCRIPTOR_CODE 0x08
|
#define KGDT_DESCRIPTOR_CODE 0x08
|
||||||
|
|
||||||
/* GDT descriptor type codes */
|
/* GDT descriptor type codes */
|
||||||
#define KGDT_TYPE_NONE 0x00
|
#define KGDT_TYPE_NONE 0x0
|
||||||
#define KGDT_TYPE_CODE (0x10 | KGDT_DESCRIPTOR_CODE | KGDT_DESCRIPTOR_EXECUTE_READ)
|
#define KGDT_TYPE_CODE (0x10 | KGDT_DESCRIPTOR_CODE | KGDT_DESCRIPTOR_EXECUTE_READ)
|
||||||
#define KGDT_TYPE_DATA (0x10 | KGDT_DESCRIPTOR_READ_WRITE)
|
#define KGDT_TYPE_DATA (0x10 | KGDT_DESCRIPTOR_READ_WRITE)
|
||||||
|
|
||||||
@@ -82,7 +82,6 @@
|
|||||||
#define KTSS_IO_MAPS 0x68
|
#define KTSS_IO_MAPS 0x68
|
||||||
|
|
||||||
/* I686 Segment Types */
|
/* I686 Segment Types */
|
||||||
#define I686_LDT 0x2
|
|
||||||
#define I686_TASK_GATE 0x5
|
#define I686_TASK_GATE 0x5
|
||||||
#define I686_TSS 0x9
|
#define I686_TSS 0x9
|
||||||
#define I686_ACTIVE_TSS 0xB
|
#define I686_ACTIVE_TSS 0xB
|
||||||
@@ -90,62 +89,6 @@
|
|||||||
#define I686_INTERRUPT_GATE 0xE
|
#define I686_INTERRUPT_GATE 0xE
|
||||||
#define I686_TRAP_GATE 0xF
|
#define I686_TRAP_GATE 0xF
|
||||||
|
|
||||||
/* Kernel CPU Standard Features */
|
|
||||||
#define KCF_VME (1ULL << 0) /* Virtual 8086 Mode Enhancements */
|
|
||||||
#define KCF_LARGE_PAGE (1ULL << 1) /* Page Size Extensions */
|
|
||||||
#define KCF_RDTSC (1ULL << 2) /* Time Stamp Counter */
|
|
||||||
#define KCF_PAE (1ULL << 3) /* Physical Address Extension */
|
|
||||||
#define KCF_MCE (1ULL << 4) /* Machine Check Exception */
|
|
||||||
#define KCF_CMPXCHG8B (1ULL << 5) /* CMPXCHG8B Instruction */
|
|
||||||
#define KCF_APIC (1ULL << 6) /* APIC On-Chip */
|
|
||||||
#define KCF_FAST_SYSCALL (1ULL << 7) /* SYSENTER/SYSEXIT Instructions */
|
|
||||||
#define KCF_MTRR (1ULL << 8) /* Memory Type Range Registers */
|
|
||||||
#define KCF_GLOBAL_PAGE (1ULL << 9) /* Page Global Enable */
|
|
||||||
#define KCF_MCA (1ULL << 10) /* Machine Check Architecture */
|
|
||||||
#define KCF_CMOV (1ULL << 11) /* Conditional Move Instructions */
|
|
||||||
#define KCF_PAT (1ULL << 12) /* Page Attribute Table */
|
|
||||||
#define KCF_PSE36 (1ULL << 13) /* 36-bit Page Size Extension */
|
|
||||||
#define KCF_CLFLUSH (1ULL << 14) /* CLFLUSH Instruction */
|
|
||||||
#define KCF_FXSR (1ULL << 15) /* FXSAVE/FXRSTOR Instructions */
|
|
||||||
#define KCF_ACPI (1ULL << 16) /* Thermal Monitor and Software Controlled Clock */
|
|
||||||
#define KCF_MMX (1ULL << 17) /* MMX Technology */
|
|
||||||
#define KCF_SSE (1ULL << 18) /* Streaming SIMD Extensions */
|
|
||||||
#define KCF_SSE2 (1ULL << 19) /* Streaming SIMD Extensions 2 */
|
|
||||||
#define KCF_SMT (1ULL << 20) /* Hyper-Threading Technology */
|
|
||||||
#define KCF_SSE3 (1ULL << 21) /* Streaming SIMD Extensions 3 */
|
|
||||||
#define KCF_VMX (1ULL << 22) /* Intel Virtual Machine Extensions */
|
|
||||||
#define KCF_SSSE3 (1ULL << 23) /* Supplemental SSE3 Instructions */
|
|
||||||
#define KCF_SSE41 (1ULL << 24) /* SSE4.1 Instructions */
|
|
||||||
#define KCF_SSE42 (1ULL << 25) /* SSE4.2 Instructions */
|
|
||||||
#define KCF_X2APIC (1ULL << 26) /* x2APIC Support */
|
|
||||||
#define KCF_POPCNT (1ULL << 27) /* POPCNT Instruction */
|
|
||||||
#define KCF_TSC_DEADLINE (1ULL << 28) /* TSC Deadline Timer */
|
|
||||||
#define KCF_AES (1ULL << 29) /* AES-NI Instruction Set */
|
|
||||||
#define KCF_XSAVE (1ULL << 30) /* XSAVE/XRSTOR Instructions */
|
|
||||||
#define KCF_AVX (1ULL << 31) /* Advanced Vector Extensions */
|
|
||||||
#define KCF_RDRAND (1ULL << 32) /* RDRAND Instruction */
|
|
||||||
#define KCF_FSGSBASE (1ULL << 33) /* RDFSBASE/WRFSBASE Instructions */
|
|
||||||
#define KCF_AVX2 (1ULL << 34) /* AVX2 Instructions */
|
|
||||||
#define KCF_SMEP (1ULL << 35) /* Supervisor Mode Execution Prevention */
|
|
||||||
#define KCF_RDSEED (1ULL << 36) /* RDSEED Instruction */
|
|
||||||
#define KCF_SMAP (1ULL << 37) /* Supervisor Mode Access Prevention */
|
|
||||||
#define KCF_SHA (1ULL << 38) /* SHA Extensions */
|
|
||||||
#define KCF_LA57 (1ULL << 39) /* 57-bit Linear Addresses */
|
|
||||||
#define KCF_ARAT (1ULL << 40) /* Always Running APIC Timer */
|
|
||||||
|
|
||||||
/* Kernel CPU Extended Features */
|
|
||||||
#define KCF_SVM (1ULL << 0) /* AMD Secure Virtual Machine */
|
|
||||||
#define KCF_SSE4A (1ULL << 1) /* SSE4A Instructions */
|
|
||||||
#define KCF_FMA4 (1ULL << 2) /* FMA4 Instructions */
|
|
||||||
#define KCF_TOPOEXT (1ULL << 3) /* AMD Topology Extensions */
|
|
||||||
#define KCF_SYSCALL (1ULL << 4) /* SYSCALL/SYSRET Instructions */
|
|
||||||
#define KCF_NX_BIT (1ULL << 5) /* No-Execute Page Protection */
|
|
||||||
#define KCF_RDTSCP (1ULL << 6) /* RDTSCP Instruction */
|
|
||||||
#define KCF_64BIT (1ULL << 7) /* Long Mode Support */
|
|
||||||
#define KCF_3DNOW_EXT (1ULL << 8) /* 3DNow! Extensions */
|
|
||||||
#define KCF_3DNOW (1ULL << 9) /* 3DNow! Instructions */
|
|
||||||
#define KCF_INVARIANT_TSC (1ULL << 10) /* Invariant Time Stamp Counter */
|
|
||||||
|
|
||||||
/* Context control flags */
|
/* Context control flags */
|
||||||
#define CONTEXT_ARCHITECTURE 0x00010000
|
#define CONTEXT_ARCHITECTURE 0x00010000
|
||||||
#define CONTEXT_CONTROL (CONTEXT_ARCHITECTURE | 0x01)
|
#define CONTEXT_CONTROL (CONTEXT_ARCHITECTURE | 0x01)
|
||||||
@@ -187,14 +130,13 @@
|
|||||||
|
|
||||||
/* XTOS Kernel stack size */
|
/* XTOS Kernel stack size */
|
||||||
#define KERNEL_STACK_SIZE 0x4000
|
#define KERNEL_STACK_SIZE 0x4000
|
||||||
#define KERNEL_STACKS 3
|
|
||||||
|
|
||||||
/* XTOS Kernel stack guard pages */
|
/* XTOS Kernel stack guard pages */
|
||||||
#define KERNEL_STACK_GUARD_PAGES 1
|
#define KERNEL_STACK_GUARD_PAGES 1
|
||||||
|
|
||||||
/* Processor structures size */
|
/* Processor structures size */
|
||||||
#define KPROCESSOR_STRUCTURES_SIZE ((KERNEL_STACKS * KERNEL_STACK_SIZE) + (GDT_ENTRIES * sizeof(KGDTENTRY)) + \
|
#define KPROCESSOR_STRUCTURES_SIZE ((2 * KERNEL_STACK_SIZE) + (GDT_ENTRIES * sizeof(KGDTENTRY)) + sizeof(KTSS) + \
|
||||||
sizeof(KTSS) + sizeof(KPROCESSOR_BLOCK) + MM_PAGE_SIZE)
|
sizeof(KPROCESSOR_BLOCK) + MM_PAGE_SIZE)
|
||||||
|
|
||||||
/* Kernel frames */
|
/* Kernel frames */
|
||||||
#define KTRAP_FRAME_ALIGN 0x08
|
#define KTRAP_FRAME_ALIGN 0x08
|
||||||
@@ -215,10 +157,6 @@
|
|||||||
#define NPX_STATE_LOADED 0x0
|
#define NPX_STATE_LOADED 0x0
|
||||||
#define NPX_STATE_UNLOADED 0xA
|
#define NPX_STATE_UNLOADED 0xA
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Floating point state storing structure */
|
/* Floating point state storing structure */
|
||||||
typedef struct _FN_SAVE_FORMAT
|
typedef struct _FN_SAVE_FORMAT
|
||||||
{
|
{
|
||||||
@@ -399,14 +337,10 @@ typedef struct _KTSS
|
|||||||
UCHAR IntDirectionMap[IOPM_DIRECTION_MAP_SIZE];
|
UCHAR IntDirectionMap[IOPM_DIRECTION_MAP_SIZE];
|
||||||
} KTSS, *PKTSS;
|
} KTSS, *PKTSS;
|
||||||
|
|
||||||
/* Exception frame definition (not available on i686) */
|
/* Exception frame definition (not available on ia32) */
|
||||||
typedef struct _KEXCEPTION_FRAME
|
typedef struct _KEXCEPTION_FRAME
|
||||||
{
|
{
|
||||||
ULONG Ebp;
|
ULONG PlaceHolder;
|
||||||
ULONG Ebx;
|
|
||||||
ULONG Edi;
|
|
||||||
ULONG Esi;
|
|
||||||
ULONG Return;
|
|
||||||
} KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;
|
} KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;
|
||||||
|
|
||||||
/* Thread start frame definition */
|
/* Thread start frame definition */
|
||||||
@@ -487,17 +421,6 @@ typedef struct _KSPECIAL_REGISTERS
|
|||||||
ULONG Reserved[6];
|
ULONG Reserved[6];
|
||||||
} KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS;
|
} KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS;
|
||||||
|
|
||||||
/* Processor start block structure definition */
|
|
||||||
typedef struct _PROCESSOR_START_BLOCK
|
|
||||||
{
|
|
||||||
ULONG_PTR Cr3;
|
|
||||||
ULONG_PTR Cr4;
|
|
||||||
PVOID EntryPoint;
|
|
||||||
PVOID ProcessorStructures;
|
|
||||||
PVOID Stack;
|
|
||||||
BOOLEAN Started;
|
|
||||||
} PROCESSOR_START_BLOCK, *PPROCESSOR_START_BLOCK;
|
|
||||||
|
|
||||||
/* Processor state frame structure definition */
|
/* Processor state frame structure definition */
|
||||||
typedef struct _KPROCESSOR_STATE
|
typedef struct _KPROCESSOR_STATE
|
||||||
{
|
{
|
||||||
@@ -523,7 +446,6 @@ typedef struct _KPROCESSOR_CONTROL_BLOCK
|
|||||||
VOLATILE ULONG_PTR TimerRequest;
|
VOLATILE ULONG_PTR TimerRequest;
|
||||||
SINGLE_LIST_ENTRY DeferredReadyListHead;
|
SINGLE_LIST_ENTRY DeferredReadyListHead;
|
||||||
PROCESSOR_POWER_STATE PowerState;
|
PROCESSOR_POWER_STATE PowerState;
|
||||||
ULONG ProfilingCountdown;
|
|
||||||
} KPROCESSOR_CONTROL_BLOCK, *PKPROCESSOR_CONTROL_BLOCK;
|
} KPROCESSOR_CONTROL_BLOCK, *PKPROCESSOR_CONTROL_BLOCK;
|
||||||
|
|
||||||
/* Processor Block structure definition */
|
/* Processor Block structure definition */
|
||||||
@@ -550,9 +472,6 @@ typedef struct _KPROCESSOR_BLOCK
|
|||||||
KAFFINITY SetMember;
|
KAFFINITY SetMember;
|
||||||
ULONG StallScaleFactor;
|
ULONG StallScaleFactor;
|
||||||
UCHAR CpuNumber;
|
UCHAR CpuNumber;
|
||||||
ULONG HardwareId;
|
|
||||||
VOLATILE BOOLEAN Started;
|
|
||||||
PINTERRUPT_HANDLER InterruptDispatchTable[256];
|
|
||||||
} KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK;
|
} KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK;
|
||||||
|
|
||||||
/* Thread Environment Block (TEB) structure definition */
|
/* Thread Environment Block (TEB) structure definition */
|
||||||
@@ -561,5 +480,4 @@ typedef struct _THREAD_ENVIRONMENT_BLOCK
|
|||||||
THREAD_INFORMATION_BLOCK InformationBlock;
|
THREAD_INFORMATION_BLOCK InformationBlock;
|
||||||
} THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
} THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_I686_KETYPES_H */
|
#endif /* __XTDK_I686_KETYPES_H */
|
||||||
|
|||||||
@@ -99,9 +99,6 @@
|
|||||||
/* HAL memory pool virtual address start */
|
/* HAL memory pool virtual address start */
|
||||||
#define MM_HARDWARE_VA_START 0xFFC00000
|
#define MM_HARDWARE_VA_START 0xFFC00000
|
||||||
|
|
||||||
/* Kernel shared data address */
|
|
||||||
#define MM_KERNEL_SHARED_DATA_ADDRESS 0xFFDF0000
|
|
||||||
|
|
||||||
/* Maximum physical address used by HAL allocations */
|
/* Maximum physical address used by HAL allocations */
|
||||||
#define MM_MAXIMUM_PHYSICAL_ADDRESS 0xFFFFFFFF
|
#define MM_MAXIMUM_PHYSICAL_ADDRESS 0xFFFFFFFF
|
||||||
|
|
||||||
@@ -120,10 +117,6 @@
|
|||||||
/* Number of pool tracking tables */
|
/* Number of pool tracking tables */
|
||||||
#define MM_POOL_TRACKING_TABLES 32
|
#define MM_POOL_TRACKING_TABLES 32
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Page size enumeration list */
|
/* Page size enumeration list */
|
||||||
typedef enum _PAGE_SIZE
|
typedef enum _PAGE_SIZE
|
||||||
{
|
{
|
||||||
@@ -444,5 +437,4 @@ typedef struct _POOL_DESCRIPTOR
|
|||||||
SIZE_T Reserved;
|
SIZE_T Reserved;
|
||||||
} POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
} POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_I686_MMTYPES_H */
|
#endif /* __XTDK_I686_MMTYPES_H */
|
||||||
|
|||||||
@@ -12,20 +12,13 @@
|
|||||||
#include <xtdefs.h>
|
#include <xtdefs.h>
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Architecture-specific enumeration lists forward references */
|
/* Architecture-specific enumeration lists forward references */
|
||||||
typedef enum _APIC_DEST_MODE APIC_DEST_MODE, *PAPIC_DEST_MODE;
|
|
||||||
typedef enum _APIC_DM APIC_DM, *PAPIC_DM;
|
typedef enum _APIC_DM APIC_DM, *PAPIC_DM;
|
||||||
typedef enum _APIC_DSH APIC_DSH, *PAPIC_DSH;
|
typedef enum _APIC_DSH APIC_DSH, *PAPIC_DSH;
|
||||||
typedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE;
|
typedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE;
|
||||||
typedef enum _APIC_REGISTER APIC_REGISTER, *PAPIC_REGISTER;
|
typedef enum _APIC_REGISTER APIC_REGISTER, *PAPIC_REGISTER;
|
||||||
typedef enum _APIC_TIMER_DIVISOR APIC_TIMER_DIVISOR, *PAPIC_TIMER_DIVISOR;
|
|
||||||
typedef enum _CPU_VENDOR CPU_VENDOR, *PCPU_VENDOR;
|
typedef enum _CPU_VENDOR CPU_VENDOR, *PCPU_VENDOR;
|
||||||
typedef enum _CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT, *PCPUID_FEATURES_ADVANCED_POWER_MANAGEMENT;
|
|
||||||
typedef enum _CPUID_FEATURES_EXTENDED CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
|
typedef enum _CPUID_FEATURES_EXTENDED CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
|
||||||
typedef enum _CPUID_FEATURES_POWER_MANAGEMENT CPUID_FEATURES_POWER_MANAGEMENT, *PCPUID_FEATURES_POWER_MANAGEMENT;
|
|
||||||
typedef enum _CPUID_FEATURES_STANDARD1 CPUID_FEATURES_STANDARD1, *PCPUID_FEATURES_STANDARD1;
|
typedef enum _CPUID_FEATURES_STANDARD1 CPUID_FEATURES_STANDARD1, *PCPUID_FEATURES_STANDARD1;
|
||||||
typedef enum _CPUID_FEATURES_STANDARD7_LEAF0 CPUID_FEATURES_STANDARD7_LEAF0, *PCPUID_FEATURES_STANDARD7_LEAF0;
|
typedef enum _CPUID_FEATURES_STANDARD7_LEAF0 CPUID_FEATURES_STANDARD7_LEAF0, *PCPUID_FEATURES_STANDARD7_LEAF0;
|
||||||
typedef enum _CPUID_FEATURES_STANDARD7_LEAF1 CPUID_FEATURES_STANDARD7_LEAF1, *PCPUID_FEATURES_STANDARD7_LEAF1;
|
typedef enum _CPUID_FEATURES_STANDARD7_LEAF1 CPUID_FEATURES_STANDARD7_LEAF1, *PCPUID_FEATURES_STANDARD7_LEAF1;
|
||||||
@@ -37,7 +30,6 @@ typedef enum _PIC_I8259_ICW1_OPERATING_MODE PIC_I8259_ICW1_OPERATING_MODE, *PPIC
|
|||||||
typedef enum _PIC_I8259_ICW4_BUFFERED_MODE PIC_I8259_ICW4_BUFFERED_MODE, *PPIC_I8259_ICW4_BUFFERED_MODE;
|
typedef enum _PIC_I8259_ICW4_BUFFERED_MODE PIC_I8259_ICW4_BUFFERED_MODE, *PPIC_I8259_ICW4_BUFFERED_MODE;
|
||||||
typedef enum _PIC_I8259_ICW4_EOI_MODE PIC_I8259_ICW4_EOI_MODE, *PPIC_I8259_ICW4_EOI_MODE;
|
typedef enum _PIC_I8259_ICW4_EOI_MODE PIC_I8259_ICW4_EOI_MODE, *PPIC_I8259_ICW4_EOI_MODE;
|
||||||
typedef enum _PIC_I8259_ICW4_SYSTEM_MODE PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;
|
typedef enum _PIC_I8259_ICW4_SYSTEM_MODE PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;
|
||||||
typedef enum _TIMER_TYPE TIMER_TYPE, *PTIMER_TYPE;
|
|
||||||
typedef enum _TRAMPOLINE_TYPE TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;
|
typedef enum _TRAMPOLINE_TYPE TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;
|
||||||
|
|
||||||
/* Architecture-specific structures forward references */
|
/* Architecture-specific structures forward references */
|
||||||
@@ -50,8 +42,6 @@ typedef struct _FX_SAVE_AREA FX_SAVE_AREA, *PFX_SAVE_AREA;
|
|||||||
typedef struct _FX_SAVE_FORMAT FX_SAVE_FORMAT, *PFX_SAVE_FORMAT;
|
typedef struct _FX_SAVE_FORMAT FX_SAVE_FORMAT, *PFX_SAVE_FORMAT;
|
||||||
typedef struct _HARDWARE_LEGACY_PTE HARDWARE_LEGACY_PTE, *PHARDWARE_LEGACY_PTE;
|
typedef struct _HARDWARE_LEGACY_PTE HARDWARE_LEGACY_PTE, *PHARDWARE_LEGACY_PTE;
|
||||||
typedef struct _HARDWARE_MODERN_PTE HARDWARE_MODERN_PTE, *PHARDWARE_MODERN_PTE;
|
typedef struct _HARDWARE_MODERN_PTE HARDWARE_MODERN_PTE, *PHARDWARE_MODERN_PTE;
|
||||||
typedef struct _HPET_REGISTERS HPET_REGISTERS, *PHPET_REGISTERS;
|
|
||||||
typedef struct _IOAPIC_DATA IOAPIC_DATA, *PIOAPIC_DATA;
|
|
||||||
typedef struct _KDESCRIPTOR KDESCRIPTOR, *PKDESCRIPTOR;
|
typedef struct _KDESCRIPTOR KDESCRIPTOR, *PKDESCRIPTOR;
|
||||||
typedef struct _KEXCEPTION_FRAME KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;
|
typedef struct _KEXCEPTION_FRAME KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;
|
||||||
typedef struct _KGDTENTRY KGDTENTRY, *PKGDTENTRY;
|
typedef struct _KGDTENTRY KGDTENTRY, *PKGDTENTRY;
|
||||||
@@ -82,7 +72,6 @@ typedef struct _MMPML3_PTE_SUBSECTION MMPML3_PTE_SUBSECTION, *PMMPML3_PTE_SUBSEC
|
|||||||
typedef struct _MMPML3_PTE_TRANSITION MMPML3_PTE_TRANSITION, *PMMPML3_PTE_TRANSITION;
|
typedef struct _MMPML3_PTE_TRANSITION MMPML3_PTE_TRANSITION, *PMMPML3_PTE_TRANSITION;
|
||||||
typedef struct _POOL_DESCRIPTOR POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
typedef struct _POOL_DESCRIPTOR POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
||||||
typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
||||||
typedef struct _TIMER_CAPABILITIES TIMER_CAPABILITIES, *PTIMER_CAPABILITIES;
|
|
||||||
|
|
||||||
/* Unions forward references */
|
/* Unions forward references */
|
||||||
typedef union _APIC_BASE_REGISTER APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER;
|
typedef union _APIC_BASE_REGISTER APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER;
|
||||||
@@ -90,7 +79,6 @@ typedef union _APIC_COMMAND_REGISTER APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGIS
|
|||||||
typedef union _APIC_LVT_REGISTER APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER;
|
typedef union _APIC_LVT_REGISTER APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER;
|
||||||
typedef union _APIC_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
|
typedef union _APIC_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
|
||||||
typedef union _HARDWARE_PTE HARDWARE_PTE, *PHARDWARE_PTE;
|
typedef union _HARDWARE_PTE HARDWARE_PTE, *PHARDWARE_PTE;
|
||||||
typedef union _IOAPIC_REDIRECTION_REGISTER IOAPIC_REDIRECTION_REGISTER, *PIOAPIC_REDIRECTION_REGISTER;
|
|
||||||
typedef union _MMPML2_PTE MMPML2_PTE, *PMMPML2_PTE;
|
typedef union _MMPML2_PTE MMPML2_PTE, *PMMPML2_PTE;
|
||||||
typedef union _MMPML3_PTE MMPML3_PTE, *PMMPML3_PTE;
|
typedef union _MMPML3_PTE MMPML3_PTE, *PMMPML3_PTE;
|
||||||
typedef union _MMPTE MMPDE, *PMMPDE;
|
typedef union _MMPTE MMPDE, *PMMPDE;
|
||||||
@@ -101,5 +89,4 @@ typedef union _PIC_I8259_ICW2 PIC_I8259_ICW2, *PPIC_I8259_ICW2;
|
|||||||
typedef union _PIC_I8259_ICW3 PIC_I8259_ICW3, *PPIC_I8259_ICW3;
|
typedef union _PIC_I8259_ICW3 PIC_I8259_ICW3, *PPIC_I8259_ICW3;
|
||||||
typedef union _PIC_I8259_ICW4 PIC_I8259_ICW4, *PPIC_I8259_ICW4;
|
typedef union _PIC_I8259_ICW4 PIC_I8259_ICW4, *PPIC_I8259_ICW4;
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_I686_XTSTRUCT_H */
|
#endif /* __XTDK_I686_XTSTRUCT_H */
|
||||||
|
|||||||
@@ -58,10 +58,6 @@
|
|||||||
#define PCI_STATUS_SIGNALED_SYSTEM_ERROR 0x4000
|
#define PCI_STATUS_SIGNALED_SYSTEM_ERROR 0x4000
|
||||||
#define PCI_STATUS_DETECTED_PARITY_ERROR 0x8000
|
#define PCI_STATUS_DETECTED_PARITY_ERROR 0x8000
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* PCI bridge control registers */
|
/* PCI bridge control registers */
|
||||||
typedef struct _PCI_BRIDGE_CONTROL_REGISTER
|
typedef struct _PCI_BRIDGE_CONTROL_REGISTER
|
||||||
{
|
{
|
||||||
@@ -218,5 +214,4 @@ typedef struct _PCI_TYPE1_DEVICE
|
|||||||
PCI_BRIDGE_CONTROL_REGISTER Bridge;
|
PCI_BRIDGE_CONTROL_REGISTER Bridge;
|
||||||
} PCI_TYPE1_DEVICE, *PPCI_TYPE1_DEVICE;
|
} PCI_TYPE1_DEVICE, *PPCI_TYPE1_DEVICE;
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_IOTYPES_H */
|
#endif /* __XTDK_IOTYPES_H */
|
||||||
|
|||||||
@@ -13,9 +13,6 @@
|
|||||||
#include <xttypes.h>
|
#include <xttypes.h>
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Kernel debugger routines forward references */
|
/* Kernel debugger routines forward references */
|
||||||
XTCLINK
|
XTCLINK
|
||||||
XTCDECL
|
XTCDECL
|
||||||
@@ -23,5 +20,4 @@ VOID
|
|||||||
DbgPrint(PCWSTR Format,
|
DbgPrint(PCWSTR Format,
|
||||||
...);
|
...);
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_KDFUNCS_H */
|
#endif /* __XTDK_KDFUNCS_H */
|
||||||
|
|||||||
@@ -21,10 +21,6 @@
|
|||||||
#define DEBUG_PROVIDER_COMPORT 0x00000001
|
#define DEBUG_PROVIDER_COMPORT 0x00000001
|
||||||
#define DEBUG_PROVIDER_FRAMEBUFFER 0x00000002
|
#define DEBUG_PROVIDER_FRAMEBUFFER 0x00000002
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Kernel routine callbacks */
|
/* Kernel routine callbacks */
|
||||||
typedef XTSTATUS (XTAPI *PKD_INIT_ROUTINE)();
|
typedef XTSTATUS (XTAPI *PKD_INIT_ROUTINE)();
|
||||||
typedef VOID (*PKD_PRINT_ROUTINE)(IN PCWSTR Format, IN ...);
|
typedef VOID (*PKD_PRINT_ROUTINE)(IN PCWSTR Format, IN ...);
|
||||||
@@ -46,5 +42,4 @@ typedef struct _KD_DISPATCH_TABLE
|
|||||||
RTL_PRINT_CONTEXT PrintContext;
|
RTL_PRINT_CONTEXT PrintContext;
|
||||||
} KD_DISPATCH_TABLE, *PKD_DISPATCH_TABLE;
|
} KD_DISPATCH_TABLE, *PKD_DISPATCH_TABLE;
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_KDTYPES_H */
|
#endif /* __XTDK_KDTYPES_H */
|
||||||
|
|||||||
@@ -15,9 +15,6 @@
|
|||||||
#include <ketypes.h>
|
#include <ketypes.h>
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Kernel services routines forward references */
|
/* Kernel services routines forward references */
|
||||||
XTCLINK
|
XTCLINK
|
||||||
XTFASTCALL
|
XTFASTCALL
|
||||||
@@ -144,12 +141,6 @@ VOID
|
|||||||
KeSetTargetProcessorDpc(IN PKDPC Dpc,
|
KeSetTargetProcessorDpc(IN PKDPC Dpc,
|
||||||
IN CCHAR Number);
|
IN CCHAR Number);
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
KeSetTimeIncrement(IN ULONG MaxIncrement,
|
|
||||||
IN ULONG MinIncrement);
|
|
||||||
|
|
||||||
XTCLINK
|
XTCLINK
|
||||||
XTAPI
|
XTAPI
|
||||||
VOID
|
VOID
|
||||||
@@ -168,5 +159,4 @@ XTAPI
|
|||||||
BOOLEAN
|
BOOLEAN
|
||||||
KeSignalCallDpcSynchronize(IN PVOID SystemArgument);
|
KeSignalCallDpcSynchronize(IN PVOID SystemArgument);
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_KEFUNCS_H */
|
#endif /* __XTDK_KEFUNCS_H */
|
||||||
|
|||||||
@@ -49,10 +49,6 @@
|
|||||||
#define THREAD_HIGH_PRIORITY 31
|
#define THREAD_HIGH_PRIORITY 31
|
||||||
#define THREAD_MAXIMUM_PRIORITY 32
|
#define THREAD_MAXIMUM_PRIORITY 32
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Adjust reason */
|
/* Adjust reason */
|
||||||
typedef enum _ADJUST_REASON
|
typedef enum _ADJUST_REASON
|
||||||
{
|
{
|
||||||
@@ -137,37 +133,6 @@ typedef enum _KPROCESS_STATE
|
|||||||
ProcessOutSwap
|
ProcessOutSwap
|
||||||
} KPROCESS_STATE, *PKPROCESS_STATE;
|
} KPROCESS_STATE, *PKPROCESS_STATE;
|
||||||
|
|
||||||
/* Kernel profiling sources */
|
|
||||||
typedef enum _KPROFILE_SOURCE
|
|
||||||
{
|
|
||||||
ProfileTime,
|
|
||||||
ProfileAlignmentFixup,
|
|
||||||
ProfileTotalIssues,
|
|
||||||
ProfilePipelineDry,
|
|
||||||
ProfileLoadInstructions,
|
|
||||||
ProfilePipelineFrozen,
|
|
||||||
ProfileBranchInstructions,
|
|
||||||
ProfileTotalNonissues,
|
|
||||||
ProfileDcacheMisses,
|
|
||||||
ProfileIcacheMisses,
|
|
||||||
ProfileCacheMisses,
|
|
||||||
ProfileBranchMispredictions,
|
|
||||||
ProfileStoreInstructions,
|
|
||||||
ProfileFpInstructions,
|
|
||||||
ProfileIntegerInstructions,
|
|
||||||
Profile2Issue,
|
|
||||||
Profile3Issue,
|
|
||||||
Profile4Issue,
|
|
||||||
ProfileSpecialInstructions,
|
|
||||||
ProfileTotalCycles,
|
|
||||||
ProfileIcacheIssues,
|
|
||||||
ProfileDcacheAccesses,
|
|
||||||
ProfileMemoryBarrierCycles,
|
|
||||||
ProfileLoadLinkedIssues,
|
|
||||||
ProfileXtKernel,
|
|
||||||
ProfileMaximum
|
|
||||||
} KPROFILE_SOURCE, *PKPROFILE_SOURCE;
|
|
||||||
|
|
||||||
/* Thread state */
|
/* Thread state */
|
||||||
typedef enum _KTHREAD_STATE
|
typedef enum _KTHREAD_STATE
|
||||||
{
|
{
|
||||||
@@ -449,29 +414,6 @@ typedef struct _KPROCESS
|
|||||||
UCHAR Spare;
|
UCHAR Spare;
|
||||||
} KPROCESS, *PKPROCESS;
|
} KPROCESS, *PKPROCESS;
|
||||||
|
|
||||||
/* System Time structure definition */
|
|
||||||
typedef struct _KSYSTEM_TIME
|
|
||||||
{
|
|
||||||
ULONG LowPart;
|
|
||||||
LONG High1Part;
|
|
||||||
LONG High2Part;
|
|
||||||
} KSYSTEM_TIME, *PKSYSTEM_TIME;
|
|
||||||
|
|
||||||
/* Kernel Shared Data (KSD) structure definition */
|
|
||||||
typedef struct _KSHARED_DATA
|
|
||||||
{
|
|
||||||
VOLATILE KSYSTEM_TIME InterruptTime;
|
|
||||||
VOLATILE KSYSTEM_TIME SystemTime;
|
|
||||||
VOLATILE KSYSTEM_TIME TickCount;
|
|
||||||
ULONG XtMajorVersion;
|
|
||||||
ULONG XtMinorVersion;
|
|
||||||
WCHAR XtBuild[8];
|
|
||||||
WCHAR XtBuildHash[11];
|
|
||||||
WCHAR XtArchitecture[8];
|
|
||||||
WCHAR XtDate[9];
|
|
||||||
WCHAR XtFullDate[25];
|
|
||||||
} KSHARED_DATA, *PKSHARED_DATA;
|
|
||||||
|
|
||||||
/* Thread control block structure definition */
|
/* Thread control block structure definition */
|
||||||
typedef struct _KTHREAD
|
typedef struct _KTHREAD
|
||||||
{
|
{
|
||||||
@@ -705,5 +647,4 @@ typedef struct _KUBSAN_TYPE_MISMATCH_DATA_V1
|
|||||||
UCHAR TypeCheckKind;
|
UCHAR TypeCheckKind;
|
||||||
} KUBSAN_TYPE_MISMATCH_DATA_V1, *PKUBSAN_TYPE_MISMATCH_DATA_V1;
|
} KUBSAN_TYPE_MISMATCH_DATA_V1, *PKUBSAN_TYPE_MISMATCH_DATA_V1;
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_KEFUNCS_H */
|
#endif /* __XTDK_KEFUNCS_H */
|
||||||
|
|||||||
@@ -38,10 +38,6 @@
|
|||||||
#define LDR_DTE_MM_LOADED 0x40000000
|
#define LDR_DTE_MM_LOADED 0x40000000
|
||||||
#define LDR_DTE_COMPAT_DATABASE_PROCESSED 0x80000000
|
#define LDR_DTE_COMPAT_DATABASE_PROCESSED 0x80000000
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Loader data table entry */
|
/* Loader data table entry */
|
||||||
typedef struct _LDR_DATA_TABLE_ENTRY
|
typedef struct _LDR_DATA_TABLE_ENTRY
|
||||||
{
|
{
|
||||||
@@ -74,5 +70,4 @@ typedef struct _LDR_DATA_TABLE_ENTRY
|
|||||||
PVOID PatchInformation;
|
PVOID PatchInformation;
|
||||||
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
|
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_LDRTYPES_H */
|
#endif /* __XTDK_LDRTYPES_H */
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: sdk/xtdk/mmfuncs.h
|
|
||||||
* DESCRIPTION: XTOS memory manager routine definitions
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __XTDK_MMFUNCS_H
|
|
||||||
#define __XTDK_MMFUNCS_H
|
|
||||||
|
|
||||||
#include <xtdefs.h>
|
|
||||||
#include <xtstruct.h>
|
|
||||||
#include <xttypes.h>
|
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Memory manager routines forward references */
|
|
||||||
XTAPI
|
|
||||||
XTSTATUS
|
|
||||||
MmAllocatePool(IN MMPOOL_TYPE PoolType,
|
|
||||||
IN SIZE_T Bytes,
|
|
||||||
OUT PVOID *Memory);
|
|
||||||
|
|
||||||
XTAPI
|
|
||||||
XTSTATUS
|
|
||||||
MmAllocatePoolWithTag(IN MMPOOL_TYPE PoolType,
|
|
||||||
IN SIZE_T Bytes,
|
|
||||||
OUT PVOID *Memory,
|
|
||||||
IN ULONG Tag);
|
|
||||||
|
|
||||||
XTAPI
|
|
||||||
XTSTATUS
|
|
||||||
MmFreePool(IN PVOID VirtualAddress);
|
|
||||||
|
|
||||||
XTAPI
|
|
||||||
XTSTATUS
|
|
||||||
MmFreePoolWithTag(IN PVOID VirtualAddress,
|
|
||||||
IN ULONG Tag);
|
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_MMFUNCS_H */
|
|
||||||
@@ -55,10 +55,6 @@
|
|||||||
/* Protection field shift */
|
/* Protection field shift */
|
||||||
#define MM_PROTECT_FIELD_SHIFT 5
|
#define MM_PROTECT_FIELD_SHIFT 5
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Memory manager page lists */
|
/* Memory manager page lists */
|
||||||
typedef enum _MMPAGELISTS
|
typedef enum _MMPAGELISTS
|
||||||
{
|
{
|
||||||
@@ -262,5 +258,4 @@ typedef struct _POOL_TRACKING_TABLE
|
|||||||
ULONG Tag;
|
ULONG Tag;
|
||||||
} POOL_TRACKING_TABLE, *PPOOL_TRACKING_TABLE;
|
} POOL_TRACKING_TABLE, *PPOOL_TRACKING_TABLE;
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_MMTYPES_H */
|
#endif /* __XTDK_MMTYPES_H */
|
||||||
|
|||||||
@@ -14,9 +14,6 @@
|
|||||||
#include <ketypes.h>
|
#include <ketypes.h>
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Power Manager routine callbacks */
|
/* Power Manager routine callbacks */
|
||||||
typedef VOID (XTFASTCALL *PPROCESSOR_IDLE_FUNCTION)(IN PPROCESSOR_POWER_STATE PowerState);
|
typedef VOID (XTFASTCALL *PPROCESSOR_IDLE_FUNCTION)(IN PPROCESSOR_POWER_STATE PowerState);
|
||||||
typedef XTSTATUS (XTFASTCALL *PSET_PROCESSOR_THROTTLE)(IN UCHAR Throttle);
|
typedef XTSTATUS (XTFASTCALL *PSET_PROCESSOR_THROTTLE)(IN UCHAR Throttle);
|
||||||
@@ -91,5 +88,4 @@ typedef struct _PROCESSOR_POWER_STATE
|
|||||||
ULONG LastC3UserTime;
|
ULONG LastC3UserTime;
|
||||||
} PROCESSOR_POWER_STATE, *PPROCESSOR_POWER_STATE;
|
} PROCESSOR_POWER_STATE, *PPROCESSOR_POWER_STATE;
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_POTYPES_H */
|
#endif /* __XTDK_POTYPES_H */
|
||||||
|
|||||||
@@ -13,9 +13,6 @@
|
|||||||
#include <ketypes.h>
|
#include <ketypes.h>
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Kernel's representation of a process object */
|
/* Kernel's representation of a process object */
|
||||||
typedef struct _EPROCESS
|
typedef struct _EPROCESS
|
||||||
{
|
{
|
||||||
@@ -30,5 +27,4 @@ typedef struct _ETHREAD
|
|||||||
UINT Reserved0;
|
UINT Reserved0;
|
||||||
} ETHREAD, *PETHREAD;
|
} ETHREAD, *PETHREAD;
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_PSTYPES_H */
|
#endif /* __XTDK_PSTYPES_H */
|
||||||
|
|||||||
@@ -15,9 +15,6 @@
|
|||||||
#include <rtltypes.h>
|
#include <rtltypes.h>
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Runtime Library routines forward references */
|
/* Runtime Library routines forward references */
|
||||||
XTCLINK
|
XTCLINK
|
||||||
XTAPI
|
XTAPI
|
||||||
@@ -297,18 +294,6 @@ BOOLEAN
|
|||||||
RtlTestBit(IN PRTL_BITMAP BitMap,
|
RtlTestBit(IN PRTL_BITMAP BitMap,
|
||||||
IN ULONG_PTR Bit);
|
IN ULONG_PTR Bit);
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTAPI
|
|
||||||
XTSTATUS
|
|
||||||
RtlTimeFieldsToUnixEpoch(IN PTIME_FIELDS TimeFields,
|
|
||||||
OUT PLONGLONG UnixTime);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTAPI
|
|
||||||
XTSTATUS
|
|
||||||
RtlTimeFieldsToXtEpoch(IN PTIME_FIELDS TimeFields,
|
|
||||||
OUT PLARGE_INTEGER XtTime);
|
|
||||||
|
|
||||||
XTCLINK
|
XTCLINK
|
||||||
XTAPI
|
XTAPI
|
||||||
PCHAR
|
PCHAR
|
||||||
@@ -385,5 +370,4 @@ VOID
|
|||||||
RtlZeroMemory(OUT PVOID Destination,
|
RtlZeroMemory(OUT PVOID Destination,
|
||||||
IN SIZE_T Length);
|
IN SIZE_T Length);
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_RTLFUNCS_H */
|
#endif /* __XTDK_RTLFUNCS_H */
|
||||||
|
|||||||
@@ -53,17 +53,6 @@
|
|||||||
#define SHA1_BLOCK_SIZE 64
|
#define SHA1_BLOCK_SIZE 64
|
||||||
#define SHA1_DIGEST_SIZE 20
|
#define SHA1_DIGEST_SIZE 20
|
||||||
|
|
||||||
/* Time related definitions */
|
|
||||||
#define TIME_SECONDS_PER_MINUTE 60
|
|
||||||
#define TIME_SECONDS_PER_HOUR 3600
|
|
||||||
#define TIME_SECONDS_PER_DAY 86400
|
|
||||||
#define TIME_TICKS_PER_SECOND 10000000
|
|
||||||
#define TIME_TICKS_PER_MILLISECOND 10000
|
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Runtime Library routine callbacks */
|
/* Runtime Library routine callbacks */
|
||||||
typedef XTSTATUS (*PWRITE_CHARACTER)(IN CHAR Character);
|
typedef XTSTATUS (*PWRITE_CHARACTER)(IN CHAR Character);
|
||||||
typedef XTSTATUS (*PWRITE_WIDE_CHARACTER)(IN WCHAR Character);
|
typedef XTSTATUS (*PWRITE_WIDE_CHARACTER)(IN WCHAR Character);
|
||||||
@@ -118,18 +107,4 @@ typedef struct _RTL_SHA1_CONTEXT
|
|||||||
UCHAR Buffer[SHA1_BLOCK_SIZE];
|
UCHAR Buffer[SHA1_BLOCK_SIZE];
|
||||||
} RTL_SHA1_CONTEXT, *PRTL_SHA1_CONTEXT;
|
} RTL_SHA1_CONTEXT, *PRTL_SHA1_CONTEXT;
|
||||||
|
|
||||||
/* Runtime time fields structure definition */
|
|
||||||
typedef struct _TIME_FIELDS
|
|
||||||
{
|
|
||||||
SHORT Year;
|
|
||||||
SHORT Month;
|
|
||||||
SHORT Day;
|
|
||||||
SHORT Hour;
|
|
||||||
SHORT Minute;
|
|
||||||
SHORT Second;
|
|
||||||
SHORT Milliseconds;
|
|
||||||
SHORT Weekday;
|
|
||||||
} TIME_FIELDS, *PTIME_FIELDS;
|
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_RTLTYPES_H */
|
#endif /* __XTDK_RTLTYPES_H */
|
||||||
|
|||||||
@@ -14,9 +14,6 @@
|
|||||||
#include <xttypes.h>
|
#include <xttypes.h>
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Kernel affinity */
|
/* Kernel affinity */
|
||||||
typedef ULONG_PTR KAFFINITY, *PKAFFINITY;
|
typedef ULONG_PTR KAFFINITY, *PKAFFINITY;
|
||||||
|
|
||||||
@@ -111,5 +108,4 @@ typedef struct _DISPATCHER_HEADER
|
|||||||
LIST_ENTRY WaitListHead;
|
LIST_ENTRY WaitListHead;
|
||||||
} DISPATCHER_HEADER, *PDISPATCHER_HEADER;
|
} DISPATCHER_HEADER, *PDISPATCHER_HEADER;
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER_ */
|
|
||||||
#endif /* __XTDK_XTBASE_H */
|
#endif /* __XTDK_XTBASE_H */
|
||||||
|
|||||||
@@ -10,15 +10,11 @@
|
|||||||
#define __XTDK_XTCOMPAT_H
|
#define __XTDK_XTCOMPAT_H
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
/* C++ definitions */
|
/* C++ definitions */
|
||||||
#define NULLPTR nullptr
|
#define NULLPTR nullptr
|
||||||
#define VIRTUAL virtual
|
#define VIRTUAL virtual
|
||||||
#define XTCLINK extern "C"
|
#define XTCLINK extern "C"
|
||||||
#define XTSYMBOL(Name) __asm__(Name)
|
|
||||||
|
|
||||||
/* C++ boolean type */
|
/* C++ boolean type */
|
||||||
typedef bool BOOLEAN, *PBOOLEAN;
|
typedef bool BOOLEAN, *PBOOLEAN;
|
||||||
@@ -32,7 +28,6 @@
|
|||||||
#define NULLPTR ((void *)0)
|
#define NULLPTR ((void *)0)
|
||||||
#define VIRTUAL
|
#define VIRTUAL
|
||||||
#define XTCLINK
|
#define XTCLINK
|
||||||
#define XTSYMBOL(Name)
|
|
||||||
|
|
||||||
/* C boolean type */
|
/* C boolean type */
|
||||||
typedef enum _BOOLEAN
|
typedef enum _BOOLEAN
|
||||||
@@ -45,5 +40,4 @@
|
|||||||
typedef unsigned short wchar;
|
typedef unsigned short wchar;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_XTCOMPAT_H */
|
#endif /* __XTDK_XTCOMPAT_H */
|
||||||
|
|||||||
@@ -58,10 +58,6 @@
|
|||||||
/* Macro for calculating size of an array */
|
/* Macro for calculating size of an array */
|
||||||
#define ARRAY_SIZE(Array) (sizeof(Array) / sizeof(*Array))
|
#define ARRAY_SIZE(Array) (sizeof(Array) / sizeof(*Array))
|
||||||
|
|
||||||
/* Macros for converting Binary Coded Decimal (BCD) into decimal and vice versa */
|
|
||||||
#define BCD_TO_DECIMAL(Value) (((Value) & 0x0F) + (((Value) >> 4) * 10))
|
|
||||||
#define DECIMAL_TO_BCD(Value) ((((Value) / 10) << 4) | ((Value) % 10))
|
|
||||||
|
|
||||||
/* Macros for concatenating two strings */
|
/* Macros for concatenating two strings */
|
||||||
#define CONCAT_STRING(Str1, Str2) Str1##Str2
|
#define CONCAT_STRING(Str1, Str2) Str1##Str2
|
||||||
#define CONCATENATE(Str1, Str2) CONCAT_STRING(Str1, Str2)
|
#define CONCATENATE(Str1, Str2) CONCAT_STRING(Str1, Str2)
|
||||||
@@ -115,6 +111,7 @@
|
|||||||
#define UNIQUE(Prefix) CONCATENATE(CONCATENATE(__UNIQUE_ID_, Prefix), __COUNTER__)
|
#define UNIQUE(Prefix) CONCATENATE(CONCATENATE(__UNIQUE_ID_, Prefix), __COUNTER__)
|
||||||
|
|
||||||
/* Variadic ABI functions */
|
/* Variadic ABI functions */
|
||||||
|
typedef __builtin_va_list VA_LIST, *PVA_LIST;
|
||||||
#define VA_ARG(Marker, Type) ((sizeof(Type) < sizeof(UINT_PTR)) ? \
|
#define VA_ARG(Marker, Type) ((sizeof(Type) < sizeof(UINT_PTR)) ? \
|
||||||
(Type)(__builtin_va_arg(Marker, UINT_PTR)) : \
|
(Type)(__builtin_va_arg(Marker, UINT_PTR)) : \
|
||||||
(Type)(__builtin_va_arg(Marker, Type)))
|
(Type)(__builtin_va_arg(Marker, Type)))
|
||||||
|
|||||||
@@ -13,9 +13,6 @@
|
|||||||
#include <xtdefs.h>
|
#include <xtdefs.h>
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef D__XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* SSF2 font header */
|
/* SSF2 font header */
|
||||||
typedef struct _SSFN_FONT_HEADER
|
typedef struct _SSFN_FONT_HEADER
|
||||||
{
|
{
|
||||||
@@ -3983,5 +3980,4 @@ UCHAR XtFbDefaultFont[] = {0x78, 0x74, 0x66, 0x6E, 0x3B, 0xE7, 0x00, 0x00, 0x03,
|
|||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0x82, 0x32, 0x4E, 0x46, 0x53};
|
0x82, 0x32, 0x4E, 0x46, 0x53};
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_XTFONT_H */
|
#endif /* __XTDK_XTFONT_H */
|
||||||
|
|||||||
@@ -19,10 +19,6 @@
|
|||||||
/* Version number of the current XTOS loader protocol */
|
/* Version number of the current XTOS loader protocol */
|
||||||
#define BOOT_PROTOCOL_VERSION 1
|
#define BOOT_PROTOCOL_VERSION 1
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Memory allocation structures */
|
/* Memory allocation structures */
|
||||||
typedef enum _LOADER_MEMORY_TYPE
|
typedef enum _LOADER_MEMORY_TYPE
|
||||||
{
|
{
|
||||||
@@ -120,5 +116,4 @@ typedef struct _KERNEL_INITIALIZATION_BLOCK
|
|||||||
FIRMWARE_INFORMATION_BLOCK FirmwareInformation;
|
FIRMWARE_INFORMATION_BLOCK FirmwareInformation;
|
||||||
} KERNEL_INITIALIZATION_BLOCK, *PKERNEL_INITIALIZATION_BLOCK;
|
} KERNEL_INITIALIZATION_BLOCK, *PKERNEL_INITIALIZATION_BLOCK;
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER_ */
|
|
||||||
#endif /* __XTDK_XTFW_H */
|
#endif /* __XTDK_XTFW_H */
|
||||||
|
|||||||
@@ -12,9 +12,6 @@
|
|||||||
#include <xttypes.h>
|
#include <xttypes.h>
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef D__XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
CHAR XTGLYPH_EXECTOS_LOGO[] =
|
CHAR XTGLYPH_EXECTOS_LOGO[] =
|
||||||
{
|
{
|
||||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x25, 0x23,
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x25, 0x23,
|
||||||
@@ -64,5 +61,4 @@ CHAR XTGLYPH_EXECTOS_LOGO[] =
|
|||||||
0x28, 0x0d, 0x0a
|
0x28, 0x0d, 0x0a
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_XTGLYPH_H */
|
#endif /* __XTDK_XTGLYPH_H */
|
||||||
|
|||||||
@@ -202,10 +202,6 @@
|
|||||||
#define PECOFF_IMAGE_SCN_MEM_READ 0x40000000
|
#define PECOFF_IMAGE_SCN_MEM_READ 0x40000000
|
||||||
#define PECOFF_IMAGE_SCN_MEM_WRITE 0x80000000
|
#define PECOFF_IMAGE_SCN_MEM_WRITE 0x80000000
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* PE/COFF image representation structure */
|
/* PE/COFF image representation structure */
|
||||||
typedef struct _PECOFF_IMAGE_CONTEXT
|
typedef struct _PECOFF_IMAGE_CONTEXT
|
||||||
{
|
{
|
||||||
@@ -642,5 +638,4 @@ typedef struct _PECOFF_IMAGE_RESOURCE_DATA_ENTRY
|
|||||||
ULONG Reserved;
|
ULONG Reserved;
|
||||||
} PECOFF_IMAGE_RESOURCE_DATA_ENTRY, *PPECOFF_IMAGE_RESOURCE_DATA_ENTRY;
|
} PECOFF_IMAGE_RESOURCE_DATA_ENTRY, *PPECOFF_IMAGE_RESOURCE_DATA_ENTRY;
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_XTIMAGE_H */
|
#endif /* __XTDK_XTIMAGE_H */
|
||||||
|
|||||||
@@ -50,7 +50,6 @@
|
|||||||
#include <hlfuncs.h>
|
#include <hlfuncs.h>
|
||||||
#include <kdfuncs.h>
|
#include <kdfuncs.h>
|
||||||
#include <kefuncs.h>
|
#include <kefuncs.h>
|
||||||
#include <mmfuncs.h>
|
|
||||||
#include <rtlfuncs.h>
|
#include <rtlfuncs.h>
|
||||||
|
|
||||||
/* Architecture specific XT routines */
|
/* Architecture specific XT routines */
|
||||||
|
|||||||
@@ -61,8 +61,6 @@
|
|||||||
#define STATUS_NO_MEMORY ((XTSTATUS) 0xC0000017L)
|
#define STATUS_NO_MEMORY ((XTSTATUS) 0xC0000017L)
|
||||||
#define STATUS_PORT_DISCONNECTED ((XTSTATUS) 0xC0000037L)
|
#define STATUS_PORT_DISCONNECTED ((XTSTATUS) 0xC0000037L)
|
||||||
#define STATUS_CRC_ERROR ((XTSTATUS) 0xC000003FL)
|
#define STATUS_CRC_ERROR ((XTSTATUS) 0xC000003FL)
|
||||||
#define STATUS_FLOAT_OVERFLOW ((XTSTATUS) 0xC0000091L)
|
|
||||||
#define STATUS_INTEGER_OVERFLOW ((XTSTATUS) 0xC0000095L)
|
|
||||||
#define STATUS_INSUFFICIENT_RESOURCES ((XTSTATUS) 0xC000009AL)
|
#define STATUS_INSUFFICIENT_RESOURCES ((XTSTATUS) 0xC000009AL)
|
||||||
#define STATUS_DEVICE_NOT_READY ((XTSTATUS) 0xC00000A3L)
|
#define STATUS_DEVICE_NOT_READY ((XTSTATUS) 0xC00000A3L)
|
||||||
#define STATUS_NOT_SUPPORTED ((XTSTATUS) 0xC00000BBL)
|
#define STATUS_NOT_SUPPORTED ((XTSTATUS) 0xC00000BBL)
|
||||||
|
|||||||
@@ -12,9 +12,6 @@
|
|||||||
#include <xtdefs.h>
|
#include <xtdefs.h>
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Enumeration lists forward references */
|
/* Enumeration lists forward references */
|
||||||
typedef enum _ADJUST_REASON ADJUST_REASON, *PADJUST_REASON;
|
typedef enum _ADJUST_REASON ADJUST_REASON, *PADJUST_REASON;
|
||||||
typedef enum _EXCEPTION_DISPOSITION EXCEPTION_DISPOSITION, *PEXCEPTION_DISPOSITION;
|
typedef enum _EXCEPTION_DISPOSITION EXCEPTION_DISPOSITION, *PEXCEPTION_DISPOSITION;
|
||||||
@@ -47,7 +44,6 @@ typedef enum _KDPC_IMPORTANCE KDPC_IMPORTANCE, *PKDPC_IMPORTANCE;
|
|||||||
typedef enum _KEVENT_TYPE KEVENT_TYPE, *PKEVENT_TYPE;
|
typedef enum _KEVENT_TYPE KEVENT_TYPE, *PKEVENT_TYPE;
|
||||||
typedef enum _KOBJECTS KOBJECTS, *PKOBJECTS;
|
typedef enum _KOBJECTS KOBJECTS, *PKOBJECTS;
|
||||||
typedef enum _KPROCESS_STATE KPROCESS_STATE, *PKPROCESS_STATE;
|
typedef enum _KPROCESS_STATE KPROCESS_STATE, *PKPROCESS_STATE;
|
||||||
typedef enum _KPROFILE_SOURCE KPROFILE_SOURCE, *PKPROFILE_SOURCE;
|
|
||||||
typedef enum _KTHREAD_STATE KTHREAD_STATE, *PKTHREAD_STATE;
|
typedef enum _KTHREAD_STATE KTHREAD_STATE, *PKTHREAD_STATE;
|
||||||
typedef enum _KTIMER_TYPE KTIMER_TYPE, *PKTIMER_TYPE;
|
typedef enum _KTIMER_TYPE KTIMER_TYPE, *PKTIMER_TYPE;
|
||||||
typedef enum _KUBSAN_DATA_TYPE KUBSAN_DATA_TYPE, *PKUBSAN_DATA_TYPE;
|
typedef enum _KUBSAN_DATA_TYPE KUBSAN_DATA_TYPE, *PKUBSAN_DATA_TYPE;
|
||||||
@@ -66,12 +62,8 @@ typedef enum _WAIT_TYPE WAIT_TYPE, *PWAIT_TYPE;
|
|||||||
typedef struct _ACPI_CACHE_LIST ACPI_CACHE_LIST, *PACPI_CACHE_LIST;
|
typedef struct _ACPI_CACHE_LIST ACPI_CACHE_LIST, *PACPI_CACHE_LIST;
|
||||||
typedef struct _ACPI_DESCRIPTION_HEADER ACPI_DESCRIPTION_HEADER, *PACPI_DESCRIPTION_HEADER;
|
typedef struct _ACPI_DESCRIPTION_HEADER ACPI_DESCRIPTION_HEADER, *PACPI_DESCRIPTION_HEADER;
|
||||||
typedef struct _ACPI_FADT ACPI_FADT, *PACPI_FADT;
|
typedef struct _ACPI_FADT ACPI_FADT, *PACPI_FADT;
|
||||||
typedef struct _ACPI_HPET ACPI_HPET, *PACPI_HPET;
|
|
||||||
typedef struct _ACPI_MADT ACPI_MADT, *PACPI_MADT;
|
typedef struct _ACPI_MADT ACPI_MADT, *PACPI_MADT;
|
||||||
typedef struct _ACPI_MADT_INTERRUPT_OVERRIDE ACPI_MADT_INTERRUPT_OVERRIDE, *PACPI_MADT_INTERRUPT_OVERRIDE;
|
typedef struct _ACPI_MADT_TABLE_LOCAL_APIC ACPI_MADT_TABLE_LOCAL_APIC, *PACPI_MADT_TABLE_LOCAL_APIC;
|
||||||
typedef struct _ACPI_MADT_IOAPIC ACPI_MADT_IOAPIC, *PACPI_MADT_IOAPIC;
|
|
||||||
typedef struct _ACPI_MADT_LOCAL_APIC ACPI_MADT_LOCAL_APIC, *PACPI_MADT_LOCAL_APIC;
|
|
||||||
typedef struct _ACPI_MADT_LOCAL_X2APIC ACPI_MADT_LOCAL_X2APIC, *PACPI_MADT_LOCAL_X2APIC;
|
|
||||||
typedef struct _ACPI_RSDP ACPI_RSDP, *PACPI_RSDP;
|
typedef struct _ACPI_RSDP ACPI_RSDP, *PACPI_RSDP;
|
||||||
typedef struct _ACPI_RSDT ACPI_RSDT, *PACPI_RSDT;
|
typedef struct _ACPI_RSDT ACPI_RSDT, *PACPI_RSDT;
|
||||||
typedef struct _ACPI_SUBTABLE_HEADER ACPI_SUBTABLE_HEADER, *PACPI_SUBTABLE_HEADER;
|
typedef struct _ACPI_SUBTABLE_HEADER ACPI_SUBTABLE_HEADER, *PACPI_SUBTABLE_HEADER;
|
||||||
@@ -263,9 +255,7 @@ typedef struct _KPROCESS KPROCESS, *PKPROCESS;
|
|||||||
typedef struct _KQUEUE KQUEUE, *PKQUEUE;
|
typedef struct _KQUEUE KQUEUE, *PKQUEUE;
|
||||||
typedef struct _KSEMAPHORE KSEMAPHORE, *PKSEMAPHORE;
|
typedef struct _KSEMAPHORE KSEMAPHORE, *PKSEMAPHORE;
|
||||||
typedef struct _KSERVICE_DESCRIPTOR_TABLE KSERVICE_DESCRIPTOR_TABLE, *PKSERVICE_DESCRIPTOR_TABLE;
|
typedef struct _KSERVICE_DESCRIPTOR_TABLE KSERVICE_DESCRIPTOR_TABLE, *PKSERVICE_DESCRIPTOR_TABLE;
|
||||||
typedef struct _KSHARED_DATA KSHARED_DATA, *PKSHARED_DATA;
|
|
||||||
typedef struct _KSPIN_LOCK_QUEUE KSPIN_LOCK_QUEUE, *PKSPIN_LOCK_QUEUE;
|
typedef struct _KSPIN_LOCK_QUEUE KSPIN_LOCK_QUEUE, *PKSPIN_LOCK_QUEUE;
|
||||||
typedef struct _KSYSTEM_TIME KSYSTEM_TIME, *PKSYSTEM_TIME;
|
|
||||||
typedef struct _KTHREAD KTHREAD, *PKTHREAD;
|
typedef struct _KTHREAD KTHREAD, *PKTHREAD;
|
||||||
typedef struct _KTIMER KTIMER, *PKTIMER;
|
typedef struct _KTIMER KTIMER, *PKTIMER;
|
||||||
typedef struct _KUBSAN_FLOAT_CAST_OVERFLOW_DATA KUBSAN_FLOAT_CAST_OVERFLOW_DATA, *PKUBSAN_FLOAT_CAST_OVERFLOW_DATA;
|
typedef struct _KUBSAN_FLOAT_CAST_OVERFLOW_DATA KUBSAN_FLOAT_CAST_OVERFLOW_DATA, *PKUBSAN_FLOAT_CAST_OVERFLOW_DATA;
|
||||||
@@ -337,8 +327,6 @@ typedef struct _STRING STRING, *PSTRING;
|
|||||||
typedef struct _STRING32 STRING32, *PSTRING32;
|
typedef struct _STRING32 STRING32, *PSTRING32;
|
||||||
typedef struct _STRING64 STRING64, *PSTRING64;
|
typedef struct _STRING64 STRING64, *PSTRING64;
|
||||||
typedef struct _THREAD_INFORMATION_BLOCK THREAD_INFORMATION_BLOCK, *PTHREAD_INFORMATION_BLOCK;
|
typedef struct _THREAD_INFORMATION_BLOCK THREAD_INFORMATION_BLOCK, *PTHREAD_INFORMATION_BLOCK;
|
||||||
typedef struct _TIME_FIELDS TIME_FIELDS, *PTIME_FIELDS;
|
|
||||||
typedef struct _TIMER_ROUTINES TIMER_ROUTINES, *PTIMER_ROUTINES;
|
|
||||||
typedef struct _UEFI_FIRMWARE_INFORMATION UEFI_FIRMWARE_INFORMATION, *PUEFI_FIRMWARE_INFORMATION;
|
typedef struct _UEFI_FIRMWARE_INFORMATION UEFI_FIRMWARE_INFORMATION, *PUEFI_FIRMWARE_INFORMATION;
|
||||||
typedef struct _UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING;
|
typedef struct _UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING;
|
||||||
typedef struct _UNICODE_STRING32 UNICODE_STRING32, *PUNICODE_STRING32;
|
typedef struct _UNICODE_STRING32 UNICODE_STRING32, *PUNICODE_STRING32;
|
||||||
@@ -375,5 +363,4 @@ typedef union _LARGE_INTEGER LARGE_INTEGER, *PLARGE_INTEGER;
|
|||||||
typedef union _SINGLE_LIST_HEADER SINGLE_LIST_HEADER, *PSINGLE_LIST_HEADER;
|
typedef union _SINGLE_LIST_HEADER SINGLE_LIST_HEADER, *PSINGLE_LIST_HEADER;
|
||||||
typedef union _ULARGE_INTEGER ULARGE_INTEGER, *PULARGE_INTEGER;
|
typedef union _ULARGE_INTEGER ULARGE_INTEGER, *PULARGE_INTEGER;
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_XTSTRUCT_H */
|
#endif /* __XTDK_XTSTRUCT_H */
|
||||||
|
|||||||
@@ -13,9 +13,6 @@
|
|||||||
#include <xtcompat.h>
|
#include <xtcompat.h>
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Standard C types */
|
/* Standard C types */
|
||||||
typedef unsigned char BYTE, *PBYTE, *LPBYTE;
|
typedef unsigned char BYTE, *PBYTE, *LPBYTE;
|
||||||
typedef char CHAR, *PCHAR, *LPCHAR;
|
typedef char CHAR, *PCHAR, *LPCHAR;
|
||||||
@@ -153,9 +150,6 @@ typedef LPCWSTR PCTSTR, LPCTSTR;
|
|||||||
typedef LPUWSTR PUTSTR, LPUTSTR;
|
typedef LPUWSTR PUTSTR, LPUTSTR;
|
||||||
typedef LPCUWSTR PCUTSTR, LPCUTSTR;
|
typedef LPCUWSTR PCUTSTR, LPCUTSTR;
|
||||||
|
|
||||||
/* Variadic ABI types */
|
|
||||||
typedef __builtin_va_list VA_LIST, *PVA_LIST;
|
|
||||||
|
|
||||||
/* 128-bit floats structure */
|
/* 128-bit floats structure */
|
||||||
typedef struct _FLOAT128
|
typedef struct _FLOAT128
|
||||||
{
|
{
|
||||||
@@ -293,5 +287,4 @@ typedef struct _UNICODE_STRING64
|
|||||||
} UNICODE_STRING64, *PUNICODE_STRING64;
|
} UNICODE_STRING64, *PUNICODE_STRING64;
|
||||||
typedef const UNICODE_STRING64 *PCUNICODE_STRING64;
|
typedef const UNICODE_STRING64 *PCUNICODE_STRING64;
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_XTTYPES_H */
|
#endif /* __XTDK_XTTYPES_H */
|
||||||
|
|||||||
@@ -373,10 +373,6 @@
|
|||||||
#define EFI_CONFIG_TABLE_SMBIOS_TABLE_GUID {0xEB9D2D31, 0x2D88, 0x11D3, {0x9A, 0x16, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}}
|
#define EFI_CONFIG_TABLE_SMBIOS_TABLE_GUID {0xEB9D2D31, 0x2D88, 0x11D3, {0x9A, 0x16, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}}
|
||||||
#define EFI_CONFIG_TABLE_SMBIOS3_TABLE_GUID {0xF2FD1544, 0x9794, 0x4A2C, {0x99, 0x2E, 0xE5, 0xBB, 0xCf, 0x20, 0xE3, 0x94}}
|
#define EFI_CONFIG_TABLE_SMBIOS3_TABLE_GUID {0xF2FD1544, 0x9794, 0x4A2C, {0x99, 0x2E, 0xE5, 0xBB, 0xCf, 0x20, 0xE3, 0x94}}
|
||||||
|
|
||||||
|
|
||||||
/* C/C++ specific code */
|
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
|
||||||
|
|
||||||
/* Basic UEFI types */
|
/* Basic UEFI types */
|
||||||
typedef PVOID EFI_EVENT, *PEFI_EVENT;
|
typedef PVOID EFI_EVENT, *PEFI_EVENT;
|
||||||
typedef PVOID EFI_HANDLE, *PEFI_HANDLE;
|
typedef PVOID EFI_HANDLE, *PEFI_HANDLE;
|
||||||
@@ -2727,5 +2723,4 @@ typedef struct _EFI_PROCESSOR_INFORMATION
|
|||||||
EFI_PROCESSOR_PHYSICAL_LOCATION Location;
|
EFI_PROCESSOR_PHYSICAL_LOCATION Location;
|
||||||
} EFI_PROCESSOR_INFORMATION, *PEFI_PROCESSOR_INFORMATION;
|
} EFI_PROCESSOR_INFORMATION, *PEFI_PROCESSOR_INFORMATION;
|
||||||
|
|
||||||
#endif /* __XTOS_ASSEMBLER__ */
|
|
||||||
#endif /* __XTDK_XTUEFI_H */
|
#endif /* __XTDK_XTUEFI_H */
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ include_directories(
|
|||||||
# Specify list of kernel source code files
|
# Specify list of kernel source code files
|
||||||
list(APPEND XTOSKRNL_SOURCE
|
list(APPEND XTOSKRNL_SOURCE
|
||||||
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/archsup.S
|
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/archsup.S
|
||||||
|
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/boot.S
|
||||||
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.cc
|
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/data.cc
|
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/data.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/procsup.cc
|
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/procsup.cc
|
||||||
@@ -17,13 +18,9 @@ list(APPEND XTOSKRNL_SOURCE
|
|||||||
${XTOSKRNL_SOURCE_DIR}/ex/exports.cc
|
${XTOSKRNL_SOURCE_DIR}/ex/exports.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ex/rundown.cc
|
${XTOSKRNL_SOURCE_DIR}/ex/rundown.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/cpu.cc
|
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/cpu.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/firmware.cc
|
|
||||||
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.cc
|
|
||||||
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/irq.cc
|
|
||||||
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/pic.cc
|
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/pic.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/rtc.cc
|
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/runlevel.cc
|
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/runlevel.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/timer.cc
|
|
||||||
${XTOSKRNL_SOURCE_DIR}/hl/acpi.cc
|
${XTOSKRNL_SOURCE_DIR}/hl/acpi.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/hl/cport.cc
|
${XTOSKRNL_SOURCE_DIR}/hl/cport.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/hl/data.cc
|
${XTOSKRNL_SOURCE_DIR}/hl/data.cc
|
||||||
@@ -34,7 +31,7 @@ list(APPEND XTOSKRNL_SOURCE
|
|||||||
${XTOSKRNL_SOURCE_DIR}/kd/data.cc
|
${XTOSKRNL_SOURCE_DIR}/kd/data.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/kd/dbgio.cc
|
${XTOSKRNL_SOURCE_DIR}/kd/dbgio.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/kd/exports.cc
|
${XTOSKRNL_SOURCE_DIR}/kd/exports.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/dispatch.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/irq.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/krnlinit.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/krnlinit.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/kthread.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/kthread.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/proc.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/proc.cc
|
||||||
@@ -42,7 +39,6 @@ list(APPEND XTOSKRNL_SOURCE
|
|||||||
${XTOSKRNL_SOURCE_DIR}/ke/bootinfo.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/bootinfo.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/crash.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/crash.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/data.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/data.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/dispatch.cc
|
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/dpc.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/dpc.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/event.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/event.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/exports.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/exports.cc
|
||||||
@@ -52,10 +48,8 @@ list(APPEND XTOSKRNL_SOURCE
|
|||||||
${XTOSKRNL_SOURCE_DIR}/ke/kubsan.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/kubsan.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/runlevel.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/runlevel.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/semphore.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/semphore.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/shdata.cc
|
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/spinlock.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/spinlock.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/sysres.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/sysres.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/systime.cc
|
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/timer.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/timer.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/mmgr.cc
|
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/mmgr.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pagemap.cc
|
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pagemap.cc
|
||||||
@@ -67,7 +61,6 @@ list(APPEND XTOSKRNL_SOURCE
|
|||||||
${XTOSKRNL_SOURCE_DIR}/mm/alloc.cc
|
${XTOSKRNL_SOURCE_DIR}/mm/alloc.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/colors.cc
|
${XTOSKRNL_SOURCE_DIR}/mm/colors.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/data.cc
|
${XTOSKRNL_SOURCE_DIR}/mm/data.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/exports.cc
|
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/hlpool.cc
|
${XTOSKRNL_SOURCE_DIR}/mm/hlpool.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/kpool.cc
|
${XTOSKRNL_SOURCE_DIR}/mm/kpool.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/mm/mmgr.cc
|
${XTOSKRNL_SOURCE_DIR}/mm/mmgr.cc
|
||||||
@@ -78,7 +71,6 @@ list(APPEND XTOSKRNL_SOURCE
|
|||||||
${XTOSKRNL_SOURCE_DIR}/po/idle.cc
|
${XTOSKRNL_SOURCE_DIR}/po/idle.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/dispatch.cc
|
${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/dispatch.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/exsup.cc
|
${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/exsup.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/intrin.cc
|
|
||||||
${XTOSKRNL_SOURCE_DIR}/rtl/atomic.cc
|
${XTOSKRNL_SOURCE_DIR}/rtl/atomic.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/rtl/bitmap.cc
|
${XTOSKRNL_SOURCE_DIR}/rtl/bitmap.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/rtl/data.cc
|
${XTOSKRNL_SOURCE_DIR}/rtl/data.cc
|
||||||
@@ -91,7 +83,6 @@ list(APPEND XTOSKRNL_SOURCE
|
|||||||
${XTOSKRNL_SOURCE_DIR}/rtl/sha1.cc
|
${XTOSKRNL_SOURCE_DIR}/rtl/sha1.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/rtl/slist.cc
|
${XTOSKRNL_SOURCE_DIR}/rtl/slist.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/rtl/string.cc
|
${XTOSKRNL_SOURCE_DIR}/rtl/string.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/rtl/time.cc
|
|
||||||
${XTOSKRNL_SOURCE_DIR}/rtl/widestr.cc)
|
${XTOSKRNL_SOURCE_DIR}/rtl/widestr.cc)
|
||||||
|
|
||||||
# Set module definition SPEC file
|
# Set module definition SPEC file
|
||||||
@@ -99,13 +90,15 @@ set_specfile(xtoskrnl.spec xtoskrnl.exe)
|
|||||||
|
|
||||||
# Link static XTOS library
|
# Link static XTOS library
|
||||||
add_library(libxtos ${XTOSKRNL_SOURCE})
|
add_library(libxtos ${XTOSKRNL_SOURCE})
|
||||||
target_link_libraries(libxtos PRIVATE xtadk)
|
|
||||||
|
|
||||||
# Link kernel executable
|
# Link kernel executable
|
||||||
add_executable(xtoskrnl ${CMAKE_CURRENT_BINARY_DIR}/xtoskrnl.def)
|
add_executable(xtoskrnl
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/xtoskrnl.def)
|
||||||
|
|
||||||
# Add linker libraries
|
# Add linker libraries
|
||||||
target_link_libraries(xtoskrnl PRIVATE libxtos)
|
target_link_libraries(xtoskrnl
|
||||||
|
PRIVATE
|
||||||
|
libxtos)
|
||||||
|
|
||||||
# Set proper binary name and install target
|
# Set proper binary name and install target
|
||||||
set_target_properties(xtoskrnl PROPERTIES SUFFIX .exe)
|
set_target_properties(xtoskrnl PROPERTIES SUFFIX .exe)
|
||||||
|
|||||||
@@ -11,23 +11,9 @@ These parameters can be configured either temporarily by editing the boot entry
|
|||||||
permanently by modifying the XTLDR configuration file.
|
permanently by modifying the XTLDR configuration file.
|
||||||
|
|
||||||
The following is a consolidated list of available kernel parameters:
|
The following is a consolidated list of available kernel parameters:
|
||||||
* **CLOCK**: Specifies the primary hardware source used to drive the periodic system clock interrupts and the thread
|
|
||||||
scheduler tick. Valid values include `LAPIC` (Local APIC Timer), `HPET` (High Precision Event Timer), and `PIT`
|
|
||||||
(Legacy Programmable Interval Timer). If this parameter is omitted, the kernel will autonomously probe the hardware
|
|
||||||
and select the most optimal clock source for the current CPU topology, (defaulting to the Local APIC on modern systems.
|
|
||||||
* **MAXCPUS**: Specifies the maximum number of logical processors the kernel is allowed to initialize and schedule.
|
|
||||||
Setting `MAXCPUS=1` explicitly disables Symmetric Multiprocessing (SMP), restricting execution exclusively to the Boot
|
|
||||||
Strap Processor (BSP) and ignoring all Application Processors (APs).
|
|
||||||
* **NOX2APIC**: Explicitly disables x2APIC support. When specified, the kernel bypasses hardware feature detection for
|
|
||||||
x2APIC and forces the use of the classic, memory-mapped (MMIO) xAPIC mode. This parameter is particularly useful for
|
|
||||||
troubleshooting interrupt routing issues or ensuring compatibility with specific hypervisors and legacy emulators.
|
|
||||||
* **NOXPA**: Disables PAE or LA57 support, depending on the CPU architecture. This parameter is handled by the
|
* **NOXPA**: Disables PAE or LA57 support, depending on the CPU architecture. This parameter is handled by the
|
||||||
bootloader, which configures paging and selects the appropriate Page Map Level (PML) before transferring control to
|
bootloader, which configures paging and selects the appropriate Page Map Level (PML) before transferring control to
|
||||||
the kernel.
|
the kernel.
|
||||||
* **TIMER**: Designates the hardware counter used for high-resolution performance tracking (Query Performance Counter)
|
|
||||||
and microsecond execution stalls. Valid values include `TSC` (Invariant Time Stamp Counter), `HPET`, `ACPI` (or `PM`)
|
|
||||||
for the ACPI Power Management Timer, and `PIT`. If not specified, the kernel evaluates hardware capabilities and
|
|
||||||
defaults to the most precise and reliable counter available (e.g., Invariant TSC).
|
|
||||||
|
|
||||||
## Source Code
|
## Source Code
|
||||||
The source code of the kernel is organized into subsystem-specific directories. Each directory name also defines the
|
The source code of the kernel is organized into subsystem-specific directories. Each directory name also defines the
|
||||||
|
|||||||
@@ -4,40 +4,29 @@
|
|||||||
* FILE: xtoskrnl/ar/amd64/archsup.S
|
* FILE: xtoskrnl/ar/amd64/archsup.S
|
||||||
* DESCRIPTION: Provides AMD64 architecture features not implementable in C
|
* DESCRIPTION: Provides AMD64 architecture features not implementable in C
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
* Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xtkmapi.h>
|
#include <ar/amd64/asmsup.h>
|
||||||
#include <xtadk.h>
|
|
||||||
|
|
||||||
.altmacro
|
.altmacro
|
||||||
.text
|
.text
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a trap or interrupt handler for the specified vector.
|
* Creates a trap handler for the specified vector.
|
||||||
*
|
*
|
||||||
* @param Vector
|
* @param Vector
|
||||||
* Supplies a trap/interrupt vector number.
|
* Supplies a trap vector number.
|
||||||
*
|
|
||||||
* @param Type
|
|
||||||
* Specifies whether the handler is designed to handle an interrupt or a trap.
|
|
||||||
*
|
*
|
||||||
* @return This macro does not return any value.
|
* @return This macro does not return any value.
|
||||||
*
|
*
|
||||||
* @since XT 1.0
|
* @since XT 1.0
|
||||||
*/
|
*/
|
||||||
.macro ArCreateHandler Vector Type
|
.macro ArCreateTrapHandler Vector
|
||||||
.global Ar\Type\Vector
|
.global ArTrap\Vector
|
||||||
Ar\Type\Vector:
|
ArTrap\Vector:
|
||||||
/* Check handler type */
|
/* Push fake error code for non-error vectors */
|
||||||
.ifc \Type,Trap
|
.if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
|
||||||
/* 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
|
push $0
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
@@ -62,122 +51,113 @@ Ar\Type\Vector:
|
|||||||
push %rax
|
push %rax
|
||||||
|
|
||||||
/* Reserve space for other registers and point RBP to the trap frame */
|
/* Reserve space for other registers and point RBP to the trap frame */
|
||||||
sub $(KTRAP_FRAME_SIZE - KTRAP_FRAME_REGISTERS_SIZE), %rsp
|
sub $(TRAP_FRAME_SIZE - TRAP_REGISTERS_SIZE), %rsp
|
||||||
lea (%rsp), %rbp
|
lea (%rsp), %rbp
|
||||||
|
|
||||||
/* Store segment selectors */
|
/* Store segment selectors */
|
||||||
mov %gs, KTRAP_FRAME_SegGs(%rbp)
|
mov %gs, TrapSegGs(%rbp)
|
||||||
mov %fs, KTRAP_FRAME_SegFs(%rbp)
|
mov %fs, TrapSegFs(%rbp)
|
||||||
mov %es, KTRAP_FRAME_SegEs(%rbp)
|
mov %es, TrapSegEs(%rbp)
|
||||||
mov %ds, KTRAP_FRAME_SegDs(%rbp)
|
mov %ds, TrapSegDs(%rbp)
|
||||||
|
|
||||||
/* Store debug registers */
|
/* Store debug registers */
|
||||||
mov %dr7, %rax
|
mov %dr7, %rax
|
||||||
mov %rax, KTRAP_FRAME_Dr7(%rbp)
|
mov %rax, TrapDr7(%rbp)
|
||||||
mov %dr6, %rax
|
mov %dr6, %rax
|
||||||
mov %rax, KTRAP_FRAME_Dr6(%rbp)
|
mov %rax, TrapDr6(%rbp)
|
||||||
mov %dr3, %rax
|
mov %dr3, %rax
|
||||||
mov %rax, KTRAP_FRAME_Dr3(%rbp)
|
mov %rax, TrapDr3(%rbp)
|
||||||
mov %dr2, %rax
|
mov %dr2, %rax
|
||||||
mov %rax, KTRAP_FRAME_Dr2(%rbp)
|
mov %rax, TrapDr2(%rbp)
|
||||||
mov %dr1, %rax
|
mov %dr1, %rax
|
||||||
mov %rax, KTRAP_FRAME_Dr1(%rbp)
|
mov %rax, TrapDr1(%rbp)
|
||||||
mov %dr0, %rax
|
mov %dr0, %rax
|
||||||
mov %rax, KTRAP_FRAME_Dr0(%rbp)
|
mov %rax, TrapDr0(%rbp)
|
||||||
|
|
||||||
/* Store CR2 and CR3 */
|
/* Store CR2 and CR3 */
|
||||||
mov %cr3, %rax
|
mov %cr3, %rax
|
||||||
mov %rax, KTRAP_FRAME_Cr3(%rbp)
|
mov %rax, TrapCr3(%rbp)
|
||||||
mov %cr2, %rax
|
mov %cr2, %rax
|
||||||
mov %rax, KTRAP_FRAME_Cr2(%rbp)
|
mov %rax, TrapCr2(%rbp)
|
||||||
|
|
||||||
/* Store MxCsr register */
|
/* Store MxCsr register */
|
||||||
stmxcsr KTRAP_FRAME_MxCsr(%rbp)
|
stmxcsr TrapMxCsr(%rbp)
|
||||||
|
|
||||||
/* Store XMM registers */
|
/* Store XMM registers */
|
||||||
movdqa %xmm15, KTRAP_FRAME_Xmm15(%rbp)
|
movdqa %xmm15, TrapXmm15(%rbp)
|
||||||
movdqa %xmm14, KTRAP_FRAME_Xmm14(%rbp)
|
movdqa %xmm14, TrapXmm14(%rbp)
|
||||||
movdqa %xmm13, KTRAP_FRAME_Xmm13(%rbp)
|
movdqa %xmm13, TrapXmm13(%rbp)
|
||||||
movdqa %xmm12, KTRAP_FRAME_Xmm12(%rbp)
|
movdqa %xmm12, TrapXmm12(%rbp)
|
||||||
movdqa %xmm11, KTRAP_FRAME_Xmm11(%rbp)
|
movdqa %xmm11, TrapXmm11(%rbp)
|
||||||
movdqa %xmm10, KTRAP_FRAME_Xmm10(%rbp)
|
movdqa %xmm10, TrapXmm10(%rbp)
|
||||||
movdqa %xmm9, KTRAP_FRAME_Xmm9(%rbp)
|
movdqa %xmm9, TrapXmm9(%rbp)
|
||||||
movdqa %xmm8, KTRAP_FRAME_Xmm8(%rbp)
|
movdqa %xmm8, TrapXmm8(%rbp)
|
||||||
movdqa %xmm7, KTRAP_FRAME_Xmm7(%rbp)
|
movdqa %xmm7, TrapXmm7(%rbp)
|
||||||
movdqa %xmm6, KTRAP_FRAME_Xmm6(%rbp)
|
movdqa %xmm6, TrapXmm6(%rbp)
|
||||||
movdqa %xmm5, KTRAP_FRAME_Xmm5(%rbp)
|
movdqa %xmm5, TrapXmm5(%rbp)
|
||||||
movdqa %xmm4, KTRAP_FRAME_Xmm4(%rbp)
|
movdqa %xmm4, TrapXmm4(%rbp)
|
||||||
movdqa %xmm3, KTRAP_FRAME_Xmm3(%rbp)
|
movdqa %xmm3, TrapXmm3(%rbp)
|
||||||
movdqa %xmm2, KTRAP_FRAME_Xmm2(%rbp)
|
movdqa %xmm2, TrapXmm2(%rbp)
|
||||||
movdqa %xmm1, KTRAP_FRAME_Xmm1(%rbp)
|
movdqa %xmm1, TrapXmm1(%rbp)
|
||||||
movdqa %xmm0, KTRAP_FRAME_Xmm0(%rbp)
|
movdqa %xmm0, TrapXmm0(%rbp)
|
||||||
|
|
||||||
/* Test previous mode and swap GS if needed */
|
/* Test previous mode and swap GS if needed */
|
||||||
movl $0, KTRAP_FRAME_PreviousMode(%rbp)
|
movl $0, TrapPreviousMode(%rbp)
|
||||||
mov KTRAP_FRAME_SegCs(%rbp), %ax
|
mov %cs, %ax
|
||||||
and $3, %al
|
and $3, %al
|
||||||
mov %al, KTRAP_FRAME_PreviousMode(%rbp)
|
mov %al, TrapPreviousMode(%rbp)
|
||||||
|
jz KernelMode$\Vector
|
||||||
/* Skip swapgs as the interrupt originated from kernel mode */
|
|
||||||
jz Dispatch\Type\Vector
|
|
||||||
|
|
||||||
swapgs
|
swapgs
|
||||||
|
jmp UserMode$\Vector
|
||||||
|
|
||||||
Dispatch\Type\Vector:
|
KernelMode$\Vector:
|
||||||
/* Set up trap frame pointer for the dispatcher and clear the direction flag */
|
/* Save kernel stack pointer (SS:RSP) */
|
||||||
|
movl %ss, %eax
|
||||||
|
mov %eax, TrapSegSs(%rbp)
|
||||||
|
lea TRAP_FRAME_SIZE(%rbp), %rax
|
||||||
|
mov %rax, TrapRsp(%rbp)
|
||||||
|
|
||||||
|
UserMode$\Vector:
|
||||||
|
/* Push Frame Pointer, clear direction flag and pass to trap dispatcher */
|
||||||
mov %rsp, %rcx
|
mov %rsp, %rcx
|
||||||
cld
|
cld
|
||||||
|
call ArDispatchTrap
|
||||||
/* 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 */
|
/* Test previous mode and swapgs if needed */
|
||||||
testb $1, KTRAP_FRAME_PreviousMode(%rbp)
|
testb $1, TrapPreviousMode(%rbp)
|
||||||
jz RestoreState\Type\Vector
|
jz KernelModeReturn$\Vector
|
||||||
cli
|
cli
|
||||||
swapgs
|
swapgs
|
||||||
|
|
||||||
RestoreState\Type\Vector:
|
KernelModeReturn$\Vector:
|
||||||
/* Restore XMM registers */
|
/* Restore XMM registers */
|
||||||
movdqa KTRAP_FRAME_Xmm0(%rbp), %xmm0
|
movdqa TrapXmm0(%rbp), %xmm0
|
||||||
movdqa KTRAP_FRAME_Xmm1(%rbp), %xmm1
|
movdqa TrapXmm1(%rbp), %xmm1
|
||||||
movdqa KTRAP_FRAME_Xmm2(%rbp), %xmm2
|
movdqa TrapXmm2(%rbp), %xmm2
|
||||||
movdqa KTRAP_FRAME_Xmm3(%rbp), %xmm3
|
movdqa TrapXmm3(%rbp), %xmm3
|
||||||
movdqa KTRAP_FRAME_Xmm4(%rbp), %xmm4
|
movdqa TrapXmm4(%rbp), %xmm4
|
||||||
movdqa KTRAP_FRAME_Xmm5(%rbp), %xmm5
|
movdqa TrapXmm5(%rbp), %xmm5
|
||||||
movdqa KTRAP_FRAME_Xmm6(%rbp), %xmm6
|
movdqa TrapXmm6(%rbp), %xmm6
|
||||||
movdqa KTRAP_FRAME_Xmm7(%rbp), %xmm7
|
movdqa TrapXmm7(%rbp), %xmm7
|
||||||
movdqa KTRAP_FRAME_Xmm8(%rbp), %xmm8
|
movdqa TrapXmm8(%rbp), %xmm8
|
||||||
movdqa KTRAP_FRAME_Xmm9(%rbp), %xmm9
|
movdqa TrapXmm9(%rbp), %xmm9
|
||||||
movdqa KTRAP_FRAME_Xmm10(%rbp), %xmm10
|
movdqa TrapXmm10(%rbp), %xmm10
|
||||||
movdqa KTRAP_FRAME_Xmm11(%rbp), %xmm11
|
movdqa TrapXmm11(%rbp), %xmm11
|
||||||
movdqa KTRAP_FRAME_Xmm12(%rbp), %xmm12
|
movdqa TrapXmm12(%rbp), %xmm12
|
||||||
movdqa KTRAP_FRAME_Xmm13(%rbp), %xmm13
|
movdqa TrapXmm13(%rbp), %xmm13
|
||||||
movdqa KTRAP_FRAME_Xmm14(%rbp), %xmm14
|
movdqa TrapXmm14(%rbp), %xmm14
|
||||||
movdqa KTRAP_FRAME_Xmm15(%rbp), %xmm15
|
movdqa TrapXmm15(%rbp), %xmm15
|
||||||
|
|
||||||
/* Load MxCsr register */
|
/* Load MxCsr register */
|
||||||
ldmxcsr KTRAP_FRAME_MxCsr(%rbp)
|
ldmxcsr TrapMxCsr(%rbp)
|
||||||
|
|
||||||
|
/* Restore segment selectors */
|
||||||
|
mov TrapSegDs(%rbp), %ds
|
||||||
|
mov TrapSegEs(%rbp), %es
|
||||||
|
mov TrapSegFs(%rbp), %fs
|
||||||
|
|
||||||
/* Free stack space */
|
/* Free stack space */
|
||||||
add $(KTRAP_FRAME_SIZE - KTRAP_FRAME_REGISTERS_SIZE), %rsp
|
add $(TRAP_FRAME_SIZE - TRAP_REGISTERS_SIZE), %rsp
|
||||||
|
|
||||||
/* Pop General Purpose Registers */
|
/* Pop General Purpose Registers */
|
||||||
pop %rax
|
pop %rax
|
||||||
@@ -201,289 +181,9 @@ RestoreState\Type\Vector:
|
|||||||
iretq
|
iretq
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
/* Populate common interrupt and trap handlers */
|
/* Populate common trap handlers */
|
||||||
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||||
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||||
ArCreateHandler 0x\i\j Interrupt
|
ArCreateTrapHandler 0x\i\j
|
||||||
ArCreateHandler 0x\i\j Trap
|
|
||||||
.endr
|
.endr
|
||||||
.endr
|
.endr
|
||||||
|
|
||||||
/* Define array of pointers to the interrupt handlers */
|
|
||||||
.global ArInterruptEntry
|
|
||||||
ArInterruptEntry:
|
|
||||||
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
|
||||||
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
|
||||||
.quad ArInterrupt0x\i\j
|
|
||||||
.endr
|
|
||||||
.endr
|
|
||||||
|
|
||||||
/* Define array of pointers to the trap handlers */
|
|
||||||
.global ArTrapEntry
|
|
||||||
ArTrapEntry:
|
|
||||||
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
|
||||||
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
|
||||||
.quad ArTrap0x\i\j
|
|
||||||
.endr
|
|
||||||
.endr
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enables eXtended Physical Addressing (XPA).
|
|
||||||
*
|
|
||||||
* @param PageMap
|
|
||||||
* Supplies a pointer to the page map to be used.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
.global ArEnableExtendedPhysicalAddressing
|
|
||||||
ArEnableExtendedPhysicalAddressing:
|
|
||||||
/* Save the original CR4 register */
|
|
||||||
movq %cr4, %rax
|
|
||||||
|
|
||||||
/* Save the state of stack pointer and non-volatile registers */
|
|
||||||
movq %rsp, XpaRegisterSaveArea(%rip)
|
|
||||||
movq %rbp, XpaRegisterSaveArea+0x08(%rip)
|
|
||||||
movq %rax, XpaRegisterSaveArea+0x10(%rip)
|
|
||||||
movq %rbx, XpaRegisterSaveArea+0x18(%rip)
|
|
||||||
|
|
||||||
/* Save the original CR0 register */
|
|
||||||
movq %cr0, %rbp
|
|
||||||
|
|
||||||
/* Load temporary GDT required for mode transitions */
|
|
||||||
leaq XpaTemporaryGdtDesc(%rip), %rax
|
|
||||||
movq %rax, XpaTemporaryGdtBase(%rip)
|
|
||||||
lgdtq XpaTemporaryGdtSize(%rip)
|
|
||||||
|
|
||||||
/* Load addresses for entering compatibility mode and re-entering long mode */
|
|
||||||
leaq XpaEnterCompatMode(%rip), %rax
|
|
||||||
leaq XpaEnterLongMode(%rip), %rbx
|
|
||||||
|
|
||||||
/* Push the 32-bit code segment selector and the target address for a far jump */
|
|
||||||
pushq $KGDT_R0_CMCODE
|
|
||||||
pushq %rax
|
|
||||||
|
|
||||||
/* Perform a far return to switch to 32-bit compatibility mode */
|
|
||||||
lretq
|
|
||||||
|
|
||||||
XpaEnterCompatMode:
|
|
||||||
/* Enter 32-bit compatibility mode */
|
|
||||||
.code32
|
|
||||||
|
|
||||||
/* Store the PageMap pointer on the stack for future use */
|
|
||||||
pushl %ecx
|
|
||||||
|
|
||||||
/* Set the stack segment to the 32-bit data segment selector */
|
|
||||||
movl $KGDT_R0_DATA, %eax
|
|
||||||
movl %eax, %ss
|
|
||||||
|
|
||||||
/* Disable PGE and PCIDE to ensure all TLB entries will be flushed */
|
|
||||||
movl %cr4, %eax
|
|
||||||
andl $~(CR4_PGE | CR4_PCIDE), %eax
|
|
||||||
movl %eax, %cr4
|
|
||||||
|
|
||||||
/* Temporarily disable paging */
|
|
||||||
movl %ebp, %eax
|
|
||||||
andl $~CR0_PG, %eax
|
|
||||||
movl %eax, %cr0
|
|
||||||
|
|
||||||
/* Disable Long Mode as prerequisite for enabling 5-level paging */
|
|
||||||
movl $X86_MSR_EFER, %ecx
|
|
||||||
rdmsr
|
|
||||||
andl $~X86_MSR_EFER_LME, %eax
|
|
||||||
wrmsr
|
|
||||||
|
|
||||||
/* Transition to 5-level paging (PML5/LA57) */
|
|
||||||
movl %cr4, %eax
|
|
||||||
orl $CR4_LA57, %eax
|
|
||||||
movl %eax, %cr4
|
|
||||||
|
|
||||||
/* Restore the PageMap pointer from the stack and load it into CR3 */
|
|
||||||
popl %ecx
|
|
||||||
movl %ecx, %cr3
|
|
||||||
|
|
||||||
/* Re-enable Long Mode */
|
|
||||||
movl $X86_MSR_EFER, %ecx
|
|
||||||
rdmsr
|
|
||||||
orl $X86_MSR_EFER_LME, %eax
|
|
||||||
wrmsr
|
|
||||||
|
|
||||||
/* Restore CR0 with paging enabled and flush the instruction pipeline */
|
|
||||||
movl %ebp, %cr0
|
|
||||||
call XpaFlushInstructions
|
|
||||||
|
|
||||||
XpaFlushInstructions:
|
|
||||||
/* Push the 64-bit code segment selector and the target address for a far jump */
|
|
||||||
pushl $KGDT_R0_CODE
|
|
||||||
pushl %ebx
|
|
||||||
|
|
||||||
/* Perform a far return to switch to 64-bit long mode */
|
|
||||||
lretl
|
|
||||||
|
|
||||||
XpaEnterLongMode:
|
|
||||||
/* Enter 64-bit long mode */
|
|
||||||
.code64
|
|
||||||
|
|
||||||
/* Restore the stack pointer and non-volatile registers */
|
|
||||||
movq XpaRegisterSaveArea(%rip), %rsp
|
|
||||||
movq XpaRegisterSaveArea+8(%rip), %rbp
|
|
||||||
movq XpaRegisterSaveArea+0x10(%rip), %rax
|
|
||||||
movq XpaRegisterSaveArea+0x18(%rip), %rbx
|
|
||||||
|
|
||||||
/* Restore the original CR4 register with LA57 bit set */
|
|
||||||
orq $CR4_LA57, %rax
|
|
||||||
movq %rax, %cr4
|
|
||||||
|
|
||||||
/* Return to the caller */
|
|
||||||
retq
|
|
||||||
|
|
||||||
/* Data section for saving registers and temporary GDT */
|
|
||||||
XpaRegisterSaveArea: .quad 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000
|
|
||||||
XpaTemporaryGdtSize: .short ArEnableExtendedPhysicalAddressingEnd - XpaTemporaryGdtDesc - 1
|
|
||||||
XpaTemporaryGdtBase: .quad 0x0000000000000000
|
|
||||||
XpaTemporaryGdtDesc: .quad 0x0000000000000000, 0x00CF9A000000FFFF, 0x00AF9A000000FFFF, 0x00CF92000000FFFF
|
|
||||||
|
|
||||||
.global ArEnableExtendedPhysicalAddressingEnd
|
|
||||||
ArEnableExtendedPhysicalAddressingEnd:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles a spurious interrupt allowing it to end up.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
.global ArHandleSpuriousInterrupt
|
|
||||||
ArHandleSpuriousInterrupt:
|
|
||||||
iretq
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts an application processor (AP).
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
.global ArStartApplicationProcessor
|
|
||||||
ArStartApplicationProcessor:
|
|
||||||
/* Enter 16-bit real mode */
|
|
||||||
.code16
|
|
||||||
|
|
||||||
/* Disable interrupts and clear direction flag */
|
|
||||||
cli
|
|
||||||
cld
|
|
||||||
|
|
||||||
/* Establish a flat addressing baseline */
|
|
||||||
movw %cs, %ax
|
|
||||||
movw %ax, %ds
|
|
||||||
movw %ax, %es
|
|
||||||
movw %ax, %ss
|
|
||||||
|
|
||||||
/* Calculate absolute physical base address */
|
|
||||||
xorl %ebx, %ebx
|
|
||||||
movw %cs, %bx
|
|
||||||
shll $4, %ebx
|
|
||||||
|
|
||||||
/* Set up a temporary stack for the AP initialization */
|
|
||||||
movl %ebx, %esp
|
|
||||||
addl $0x1000, %esp
|
|
||||||
|
|
||||||
/* Load the temporary Global Descriptor Table */
|
|
||||||
leal (ApTemporaryGdtDesc - ArStartApplicationProcessor)(%ebx), %eax
|
|
||||||
movl %eax, (ApTemporaryGdtBase - ArStartApplicationProcessor)
|
|
||||||
lgdtl (ApTemporaryGdtSize - ArStartApplicationProcessor)
|
|
||||||
|
|
||||||
/* Enable Protected Mode */
|
|
||||||
movl %cr0, %eax
|
|
||||||
orl $0x01, %eax
|
|
||||||
movl %eax, %cr0
|
|
||||||
|
|
||||||
/* Far return to enter 32-bit protected mode */
|
|
||||||
leal (ApEnterProtectedMode - ArStartApplicationProcessor)(%ebx), %eax
|
|
||||||
pushl $KGDT_R0_CMCODE
|
|
||||||
pushl %eax
|
|
||||||
lretl
|
|
||||||
|
|
||||||
ApEnterProtectedMode:
|
|
||||||
/* Enter 32-bit protected mode */
|
|
||||||
.code32
|
|
||||||
|
|
||||||
/* Setup all data segment registers */
|
|
||||||
movw $KGDT_R0_DATA, %ax
|
|
||||||
movw %ax, %ds
|
|
||||||
movw %ax, %es
|
|
||||||
movw %ax, %ss
|
|
||||||
xorw %ax, %ax
|
|
||||||
movw %ax, %fs
|
|
||||||
movw %ax, %gs
|
|
||||||
|
|
||||||
/* Locate PROCESSOR_START_BLOCK structure */
|
|
||||||
leal (ArStartApplicationProcessorEnd - ArStartApplicationProcessor)(%ebx), %edi
|
|
||||||
|
|
||||||
/* Load CR4 from BSP, but mask PCIDE and PGE */
|
|
||||||
movl PROCESSOR_START_BLOCK_Cr4(%edi), %eax
|
|
||||||
andl $~(CR4_PGE | CR4_PCIDE), %eax
|
|
||||||
movl %eax, %cr4
|
|
||||||
|
|
||||||
/* Load the Kernel Page Directory Base from BSP */
|
|
||||||
movl PROCESSOR_START_BLOCK_Cr3(%edi), %eax
|
|
||||||
movl %eax, %cr3
|
|
||||||
|
|
||||||
/* Enable Long Mode and No-Execute */
|
|
||||||
movl $X86_MSR_EFER, %ecx
|
|
||||||
rdmsr
|
|
||||||
orl $(X86_MSR_EFER_LME | X86_MSR_EFER_NXE), %eax
|
|
||||||
wrmsr
|
|
||||||
|
|
||||||
/* Enable Paging */
|
|
||||||
movl %cr0, %eax
|
|
||||||
orl $CR0_PG, %eax
|
|
||||||
movl %eax, %cr0
|
|
||||||
|
|
||||||
/* Far return to enter 64-bit long mode */
|
|
||||||
leal (ApEnterLongMode - ArStartApplicationProcessor)(%ebx), %eax
|
|
||||||
pushl $KGDT_R0_CODE
|
|
||||||
pushl %eax
|
|
||||||
lretl
|
|
||||||
|
|
||||||
ApEnterLongMode:
|
|
||||||
/* Enter 64-bit long mode */
|
|
||||||
.code64
|
|
||||||
|
|
||||||
/* Clear all segment registers */
|
|
||||||
xorw %ax, %ax
|
|
||||||
movw %ax, %ds
|
|
||||||
movw %ax, %es
|
|
||||||
movw %ax, %ss
|
|
||||||
movw %ax, %fs
|
|
||||||
movw %ax, %gs
|
|
||||||
|
|
||||||
/* Zero-extend EDI into RDI to ensure safe 64-bit pointer usage */
|
|
||||||
movl %edi, %edi
|
|
||||||
|
|
||||||
/* Load dedicated Stack for AP */
|
|
||||||
movq PROCESSOR_START_BLOCK_Stack(%rdi), %rsp
|
|
||||||
|
|
||||||
/* Save the pointer to PROCESSOR_START_BLOCK */
|
|
||||||
movq %rdi, %rcx
|
|
||||||
pushq %rdi
|
|
||||||
|
|
||||||
/* Call the EntryPoint routine */
|
|
||||||
movq PROCESSOR_START_BLOCK_EntryPoint(%rdi), %rax
|
|
||||||
call *%rax
|
|
||||||
|
|
||||||
/* Fire the breakpoint and halt if the entry point returns */
|
|
||||||
.ApNoReturnPoint:
|
|
||||||
int $0x03
|
|
||||||
hlt
|
|
||||||
jmp .ApNoReturnPoint
|
|
||||||
|
|
||||||
/* Data section for temporary GDT */
|
|
||||||
.align 8
|
|
||||||
ApTemporaryGdtSize: .short ArStartApplicationProcessorEnd - ApTemporaryGdtDesc - 1
|
|
||||||
ApTemporaryGdtBase: .quad 0x0000000000000000
|
|
||||||
ApTemporaryGdtDesc: .quad 0x0000000000000000, 0x00CF9A000000FFFF, 0x00AF9A000000FFFF, 0x00CF92000000FFFF
|
|
||||||
|
|
||||||
.global ArStartApplicationProcessorEnd
|
|
||||||
ArStartApplicationProcessorEnd:
|
|
||||||
|
|||||||
147
xtoskrnl/ar/amd64/boot.S
Normal file
147
xtoskrnl/ar/amd64/boot.S
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
/**
|
||||||
|
* PROJECT: ExectOS
|
||||||
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
|
* FILE: xtoskrnl/ar/amd64/boot.S
|
||||||
|
* DESCRIPTION: AMD64-specific boot code for setting up the low-level CPU environment
|
||||||
|
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ar/amd64/asmsup.h>
|
||||||
|
|
||||||
|
.altmacro
|
||||||
|
.text
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables eXtended Physical Addressing (XPA).
|
||||||
|
*
|
||||||
|
* @param PageMap
|
||||||
|
* Supplies a pointer to the page map to be used.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
.global ArEnableExtendedPhysicalAddressing
|
||||||
|
ArEnableExtendedPhysicalAddressing:
|
||||||
|
/* Save the original CR4 register */
|
||||||
|
movq %cr4, %rax
|
||||||
|
|
||||||
|
/* Save the state of stack pointer and non-volatile registers */
|
||||||
|
movq %rsp, XpaRegisterSaveArea(%rip)
|
||||||
|
movq %rbp, XpaRegisterSaveArea+0x08(%rip)
|
||||||
|
movq %rax, XpaRegisterSaveArea+0x10(%rip)
|
||||||
|
movq %rbx, XpaRegisterSaveArea+0x18(%rip)
|
||||||
|
|
||||||
|
/* Save the original CR0 register */
|
||||||
|
movq %cr0, %rbp
|
||||||
|
|
||||||
|
/* Load temporary GDT required for mode transitions */
|
||||||
|
leaq XpaTemporaryGdtDesc(%rip), %rax
|
||||||
|
movq %rax, XpaTemporaryGdtBase(%rip)
|
||||||
|
lgdtq XpaTemporaryGdtSize(%rip)
|
||||||
|
|
||||||
|
/* Load addresses for entering compatibility mode and re-entering long mode */
|
||||||
|
leaq XpaEnterCompatMode(%rip), %rax
|
||||||
|
leaq XpaEnterLongMode(%rip), %rbx
|
||||||
|
|
||||||
|
/* Push the 32-bit code segment selector and the target address for a far jump */
|
||||||
|
pushq $GDT_R0_CMCODE
|
||||||
|
pushq %rax
|
||||||
|
|
||||||
|
/* Perform a far return to switch to 32-bit compatibility mode */
|
||||||
|
lretq
|
||||||
|
|
||||||
|
XpaEnterCompatMode:
|
||||||
|
/* Enter 32-bit compatibility mode */
|
||||||
|
.code32
|
||||||
|
|
||||||
|
/* Store the PageMap pointer on the stack for future use */
|
||||||
|
pushl %ecx
|
||||||
|
|
||||||
|
/* Set the stack segment to the 32-bit data segment selector */
|
||||||
|
movl $GDT_R0_DATA, %eax
|
||||||
|
movl %eax, %ss
|
||||||
|
|
||||||
|
/* Disable PGE and PCIDE to ensure all TLB entries will be flushed */
|
||||||
|
movl %cr4, %eax
|
||||||
|
andl $~(CR4_PGE | CR4_PCIDE), %eax
|
||||||
|
movl %eax, %cr4
|
||||||
|
|
||||||
|
/* Temporarily disable paging */
|
||||||
|
movl %ebp, %eax
|
||||||
|
andl $~CR0_PG, %eax
|
||||||
|
movl %eax, %cr0
|
||||||
|
|
||||||
|
/* Disable Long Mode as prerequisite for enabling 5-level paging */
|
||||||
|
movl $X86_MSR_EFER, %ecx
|
||||||
|
rdmsr
|
||||||
|
andl $~X86_MSR_EFER_LME, %eax
|
||||||
|
wrmsr
|
||||||
|
|
||||||
|
/* Transition to 5-level paging (PML5/LA57) */
|
||||||
|
movl %cr4, %eax
|
||||||
|
orl $CR4_LA57, %eax
|
||||||
|
movl %eax, %cr4
|
||||||
|
|
||||||
|
/* Restore the PageMap pointer from the stack and load it into CR3 */
|
||||||
|
popl %ecx
|
||||||
|
movl %ecx, %cr3
|
||||||
|
|
||||||
|
/* Re-enable Long Mode */
|
||||||
|
movl $X86_MSR_EFER, %ecx
|
||||||
|
rdmsr
|
||||||
|
orl $X86_MSR_EFER_LME, %eax
|
||||||
|
wrmsr
|
||||||
|
|
||||||
|
/* Restore CR0 with paging enabled and flush the instruction pipeline */
|
||||||
|
movl %ebp, %cr0
|
||||||
|
call XpaFlushInstructions
|
||||||
|
|
||||||
|
XpaFlushInstructions:
|
||||||
|
/* Push the 64-bit code segment selector and the target address for a far jump */
|
||||||
|
pushl $GDT_R0_CODE
|
||||||
|
pushl %ebx
|
||||||
|
|
||||||
|
/* Perform a far return to switch to 64-bit long mode */
|
||||||
|
lretl
|
||||||
|
|
||||||
|
XpaEnterLongMode:
|
||||||
|
/* Enter 64-bit long mode */
|
||||||
|
.code64
|
||||||
|
|
||||||
|
/* Restore the stack pointer and non-volatile registers */
|
||||||
|
movq XpaRegisterSaveArea(%rip), %rsp
|
||||||
|
movq XpaRegisterSaveArea+8(%rip), %rbp
|
||||||
|
movq XpaRegisterSaveArea+0x10(%rip), %rax
|
||||||
|
movq XpaRegisterSaveArea+0x18(%rip), %rbx
|
||||||
|
|
||||||
|
/* Restore the original CR4 register with LA57 bit set */
|
||||||
|
orq $CR4_LA57, %rax
|
||||||
|
movq %rax, %cr4
|
||||||
|
|
||||||
|
/* Return to the caller */
|
||||||
|
retq
|
||||||
|
|
||||||
|
/* Data section for saving registers and temporary GDT */
|
||||||
|
XpaRegisterSaveArea: .quad 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000
|
||||||
|
XpaTemporaryGdtSize: .short ArEnableExtendedPhysicalAddressingEnd - XpaTemporaryGdtDesc - 1
|
||||||
|
XpaTemporaryGdtBase: .quad 0x0000000000000000
|
||||||
|
XpaTemporaryGdtDesc: .quad 0x0000000000000000, 0x00CF9A000000FFFF, 0x00AF9A000000FFFF, 0x00CF92000000FFFF
|
||||||
|
|
||||||
|
.global ArEnableExtendedPhysicalAddressingEnd
|
||||||
|
ArEnableExtendedPhysicalAddressingEnd:
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts an application processor (AP). This is just a stub.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
.global ArStartApplicationProcessor
|
||||||
|
ArStartApplicationProcessor:
|
||||||
|
|
||||||
|
.global ArStartApplicationProcessorEnd
|
||||||
|
ArStartApplicationProcessorEnd:
|
||||||
@@ -573,33 +573,6 @@ AR::CpuFunc::ReadTimeStampCounter(VOID)
|
|||||||
return ((ULONGLONG)High << 32) | Low;
|
return ((ULONGLONG)High << 32) | Low;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads the current value of the CPU's time-stamp counter and processor ID.
|
|
||||||
*
|
|
||||||
* @param TscAux
|
|
||||||
* Supplies a pointer to a variable that receives the auxiliary TSC information (IA32_TSC_AUX).
|
|
||||||
*
|
|
||||||
* @return This routine returns the current instruction cycle count since the processor was last reset.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
ULONGLONG
|
|
||||||
AR::CpuFunc::ReadTimeStampCounterProcessor(OUT PULONG TscAux)
|
|
||||||
{
|
|
||||||
ULONG Low, High;
|
|
||||||
|
|
||||||
/* Execute the RDTSCP instruction */
|
|
||||||
__asm__ volatile("rdtscp"
|
|
||||||
: "=a" (Low),
|
|
||||||
"=d" (High),
|
|
||||||
"=c" (*TscAux)
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Combine the two 32-bit registers into a single 64-bit unsigned integer and return the value */
|
|
||||||
return ((ULONGLONG)High << 32) | Low;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Orders memory accesses as seen by other processors, without fence.
|
* Orders memory accesses as seen by other processors, without fence.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -26,9 +26,3 @@ KPROCESSOR_BLOCK AR::ProcSup::InitialProcessorBlock;
|
|||||||
|
|
||||||
/* Initial TSS */
|
/* Initial TSS */
|
||||||
KTSS AR::ProcSup::InitialTss;
|
KTSS AR::ProcSup::InitialTss;
|
||||||
|
|
||||||
/* Initial kernel NMI stack */
|
|
||||||
UCHAR AR::ProcSup::NmiStack[KERNEL_STACK_SIZE] = {};
|
|
||||||
|
|
||||||
/* Unhandled interrupt routine */
|
|
||||||
PINTERRUPT_HANDLER AR::Traps::UnhandledInterruptRoutine = NULLPTR;
|
|
||||||
|
|||||||
@@ -20,8 +20,7 @@ XTAPI
|
|||||||
PVOID
|
PVOID
|
||||||
AR::ProcSup::GetBootStack(VOID)
|
AR::ProcSup::GetBootStack(VOID)
|
||||||
{
|
{
|
||||||
/* Return base address of kernel boot stack */
|
return (PVOID)BootStack;
|
||||||
return (PVOID)((ULONG_PTR)BootStack + KERNEL_STACK_SIZE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XTAPI
|
XTAPI
|
||||||
@@ -30,23 +29,19 @@ AR::ProcSup::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
|
|||||||
OUT PVOID *TrampolineCode,
|
OUT PVOID *TrampolineCode,
|
||||||
OUT PULONG_PTR TrampolineSize)
|
OUT PULONG_PTR TrampolineSize)
|
||||||
{
|
{
|
||||||
/* Get trampoline information */
|
|
||||||
switch(TrampolineType)
|
switch(TrampolineType)
|
||||||
{
|
{
|
||||||
case TrampolineApStartup:
|
case TrampolineApStartup:
|
||||||
/* Get AP startup trampoline information */
|
|
||||||
*TrampolineCode = (PVOID)ArStartApplicationProcessor;
|
*TrampolineCode = (PVOID)ArStartApplicationProcessor;
|
||||||
*TrampolineSize = (ULONG_PTR)ArStartApplicationProcessorEnd -
|
*TrampolineSize = (ULONG_PTR)ArStartApplicationProcessorEnd -
|
||||||
(ULONG_PTR)ArStartApplicationProcessor;
|
(ULONG_PTR)ArStartApplicationProcessor;
|
||||||
break;
|
break;
|
||||||
case TrampolineEnableXpa:
|
case TrampolineEnableXpa:
|
||||||
/* Get Enable XPA trampoline information */
|
|
||||||
*TrampolineCode = (PVOID)ArEnableExtendedPhysicalAddressing;
|
*TrampolineCode = (PVOID)ArEnableExtendedPhysicalAddressing;
|
||||||
*TrampolineSize = (ULONG_PTR)ArEnableExtendedPhysicalAddressingEnd -
|
*TrampolineSize = (ULONG_PTR)ArEnableExtendedPhysicalAddressingEnd -
|
||||||
(ULONG_PTR)ArEnableExtendedPhysicalAddressing;
|
(ULONG_PTR)ArEnableExtendedPhysicalAddressing;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Unknown trampoline type */
|
|
||||||
*TrampolineCode = NULLPTR;
|
*TrampolineCode = NULLPTR;
|
||||||
*TrampolineSize = 0;
|
*TrampolineSize = 0;
|
||||||
break;
|
break;
|
||||||
@@ -69,13 +64,16 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
|||||||
CPUID_REGISTERS CpuRegisters;
|
CPUID_REGISTERS CpuRegisters;
|
||||||
CPUID_SIGNATURE CpuSignature;
|
CPUID_SIGNATURE CpuSignature;
|
||||||
|
|
||||||
|
/* Not fully implemented yet */
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
|
||||||
/* Get current processor control block */
|
/* Get current processor control block */
|
||||||
Prcb = KE::Processor::GetCurrentProcessorControlBlock();
|
Prcb = KE::Processor::GetCurrentProcessorControlBlock();
|
||||||
|
|
||||||
/* Get CPU vendor by issueing CPUID instruction */
|
/* Get CPU vendor by issueing CPUID instruction */
|
||||||
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||||
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
|
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
|
||||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
CpuFunc::CpuId(&CpuRegisters);
|
||||||
|
|
||||||
/* Store CPU vendor in processor control block */
|
/* Store CPU vendor in processor control block */
|
||||||
Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx;
|
Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx;
|
||||||
@@ -87,7 +85,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
|||||||
/* Get CPU standard features */
|
/* Get CPU standard features */
|
||||||
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
CpuFunc::CpuId(&CpuRegisters);
|
||||||
|
|
||||||
/* Store CPU signature in processor control block */
|
/* Store CPU signature in processor control block */
|
||||||
CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax;
|
CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax;
|
||||||
@@ -99,23 +97,23 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
|||||||
if(Prcb->CpuId.Vendor == CPU_VENDOR_AMD)
|
if(Prcb->CpuId.Vendor == CPU_VENDOR_AMD)
|
||||||
{
|
{
|
||||||
/* AMD CPU */
|
/* AMD CPU */
|
||||||
if(CpuSignature.Family == 0xF)
|
if(Prcb->CpuId.Family >= 0xF)
|
||||||
{
|
{
|
||||||
Prcb->CpuId.Family += CpuSignature.ExtendedFamily;
|
Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
|
||||||
Prcb->CpuId.Model += (CpuSignature.ExtendedModel << 4);
|
Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(Prcb->CpuId.Vendor == CPU_VENDOR_INTEL)
|
else if(Prcb->CpuId.Vendor == CPU_VENDOR_INTEL)
|
||||||
{
|
{
|
||||||
/* Intel CPU */
|
/* Intel CPU */
|
||||||
if(CpuSignature.Family == 0xF)
|
if(Prcb->CpuId.Family == 0xF)
|
||||||
{
|
{
|
||||||
Prcb->CpuId.Family += CpuSignature.ExtendedFamily;
|
Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((CpuSignature.Family == 0x6) || (CpuSignature.Family == 0xF))
|
if((Prcb->CpuId.Family == 0x6) || (Prcb->CpuId.Family == 0xF))
|
||||||
{
|
{
|
||||||
Prcb->CpuId.Model += (CpuSignature.ExtendedModel << 4);
|
Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -124,12 +122,11 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
|||||||
Prcb->CpuId.Vendor = CPU_VENDOR_UNKNOWN;
|
Prcb->CpuId.Vendor = CPU_VENDOR_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Identify processor features */
|
/* TODO: Store a list of CPU features in processor control block */
|
||||||
IdentifyProcessorFeatures();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identifies processor features and stores them in Processor Control Block (PRCB).
|
* Initializes AMD64 processor specific structures.
|
||||||
*
|
*
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
@@ -137,133 +134,70 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
VOID
|
VOID
|
||||||
AR::ProcSup::IdentifyProcessorFeatures(VOID)
|
AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||||
{
|
{
|
||||||
ULONG MaxExtendedLeaf, MaxStandardLeaf;
|
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
|
||||||
PKPROCESSOR_CONTROL_BLOCK Prcb;
|
PVOID KernelBootStack, KernelFaultStack;
|
||||||
CPUID_REGISTERS CpuRegisters;
|
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||||
|
PKGDTENTRY Gdt;
|
||||||
|
PKIDTENTRY Idt;
|
||||||
|
PKTSS Tss;
|
||||||
|
|
||||||
/* Get current processor control block */
|
/* Check if processor structures buffer provided */
|
||||||
Prcb = KE::Processor::GetCurrentProcessorControlBlock();
|
if(ProcessorStructures)
|
||||||
|
|
||||||
/* Get maximum CPUID standard leaf */
|
|
||||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
|
||||||
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
|
|
||||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
|
||||||
MaxStandardLeaf = CpuRegisters.Eax;
|
|
||||||
|
|
||||||
/* Get maximum CPUID extended leaf */
|
|
||||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
|
||||||
CpuRegisters.Leaf = CPUID_GET_EXTENDED_MAX;
|
|
||||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
|
||||||
MaxExtendedLeaf = CpuRegisters.Eax;
|
|
||||||
|
|
||||||
/* Check if CPU supports standard features leaf */
|
|
||||||
if(MaxStandardLeaf >= CPUID_GET_STANDARD1_FEATURES)
|
|
||||||
{
|
{
|
||||||
/* Get CPU standard features */
|
/* Assign CPU structures from provided buffer */
|
||||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
|
||||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
&KernelBootStack, &KernelFaultStack);
|
||||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
|
||||||
|
|
||||||
/* Store CPU standard features in processor control block */
|
/* Use global IDT */
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE3) Prcb->CpuId.FeatureBits |= KCF_SSE3;
|
Idt = InitialIdt;
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_VMX) Prcb->CpuId.FeatureBits |= KCF_VMX;
|
}
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSSE3) Prcb->CpuId.FeatureBits |= KCF_SSSE3;
|
else
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4_1) Prcb->CpuId.FeatureBits |= KCF_SSE41;
|
{
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4_2) Prcb->CpuId.FeatureBits |= KCF_SSE42;
|
/* Use initial structures */
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_X2APIC) Prcb->CpuId.FeatureBits |= KCF_X2APIC;
|
Gdt = InitialGdt;
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_POPCNT) Prcb->CpuId.FeatureBits |= KCF_POPCNT;
|
Idt = InitialIdt;
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_TSC_DEADLINE) Prcb->CpuId.FeatureBits |= KCF_TSC_DEADLINE;
|
Tss = &InitialTss;
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_AES) Prcb->CpuId.FeatureBits |= KCF_AES;
|
KernelBootStack = &BootStack;
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_XSAVE) Prcb->CpuId.FeatureBits |= KCF_XSAVE;
|
KernelFaultStack = &FaultStack;
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_AVX) Prcb->CpuId.FeatureBits |= KCF_AVX;
|
ProcessorBlock = &InitialProcessorBlock;
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_RDRAND) Prcb->CpuId.FeatureBits |= KCF_RDRAND;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_VME) Prcb->CpuId.FeatureBits |= KCF_VME;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PSE) Prcb->CpuId.FeatureBits |= KCF_LARGE_PAGE;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSC) Prcb->CpuId.FeatureBits |= KCF_RDTSC;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PAE) Prcb->CpuId.FeatureBits |= KCF_PAE;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MCE) Prcb->CpuId.FeatureBits |= KCF_MCE;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CX8) Prcb->CpuId.FeatureBits |= KCF_CMPXCHG8B;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_APIC) Prcb->CpuId.FeatureBits |= KCF_APIC;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SEP) Prcb->CpuId.FeatureBits |= KCF_FAST_SYSCALL;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MTRR) Prcb->CpuId.FeatureBits |= KCF_MTRR;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PGE) Prcb->CpuId.FeatureBits |= KCF_GLOBAL_PAGE;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MCA) Prcb->CpuId.FeatureBits |= KCF_MCA;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CMOV) Prcb->CpuId.FeatureBits |= KCF_CMOV;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PAT) Prcb->CpuId.FeatureBits |= KCF_PAT;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PSE36) Prcb->CpuId.FeatureBits |= KCF_PSE36;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CLFLUSH) Prcb->CpuId.FeatureBits |= KCF_CLFLUSH;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_FXSR) Prcb->CpuId.FeatureBits |= KCF_FXSR;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_ACPI) Prcb->CpuId.FeatureBits |= KCF_ACPI;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MMX) Prcb->CpuId.FeatureBits |= KCF_MMX;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SSE) Prcb->CpuId.FeatureBits |= KCF_SSE;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SSE2) Prcb->CpuId.FeatureBits |= KCF_SSE2;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_HTT) Prcb->CpuId.FeatureBits |= KCF_SMT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if CPU supports standard7 features leaf */
|
/* Initialize processor block */
|
||||||
if(MaxStandardLeaf >= CPUID_GET_STANDARD7_FEATURES)
|
InitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);
|
||||||
{
|
|
||||||
/* Get CPU standard features */
|
|
||||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
|
||||||
CpuRegisters.Leaf = CPUID_GET_STANDARD7_FEATURES;
|
|
||||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
|
||||||
|
|
||||||
/* Store CPU standard7 features in processor control block */
|
/* Initialize GDT, IDT and TSS */
|
||||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_FSGSBASE) Prcb->CpuId.FeatureBits |= KCF_FSGSBASE;
|
InitializeGdt(ProcessorBlock);
|
||||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_AVX2) Prcb->CpuId.FeatureBits |= KCF_AVX2;
|
InitializeIdt(ProcessorBlock);
|
||||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SMEP) Prcb->CpuId.FeatureBits |= KCF_SMEP;
|
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack);
|
||||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_RDSEED) Prcb->CpuId.FeatureBits |= KCF_RDSEED;
|
|
||||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SMAP) Prcb->CpuId.FeatureBits |= KCF_SMAP;
|
|
||||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SHA) Prcb->CpuId.FeatureBits |= KCF_SHA;
|
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_LA57) Prcb->CpuId.FeatureBits |= KCF_LA57;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if CPU supports power management leaf */
|
/* Set GDT and IDT descriptors */
|
||||||
if(MaxStandardLeaf >= CPUID_GET_POWER_MANAGEMENT)
|
GdtDescriptor.Base = Gdt;
|
||||||
{
|
GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1;
|
||||||
/* Get CPU power management features */
|
IdtDescriptor.Base = Idt;
|
||||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;
|
||||||
CpuRegisters.Leaf = CPUID_GET_POWER_MANAGEMENT;
|
|
||||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
|
||||||
|
|
||||||
/* Store CPU power management features in processor control block */
|
/* Load GDT, IDT and TSS */
|
||||||
if(CpuRegisters.Eax & CPUID_FEATURES_EAX_ARAT) Prcb->CpuId.FeatureBits |= KCF_ARAT;
|
CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
|
||||||
}
|
CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
|
||||||
|
CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS);
|
||||||
|
|
||||||
/* Check if CPU supports extended features leaf */
|
/* Enter passive IRQ level */
|
||||||
if(MaxExtendedLeaf >= CPUID_GET_EXTENDED_FEATURES)
|
HL::RunLevel::SetRunLevel(PASSIVE_LEVEL);
|
||||||
{
|
|
||||||
/* Get CPU extended features */
|
|
||||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
|
||||||
CpuRegisters.Leaf = CPUID_GET_EXTENDED_FEATURES;
|
|
||||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
|
||||||
|
|
||||||
/* Store CPU extended features in processor control block */
|
/* Initialize segment registers */
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SVM) Prcb->CpuId.ExtendedFeatureBits |= KCF_SVM;
|
InitializeSegments();
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4A) Prcb->CpuId.ExtendedFeatureBits |= KCF_SSE4A;
|
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_FMA4) Prcb->CpuId.ExtendedFeatureBits |= KCF_FMA4;
|
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_TOPOLOGY_EXTENSIONS) Prcb->CpuId.ExtendedFeatureBits |= KCF_TOPOEXT;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SYSCALL_SYSRET) Prcb->CpuId.ExtendedFeatureBits |= KCF_SYSCALL;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_NX) Prcb->CpuId.ExtendedFeatureBits |= KCF_NX_BIT;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_RDTSCP) Prcb->CpuId.ExtendedFeatureBits |= KCF_RDTSCP;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_LONG_MODE) Prcb->CpuId.ExtendedFeatureBits |= KCF_64BIT;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_3DNOW_EXT) Prcb->CpuId.ExtendedFeatureBits |= KCF_3DNOW_EXT;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_3DNOW) Prcb->CpuId.ExtendedFeatureBits |= KCF_3DNOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if CPU supports advanced power management leaf */
|
/* Set GS base */
|
||||||
if(MaxExtendedLeaf >= CPUID_GET_ADVANCED_POWER_MANAGEMENT)
|
CpuFunc::WriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock);
|
||||||
{
|
CpuFunc::WriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock);
|
||||||
/* Get CPU advanced power management features */
|
|
||||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
|
||||||
CpuRegisters.Leaf = CPUID_GET_ADVANCED_POWER_MANAGEMENT;
|
|
||||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
|
||||||
|
|
||||||
/* Store CPU advanced power management features in processor control block */
|
/* Initialize processor registers */
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSCI) Prcb->CpuId.ExtendedFeatureBits |= KCF_INVARIANT_TSC;
|
InitializeProcessorRegisters();
|
||||||
}
|
|
||||||
|
/* Identify processor */
|
||||||
|
IdentifyProcessor();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -315,108 +249,34 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
|||||||
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
|
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
|
||||||
{
|
{
|
||||||
/* Set the IDT to handle unexpected interrupts */
|
/* Set the IDT to handle unexpected interrupts */
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArInterruptEntry[Vector], KGDT_R0_CODE,
|
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||||
KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup IDT handlers for known interrupts and traps */
|
/* Setup IDT handlers for known interrupts and traps */
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrapEntry[0x00], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrapEntry[0x01], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrapEntry[0x02], KGDT_R0_CODE, KIDT_IST_NMI, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrapEntry[0x03], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrapEntry[0x04], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrapEntry[0x05], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrapEntry[0x06], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrapEntry[0x07], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrapEntry[0x08], KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrapEntry[0x09], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrapEntry[0x0A], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrapEntry[0x0B], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrapEntry[0x0C], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrapEntry[0x0D], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrapEntry[0x0E], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrapEntry[0x10], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrapEntry[0x11], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrapEntry[0x12], KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrapEntry[0x13], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x1F, (PVOID)ArTrapEntry[0x1F], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x1F, (PVOID)ArTrap0x1F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrapEntry[0x2C], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrapEntry[0x2D], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrapEntry[0x2F], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrap0x2F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArInterruptEntry[0xE1], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArTrap0xE1, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes AMD64 processor specific structures.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
|
||||||
{
|
|
||||||
PVOID KernelBootStack, KernelFaultStack, KernelNmiStack;
|
|
||||||
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
|
|
||||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
|
||||||
PKGDTENTRY Gdt;
|
|
||||||
PKIDTENTRY Idt;
|
|
||||||
PKTSS Tss;
|
|
||||||
|
|
||||||
/* Check if processor structures buffer provided */
|
|
||||||
if(ProcessorStructures)
|
|
||||||
{
|
|
||||||
/* Assign CPU structures from provided buffer */
|
|
||||||
InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
|
|
||||||
&KernelBootStack, &KernelFaultStack, &KernelNmiStack);
|
|
||||||
|
|
||||||
/* Use global IDT */
|
|
||||||
Idt = InitialIdt;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Use initial structures */
|
|
||||||
Gdt = InitialGdt;
|
|
||||||
Idt = InitialIdt;
|
|
||||||
Tss = &InitialTss;
|
|
||||||
KernelBootStack = (PVOID)((ULONG_PTR)&BootStack + KERNEL_STACK_SIZE);
|
|
||||||
KernelFaultStack = (PVOID)((ULONG_PTR)&FaultStack + KERNEL_STACK_SIZE);
|
|
||||||
KernelNmiStack = (PVOID)((ULONG_PTR)&NmiStack + KERNEL_STACK_SIZE);
|
|
||||||
ProcessorBlock = &InitialProcessorBlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize processor block */
|
|
||||||
InitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);
|
|
||||||
|
|
||||||
/* Initialize GDT, IDT and TSS */
|
|
||||||
InitializeGdt(ProcessorBlock);
|
|
||||||
InitializeIdt(ProcessorBlock);
|
|
||||||
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack, KernelNmiStack);
|
|
||||||
|
|
||||||
/* Set GDT and IDT descriptors */
|
|
||||||
GdtDescriptor.Base = Gdt;
|
|
||||||
GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1;
|
|
||||||
IdtDescriptor.Base = Idt;
|
|
||||||
IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;
|
|
||||||
|
|
||||||
/* Load GDT, IDT and TSS */
|
|
||||||
AR::CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
|
|
||||||
AR::CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
|
|
||||||
AR::CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS);
|
|
||||||
|
|
||||||
/* Initialize segment registers */
|
|
||||||
InitializeSegments();
|
|
||||||
|
|
||||||
/* Set GS base */
|
|
||||||
AR::CpuFunc::WriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock);
|
|
||||||
AR::CpuFunc::WriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock);
|
|
||||||
|
|
||||||
/* Initialize processor registers */
|
|
||||||
InitializeProcessorRegisters();
|
|
||||||
|
|
||||||
/* Identify processor */
|
|
||||||
IdentifyProcessor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -495,45 +355,45 @@ AR::ProcSup::InitializeProcessorRegisters(VOID)
|
|||||||
ULONGLONG PatAttributes;
|
ULONGLONG PatAttributes;
|
||||||
|
|
||||||
/* Enable FXSAVE restore */
|
/* Enable FXSAVE restore */
|
||||||
AR::CpuFunc::WriteControlRegister(4, AR::CpuFunc::ReadControlRegister(4) | CR4_FXSR);
|
CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_FXSR);
|
||||||
|
|
||||||
/* Enable XMMI exceptions */
|
/* Enable XMMI exceptions */
|
||||||
AR::CpuFunc::WriteControlRegister(4, AR::CpuFunc::ReadControlRegister(4) | CR4_XMMEXCPT);
|
CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_XMMEXCPT);
|
||||||
|
|
||||||
/* Set debugger extension */
|
/* Set debugger extension */
|
||||||
AR::CpuFunc::WriteControlRegister(4, AR::CpuFunc::ReadControlRegister(4) | CR4_DE);
|
CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_DE);
|
||||||
|
|
||||||
/* Enable large pages */
|
/* Enable large pages */
|
||||||
AR::CpuFunc::WriteControlRegister(4, AR::CpuFunc::ReadControlRegister(4) | CR4_PSE);
|
CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_PSE);
|
||||||
|
|
||||||
/* Enable write-protection */
|
/* Enable write-protection */
|
||||||
AR::CpuFunc::WriteControlRegister(0, AR::CpuFunc::ReadControlRegister(0) | CR0_WP);
|
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_WP);
|
||||||
|
|
||||||
/* Set alignment mask */
|
/* Set alignment mask */
|
||||||
AR::CpuFunc::WriteControlRegister(0, AR::CpuFunc::ReadControlRegister(0) | CR0_AM);
|
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_AM);
|
||||||
|
|
||||||
/* Disable FPU monitoring */
|
/* Disable FPU monitoring */
|
||||||
AR::CpuFunc::WriteControlRegister(0, AR::CpuFunc::ReadControlRegister(0) & ~CR0_MP);
|
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) & ~CR0_MP);
|
||||||
|
|
||||||
/* Disable x87 FPU exceptions */
|
/* Disable x87 FPU exceptions */
|
||||||
AR::CpuFunc::WriteControlRegister(0, AR::CpuFunc::ReadControlRegister(0) & ~CR0_NE);
|
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) & ~CR0_NE);
|
||||||
|
|
||||||
/* Flush the TLB */
|
/* Flush the TLB */
|
||||||
AR::CpuFunc::FlushTlb();
|
CpuFunc::FlushTlb();
|
||||||
|
|
||||||
/* Initialize system call MSRs */
|
/* Initialize system call MSRs */
|
||||||
AR::Traps::InitializeSystemCallMsrs();
|
Traps::InitializeSystemCallMsrs();
|
||||||
|
|
||||||
/* Enable No-Execute (NXE) in EFER MSR */
|
/* Enable No-Execute (NXE) in EFER MSR */
|
||||||
AR::CpuFunc::WriteModelSpecificRegister(X86_MSR_EFER, CpuFunc::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_NXE);
|
CpuFunc::WriteModelSpecificRegister(X86_MSR_EFER, CpuFunc::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_NXE);
|
||||||
|
|
||||||
/* Initialize Page Attribute Table */
|
/* Initialize Page Attribute Table */
|
||||||
PatAttributes = (PAT_TYPE_WB << 0) | (PAT_TYPE_USWC << 8) | (PAT_TYPE_WEAK_UC << 16) | (PAT_TYPE_STRONG_UC << 24) |
|
PatAttributes = (PAT_TYPE_WB << 0) | (PAT_TYPE_USWC << 8) | (PAT_TYPE_WEAK_UC << 16) | (PAT_TYPE_STRONG_UC << 24) |
|
||||||
(PAT_TYPE_WB << 32) | (PAT_TYPE_USWC << 40) | (PAT_TYPE_WEAK_UC << 48) | (PAT_TYPE_STRONG_UC << 56);
|
(PAT_TYPE_WB << 32) | (PAT_TYPE_USWC << 40) | (PAT_TYPE_WEAK_UC << 48) | (PAT_TYPE_STRONG_UC << 56);
|
||||||
AR::CpuFunc::WriteModelSpecificRegister(X86_MSR_PAT, PatAttributes);
|
CpuFunc::WriteModelSpecificRegister(X86_MSR_PAT, PatAttributes);
|
||||||
|
|
||||||
/* Initialize MXCSR register */
|
/* Initialize MXCSR register */
|
||||||
AR::CpuFunc::LoadMxcsrRegister(INITIAL_MXCSR);
|
CpuFunc::LoadMxcsrRegister(INITIAL_MXCSR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -568,8 +428,7 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
|||||||
OUT PKTSS *Tss,
|
OUT PKTSS *Tss,
|
||||||
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
||||||
OUT PVOID *KernelBootStack,
|
OUT PVOID *KernelBootStack,
|
||||||
OUT PVOID *KernelFaultStack,
|
OUT PVOID *KernelFaultStack)
|
||||||
OUT PVOID *KernelNmiStack)
|
|
||||||
{
|
{
|
||||||
UINT_PTR Address;
|
UINT_PTR Address;
|
||||||
|
|
||||||
@@ -577,49 +436,22 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
|||||||
Address = ROUND_UP((UINT_PTR)ProcessorStructures, MM_PAGE_SIZE) + KERNEL_STACK_SIZE;
|
Address = ROUND_UP((UINT_PTR)ProcessorStructures, MM_PAGE_SIZE) + KERNEL_STACK_SIZE;
|
||||||
|
|
||||||
/* Assign a space for kernel boot stack and advance */
|
/* Assign a space for kernel boot stack and advance */
|
||||||
if(KernelBootStack != NULLPTR)
|
*KernelBootStack = (PVOID)Address;
|
||||||
{
|
|
||||||
/* Return kernel boot stack address */
|
|
||||||
*KernelBootStack = (PVOID)Address;
|
|
||||||
}
|
|
||||||
Address += KERNEL_STACK_SIZE;
|
Address += KERNEL_STACK_SIZE;
|
||||||
|
|
||||||
/* Assign a space for kernel fault stack and advance */
|
/* Assign a space for kernel fault stack, no advance needed as stack grows down */
|
||||||
if(KernelFaultStack != NULLPTR)
|
*KernelFaultStack = (PVOID)Address;
|
||||||
{
|
|
||||||
/* Return kernel fault stack address */
|
|
||||||
*KernelFaultStack = (PVOID)Address;
|
|
||||||
}
|
|
||||||
Address += KERNEL_STACK_SIZE;
|
|
||||||
|
|
||||||
/* Assign a space for kernel NMI stack, no advance needed as stack grows down */
|
|
||||||
if(KernelNmiStack != NULLPTR)
|
|
||||||
{
|
|
||||||
/* Return kernel NMI stack address */
|
|
||||||
*KernelNmiStack = (PVOID)Address;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Assign a space for GDT and advance */
|
/* Assign a space for GDT and advance */
|
||||||
if(Gdt != NULLPTR)
|
*Gdt = (PKGDTENTRY)(PVOID)Address;
|
||||||
{
|
Address += sizeof(InitialGdt);
|
||||||
/* Return GDT base address */
|
|
||||||
*Gdt = (PKGDTENTRY)(PVOID)Address;
|
|
||||||
}
|
|
||||||
Address += (GDT_ENTRIES * sizeof(KGDTENTRY));
|
|
||||||
|
|
||||||
/* Assign a space for TSS and advance */
|
|
||||||
if(Tss != NULLPTR)
|
|
||||||
{
|
|
||||||
*Tss = (PKTSS)(PVOID)Address;
|
|
||||||
}
|
|
||||||
Address += sizeof(KTSS);
|
|
||||||
|
|
||||||
/* Assign a space for Processor Block and advance */
|
/* Assign a space for Processor Block and advance */
|
||||||
if(ProcessorBlock != NULLPTR)
|
*ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address;
|
||||||
{
|
Address += sizeof(InitialProcessorBlock);
|
||||||
/* Return processor block address */
|
|
||||||
*ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address;
|
/* Assign a space for TSS */
|
||||||
}
|
*Tss = (PKTSS)(PVOID)Address;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -634,12 +466,12 @@ VOID
|
|||||||
AR::ProcSup::InitializeSegments(VOID)
|
AR::ProcSup::InitializeSegments(VOID)
|
||||||
{
|
{
|
||||||
/* Initialize segments */
|
/* Initialize segments */
|
||||||
AR::CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
|
CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
|
||||||
AR::CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
|
CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
|
||||||
AR::CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
|
CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
|
||||||
AR::CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK);
|
CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK);
|
||||||
AR::CpuFunc::LoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK);
|
CpuFunc::LoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK);
|
||||||
AR::CpuFunc::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);
|
CpuFunc::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -659,8 +491,7 @@ XTAPI
|
|||||||
VOID
|
VOID
|
||||||
AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||||
IN PVOID KernelBootStack,
|
IN PVOID KernelBootStack,
|
||||||
IN PVOID KernelFaultStack,
|
IN PVOID KernelFaultStack)
|
||||||
IN PVOID KernelNmiStack)
|
|
||||||
{
|
{
|
||||||
/* Fill TSS with zeroes */
|
/* Fill TSS with zeroes */
|
||||||
RtlZeroMemory(ProcessorBlock->TssBase, sizeof(KTSS));
|
RtlZeroMemory(ProcessorBlock->TssBase, sizeof(KTSS));
|
||||||
@@ -670,7 +501,6 @@ AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
|||||||
ProcessorBlock->TssBase->Rsp0 = (ULONG_PTR)KernelBootStack;
|
ProcessorBlock->TssBase->Rsp0 = (ULONG_PTR)KernelBootStack;
|
||||||
ProcessorBlock->TssBase->Ist[KIDT_IST_PANIC] = (ULONG_PTR)KernelFaultStack;
|
ProcessorBlock->TssBase->Ist[KIDT_IST_PANIC] = (ULONG_PTR)KernelFaultStack;
|
||||||
ProcessorBlock->TssBase->Ist[KIDT_IST_MCA] = (ULONG_PTR)KernelFaultStack;
|
ProcessorBlock->TssBase->Ist[KIDT_IST_MCA] = (ULONG_PTR)KernelFaultStack;
|
||||||
ProcessorBlock->TssBase->Ist[KIDT_IST_NMI] = (ULONG_PTR)KernelNmiStack;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -9,44 +9,6 @@
|
|||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dispatches the interrupt provided by common interrupt handler.
|
|
||||||
*
|
|
||||||
* @param TrapFrame
|
|
||||||
* Supplies a kernel trap frame pushed by common interrupt handler on the stack.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
AR::Traps::DispatchInterrupt(IN PKTRAP_FRAME TrapFrame)
|
|
||||||
{
|
|
||||||
PINTERRUPT_HANDLER Handler;
|
|
||||||
|
|
||||||
/* Read the handler pointer from the CPU's interrupt dispatch table */
|
|
||||||
Handler = (PINTERRUPT_HANDLER)AR::CpuFunc::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, InterruptDispatchTable) +
|
|
||||||
(TrapFrame->Vector * sizeof(PINTERRUPT_HANDLER)));
|
|
||||||
|
|
||||||
/* Check if the interrupt has a handler registered */
|
|
||||||
if(Handler != NULLPTR)
|
|
||||||
{
|
|
||||||
/* Call the handler */
|
|
||||||
Handler(TrapFrame);
|
|
||||||
}
|
|
||||||
else if(UnhandledInterruptRoutine != NULLPTR)
|
|
||||||
{
|
|
||||||
/* Call the unhandled interrupt routine */
|
|
||||||
UnhandledInterruptRoutine(TrapFrame);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Dispatcher not initialized, print a debug message */
|
|
||||||
DebugPrint(L"ERROR: Caught unhandled interrupt: 0x%.2llX\n", TrapFrame->Vector);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispatches the trap provided by common trap handler.
|
* Dispatches the trap provided by common trap handler.
|
||||||
*
|
*
|
||||||
@@ -265,6 +227,7 @@ VOID
|
|||||||
AR::Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame)
|
AR::Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame)
|
||||||
{
|
{
|
||||||
DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n");
|
DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n");
|
||||||
|
KE::Crash::Panic(0x02);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -682,19 +645,19 @@ AR::Traps::InitializeSystemCallMsrs(VOID)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the unhandled interrupt routine used for vectors that have no handler registered.
|
* C-linkage wrapper for dispatching the trap provided by common trap handler.
|
||||||
*
|
*
|
||||||
* @param Handler
|
* @param TrapFrame
|
||||||
* Supplies the pointer to the interrupt handler routine.
|
* Supplies a kernel trap frame pushed by common trap handler on the stack.
|
||||||
*
|
*
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
* @since XT 1.0
|
* @since XT 1.0
|
||||||
*/
|
*/
|
||||||
XTAPI
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
VOID
|
VOID
|
||||||
AR::Traps::SetUnhandledInterruptRoutine(PINTERRUPT_HANDLER Handler)
|
ArDispatchTrap(IN PKTRAP_FRAME TrapFrame)
|
||||||
{
|
{
|
||||||
/* Set the unhandled interrupt routine */
|
AR::Traps::DispatchTrap(TrapFrame);
|
||||||
UnhandledInterruptRoutine = Handler;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,334 +4,132 @@
|
|||||||
* FILE: xtoskrnl/ar/i686/archsup.S
|
* FILE: xtoskrnl/ar/i686/archsup.S
|
||||||
* DESCRIPTION: Provides i686 architecture features not implementable in C.
|
* DESCRIPTION: Provides i686 architecture features not implementable in C.
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
* Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xtkmapi.h>
|
#include <ar/i686/asmsup.h>
|
||||||
#include <xtadk.h>
|
|
||||||
|
|
||||||
.altmacro
|
.altmacro
|
||||||
.text
|
.text
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a task, trap or interrupt handler for the specified vector.
|
* This macro creates a trap handler for the specified vector.
|
||||||
*
|
*
|
||||||
* @param Vector
|
* @param Vector
|
||||||
* Supplies a vector number.
|
* Supplies a trap vector number.
|
||||||
*
|
|
||||||
* @param Type
|
|
||||||
* Specifies whether the handler is designed to handle an interrupt, a task or a trap.
|
|
||||||
*
|
*
|
||||||
* @return This macro does not return any value.
|
* @return This macro does not return any value.
|
||||||
*
|
*
|
||||||
* @since XT 1.0
|
* @since XT 1.0
|
||||||
*/
|
*/
|
||||||
.macro ArCreateHandler Vector Type
|
.macro ArCreateTrapHandler Vector
|
||||||
.global _Ar\Type\Vector
|
.global _ArTrap\Vector
|
||||||
_Ar\Type\Vector:
|
_ArTrap\Vector:
|
||||||
/* Check handler type */
|
/* Push fake error code for non-error vectors */
|
||||||
.ifc \Type,Task
|
.if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
|
||||||
_Ar\Type\Vector\()Start:
|
push $0
|
||||||
/* 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
|
|
||||||
|
|
||||||
/* Push General Purpose Registers */
|
|
||||||
push %ebp
|
|
||||||
push %edi
|
|
||||||
push %esi
|
|
||||||
push %edx
|
|
||||||
push %ecx
|
|
||||||
push %ebx
|
|
||||||
push %eax
|
|
||||||
|
|
||||||
/* Reserve space for other registers and point RBP to the trap frame */
|
|
||||||
sub $(KTRAP_FRAME_SIZE - KTRAP_FRAME_REGISTERS_SIZE), %esp
|
|
||||||
lea (%esp), %ebp
|
|
||||||
|
|
||||||
/* Store segment selectors */
|
|
||||||
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, KTRAP_FRAME_Dr7(%ebp)
|
|
||||||
mov %dr6, %eax
|
|
||||||
mov %eax, KTRAP_FRAME_Dr6(%ebp)
|
|
||||||
mov %dr3, %eax
|
|
||||||
mov %eax, KTRAP_FRAME_Dr3(%ebp)
|
|
||||||
mov %dr2, %eax
|
|
||||||
mov %eax, KTRAP_FRAME_Dr2(%ebp)
|
|
||||||
mov %dr1, %eax
|
|
||||||
mov %eax, KTRAP_FRAME_Dr1(%ebp)
|
|
||||||
mov %dr0, %eax
|
|
||||||
mov %eax, KTRAP_FRAME_Dr0(%ebp)
|
|
||||||
|
|
||||||
/* Store CR2 and CR3 */
|
|
||||||
mov %cr3, %eax
|
|
||||||
mov %eax, KTRAP_FRAME_Cr3(%ebp)
|
|
||||||
mov %cr2, %eax
|
|
||||||
mov %eax, KTRAP_FRAME_Cr2(%ebp)
|
|
||||||
|
|
||||||
/* Test previous mode */
|
|
||||||
movl $0, KTRAP_FRAME_PreviousMode(%ebp)
|
|
||||||
mov KTRAP_FRAME_SegCs(%ebp), %ax
|
|
||||||
and $3, %al
|
|
||||||
mov %al, KTRAP_FRAME_PreviousMode(%ebp)
|
|
||||||
jz Dispatch\Type\Vector
|
|
||||||
|
|
||||||
/* Load Kernel PB selector into FS */
|
|
||||||
mov $KGDT_R0_PB, %ax
|
|
||||||
mov %ax, %fs
|
|
||||||
|
|
||||||
/* 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 disable interrupts before user mode return */
|
|
||||||
testb $1, KTRAP_FRAME_PreviousMode(%ebp)
|
|
||||||
jz RestoreState\Type\Vector
|
|
||||||
cli
|
|
||||||
|
|
||||||
RestoreState\Type\Vector:
|
|
||||||
/* Restore segment selectors */
|
|
||||||
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 $(KTRAP_FRAME_SIZE - KTRAP_FRAME_REGISTERS_SIZE), %esp
|
|
||||||
|
|
||||||
/* Pop General Purpose Registers */
|
|
||||||
pop %eax
|
|
||||||
pop %ebx
|
|
||||||
pop %ecx
|
|
||||||
pop %edx
|
|
||||||
pop %esi
|
|
||||||
pop %edi
|
|
||||||
pop %ebp
|
|
||||||
|
|
||||||
/* Skip error code and vector number, then return */
|
|
||||||
add $(2 * 4), %esp
|
|
||||||
iretl
|
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
|
/* Push vector number */
|
||||||
|
push $\Vector
|
||||||
|
|
||||||
|
/* Push General Purpose Registers */
|
||||||
|
push %ebp
|
||||||
|
push %edi
|
||||||
|
push %esi
|
||||||
|
push %edx
|
||||||
|
push %ecx
|
||||||
|
push %ebx
|
||||||
|
push %eax
|
||||||
|
|
||||||
|
/* Reserve space for other registers and point RBP to the trap frame */
|
||||||
|
sub $(TRAP_FRAME_SIZE - TRAP_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)
|
||||||
|
|
||||||
|
/* Store debug registers */
|
||||||
|
mov %dr7, %eax
|
||||||
|
mov %eax, TrapDr7(%ebp)
|
||||||
|
mov %dr6, %eax
|
||||||
|
mov %eax, TrapDr6(%ebp)
|
||||||
|
mov %dr3, %eax
|
||||||
|
mov %eax, TrapDr3(%ebp)
|
||||||
|
mov %dr2, %eax
|
||||||
|
mov %eax, TrapDr2(%ebp)
|
||||||
|
mov %dr1, %eax
|
||||||
|
mov %eax, TrapDr1(%ebp)
|
||||||
|
mov %dr0, %eax
|
||||||
|
mov %eax, TrapDr0(%ebp)
|
||||||
|
|
||||||
|
/* Store CR2 and CR3 */
|
||||||
|
mov %cr3, %eax
|
||||||
|
mov %eax, TrapCr3(%ebp)
|
||||||
|
mov %cr2, %eax
|
||||||
|
mov %eax, TrapCr2(%ebp)
|
||||||
|
|
||||||
|
/* Test previous mode and swap GS if needed */
|
||||||
|
movl $0, TrapPreviousMode(%ebp)
|
||||||
|
mov %cs, %ax
|
||||||
|
and $3, %al
|
||||||
|
mov %al, TrapPreviousMode(%ebp)
|
||||||
|
jz KernelMode$\Vector
|
||||||
|
swapgs
|
||||||
|
jmp UserMode$\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)
|
||||||
|
|
||||||
|
UserMode$\Vector:
|
||||||
|
/* Push Frame Pointer, clear direction flag and pass to trap dispatcher */
|
||||||
|
push %esp
|
||||||
|
cld
|
||||||
|
call _ArDispatchTrap
|
||||||
|
|
||||||
|
/* Clean up the stack */
|
||||||
|
add $4, %esp
|
||||||
|
|
||||||
|
/* Test previous mode and swapgs if needed */
|
||||||
|
testb $1, TrapPreviousMode(%ebp)
|
||||||
|
jz KernelModeReturn$\Vector
|
||||||
|
cli
|
||||||
|
swapgs
|
||||||
|
|
||||||
|
KernelModeReturn$\Vector:
|
||||||
|
/* Restore segment selectors */
|
||||||
|
mov TrapSegDs(%ebp), %ds
|
||||||
|
mov TrapSegEs(%ebp), %es
|
||||||
|
mov TrapSegFs(%ebp), %fs
|
||||||
|
mov TrapSegGs(%ebp), %gs
|
||||||
|
|
||||||
|
/* Free stack space */
|
||||||
|
add $(TRAP_FRAME_SIZE - TRAP_REGISTERS_SIZE), %esp
|
||||||
|
|
||||||
|
/* Pop General Purpose Registers */
|
||||||
|
pop %eax
|
||||||
|
pop %ebx
|
||||||
|
pop %ecx
|
||||||
|
pop %edx
|
||||||
|
pop %esi
|
||||||
|
pop %edi
|
||||||
|
pop %ebp
|
||||||
|
|
||||||
|
/* Skip error code and vector number, then return */
|
||||||
|
add $(2 * 4), %esp
|
||||||
|
iretl
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
/* Populate common interrupt, task and trap handlers */
|
/* Populate common trap handlers */
|
||||||
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||||
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||||
ArCreateHandler 0x\i\j Interrupt
|
ArCreateTrapHandler 0x\i\j
|
||||||
.if 0x\i\j == 0x02 || 0x\i\j == 0x08
|
|
||||||
ArCreateHandler 0x\i\j Task
|
|
||||||
.else
|
|
||||||
ArCreateHandler 0x\i\j Trap
|
|
||||||
.endif
|
|
||||||
.endr
|
.endr
|
||||||
.endr
|
.endr
|
||||||
|
|
||||||
/* Define array of pointers to the interrupt handlers */
|
|
||||||
.global _ArInterruptEntry
|
|
||||||
_ArInterruptEntry:
|
|
||||||
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
|
||||||
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
|
||||||
.long _ArInterrupt0x\i\j
|
|
||||||
.endr
|
|
||||||
.endr
|
|
||||||
|
|
||||||
/* Define array of pointers to the trap handlers */
|
|
||||||
.global _ArTrapEntry
|
|
||||||
_ArTrapEntry:
|
|
||||||
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
|
||||||
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
|
||||||
.if 0x\i\j == 0x02 || 0x\i\j == 0x08
|
|
||||||
.long _ArTask0x\i\j
|
|
||||||
.else
|
|
||||||
.long _ArTrap0x\i\j
|
|
||||||
.endif
|
|
||||||
.endr
|
|
||||||
.endr
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enables eXtended Physical Addressing (XPA). On i386, this is just a stub.
|
|
||||||
*
|
|
||||||
* @param PageMap
|
|
||||||
* Supplies a pointer to the page map to be used.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
.global ArEnableExtendedPhysicalAddressing
|
|
||||||
ArEnableExtendedPhysicalAddressing:
|
|
||||||
|
|
||||||
.global ArEnableExtendedPhysicalAddressingEnd
|
|
||||||
ArEnableExtendedPhysicalAddressingEnd:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles a spurious interrupt allowing it to end up.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
.global _ArHandleSpuriousInterrupt
|
|
||||||
_ArHandleSpuriousInterrupt:
|
|
||||||
iret
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts an application processor (AP).
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
.global _ArStartApplicationProcessor
|
|
||||||
_ArStartApplicationProcessor:
|
|
||||||
/* Enter 16-bit real mode */
|
|
||||||
.code16
|
|
||||||
|
|
||||||
/* Disable interrupts and clear direction flag */
|
|
||||||
cli
|
|
||||||
cld
|
|
||||||
|
|
||||||
/* Establish a flat addressing baseline */
|
|
||||||
movw %cs, %ax
|
|
||||||
movw %ax, %ds
|
|
||||||
movw %ax, %es
|
|
||||||
movw %ax, %ss
|
|
||||||
|
|
||||||
/* Calculate absolute physical base address */
|
|
||||||
xorl %ebx, %ebx
|
|
||||||
movw %cs, %bx
|
|
||||||
shll $4, %ebx
|
|
||||||
|
|
||||||
/* Set up a temporary stack for the AP initialization */
|
|
||||||
movl %ebx, %esp
|
|
||||||
addl $0x1000, %esp
|
|
||||||
|
|
||||||
/* Load the temporary Global Descriptor Table */
|
|
||||||
leal (ApTemporaryGdtDesc - _ArStartApplicationProcessor)(%ebx), %eax
|
|
||||||
movl %eax, (ApTemporaryGdtBase - _ArStartApplicationProcessor)
|
|
||||||
lgdtl (ApTemporaryGdtSize - _ArStartApplicationProcessor)
|
|
||||||
|
|
||||||
/* Enable Protected Mode */
|
|
||||||
movl %cr0, %eax
|
|
||||||
orl $0x01, %eax
|
|
||||||
movl %eax, %cr0
|
|
||||||
|
|
||||||
/* Far return to enter 32-bit protected mode */
|
|
||||||
leal (ApEnterProtectedMode - _ArStartApplicationProcessor)(%ebx), %eax
|
|
||||||
pushl $KGDT_R0_CODE
|
|
||||||
pushl %eax
|
|
||||||
lretl
|
|
||||||
|
|
||||||
ApEnterProtectedMode:
|
|
||||||
/* Enter 32-bit protected mode */
|
|
||||||
.code32
|
|
||||||
|
|
||||||
/* Setup all data segment registers */
|
|
||||||
movw $KGDT_R0_DATA, %ax
|
|
||||||
movw %ax, %ds
|
|
||||||
movw %ax, %es
|
|
||||||
movw %ax, %ss
|
|
||||||
xorw %ax, %ax
|
|
||||||
movw %ax, %fs
|
|
||||||
movw %ax, %gs
|
|
||||||
|
|
||||||
/* Locate PROCESSOR_START_BLOCK structure */
|
|
||||||
leal (_ArStartApplicationProcessorEnd - _ArStartApplicationProcessor)(%ebx), %edi
|
|
||||||
|
|
||||||
/* Load CR4 from BSP, but mask PCIDE and PGE */
|
|
||||||
movl PROCESSOR_START_BLOCK_Cr4(%edi), %eax
|
|
||||||
andl $~(CR4_PGE | CR4_PCIDE), %eax
|
|
||||||
movl %eax, %cr4
|
|
||||||
|
|
||||||
/* Load the Kernel Page Directory Base from BSP */
|
|
||||||
movl PROCESSOR_START_BLOCK_Cr3(%edi), %eax
|
|
||||||
movl %eax, %cr3
|
|
||||||
|
|
||||||
/* Enable Paging */
|
|
||||||
movl %cr0, %eax
|
|
||||||
orl $CR0_PG, %eax
|
|
||||||
movl %eax, %cr0
|
|
||||||
|
|
||||||
/* Load dedicated Stack for AP */
|
|
||||||
movl PROCESSOR_START_BLOCK_Stack(%edi), %esp
|
|
||||||
|
|
||||||
/* Save the pointer to PROCESSOR_START_BLOCK */
|
|
||||||
movl %edi, %ecx
|
|
||||||
pushl %edi
|
|
||||||
|
|
||||||
/* Call the EntryPoint routine */
|
|
||||||
movl PROCESSOR_START_BLOCK_EntryPoint(%edi), %eax
|
|
||||||
call *%eax
|
|
||||||
|
|
||||||
/* Fire the breakpoint and halt if the entry point returns */
|
|
||||||
.ApNoReturnPoint:
|
|
||||||
int $0x03
|
|
||||||
hlt
|
|
||||||
jmp .ApNoReturnPoint
|
|
||||||
|
|
||||||
/* Data section for temporary GDT */
|
|
||||||
.align 8
|
|
||||||
ApTemporaryGdtSize: .short _ArStartApplicationProcessorEnd - ApTemporaryGdtDesc - 1
|
|
||||||
ApTemporaryGdtBase: .long 0x00000000
|
|
||||||
ApTemporaryGdtDesc: .quad 0x0000000000000000, 0x00CF9A000000FFFF, 0x00CF92000000FFFF
|
|
||||||
|
|
||||||
.global _ArStartApplicationProcessorEnd
|
|
||||||
_ArStartApplicationProcessorEnd:
|
|
||||||
|
|||||||
26
xtoskrnl/ar/i686/boot.S
Normal file
26
xtoskrnl/ar/i686/boot.S
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* PROJECT: ExectOS
|
||||||
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
|
* FILE: xtoskrnl/ar/i686/boot.S
|
||||||
|
* DESCRIPTION: i686-specific boot code for setting up the low-level CPU environment
|
||||||
|
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ar/amd64/asmsup.h>
|
||||||
|
|
||||||
|
.altmacro
|
||||||
|
.text
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts an application processor (AP). This is just a stub.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
.global _ArStartApplicationProcessor
|
||||||
|
_ArStartApplicationProcessor:
|
||||||
|
|
||||||
|
.global _ArStartApplicationProcessorEnd
|
||||||
|
_ArStartApplicationProcessorEnd:
|
||||||
@@ -255,7 +255,7 @@ AR::CpuFunc::LoadLocalDescriptorTable(IN USHORT Source)
|
|||||||
XTCDECL
|
XTCDECL
|
||||||
VOID
|
VOID
|
||||||
AR::CpuFunc::LoadSegment(IN USHORT Segment,
|
AR::CpuFunc::LoadSegment(IN USHORT Segment,
|
||||||
IN ULONG Source)
|
IN ULONG Source)
|
||||||
{
|
{
|
||||||
switch(Segment)
|
switch(Segment)
|
||||||
{
|
{
|
||||||
@@ -543,33 +543,6 @@ AR::CpuFunc::ReadTimeStampCounter(VOID)
|
|||||||
return Value;
|
return Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads the current value of the CPU's time-stamp counter and processor ID.
|
|
||||||
*
|
|
||||||
* @param TscAux
|
|
||||||
* Supplies a pointer to a variable that receives the auxiliary TSC information (IA32_TSC_AUX).
|
|
||||||
*
|
|
||||||
* @return This routine returns the current instruction cycle count since the processor was last reset.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
ULONGLONG
|
|
||||||
AR::CpuFunc::ReadTimeStampCounterProcessor(OUT PULONG TscAux)
|
|
||||||
{
|
|
||||||
ULONG Low, High;
|
|
||||||
|
|
||||||
/* Execute the RDTSCP instruction */
|
|
||||||
__asm__ volatile("rdtscp"
|
|
||||||
: "=a" (Low),
|
|
||||||
"=d" (High),
|
|
||||||
"=c" (*TscAux)
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Combine the two 32-bit registers into a single 64-bit unsigned integer and return the value */
|
|
||||||
return ((ULONGLONG)High << 32) | Low;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Orders memory accesses as seen by other processors, without fence.
|
* Orders memory accesses as seen by other processors, without fence.
|
||||||
*
|
*
|
||||||
@@ -677,7 +650,7 @@ AR::CpuFunc::StoreLocalDescriptorTable(OUT PVOID Destination)
|
|||||||
XTCDECL
|
XTCDECL
|
||||||
VOID
|
VOID
|
||||||
AR::CpuFunc::StoreSegment(IN USHORT Segment,
|
AR::CpuFunc::StoreSegment(IN USHORT Segment,
|
||||||
OUT PVOID Destination)
|
OUT PVOID Destination)
|
||||||
{
|
{
|
||||||
switch(Segment)
|
switch(Segment)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,11 +30,5 @@ KPROCESSOR_BLOCK AR::ProcSup::InitialProcessorBlock;
|
|||||||
/* Initial TSS */
|
/* Initial TSS */
|
||||||
KTSS AR::ProcSup::InitialTss;
|
KTSS AR::ProcSup::InitialTss;
|
||||||
|
|
||||||
/* Initial kernel NMI stack */
|
|
||||||
UCHAR AR::ProcSup::NmiStack[KERNEL_STACK_SIZE] = {};
|
|
||||||
|
|
||||||
/* NMI task gate */
|
/* NMI task gate */
|
||||||
UCHAR AR::ProcSup::NonMaskableInterruptTss[KTSS_IO_MAPS];
|
UCHAR AR::ProcSup::NonMaskableInterruptTss[KTSS_IO_MAPS];
|
||||||
|
|
||||||
/* Unhandled interrupt routine */
|
|
||||||
PINTERRUPT_HANDLER AR::Traps::UnhandledInterruptRoutine = NULLPTR;
|
|
||||||
|
|||||||
@@ -20,8 +20,7 @@ XTAPI
|
|||||||
PVOID
|
PVOID
|
||||||
AR::ProcSup::GetBootStack(VOID)
|
AR::ProcSup::GetBootStack(VOID)
|
||||||
{
|
{
|
||||||
/* Return base address of kernel boot stack */
|
return (PVOID)BootStack;
|
||||||
return (PVOID)((ULONG_PTR)BootStack + KERNEL_STACK_SIZE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XTAPI
|
XTAPI
|
||||||
@@ -30,17 +29,14 @@ AR::ProcSup::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
|
|||||||
OUT PVOID *TrampolineCode,
|
OUT PVOID *TrampolineCode,
|
||||||
OUT PULONG_PTR TrampolineSize)
|
OUT PULONG_PTR TrampolineSize)
|
||||||
{
|
{
|
||||||
/* Get trampoline information */
|
|
||||||
switch(TrampolineType)
|
switch(TrampolineType)
|
||||||
{
|
{
|
||||||
case TrampolineApStartup:
|
case TrampolineApStartup:
|
||||||
/* Get AP startup trampoline information */
|
|
||||||
*TrampolineCode = (PVOID)ArStartApplicationProcessor;
|
*TrampolineCode = (PVOID)ArStartApplicationProcessor;
|
||||||
*TrampolineSize = (ULONG_PTR)ArStartApplicationProcessorEnd -
|
*TrampolineSize = (ULONG_PTR)ArStartApplicationProcessorEnd -
|
||||||
(ULONG_PTR)ArStartApplicationProcessor;
|
(ULONG_PTR)ArStartApplicationProcessor;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Unknown trampoline type */
|
|
||||||
*TrampolineCode = NULLPTR;
|
*TrampolineCode = NULLPTR;
|
||||||
*TrampolineSize = 0;
|
*TrampolineSize = 0;
|
||||||
break;
|
break;
|
||||||
@@ -48,7 +44,8 @@ AR::ProcSup::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identifies processor type (vendor, model, stepping) and stores them in Processor Control Block (PRCB).
|
* Identifies processor type (vendor, model, stepping) as well as looks for available CPU features and stores them
|
||||||
|
* in Processor Control Block (PRCB).
|
||||||
*
|
*
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
@@ -62,13 +59,16 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
|||||||
CPUID_REGISTERS CpuRegisters;
|
CPUID_REGISTERS CpuRegisters;
|
||||||
CPUID_SIGNATURE CpuSignature;
|
CPUID_SIGNATURE CpuSignature;
|
||||||
|
|
||||||
|
/* Not fully implemented yet */
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
|
||||||
/* Get current processor control block */
|
/* Get current processor control block */
|
||||||
Prcb = KE::Processor::GetCurrentProcessorControlBlock();
|
Prcb = KE::Processor::GetCurrentProcessorControlBlock();
|
||||||
|
|
||||||
/* Get CPU vendor by issueing CPUID instruction */
|
/* Get CPU vendor by issueing CPUID instruction */
|
||||||
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||||
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
|
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
|
||||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
CpuFunc::CpuId(&CpuRegisters);
|
||||||
|
|
||||||
/* Store CPU vendor in processor control block */
|
/* Store CPU vendor in processor control block */
|
||||||
Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx;
|
Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx;
|
||||||
@@ -80,7 +80,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
|||||||
/* Get CPU standard features */
|
/* Get CPU standard features */
|
||||||
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
CpuFunc::CpuId(&CpuRegisters);
|
||||||
|
|
||||||
/* Store CPU signature in processor control block */
|
/* Store CPU signature in processor control block */
|
||||||
CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax;
|
CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax;
|
||||||
@@ -92,23 +92,23 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
|||||||
if(Prcb->CpuId.Vendor == CPU_VENDOR_AMD)
|
if(Prcb->CpuId.Vendor == CPU_VENDOR_AMD)
|
||||||
{
|
{
|
||||||
/* AMD CPU */
|
/* AMD CPU */
|
||||||
if(CpuSignature.Family == 0xF)
|
if(Prcb->CpuId.Family >= 0xF)
|
||||||
{
|
{
|
||||||
Prcb->CpuId.Family += CpuSignature.ExtendedFamily;
|
Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
|
||||||
Prcb->CpuId.Model += (CpuSignature.ExtendedModel << 4);
|
Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(Prcb->CpuId.Vendor == CPU_VENDOR_INTEL)
|
else if(Prcb->CpuId.Vendor == CPU_VENDOR_INTEL)
|
||||||
{
|
{
|
||||||
/* Intel CPU */
|
/* Intel CPU */
|
||||||
if(CpuSignature.Family == 0xF)
|
if(Prcb->CpuId.Family == 0xF)
|
||||||
{
|
{
|
||||||
Prcb->CpuId.Family += CpuSignature.ExtendedFamily;
|
Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((CpuSignature.Family == 0x6) || (CpuSignature.Family == 0xF))
|
if((Prcb->CpuId.Family == 0x6) || (Prcb->CpuId.Family == 0xF))
|
||||||
{
|
{
|
||||||
Prcb->CpuId.Model += (CpuSignature.ExtendedModel << 4);
|
Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -117,12 +117,11 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
|||||||
Prcb->CpuId.Vendor = CPU_VENDOR_UNKNOWN;
|
Prcb->CpuId.Vendor = CPU_VENDOR_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Identify processor features */
|
/* TODO: Store a list of CPU features in processor control block */
|
||||||
IdentifyProcessorFeatures();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identifies processor features and stores them in Processor Control Block (PRCB).
|
* Initializes i686 processor specific structures.
|
||||||
*
|
*
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
@@ -130,133 +129,66 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
VOID
|
VOID
|
||||||
AR::ProcSup::IdentifyProcessorFeatures(VOID)
|
AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||||
{
|
{
|
||||||
ULONG MaxExtendedLeaf, MaxStandardLeaf;
|
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
|
||||||
PKPROCESSOR_CONTROL_BLOCK Prcb;
|
PVOID KernelBootStack, KernelFaultStack;
|
||||||
CPUID_REGISTERS CpuRegisters;
|
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||||
|
PKGDTENTRY Gdt;
|
||||||
|
PKIDTENTRY Idt;
|
||||||
|
PKTSS Tss;
|
||||||
|
|
||||||
/* Get current processor control block */
|
/* Check if processor structures buffer provided */
|
||||||
Prcb = KE::Processor::GetCurrentProcessorControlBlock();
|
if(ProcessorStructures)
|
||||||
|
|
||||||
/* Get maximum CPUID standard leaf */
|
|
||||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
|
||||||
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
|
|
||||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
|
||||||
MaxStandardLeaf = CpuRegisters.Eax;
|
|
||||||
|
|
||||||
/* Get maximum CPUID extended leaf */
|
|
||||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
|
||||||
CpuRegisters.Leaf = CPUID_GET_EXTENDED_MAX;
|
|
||||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
|
||||||
MaxExtendedLeaf = CpuRegisters.Eax;
|
|
||||||
|
|
||||||
/* Check if CPU supports standard features leaf */
|
|
||||||
if(MaxStandardLeaf >= CPUID_GET_STANDARD1_FEATURES)
|
|
||||||
{
|
{
|
||||||
/* Get CPU standard features */
|
/* Assign CPU structures from provided buffer */
|
||||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
|
||||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
&KernelBootStack, &KernelFaultStack);
|
||||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
|
||||||
|
|
||||||
/* Store CPU standard features in processor control block */
|
/* Use global IDT */
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE3) Prcb->CpuId.FeatureBits |= KCF_SSE3;
|
Idt = InitialIdt;
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_VMX) Prcb->CpuId.FeatureBits |= KCF_VMX;
|
}
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSSE3) Prcb->CpuId.FeatureBits |= KCF_SSSE3;
|
else
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4_1) Prcb->CpuId.FeatureBits |= KCF_SSE41;
|
{
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4_2) Prcb->CpuId.FeatureBits |= KCF_SSE42;
|
/* Use initial structures */
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_X2APIC) Prcb->CpuId.FeatureBits |= KCF_X2APIC;
|
Gdt = InitialGdt;
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_POPCNT) Prcb->CpuId.FeatureBits |= KCF_POPCNT;
|
Idt = InitialIdt;
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_TSC_DEADLINE) Prcb->CpuId.FeatureBits |= KCF_TSC_DEADLINE;
|
Tss = &InitialTss;
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_AES) Prcb->CpuId.FeatureBits |= KCF_AES;
|
KernelBootStack = &BootStack;
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_XSAVE) Prcb->CpuId.FeatureBits |= KCF_XSAVE;
|
KernelFaultStack = &FaultStack;
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_AVX) Prcb->CpuId.FeatureBits |= KCF_AVX;
|
ProcessorBlock = &InitialProcessorBlock;
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_RDRAND) Prcb->CpuId.FeatureBits |= KCF_RDRAND;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_VME) Prcb->CpuId.FeatureBits |= KCF_VME;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PSE) Prcb->CpuId.FeatureBits |= KCF_LARGE_PAGE;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSC) Prcb->CpuId.FeatureBits |= KCF_RDTSC;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PAE) Prcb->CpuId.FeatureBits |= KCF_PAE;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MCE) Prcb->CpuId.FeatureBits |= KCF_MCE;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CX8) Prcb->CpuId.FeatureBits |= KCF_CMPXCHG8B;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_APIC) Prcb->CpuId.FeatureBits |= KCF_APIC;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SEP) Prcb->CpuId.FeatureBits |= KCF_FAST_SYSCALL;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MTRR) Prcb->CpuId.FeatureBits |= KCF_MTRR;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PGE) Prcb->CpuId.FeatureBits |= KCF_GLOBAL_PAGE;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MCA) Prcb->CpuId.FeatureBits |= KCF_MCA;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CMOV) Prcb->CpuId.FeatureBits |= KCF_CMOV;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PAT) Prcb->CpuId.FeatureBits |= KCF_PAT;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PSE36) Prcb->CpuId.FeatureBits |= KCF_PSE36;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CLFLUSH) Prcb->CpuId.FeatureBits |= KCF_CLFLUSH;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_FXSR) Prcb->CpuId.FeatureBits |= KCF_FXSR;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_ACPI) Prcb->CpuId.FeatureBits |= KCF_ACPI;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MMX) Prcb->CpuId.FeatureBits |= KCF_MMX;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SSE) Prcb->CpuId.FeatureBits |= KCF_SSE;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SSE2) Prcb->CpuId.FeatureBits |= KCF_SSE2;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_HTT) Prcb->CpuId.FeatureBits |= KCF_SMT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if CPU supports standard7 features leaf */
|
/* Initialize processor block */
|
||||||
if(MaxStandardLeaf >= CPUID_GET_STANDARD7_FEATURES)
|
InitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);
|
||||||
{
|
|
||||||
/* Get CPU standard features */
|
|
||||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
|
||||||
CpuRegisters.Leaf = CPUID_GET_STANDARD7_FEATURES;
|
|
||||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
|
||||||
|
|
||||||
/* Store CPU standard7 features in processor control block */
|
/* Initialize GDT, IDT and TSS */
|
||||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_FSGSBASE) Prcb->CpuId.FeatureBits |= KCF_FSGSBASE;
|
InitializeGdt(ProcessorBlock);
|
||||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_AVX2) Prcb->CpuId.FeatureBits |= KCF_AVX2;
|
InitializeIdt(ProcessorBlock);
|
||||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SMEP) Prcb->CpuId.FeatureBits |= KCF_SMEP;
|
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack);
|
||||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_RDSEED) Prcb->CpuId.FeatureBits |= KCF_RDSEED;
|
|
||||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SMAP) Prcb->CpuId.FeatureBits |= KCF_SMAP;
|
|
||||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SHA) Prcb->CpuId.FeatureBits |= KCF_SHA;
|
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_LA57) Prcb->CpuId.FeatureBits |= KCF_LA57;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if CPU supports power management leaf */
|
/* Set GDT and IDT descriptors */
|
||||||
if(MaxStandardLeaf >= CPUID_GET_POWER_MANAGEMENT)
|
GdtDescriptor.Base = Gdt;
|
||||||
{
|
GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1;
|
||||||
/* Get CPU power management features */
|
IdtDescriptor.Base = Idt;
|
||||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;
|
||||||
CpuRegisters.Leaf = CPUID_GET_POWER_MANAGEMENT;
|
|
||||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
|
||||||
|
|
||||||
/* Store CPU power management features in processor control block */
|
/* Load GDT, IDT and TSS */
|
||||||
if(CpuRegisters.Eax & CPUID_FEATURES_EAX_ARAT) Prcb->CpuId.FeatureBits |= KCF_ARAT;
|
CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
|
||||||
}
|
CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
|
||||||
|
CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS);
|
||||||
|
|
||||||
/* Check if CPU supports extended features leaf */
|
/* Enter passive IRQ level */
|
||||||
if(MaxExtendedLeaf >= CPUID_GET_EXTENDED_FEATURES)
|
HL::RunLevel::SetRunLevel(PASSIVE_LEVEL);
|
||||||
{
|
|
||||||
/* Get CPU extended features */
|
|
||||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
|
||||||
CpuRegisters.Leaf = CPUID_GET_EXTENDED_FEATURES;
|
|
||||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
|
||||||
|
|
||||||
/* Store CPU extended features in processor control block */
|
/* Initialize segment registers */
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SVM) Prcb->CpuId.ExtendedFeatureBits |= KCF_SVM;
|
InitializeSegments();
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4A) Prcb->CpuId.ExtendedFeatureBits |= KCF_SSE4A;
|
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_FMA4) Prcb->CpuId.ExtendedFeatureBits |= KCF_FMA4;
|
|
||||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_TOPOLOGY_EXTENSIONS) Prcb->CpuId.ExtendedFeatureBits |= KCF_TOPOEXT;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SYSCALL_SYSRET) Prcb->CpuId.ExtendedFeatureBits |= KCF_SYSCALL;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_NX) Prcb->CpuId.ExtendedFeatureBits |= KCF_NX_BIT;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_RDTSCP) Prcb->CpuId.ExtendedFeatureBits |= KCF_RDTSCP;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_LONG_MODE) Prcb->CpuId.ExtendedFeatureBits |= KCF_64BIT;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_3DNOW_EXT) Prcb->CpuId.ExtendedFeatureBits |= KCF_3DNOW_EXT;
|
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_3DNOW) Prcb->CpuId.ExtendedFeatureBits |= KCF_3DNOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if CPU supports advanced power management leaf */
|
/* Initialize processor registers */
|
||||||
if(MaxExtendedLeaf >= CPUID_GET_ADVANCED_POWER_MANAGEMENT)
|
InitializeProcessorRegisters();
|
||||||
{
|
|
||||||
/* Get CPU advanced power management features */
|
|
||||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
|
||||||
CpuRegisters.Leaf = CPUID_GET_ADVANCED_POWER_MANAGEMENT;
|
|
||||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
|
||||||
|
|
||||||
/* Store CPU advanced power management features in processor control block */
|
/* Identify processor */
|
||||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSCI) Prcb->CpuId.ExtendedFeatureBits |= KCF_INVARIANT_TSC;
|
IdentifyProcessor();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -283,9 +215,9 @@ AR::ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
|||||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_PB, (ULONG_PTR)ProcessorBlock, sizeof(KPROCESSOR_BLOCK), KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2);
|
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_PB, (ULONG_PTR)ProcessorBlock, sizeof(KPROCESSOR_BLOCK), KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2);
|
||||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_TEB, 0x0, 0xFFF, KGDT_TYPE_DATA | KGDT_DESCRIPTOR_ACCESSED, KGDT_DPL_USER, 2);
|
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_TEB, 0x0, 0xFFF, KGDT_TYPE_DATA | KGDT_DESCRIPTOR_ACCESSED, KGDT_DPL_USER, 2);
|
||||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDM_TILE, 0x0400, 0xFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 0);
|
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDM_TILE, 0x0400, 0xFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 0);
|
||||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0x0, I686_LDT, KGDT_DPL_SYSTEM, 0);
|
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0);
|
||||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_DF_TSS, 0x20000, 0xFFFF, I686_TSS, KGDT_DPL_SYSTEM, 0);
|
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_DF_TSS, 0x20000, 0xFFFF, I686_TSS, KGDT_DPL_SYSTEM, 0);
|
||||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NMI_TSS, 0x20000, 0xFFFF, I686_TSS, KGDT_DPL_SYSTEM, 0);
|
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NMI_TSS, 0x20000, 0xFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0);
|
||||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDBS, 0xB8000, 0x3FFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0);
|
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDBS, 0xB8000, 0x3FFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0);
|
||||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_ALIAS, (ULONG_PTR)ProcessorBlock->GdtBase, (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0);
|
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_ALIAS, (ULONG_PTR)ProcessorBlock->GdtBase, (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0);
|
||||||
}
|
}
|
||||||
@@ -310,105 +242,34 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
|||||||
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
|
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
|
||||||
{
|
{
|
||||||
/* Set the IDT to handle unexpected interrupts */
|
/* Set the IDT to handle unexpected interrupts */
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArInterruptEntry[Vector],
|
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||||
KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup IDT handlers for known interrupts and traps */
|
/* Setup IDT handlers for known interrupts and traps */
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrapEntry[0x00], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrapEntry[0x01], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrapEntry[0x02], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TASK_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrapEntry[0x03], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrapEntry[0x04], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrapEntry[0x05], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrapEntry[0x06], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrapEntry[0x07], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrapEntry[0x08], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TASK_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrapEntry[0x09], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrapEntry[0x0A], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrapEntry[0x0B], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrapEntry[0x0C], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrapEntry[0x0D], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrapEntry[0x0E], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrapEntry[0x10], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrapEntry[0x11], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrapEntry[0x12], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrapEntry[0x13], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrapEntry[0x2A], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrap0x2A, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrapEntry[0x2B], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrap0x2B, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrapEntry[0x2C], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrapEntry[0x2D], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrapEntry[0x2E], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrap0x2E, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes i686 processor specific structures.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
|
||||||
{
|
|
||||||
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
|
|
||||||
PVOID KernelBootStack, KernelFaultStack, KernelNmiStack;
|
|
||||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
|
||||||
PKGDTENTRY Gdt;
|
|
||||||
PKIDTENTRY Idt;
|
|
||||||
PKTSS Tss;
|
|
||||||
|
|
||||||
/* Check if processor structures buffer provided */
|
|
||||||
if(ProcessorStructures)
|
|
||||||
{
|
|
||||||
/* Assign CPU structures from provided buffer */
|
|
||||||
InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
|
|
||||||
&KernelBootStack, &KernelFaultStack, &KernelNmiStack);
|
|
||||||
|
|
||||||
/* Use global IDT */
|
|
||||||
Idt = InitialIdt;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Use initial structures */
|
|
||||||
Gdt = InitialGdt;
|
|
||||||
Idt = InitialIdt;
|
|
||||||
Tss = &InitialTss;
|
|
||||||
KernelBootStack = (PVOID)((ULONG_PTR)&BootStack + KERNEL_STACK_SIZE);
|
|
||||||
KernelFaultStack = (PVOID)((ULONG_PTR)&FaultStack + KERNEL_STACK_SIZE);
|
|
||||||
KernelNmiStack = (PVOID)((ULONG_PTR)&NmiStack + KERNEL_STACK_SIZE);
|
|
||||||
ProcessorBlock = &InitialProcessorBlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize processor block */
|
|
||||||
InitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);
|
|
||||||
|
|
||||||
/* Initialize GDT, IDT and TSS */
|
|
||||||
InitializeGdt(ProcessorBlock);
|
|
||||||
InitializeIdt(ProcessorBlock);
|
|
||||||
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack, KernelNmiStack);
|
|
||||||
|
|
||||||
/* Set GDT and IDT descriptors */
|
|
||||||
GdtDescriptor.Base = Gdt;
|
|
||||||
GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1;
|
|
||||||
IdtDescriptor.Base = Idt;
|
|
||||||
IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;
|
|
||||||
|
|
||||||
/* Load GDT, IDT and TSS */
|
|
||||||
AR::CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
|
|
||||||
AR::CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
|
|
||||||
AR::CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS);
|
|
||||||
|
|
||||||
/* Initialize segment registers */
|
|
||||||
InitializeSegments();
|
|
||||||
|
|
||||||
/* Initialize processor registers */
|
|
||||||
InitializeProcessorRegisters();
|
|
||||||
|
|
||||||
/* Identify processor */
|
|
||||||
IdentifyProcessor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -481,10 +342,10 @@ VOID
|
|||||||
AR::ProcSup::InitializeProcessorRegisters(VOID)
|
AR::ProcSup::InitializeProcessorRegisters(VOID)
|
||||||
{
|
{
|
||||||
/* Clear EFLAGS register */
|
/* Clear EFLAGS register */
|
||||||
AR::CpuFunc::WriteEflagsRegister(0);
|
CpuFunc::WriteEflagsRegister(0);
|
||||||
|
|
||||||
/* Enable write-protection */
|
/* Enable write-protection */
|
||||||
AR::CpuFunc::WriteControlRegister(0, AR::CpuFunc::ReadControlRegister(0) | CR0_WP);
|
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_WP);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -519,8 +380,7 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
|||||||
OUT PKTSS *Tss,
|
OUT PKTSS *Tss,
|
||||||
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
||||||
OUT PVOID *KernelBootStack,
|
OUT PVOID *KernelBootStack,
|
||||||
OUT PVOID *KernelFaultStack,
|
OUT PVOID *KernelFaultStack)
|
||||||
OUT PVOID *KernelNmiStack)
|
|
||||||
{
|
{
|
||||||
UINT_PTR Address;
|
UINT_PTR Address;
|
||||||
|
|
||||||
@@ -528,49 +388,22 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
|||||||
Address = ROUND_UP((UINT_PTR)ProcessorStructures, MM_PAGE_SIZE) + KERNEL_STACK_SIZE;
|
Address = ROUND_UP((UINT_PTR)ProcessorStructures, MM_PAGE_SIZE) + KERNEL_STACK_SIZE;
|
||||||
|
|
||||||
/* Assign a space for kernel boot stack and advance */
|
/* Assign a space for kernel boot stack and advance */
|
||||||
if(KernelBootStack != NULLPTR)
|
*KernelBootStack = (PVOID)Address;
|
||||||
{
|
|
||||||
/* Return kernel boot stack address */
|
|
||||||
*KernelBootStack = (PVOID)Address;
|
|
||||||
}
|
|
||||||
Address += KERNEL_STACK_SIZE;
|
Address += KERNEL_STACK_SIZE;
|
||||||
|
|
||||||
/* Assign a space for kernel fault stack and advance */
|
/* Assign a space for kernel fault stack, no advance needed as stack grows down */
|
||||||
if(KernelFaultStack != NULLPTR)
|
*KernelFaultStack = (PVOID)Address;
|
||||||
{
|
|
||||||
/* Return kernel fault stack address */
|
|
||||||
*KernelFaultStack = (PVOID)Address;
|
|
||||||
}
|
|
||||||
Address += KERNEL_STACK_SIZE;
|
|
||||||
|
|
||||||
/* Assign a space for kernel NMI stack, no advance needed as stack grows down */
|
|
||||||
if(KernelNmiStack != NULLPTR)
|
|
||||||
{
|
|
||||||
/* Return kernel NMI stack address */
|
|
||||||
*KernelNmiStack = (PVOID)Address;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Assign a space for GDT and advance */
|
/* Assign a space for GDT and advance */
|
||||||
if(Gdt != NULLPTR)
|
*Gdt = (PKGDTENTRY)(PVOID)Address;
|
||||||
{
|
Address += sizeof(InitialGdt);
|
||||||
/* Return GDT base address */
|
|
||||||
*Gdt = (PKGDTENTRY)(PVOID)Address;
|
|
||||||
}
|
|
||||||
Address += (GDT_ENTRIES * sizeof(KGDTENTRY));
|
|
||||||
|
|
||||||
/* Assign a space for TSS and advance */
|
|
||||||
if(Tss != NULLPTR)
|
|
||||||
{
|
|
||||||
*Tss = (PKTSS)(PVOID)Address;
|
|
||||||
}
|
|
||||||
Address += sizeof(KTSS);
|
|
||||||
|
|
||||||
/* Assign a space for Processor Block and advance */
|
/* Assign a space for Processor Block and advance */
|
||||||
if(ProcessorBlock != NULLPTR)
|
*ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address;
|
||||||
{
|
Address += sizeof(InitialProcessorBlock);
|
||||||
/* Return processor block address */
|
|
||||||
*ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address;
|
/* Assign a space for TSS */
|
||||||
}
|
*Tss = (PKTSS)(PVOID)Address;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -585,12 +418,10 @@ VOID
|
|||||||
AR::ProcSup::InitializeSegments(VOID)
|
AR::ProcSup::InitializeSegments(VOID)
|
||||||
{
|
{
|
||||||
/* Initialize segments */
|
/* Initialize segments */
|
||||||
AR::CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
|
CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
|
||||||
AR::CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
|
CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
|
||||||
AR::CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
|
CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
|
||||||
AR::CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R0_PB);
|
CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R0_PB);
|
||||||
AR::CpuFunc::LoadSegment(SEGMENT_GS, 0);
|
|
||||||
AR::CpuFunc::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -607,19 +438,8 @@ XTAPI
|
|||||||
VOID
|
VOID
|
||||||
AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||||
IN PVOID KernelBootStack,
|
IN PVOID KernelBootStack,
|
||||||
IN PVOID KernelFaultStack,
|
IN PVOID KernelFaultStack)
|
||||||
IN PVOID KernelNmiStack)
|
|
||||||
{
|
{
|
||||||
PKGDTENTRY TssEntry;
|
|
||||||
|
|
||||||
/* Setup System TSS entry in Global Descriptor Table */
|
|
||||||
TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_SYS_TSS / sizeof(KGDTENTRY)]));
|
|
||||||
TssEntry->LimitLow = sizeof(KTSS) - 1;
|
|
||||||
TssEntry->Bits.LimitHigh = 0;
|
|
||||||
TssEntry->Bits.Dpl = 0;
|
|
||||||
TssEntry->Bits.Present = 1;
|
|
||||||
TssEntry->Bits.Type = I686_TSS;
|
|
||||||
|
|
||||||
/* Clear I/O map */
|
/* Clear I/O map */
|
||||||
RtlSetMemory(ProcessorBlock->TssBase->IoMaps[0].IoMap, 0xFF, IOPM_FULL_SIZE);
|
RtlSetMemory(ProcessorBlock->TssBase->IoMaps[0].IoMap, 0xFF, IOPM_FULL_SIZE);
|
||||||
|
|
||||||
@@ -641,16 +461,16 @@ AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
|||||||
|
|
||||||
/* Set I/O map base and disable traps */
|
/* Set I/O map base and disable traps */
|
||||||
ProcessorBlock->TssBase->IoMapBase = sizeof(KTSS);
|
ProcessorBlock->TssBase->IoMapBase = sizeof(KTSS);
|
||||||
|
ProcessorBlock->TssBase->Esp0 = (ULONG_PTR)KernelBootStack;
|
||||||
ProcessorBlock->TssBase->Flags = 0;
|
ProcessorBlock->TssBase->Flags = 0;
|
||||||
|
|
||||||
/* Set CR3, LDT and SS */
|
/* Set LDT and SS */
|
||||||
ProcessorBlock->TssBase->CR3 = AR::CpuFunc::ReadControlRegister(3);
|
ProcessorBlock->TssBase->LDT = KGDT_R0_LDT;
|
||||||
ProcessorBlock->TssBase->LDT = 0;
|
|
||||||
ProcessorBlock->TssBase->Ss0 = KGDT_R0_DATA;
|
ProcessorBlock->TssBase->Ss0 = KGDT_R0_DATA;
|
||||||
|
|
||||||
/* Initialize task gates for DoubleFault and NMI traps */
|
/* Initialize task gates for DoubleFault and NMI traps */
|
||||||
SetDoubleFaultTssEntry(ProcessorBlock, KernelFaultStack);
|
SetDoubleFaultTssEntry(ProcessorBlock, KernelFaultStack);
|
||||||
SetNonMaskableInterruptTssEntry(ProcessorBlock, KernelNmiStack);
|
SetNonMaskableInterruptTssEntry(ProcessorBlock, KernelFaultStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -682,24 +502,24 @@ AR::ProcSup::SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
|||||||
Tss = (PKTSS)DoubleFaultTss;
|
Tss = (PKTSS)DoubleFaultTss;
|
||||||
Tss->IoMapBase = sizeof(KTSS);
|
Tss->IoMapBase = sizeof(KTSS);
|
||||||
Tss->Flags = 0;
|
Tss->Flags = 0;
|
||||||
Tss->LDT = 0;
|
Tss->LDT = KGDT_R0_LDT;
|
||||||
Tss->CR3 = AR::CpuFunc::ReadControlRegister(3);
|
Tss->CR3 = CpuFunc::ReadControlRegister(3);
|
||||||
Tss->Esp = (ULONG_PTR)KernelFaultStack;
|
Tss->Esp = (ULONG_PTR)KernelFaultStack;
|
||||||
Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
|
Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
|
||||||
Tss->Eip = (ULONG)(ULONG_PTR)ArTrapEntry[0x08];
|
Tss->Eip = PtrToUlong(ArTrap0x08);
|
||||||
Tss->Cs = KGDT_R0_CODE;
|
Tss->Cs = KGDT_R0_CODE;
|
||||||
Tss->Ds = KGDT_R3_DATA | RPL_MASK;
|
Tss->Ds = KGDT_R3_DATA | RPL_MASK;
|
||||||
Tss->Es = KGDT_R3_DATA | RPL_MASK;
|
Tss->Es = KGDT_R3_DATA | RPL_MASK;
|
||||||
Tss->Fs = KGDT_R0_PB;
|
Tss->Fs = KGDT_R0_PB;
|
||||||
Tss->Ss = KGDT_R0_DATA;
|
|
||||||
Tss->Ss0 = KGDT_R0_DATA;
|
Tss->Ss0 = KGDT_R0_DATA;
|
||||||
|
CpuFunc::StoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss);
|
||||||
|
|
||||||
/* Setup DoubleFault TSS entry in Global Descriptor Table */
|
/* Setup DoubleFault TSS entry in Global Descriptor Table */
|
||||||
TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_DF_TSS / sizeof(KGDTENTRY)]));
|
TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_DF_TSS / sizeof(KGDTENTRY)]));
|
||||||
TssEntry->BaseLow = ((ULONG_PTR)Tss & 0xFFFF);
|
TssEntry->BaseLow = ((ULONG_PTR)Tss & 0xFFFF);
|
||||||
TssEntry->Bytes.BaseMiddle = ((ULONG_PTR)Tss >> 16);
|
TssEntry->Bytes.BaseMiddle = ((ULONG_PTR)Tss >> 16);
|
||||||
TssEntry->Bytes.BaseHigh = ((ULONG_PTR)Tss >> 24);
|
TssEntry->Bytes.BaseHigh = ((ULONG_PTR)Tss >> 24);
|
||||||
TssEntry->LimitLow = 0x68;
|
TssEntry->LimitLow = sizeof(KTSS) - 1;
|
||||||
TssEntry->Bits.LimitHigh = 0;
|
TssEntry->Bits.LimitHigh = 0;
|
||||||
TssEntry->Bits.Dpl = 0;
|
TssEntry->Bits.Dpl = 0;
|
||||||
TssEntry->Bits.Present = 1;
|
TssEntry->Bits.Present = 1;
|
||||||
@@ -880,7 +700,7 @@ AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
|
|||||||
XTAPI
|
XTAPI
|
||||||
VOID
|
VOID
|
||||||
AR::ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
AR::ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||||
IN PVOID KernelNmiStack)
|
IN PVOID KernelFaultStack)
|
||||||
{
|
{
|
||||||
PKGDTENTRY TaskGateEntry, TssEntry;
|
PKGDTENTRY TaskGateEntry, TssEntry;
|
||||||
PKTSS Tss;
|
PKTSS Tss;
|
||||||
@@ -896,24 +716,23 @@ AR::ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock
|
|||||||
Tss = (PKTSS)NonMaskableInterruptTss;
|
Tss = (PKTSS)NonMaskableInterruptTss;
|
||||||
Tss->IoMapBase = sizeof(KTSS);
|
Tss->IoMapBase = sizeof(KTSS);
|
||||||
Tss->Flags = 0;
|
Tss->Flags = 0;
|
||||||
Tss->LDT = 0;
|
Tss->LDT = KGDT_R0_LDT;
|
||||||
Tss->CR3 = AR::CpuFunc::ReadControlRegister(3);
|
Tss->CR3 = CpuFunc::ReadControlRegister(3);
|
||||||
Tss->Esp = (ULONG_PTR)KernelNmiStack;
|
Tss->Esp = (ULONG_PTR)KernelFaultStack;
|
||||||
Tss->Esp0 = (ULONG_PTR)KernelNmiStack;
|
Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
|
||||||
Tss->Eip = (ULONG)(ULONG_PTR)ArTrapEntry[0x02];
|
Tss->Eip = PtrToUlong(ArTrap0x02);
|
||||||
Tss->Cs = KGDT_R0_CODE;
|
Tss->Cs = KGDT_R0_CODE;
|
||||||
Tss->Ds = KGDT_R3_DATA | RPL_MASK;
|
Tss->Ds = KGDT_R3_DATA | RPL_MASK;
|
||||||
Tss->Es = KGDT_R3_DATA | RPL_MASK;
|
Tss->Es = KGDT_R3_DATA | RPL_MASK;
|
||||||
Tss->Fs = KGDT_R0_PB;
|
Tss->Fs = KGDT_R0_PB;
|
||||||
Tss->Ss = KGDT_R0_DATA;
|
CpuFunc::StoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss);
|
||||||
Tss->Ss0 = KGDT_R0_DATA;
|
|
||||||
|
|
||||||
/* Setup NMI TSS entry in Global Descriptor Table */
|
/* Setup NMI TSS entry in Global Descriptor Table */
|
||||||
TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_NMI_TSS / sizeof(KGDTENTRY)]));
|
TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_NMI_TSS / sizeof(KGDTENTRY)]));
|
||||||
TssEntry->BaseLow = ((ULONG_PTR)Tss & 0xFFFF);
|
TssEntry->BaseLow = ((ULONG_PTR)Tss & 0xFFFF);
|
||||||
TssEntry->Bytes.BaseMiddle = ((ULONG_PTR)Tss >> 16);
|
TssEntry->Bytes.BaseMiddle = ((ULONG_PTR)Tss >> 16);
|
||||||
TssEntry->Bytes.BaseHigh = ((ULONG_PTR)Tss >> 24);
|
TssEntry->Bytes.BaseHigh = ((ULONG_PTR)Tss >> 24);
|
||||||
TssEntry->LimitLow = 0x68;
|
TssEntry->LimitLow = sizeof(KTSS) - 1;
|
||||||
TssEntry->Bits.LimitHigh = 0;
|
TssEntry->Bits.LimitHigh = 0;
|
||||||
TssEntry->Bits.Dpl = 0;
|
TssEntry->Bits.Dpl = 0;
|
||||||
TssEntry->Bits.Present = 1;
|
TssEntry->Bits.Present = 1;
|
||||||
|
|||||||
@@ -9,44 +9,6 @@
|
|||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dispatches the interrupt provided by common interrupt handler.
|
|
||||||
*
|
|
||||||
* @param TrapFrame
|
|
||||||
* Supplies a kernel trap frame pushed by common interrupt handler on the stack.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
AR::Traps::DispatchInterrupt(IN PKTRAP_FRAME TrapFrame)
|
|
||||||
{
|
|
||||||
PINTERRUPT_HANDLER Handler;
|
|
||||||
|
|
||||||
/* Read the handler pointer from the CPU's interrupt dispatch table */
|
|
||||||
Handler = (PINTERRUPT_HANDLER)AR::CpuFunc::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, InterruptDispatchTable) +
|
|
||||||
(TrapFrame->Vector * sizeof(PINTERRUPT_HANDLER)));
|
|
||||||
|
|
||||||
/* Check if the interrupt has a handler registered */
|
|
||||||
if(Handler != NULLPTR)
|
|
||||||
{
|
|
||||||
/* Call the handler */
|
|
||||||
Handler(TrapFrame);
|
|
||||||
}
|
|
||||||
else if(UnhandledInterruptRoutine != NULLPTR)
|
|
||||||
{
|
|
||||||
/* Call the unhandled interrupt routine */
|
|
||||||
UnhandledInterruptRoutine(TrapFrame);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Dispatcher not initialized, print a debug message */
|
|
||||||
DebugPrint(L"ERROR: Caught unhandled interrupt: 0x%.2lX\n", TrapFrame->Vector);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispatches the trap provided by common trap handler.
|
* Dispatches the trap provided by common trap handler.
|
||||||
*
|
*
|
||||||
@@ -233,6 +195,7 @@ VOID
|
|||||||
AR::Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame)
|
AR::Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame)
|
||||||
{
|
{
|
||||||
DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n");
|
DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n");
|
||||||
|
KE::Crash::Panic(0x02);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -629,19 +592,19 @@ AR::Traps::HandleTrapFF(IN PKTRAP_FRAME TrapFrame)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the unhandled interrupt routine used for vectors that have no handler registered.
|
* C-linkage wrapper for dispatching the trap provided by common trap handler.
|
||||||
*
|
*
|
||||||
* @param Handler
|
* @param TrapFrame
|
||||||
* Supplies the pointer to the interrupt handler routine.
|
* Supplies a kernel trap frame pushed by common trap handler on the stack.
|
||||||
*
|
*
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
* @since XT 1.0
|
* @since XT 1.0
|
||||||
*/
|
*/
|
||||||
|
XTCLINK
|
||||||
XTCDECL
|
XTCDECL
|
||||||
VOID
|
VOID
|
||||||
AR::Traps::SetUnhandledInterruptRoutine(PINTERRUPT_HANDLER Handler)
|
ArDispatchTrap(IN PKTRAP_FRAME TrapFrame)
|
||||||
{
|
{
|
||||||
/* Set the unhandled interrupt routine */
|
AR::Traps::DispatchTrap(TrapFrame);
|
||||||
UnhandledInterruptRoutine = Handler;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
* FILE: xtoskrnl/hl/x86/acpi.cc
|
* FILE: xtoskrnl/hl/x86/acpi.cc
|
||||||
* DESCRIPTION: Advanced Configuration and Power Interface (ACPI) support
|
* DESCRIPTION: Advanced Configuration and Power Interface (ACPI) support
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
* Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
@@ -26,21 +25,8 @@ HL::Acpi::CacheAcpiTable(IN PACPI_DESCRIPTION_HEADER AcpiTable)
|
|||||||
{
|
{
|
||||||
PACPI_CACHE_LIST AcpiCache;
|
PACPI_CACHE_LIST AcpiCache;
|
||||||
|
|
||||||
/* Check if there are free slots in static early-boot cache array */
|
/* Create new ACPI table cache entry */
|
||||||
if(CacheCount >= ACPI_MAX_CACHED_TABLES)
|
AcpiCache = CONTAIN_RECORD(AcpiTable, ACPI_CACHE_LIST, Header);
|
||||||
{
|
|
||||||
/* Cache is full, the table is mapped but not cached */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the next available static cache entry */
|
|
||||||
AcpiCache = &CacheEntries[CacheCount];
|
|
||||||
CacheCount++;
|
|
||||||
|
|
||||||
/* Store the pointer to the mapped ACPI table */
|
|
||||||
AcpiCache->Table = AcpiTable;
|
|
||||||
|
|
||||||
/* Insert entry into the global ACPI cache list */
|
|
||||||
RTL::LinkedList::InsertTailList(&CacheList, &AcpiCache->ListEntry);
|
RTL::LinkedList::InsertTailList(&CacheList, &AcpiCache->ListEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,46 +91,6 @@ HL::Acpi::GetAcpiTable(IN ULONG Signature,
|
|||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the ACPI timer information.
|
|
||||||
*
|
|
||||||
* @param AcpiTimerInfo
|
|
||||||
* Supplies a pointer to memory area, where ACPI timer information will be stored.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
HL::Acpi::GetAcpiTimerInfo(OUT PACPI_TIMER_INFO *AcpiTimerInfo)
|
|
||||||
{
|
|
||||||
/* Check if ACPI timer info is available */
|
|
||||||
if(AcpiTimerInfo)
|
|
||||||
{
|
|
||||||
/* Return ACPI timer info */
|
|
||||||
*AcpiTimerInfo = &TimerInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the ACPI system information structure containing processor and topology data.
|
|
||||||
*
|
|
||||||
* @param SystemInfo
|
|
||||||
* Supplies a pointer to the memory area where the pointer to the system information structure will be stored.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
HL::Acpi::GetSystemInformation(OUT PACPI_SYSTEM_INFO *SystemInfo)
|
|
||||||
{
|
|
||||||
/* Return a pointer to the ACPI system information */
|
|
||||||
*SystemInfo = &HL::Acpi::SystemInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs an initialization of the ACPI subsystem.
|
* Performs an initialization of the ACPI subsystem.
|
||||||
*
|
*
|
||||||
@@ -250,23 +196,14 @@ HL::Acpi::InitializeAcpiSystemDescriptionTable(OUT PACPI_DESCRIPTION_HEADER *Acp
|
|||||||
AcpiResource = (PSYSTEM_RESOURCE_ACPI)ResourceHeader;
|
AcpiResource = (PSYSTEM_RESOURCE_ACPI)ResourceHeader;
|
||||||
RsdpAddress.QuadPart = (LONGLONG)AcpiResource->Header.PhysicalAddress;
|
RsdpAddress.QuadPart = (LONGLONG)AcpiResource->Header.PhysicalAddress;
|
||||||
|
|
||||||
/* Map RSDP using hardware memory pool */
|
/* Map RSDP and mark it as CD/WT to avoid delays in write-back cache */
|
||||||
Status = MM::HardwarePool::MapHardwareMemory(RsdpAddress, 1, TRUE, (PVOID *)&RsdpStructure);
|
Status = MM::HardwarePool::MapHardwareMemory(RsdpAddress, 1, TRUE, (PVOID *)&RsdpStructure);
|
||||||
if(Status != STATUS_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to map RSDP, return error */
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Mark RSDP as CD/WT to avoid delays in write-back cache */
|
|
||||||
MM::HardwarePool::MarkHardwareMemoryWriteThrough(RsdpStructure, 1);
|
MM::HardwarePool::MarkHardwareMemoryWriteThrough(RsdpStructure, 1);
|
||||||
|
|
||||||
/* Validate RSDP signature */
|
/* Validate RSDP signature */
|
||||||
if(RsdpStructure->Signature != ACPI_RSDP_SIGNATURE)
|
if(Status != STATUS_SUCCESS || RsdpStructure->Signature != ACPI_RSDP_SIGNATURE)
|
||||||
{
|
{
|
||||||
/* Invalid RSDP signature, unmap and return error */
|
/* Not mapped correctly or invalid RSDP signature, return error */
|
||||||
MM::HardwarePool::UnmapHardwareMemory(RsdpStructure, 1, TRUE);
|
|
||||||
RsdpStructure = NULLPTR;
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,40 +219,34 @@ HL::Acpi::InitializeAcpiSystemDescriptionTable(OUT PACPI_DESCRIPTION_HEADER *Acp
|
|||||||
RsdtAddress.QuadPart = (LONGLONG)RsdpStructure->RsdtAddress;
|
RsdtAddress.QuadPart = (LONGLONG)RsdpStructure->RsdtAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Map RSDT/XSDT using hardware memory pool */
|
/* Map RSDT/XSDT as CD/WT */
|
||||||
Status = MM::HardwarePool::MapHardwareMemory(RsdtAddress, 2, TRUE, (PVOID *)&Rsdt);
|
Status = MM::HardwarePool::MapHardwareMemory(RsdtAddress, 2, TRUE, (PVOID *)&Rsdt);
|
||||||
if(Status != STATUS_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to map RSDT/XSDT, return error */
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Mark RSDT/XSDT as CD/WT */
|
|
||||||
MM::HardwarePool::MarkHardwareMemoryWriteThrough(Rsdt, 2);
|
MM::HardwarePool::MarkHardwareMemoryWriteThrough(Rsdt, 2);
|
||||||
|
|
||||||
/* Validate RSDT/XSDT signature */
|
/* Validate RSDT/XSDT signature */
|
||||||
if(Rsdt->Header.Signature != ACPI_RSDT_SIGNATURE && Rsdt->Header.Signature != ACPI_XSDT_SIGNATURE)
|
if((Status != STATUS_SUCCESS) ||
|
||||||
|
(Rsdt->Header.Signature != ACPI_RSDT_SIGNATURE &&
|
||||||
|
Rsdt->Header.Signature != ACPI_XSDT_SIGNATURE))
|
||||||
{
|
{
|
||||||
/* Not mapped correctly or invalid RSDT/XSDT signature, unmap and return error */
|
/* Not mapped correctly or invalid RSDT/XSDT signature, return error */
|
||||||
MM::HardwarePool::UnmapHardwareMemory(Rsdt, 2, TRUE);
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the length of all available ACPI tables and remap it if needed */
|
/* Calculate the length of all available ACPI tables and remap it if needed */
|
||||||
RsdtPages = (((RsdtAddress.LowPart & (MM_PAGE_SIZE - 1)) + Rsdt->Header.Length + (MM_PAGE_SIZE - 1)) >> MM_PAGE_SHIFT);
|
RsdtPages = ((RsdtAddress.LowPart & (MM_PAGE_SIZE - 1)) + Rsdt->Header.Length + (MM_PAGE_SIZE - 1)) >> MM_PAGE_SHIFT;
|
||||||
if(RsdtPages != 2)
|
if(RsdtPages != 2)
|
||||||
{
|
{
|
||||||
/* RSDT/XSDT needs less or more than 2 pages, remap it */
|
/* RSDT/XSDT needs less or more than 2 pages, remap it */
|
||||||
MM::HardwarePool::UnmapHardwareMemory(Rsdt, 2, TRUE);
|
MM::HardwarePool::UnmapHardwareMemory(Rsdt, 2, TRUE);
|
||||||
Status = MM::HardwarePool::MapHardwareMemory(RsdtAddress, RsdtPages, TRUE, (PVOID *)&Rsdt);
|
Status = MM::HardwarePool::MapHardwareMemory(RsdtAddress, RsdtPages, TRUE, (PVOID *)&Rsdt);
|
||||||
|
MM::HardwarePool::MarkHardwareMemoryWriteThrough(Rsdt, RsdtPages);
|
||||||
|
|
||||||
|
/* Make sure remapping was successful */
|
||||||
if(Status != STATUS_SUCCESS)
|
if(Status != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Remapping failed, return error */
|
/* Remapping failed, return error */
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mark remapped RSDT/XSDT as CD/WT */
|
|
||||||
MM::HardwarePool::MarkHardwareMemoryWriteThrough(Rsdt, RsdtPages);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get ACPI table header and return success */
|
/* Get ACPI table header and return success */
|
||||||
@@ -336,7 +267,6 @@ HL::Acpi::InitializeAcpiSystemInformation(VOID)
|
|||||||
{
|
{
|
||||||
PACPI_MADT_LOCAL_X2APIC LocalX2Apic;
|
PACPI_MADT_LOCAL_X2APIC LocalX2Apic;
|
||||||
PACPI_MADT_LOCAL_APIC LocalApic;
|
PACPI_MADT_LOCAL_APIC LocalApic;
|
||||||
PACPI_SUBTABLE_HEADER SubTable;
|
|
||||||
ULONG_PTR MadtTable;
|
ULONG_PTR MadtTable;
|
||||||
PACPI_MADT Madt;
|
PACPI_MADT Madt;
|
||||||
XTSTATUS Status;
|
XTSTATUS Status;
|
||||||
@@ -363,20 +293,11 @@ HL::Acpi::InitializeAcpiSystemInformation(VOID)
|
|||||||
CpuCount = 0;
|
CpuCount = 0;
|
||||||
|
|
||||||
/* Traverse all MADT tables to get system information */
|
/* Traverse all MADT tables to get system information */
|
||||||
while(MadtTable < ((ULONG_PTR)Madt + Madt->Header.Length))
|
while(MadtTable <= ((ULONG_PTR)Madt + Madt->Header.Length))
|
||||||
{
|
{
|
||||||
/* Get current MADT subtable header */
|
|
||||||
SubTable = (PACPI_SUBTABLE_HEADER)MadtTable;
|
|
||||||
|
|
||||||
/* Prevent infinite loops if BIOS provides 0 length */
|
|
||||||
if(SubTable->Length == 0)
|
|
||||||
{
|
|
||||||
/* Broken ACPI table, abort traversal */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if this is a local APIC subtable */
|
/* Check if this is a local APIC subtable */
|
||||||
if(SubTable->Type == ACPI_MADT_TYPE_LOCAL_APIC && SubTable->Length >= sizeof(ACPI_MADT_LOCAL_APIC))
|
if((((PACPI_SUBTABLE_HEADER)MadtTable)->Type == ACPI_MADT_TYPE_LOCAL_APIC) &&
|
||||||
|
(((PACPI_SUBTABLE_HEADER)MadtTable)->Length == sizeof(ACPI_MADT_LOCAL_APIC)))
|
||||||
{
|
{
|
||||||
/* Get local APIC subtable */
|
/* Get local APIC subtable */
|
||||||
LocalApic = (PACPI_MADT_LOCAL_APIC)MadtTable;
|
LocalApic = (PACPI_MADT_LOCAL_APIC)MadtTable;
|
||||||
@@ -392,8 +313,12 @@ HL::Acpi::InitializeAcpiSystemInformation(VOID)
|
|||||||
/* Increment number of CPUs */
|
/* Increment number of CPUs */
|
||||||
CpuCount++;
|
CpuCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Go to the next MADT table */
|
||||||
|
MadtTable += ((PACPI_SUBTABLE_HEADER)MadtTable)->Length;
|
||||||
}
|
}
|
||||||
else if(SubTable->Type == ACPI_MADT_TYPE_LOCAL_X2APIC && SubTable->Length >= sizeof(ACPI_MADT_LOCAL_X2APIC))
|
else if((((PACPI_SUBTABLE_HEADER)MadtTable)->Type == ACPI_MADT_TYPE_LOCAL_X2APIC) &&
|
||||||
|
(((PACPI_SUBTABLE_HEADER)MadtTable)->Length == sizeof(ACPI_MADT_LOCAL_X2APIC)))
|
||||||
{
|
{
|
||||||
/* Get local X2APIC subtable */
|
/* Get local X2APIC subtable */
|
||||||
LocalX2Apic = (PACPI_MADT_LOCAL_X2APIC)MadtTable;
|
LocalX2Apic = (PACPI_MADT_LOCAL_X2APIC)MadtTable;
|
||||||
@@ -409,10 +334,15 @@ HL::Acpi::InitializeAcpiSystemInformation(VOID)
|
|||||||
/* Increment number of CPUs */
|
/* Increment number of CPUs */
|
||||||
CpuCount++;
|
CpuCount++;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Safely advance pointer using proper subtable length */
|
/* Go to the next MADT table */
|
||||||
MadtTable += SubTable->Length;
|
MadtTable += ((PACPI_SUBTABLE_HEADER)MadtTable)->Length;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Any other MADT table, try to go to the next one byte-by-byte */
|
||||||
|
MadtTable += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store number of CPUs */
|
/* Store number of CPUs */
|
||||||
@@ -434,7 +364,6 @@ XTSTATUS
|
|||||||
HL::Acpi::InitializeAcpiSystemStructure(VOID)
|
HL::Acpi::InitializeAcpiSystemStructure(VOID)
|
||||||
{
|
{
|
||||||
PHYSICAL_ADDRESS PhysicalAddress;
|
PHYSICAL_ADDRESS PhysicalAddress;
|
||||||
PACPI_SUBTABLE_HEADER SubTable;
|
|
||||||
PFN_NUMBER PageCount;
|
PFN_NUMBER PageCount;
|
||||||
ULONG_PTR MadtTable;
|
ULONG_PTR MadtTable;
|
||||||
PACPI_MADT Madt;
|
PACPI_MADT Madt;
|
||||||
@@ -454,19 +383,11 @@ HL::Acpi::InitializeAcpiSystemStructure(VOID)
|
|||||||
CpuCount = 0;
|
CpuCount = 0;
|
||||||
|
|
||||||
/* Traverse all MADT tables to get number of processors */
|
/* Traverse all MADT tables to get number of processors */
|
||||||
while(MadtTable < ((ULONG_PTR)Madt + Madt->Header.Length))
|
while(MadtTable <= ((ULONG_PTR)Madt + Madt->Header.Length))
|
||||||
{
|
{
|
||||||
SubTable = (PACPI_SUBTABLE_HEADER)MadtTable;
|
|
||||||
|
|
||||||
/* Prevent infinite loops if BIOS provides 0 length */
|
|
||||||
if(SubTable->Length == 0)
|
|
||||||
{
|
|
||||||
/* Broken ACPI table, abort traversal */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if this is a local APIC subtable */
|
/* Check if this is a local APIC subtable */
|
||||||
if(SubTable->Type == ACPI_MADT_TYPE_LOCAL_APIC && SubTable->Length >= sizeof(ACPI_MADT_LOCAL_APIC))
|
if((((PACPI_SUBTABLE_HEADER)MadtTable)->Type == ACPI_MADT_TYPE_LOCAL_APIC) &&
|
||||||
|
(((PACPI_SUBTABLE_HEADER)MadtTable)->Length == sizeof(ACPI_MADT_LOCAL_APIC)))
|
||||||
{
|
{
|
||||||
/* Make sure, this CPU can be enabled */
|
/* Make sure, this CPU can be enabled */
|
||||||
if(((PACPI_MADT_LOCAL_APIC)MadtTable)->Flags & ACPI_MADT_PLAOC_ENABLED)
|
if(((PACPI_MADT_LOCAL_APIC)MadtTable)->Flags & ACPI_MADT_PLAOC_ENABLED)
|
||||||
@@ -474,8 +395,12 @@ HL::Acpi::InitializeAcpiSystemStructure(VOID)
|
|||||||
/* Increment number of CPUs */
|
/* Increment number of CPUs */
|
||||||
CpuCount++;
|
CpuCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Go to the next MADT table */
|
||||||
|
MadtTable += ((PACPI_SUBTABLE_HEADER)MadtTable)->Length;
|
||||||
}
|
}
|
||||||
else if(SubTable->Type == ACPI_MADT_TYPE_LOCAL_X2APIC && SubTable->Length >= sizeof(ACPI_MADT_LOCAL_X2APIC))
|
else if((((PACPI_SUBTABLE_HEADER)MadtTable)->Type == ACPI_MADT_TYPE_LOCAL_X2APIC) &&
|
||||||
|
(((PACPI_SUBTABLE_HEADER)MadtTable)->Length == sizeof(ACPI_MADT_LOCAL_X2APIC)))
|
||||||
{
|
{
|
||||||
/* Make sure, this CPU can be enabled */
|
/* Make sure, this CPU can be enabled */
|
||||||
if(((PACPI_MADT_LOCAL_X2APIC)MadtTable)->Flags & ACPI_MADT_PLAOC_ENABLED)
|
if(((PACPI_MADT_LOCAL_X2APIC)MadtTable)->Flags & ACPI_MADT_PLAOC_ENABLED)
|
||||||
@@ -483,10 +408,15 @@ HL::Acpi::InitializeAcpiSystemStructure(VOID)
|
|||||||
/* Increment number of CPUs */
|
/* Increment number of CPUs */
|
||||||
CpuCount++;
|
CpuCount++;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Safely advance pointer using proper subtable length */
|
/* Go to the next MADT table */
|
||||||
MadtTable += SubTable->Length;
|
MadtTable += ((PACPI_SUBTABLE_HEADER)MadtTable)->Length;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Any other MADT table, try to go to the next one byte-by-byte */
|
||||||
|
MadtTable += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Zero the ACPI system information structure */
|
/* Zero the ACPI system information structure */
|
||||||
@@ -496,7 +426,7 @@ HL::Acpi::InitializeAcpiSystemStructure(VOID)
|
|||||||
PageCount = SIZE_TO_PAGES(CpuCount * sizeof(PROCESSOR_IDENTITY));
|
PageCount = SIZE_TO_PAGES(CpuCount * sizeof(PROCESSOR_IDENTITY));
|
||||||
|
|
||||||
/* Allocate memory for CPU information */
|
/* Allocate memory for CPU information */
|
||||||
Status = MM::HardwarePool::AllocateHardwareMemory(PageCount, TRUE, MM_MAXIMUM_PHYSICAL_ADDRESS, &PhysicalAddress);
|
Status = MM::HardwarePool::AllocateHardwareMemory(PageCount, TRUE, &PhysicalAddress);
|
||||||
if(Status != STATUS_SUCCESS)
|
if(Status != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Failed to allocate memory, return error */
|
/* Failed to allocate memory, return error */
|
||||||
@@ -592,10 +522,10 @@ HL::Acpi::QueryAcpiCache(IN ULONG Signature,
|
|||||||
AcpiCache = CONTAIN_RECORD(ListEntry, ACPI_CACHE_LIST, ListEntry);
|
AcpiCache = CONTAIN_RECORD(ListEntry, ACPI_CACHE_LIST, ListEntry);
|
||||||
|
|
||||||
/* Check if ACPI table signature matches */
|
/* Check if ACPI table signature matches */
|
||||||
if(AcpiCache->Table->Signature == Signature)
|
if(AcpiCache->Header.Signature == Signature)
|
||||||
{
|
{
|
||||||
/* ACPI table found in cache, return it */
|
/* ACPI table found in cache, return it */
|
||||||
TableHeader = AcpiCache->Table;
|
TableHeader = &AcpiCache->Header;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -666,31 +596,18 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
|
|||||||
/* Check if DSDT or FACS table requested */
|
/* Check if DSDT or FACS table requested */
|
||||||
if(Signature == ACPI_DSDT_SIGNATURE)
|
if(Signature == ACPI_DSDT_SIGNATURE)
|
||||||
{
|
{
|
||||||
/* Prefer 64-bit address on ACPI 2.0+ */
|
/* Get DSDT address */
|
||||||
if(Fadt->Header.Revision >= 2 && Fadt->XDsdt.QuadPart != 0)
|
TableAddress.LowPart = Fadt->Dsdt;
|
||||||
{
|
|
||||||
TableAddress.QuadPart = Fadt->XDsdt.QuadPart;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TableAddress.LowPart = Fadt->Dsdt;
|
|
||||||
TableAddress.HighPart = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Prefer 64-bit address on ACPI 2.0+ */
|
/* Get FACS address */
|
||||||
if(Fadt->Header.Revision >= 2 && Fadt->XFirmwareCtrl.QuadPart != 0)
|
TableAddress.LowPart = Fadt->FirmwareCtrl;
|
||||||
{
|
|
||||||
TableAddress.QuadPart = Fadt->XFirmwareCtrl.QuadPart;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TableAddress.LowPart = Fadt->FirmwareCtrl;
|
|
||||||
TableAddress.HighPart = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fill in high part of ACPI table address */
|
||||||
|
TableAddress.HighPart = 0;
|
||||||
|
|
||||||
/* Map table using hardware memory pool */
|
/* Map table using hardware memory pool */
|
||||||
Status = MM::HardwarePool::MapHardwareMemory(TableAddress, 2, TRUE, (PVOID*)&TableHeader);
|
Status = MM::HardwarePool::MapHardwareMemory(TableAddress, 2, TRUE, (PVOID*)&TableHeader);
|
||||||
if(Status != STATUS_SUCCESS)
|
if(Status != STATUS_SUCCESS)
|
||||||
@@ -701,12 +618,11 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Query cache for XSDT table */
|
/* Query cache for XSDP table */
|
||||||
Status = QueryAcpiCache(ACPI_XSDT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Xsdt);
|
Status = QueryAcpiCache(ACPI_XSDT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Xsdt);
|
||||||
if(Status != STATUS_SUCCESS)
|
if(Status != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
/* XSDT not found, query cache for RSDT table */
|
/* XSDP not found, query cache for RSDP table */
|
||||||
Xsdt = NULLPTR;
|
|
||||||
Status = QueryAcpiCache(ACPI_RSDT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Rsdt);
|
Status = QueryAcpiCache(ACPI_RSDT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Rsdt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -717,22 +633,22 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get table count depending on root table type securely */
|
/* Get table count depending on root table type */
|
||||||
if(Xsdt != NULLPTR)
|
if(Xsdt != NULLPTR)
|
||||||
{
|
{
|
||||||
if(Xsdt->Header.Length < sizeof(ACPI_DESCRIPTION_HEADER)) return STATUS_INVALID_PARAMETER;
|
/* Get table count from XSDT */
|
||||||
TableCount = (Xsdt->Header.Length - sizeof(ACPI_DESCRIPTION_HEADER)) / 8;
|
TableCount = (Xsdt->Header.Length - sizeof(ACPI_DESCRIPTION_HEADER)) / 8;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(Rsdt->Header.Length < sizeof(ACPI_DESCRIPTION_HEADER)) return STATUS_INVALID_PARAMETER;
|
/* Get table count from RSDT */
|
||||||
TableCount = (Rsdt->Header.Length - sizeof(ACPI_DESCRIPTION_HEADER)) / 4;
|
TableCount = (Rsdt->Header.Length - sizeof(ACPI_DESCRIPTION_HEADER)) / 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Iterate over all ACPI tables */
|
/* Iterate over all ACPI tables */
|
||||||
for(TableIndex = 0; TableIndex < TableCount; TableIndex++)
|
for(TableIndex = 0; TableIndex < TableCount; TableIndex++)
|
||||||
{
|
{
|
||||||
/* Check if XSDT or RSDT is used */
|
/* Check if XSDP or RSDT is used */
|
||||||
if(Xsdt != NULLPTR)
|
if(Xsdt != NULLPTR)
|
||||||
{
|
{
|
||||||
/* Get table header physical address from XSDT */
|
/* Get table header physical address from XSDT */
|
||||||
@@ -745,6 +661,13 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
|
|||||||
TableAddress.HighPart = 0;
|
TableAddress.HighPart = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check whether some table is already mapped */
|
||||||
|
if(TableHeader != NULLPTR)
|
||||||
|
{
|
||||||
|
/* Unmap previous table */
|
||||||
|
MM::HardwarePool::UnmapHardwareMemory(TableHeader, 2, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
/* Map table using hardware memory pool */
|
/* Map table using hardware memory pool */
|
||||||
Status = MM::HardwarePool::MapHardwareMemory(TableAddress, 2, TRUE, (PVOID*)&TableHeader);
|
Status = MM::HardwarePool::MapHardwareMemory(TableAddress, 2, TRUE, (PVOID*)&TableHeader);
|
||||||
if(Status != STATUS_SUCCESS)
|
if(Status != STATUS_SUCCESS)
|
||||||
@@ -759,31 +682,25 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
|
|||||||
/* Found requested ACPI table */
|
/* Found requested ACPI table */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unmap non-matching table and try next one */
|
|
||||||
MM::HardwarePool::UnmapHardwareMemory(TableHeader, 2, TRUE);
|
|
||||||
TableHeader = NULLPTR;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure the table was actually found and mapped */
|
/* Make sure table was found */
|
||||||
if(TableHeader == NULLPTR)
|
|
||||||
{
|
|
||||||
/* ACPI table not found, return error */
|
|
||||||
return STATUS_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if we broke out of the loop with the wrong table (safety check) */
|
|
||||||
if(TableHeader->Signature != Signature)
|
if(TableHeader->Signature != Signature)
|
||||||
{
|
{
|
||||||
/* Unmap non-matching ACPI table and return error */
|
/* ACPI table not found, check if cleanup is needed */
|
||||||
MM::HardwarePool::UnmapHardwareMemory(TableHeader, 2, TRUE);
|
if(TableHeader != NULLPTR)
|
||||||
|
{
|
||||||
|
/* Unmap non-matching ACPI table */
|
||||||
|
MM::HardwarePool::UnmapHardwareMemory(TableHeader, 2, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return error */
|
||||||
return STATUS_NOT_FOUND;
|
return STATUS_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't validate FACS and FADT on old, broken firmwares with ACPI 2.0 or older */
|
/* Don't validate FADT on old, broken firmwares with ACPI 2.0 or older */
|
||||||
if((TableHeader->Signature != ACPI_FADT_SIGNATURE || TableHeader->Revision > 2) &&
|
if(TableHeader->Signature != ACPI_FADT_SIGNATURE || TableHeader->Revision > 2)
|
||||||
(TableHeader->Signature != ACPI_FACS_SIGNATURE))
|
|
||||||
{
|
{
|
||||||
/* Validate table checksum */
|
/* Validate table checksum */
|
||||||
if(!ValidateAcpiTable(TableHeader, TableHeader->Length))
|
if(!ValidateAcpiTable(TableHeader, TableHeader->Length))
|
||||||
@@ -795,7 +712,7 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the length of ACPI table and remap it if needed */
|
/* Calculate the length of ACPI table and remap it if needed */
|
||||||
TablePages = (((TableAddress.LowPart & (MM_PAGE_SIZE - 1)) + TableHeader->Length + (MM_PAGE_SIZE - 1)) >> MM_PAGE_SHIFT);
|
TablePages = (((ULONG_PTR)TableHeader & (MM_PAGE_SIZE - 1)) + TableHeader->Length + (MM_PAGE_SIZE - 1)) >> MM_PAGE_SHIFT;
|
||||||
if(TablePages != 2)
|
if(TablePages != 2)
|
||||||
{
|
{
|
||||||
/* ACPI table needs less or more than 2 pages, remap it */
|
/* ACPI table needs less or more than 2 pages, remap it */
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/hl/amd64/firmware.cc
|
|
||||||
* DESCRIPTION: UEFI/BIOS Firmware support
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/* Include common Firmware interface */
|
|
||||||
#include ARCH_COMMON(firmware.cc)
|
|
||||||
@@ -1,260 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/hl/amd64/irq.cc
|
|
||||||
* DESCRIPTION: Interrupts support for AMD64 architecture
|
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
|
||||||
* Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Begins a system interrupt handler by raising the processor's run level and re-enabling
|
|
||||||
* hardware interrupts to allow preemption by higher-priority events.
|
|
||||||
*
|
|
||||||
* @param RunLevel
|
|
||||||
* Supplies the target run level to raise the processor to.
|
|
||||||
*
|
|
||||||
* @param OldRunLevel
|
|
||||||
* Receives the previous run level before the elevation.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
HL::Irq::BeginSystemInterrupt(IN KRUNLEVEL RunLevel,
|
|
||||||
OUT PKRUNLEVEL OldRunLevel)
|
|
||||||
{
|
|
||||||
/* Get the current IRQL */
|
|
||||||
*OldRunLevel = KE::RunLevel::GetCurrentRunLevel();
|
|
||||||
|
|
||||||
/* Raise run level */
|
|
||||||
KE::RunLevel::RaiseRunLevel(RunLevel);
|
|
||||||
|
|
||||||
/* Enable interrupts */
|
|
||||||
AR::CpuFunc::SetInterruptFlag();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Safely concludes an interrupt handler by disabling hardware interrupts.
|
|
||||||
*
|
|
||||||
* @param TrapFrame
|
|
||||||
* Supplies a pointer to the kernel trap frame containing the interrupted execution state.
|
|
||||||
*
|
|
||||||
* @param OldRunLevel
|
|
||||||
* Supplies the previous run level to restore.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
HL::Irq::EndInterrupt(IN PKTRAP_FRAME TrapFrame,
|
|
||||||
IN KRUNLEVEL OldRunLevel)
|
|
||||||
{
|
|
||||||
/* Disable interrupts */
|
|
||||||
AR::CpuFunc::ClearInterruptFlag();
|
|
||||||
|
|
||||||
/* End system interrupt */
|
|
||||||
EndSystemInterrupt(TrapFrame, OldRunLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Concludes a system interrupt by sending an End of Interrupt (EOI) to the hardware
|
|
||||||
* controller and restoring the processor's previous run level.
|
|
||||||
*
|
|
||||||
* @param TrapFrame
|
|
||||||
* Supplies a pointer to the kernel trap frame containing the interrupted execution state.
|
|
||||||
*
|
|
||||||
* @param OldRunLevel
|
|
||||||
* Supplies the previous run level to restore.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
HL::Irq::EndSystemInterrupt(IN PKTRAP_FRAME TrapFrame,
|
|
||||||
IN KRUNLEVEL OldRunLevel)
|
|
||||||
{
|
|
||||||
/* Send EOI */
|
|
||||||
HL::Pic::SendEoi();
|
|
||||||
|
|
||||||
/* Restore previous run level */
|
|
||||||
KE::RunLevel::LowerRunLevel(OldRunLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles profiling interrupt.
|
|
||||||
*
|
|
||||||
* @param TrapFrame
|
|
||||||
* Supplies a kernel trap frame pushed by common interrupt handler.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
HL::Irq::HandleProfileInterrupt(IN PKTRAP_FRAME TrapFrame)
|
|
||||||
{
|
|
||||||
/* Send EOI */
|
|
||||||
HL::Pic::SendEoi();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles unexpected or unmapped system interrupts.
|
|
||||||
*
|
|
||||||
* @param TrapFrame
|
|
||||||
* Supplies a kernel trap frame pushed by common interrupt handler.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
HL::Irq::HandleUnexpectedInterrupt(IN PKTRAP_FRAME TrapFrame)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
|
|
||||||
/* Disable interrupts */
|
|
||||||
AR::CpuFunc::ClearInterruptFlag();
|
|
||||||
|
|
||||||
/* Print debug message and raise kernel panic */
|
|
||||||
DebugPrint(L"ERROR: Caught unexpected interrupt (0x%.2llX)!\n", TrapFrame->Vector);
|
|
||||||
KE::Crash::Panic(0x47, TrapFrame->Vector, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the registered interrupt handler for the specified IDT vector.
|
|
||||||
*
|
|
||||||
* @param Vector
|
|
||||||
* Supplies the interrupt vector number.
|
|
||||||
*
|
|
||||||
* @return This routine returns the pointer to the IDT interrupt handler routine.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PVOID
|
|
||||||
HL::Irq::QueryInterruptHandler(IN ULONG Vector)
|
|
||||||
{
|
|
||||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
|
||||||
PKIDTENTRY IdtEntry;
|
|
||||||
|
|
||||||
/* Get current processor block and IDT entry */
|
|
||||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
|
||||||
IdtEntry = &ProcessorBlock->IdtBase[Vector];
|
|
||||||
|
|
||||||
/* Return address of the interrupt handler */
|
|
||||||
return (PVOID)((ULONGLONG)IdtEntry->OffsetHigh << 32 |
|
|
||||||
(ULONGLONG)IdtEntry->OffsetMiddle << 16 |
|
|
||||||
(ULONGLONG)IdtEntry->OffsetLow);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the registered interrupt handler for the specified vector.
|
|
||||||
*
|
|
||||||
* @param Vector
|
|
||||||
* Supplies the interrupt vector number.
|
|
||||||
*
|
|
||||||
* @return This routine returns the pointer to the interrupt handler routine.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PVOID
|
|
||||||
HL::Irq::QuerySystemInterruptHandler(IN ULONG Vector)
|
|
||||||
{
|
|
||||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
|
||||||
|
|
||||||
/* Get current processor block */
|
|
||||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
|
||||||
|
|
||||||
return (PVOID)ProcessorBlock->InterruptDispatchTable[Vector];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers new interrupt handler for the existing IDT entry.
|
|
||||||
*
|
|
||||||
* @param HalVector
|
|
||||||
* Supplies the interrupt vector number.
|
|
||||||
*
|
|
||||||
* @param Handler
|
|
||||||
* Supplies the pointer to the interrupt handler routine.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
HL::Irq::RegisterInterruptHandler(IN ULONG Vector,
|
|
||||||
IN PVOID Handler)
|
|
||||||
{
|
|
||||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
|
||||||
|
|
||||||
/* Get current processor block */
|
|
||||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
|
||||||
|
|
||||||
/* Update interrupt handler */
|
|
||||||
AR::ProcSup::SetIdtGate(ProcessorBlock->IdtBase,
|
|
||||||
Vector,
|
|
||||||
Handler,
|
|
||||||
KGDT_R0_CODE,
|
|
||||||
0,
|
|
||||||
KIDT_ACCESS_RING0,
|
|
||||||
AMD64_INTERRUPT_GATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers the interrupt handler for the specified vector.
|
|
||||||
*
|
|
||||||
* @param HalVector
|
|
||||||
* Supplies the interrupt vector number.
|
|
||||||
*
|
|
||||||
* @param Handler
|
|
||||||
* Supplies the pointer to the interrupt handler routine.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
HL::Irq::RegisterSystemInterruptHandler(IN ULONG Vector,
|
|
||||||
IN PINTERRUPT_HANDLER Handler)
|
|
||||||
{
|
|
||||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
|
||||||
|
|
||||||
/* Get current processor block */
|
|
||||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
|
||||||
|
|
||||||
/* Update interrupt handler in the processor's interrupt dispatch table */
|
|
||||||
ProcessorBlock->InterruptDispatchTable[Vector] = Handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Requests a software interrupt by sending a Self-IPI mapped to the specified run level.
|
|
||||||
*
|
|
||||||
* @param RunLevel
|
|
||||||
* Supplies the target run level for the software interrupt.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTFASTCALL
|
|
||||||
VOID
|
|
||||||
HL::Irq::SendSoftwareInterrupt(IN KRUNLEVEL RunLevel)
|
|
||||||
{
|
|
||||||
/* Request a software interrupt */
|
|
||||||
HL::Pic::SendSelfIpi(HL::RunLevel::TransformRunLevelToSoftwareVector(RunLevel));
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/hl/amd64/rtc.cc
|
|
||||||
* DESCRIPTION: Hardware Real-Time Clock (RTC) support
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/* Include common RTC interface */
|
|
||||||
#include ARCH_COMMON(rtc.cc)
|
|
||||||
@@ -20,7 +20,6 @@ XTFASTCALL
|
|||||||
KRUNLEVEL
|
KRUNLEVEL
|
||||||
HL::RunLevel::GetRunLevel(VOID)
|
HL::RunLevel::GetRunLevel(VOID)
|
||||||
{
|
{
|
||||||
/* Read current run level */
|
|
||||||
return (KRUNLEVEL)AR::CpuFunc::ReadControlRegister(8);
|
return (KRUNLEVEL)AR::CpuFunc::ReadControlRegister(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +37,6 @@ XTFASTCALL
|
|||||||
VOID
|
VOID
|
||||||
HL::RunLevel::SetRunLevel(IN KRUNLEVEL RunLevel)
|
HL::RunLevel::SetRunLevel(IN KRUNLEVEL RunLevel)
|
||||||
{
|
{
|
||||||
/* Set new run level */
|
|
||||||
AR::CpuFunc::WriteControlRegister(8, RunLevel);
|
AR::CpuFunc::WriteControlRegister(8, RunLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +54,6 @@ XTFASTCALL
|
|||||||
KRUNLEVEL
|
KRUNLEVEL
|
||||||
HL::RunLevel::TransformApicTprToRunLevel(IN UCHAR Tpr)
|
HL::RunLevel::TransformApicTprToRunLevel(IN UCHAR Tpr)
|
||||||
{
|
{
|
||||||
/* Transform APIC TPR to run level */
|
|
||||||
return (KRUNLEVEL)(Tpr >> 4);
|
return (KRUNLEVEL)(Tpr >> 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,25 +71,5 @@ XTFASTCALL
|
|||||||
UCHAR
|
UCHAR
|
||||||
HL::RunLevel::TransformRunLevelToApicTpr(IN KRUNLEVEL RunLevel)
|
HL::RunLevel::TransformRunLevelToApicTpr(IN KRUNLEVEL RunLevel)
|
||||||
{
|
{
|
||||||
/* Transform run level to APIC TPR */
|
|
||||||
return (RunLevel << 4);
|
return (RunLevel << 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Transforms a given execution run level into a corresponding hardware interrupt vector
|
|
||||||
* suitable for software interrupts.
|
|
||||||
*
|
|
||||||
* @param RunLevel
|
|
||||||
* Supplies the run level to be translated into a software interrupt vector.
|
|
||||||
*
|
|
||||||
* @return This routine returns the 8-bit APIC vector corresponding to the requested software interrupt level.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTFASTCALL
|
|
||||||
UCHAR
|
|
||||||
HL::RunLevel::TransformRunLevelToSoftwareVector(IN KRUNLEVEL RunLevel)
|
|
||||||
{
|
|
||||||
/* Transform run level to APIC interrupt vector */
|
|
||||||
return TransformRunLevelToApicTpr(RunLevel) | 0xF;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/hl/amd64/timer.cc
|
|
||||||
* DESCRIPTION: Timer support for AMD64
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/* Include common Timer interface */
|
|
||||||
#include ARCH_COMMON(timer.cc)
|
|
||||||
@@ -9,104 +9,26 @@
|
|||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
/* Tracks the total number of currently cached ACPI tables */
|
/* ACPI tables cache list */
|
||||||
ULONG HL::Acpi::CacheCount = 0;
|
|
||||||
|
|
||||||
/* Array holding the cached ACPI tables */
|
|
||||||
ACPI_CACHE_LIST HL::Acpi::CacheEntries[ACPI_MAX_CACHED_TABLES];
|
|
||||||
|
|
||||||
/* Head of the linked list tracking dynamically mapped ACPI tables */
|
|
||||||
LIST_ENTRY HL::Acpi::CacheList;
|
LIST_ENTRY HL::Acpi::CacheList;
|
||||||
|
|
||||||
/* Pointer to the ACPI Root System Description Pointer (RSDP) */
|
/* ACPI Root System Description Pointer (RSDP) */
|
||||||
PACPI_RSDP HL::Acpi::RsdpStructure;
|
PACPI_RSDP HL::Acpi::RsdpStructure;
|
||||||
|
|
||||||
/* Global architectural system states and hardware feature flags parsed from the ACPI tables */
|
/* System information */
|
||||||
ACPI_SYSTEM_INFO HL::Acpi::SystemInfo;
|
ACPI_SYSTEM_INFO HL::Acpi::SystemInfo;
|
||||||
|
|
||||||
/* Hardware configuration details and port addresses for the ACPI Power Management Timer */
|
/* ACPI timer information */
|
||||||
ACPI_TIMER_INFO HL::Acpi::TimerInfo;
|
ACPI_TIMER_INFO HL::Acpi::TimerInfo;
|
||||||
|
|
||||||
/* Represents the number of active processors */
|
/* Active processors count */
|
||||||
KAFFINITY HL::Cpu::ActiveProcessors;
|
KAFFINITY HL::Cpu::ActiveProcessors;
|
||||||
|
|
||||||
/* Metadata detailing the linear frame buffer geometry */
|
/* FrameBuffer information */
|
||||||
HL_FRAMEBUFFER_DATA HL::FrameBuffer::FrameBufferData;
|
HL_FRAMEBUFFER_DATA HL::FrameBuffer::FrameBufferData;
|
||||||
|
|
||||||
/* Pointer to the RAM shadow buffer used for double-buffered rendering */
|
/* Scroll region information */
|
||||||
PVOID HL::FrameBuffer::ScreenShadowBuffer;
|
|
||||||
|
|
||||||
/* Tracks the bounding box, dimensions, and cursor position for the kernel video console */
|
|
||||||
HL_SCROLL_REGION_DATA HL::FrameBuffer::ScrollRegionData;
|
HL_SCROLL_REGION_DATA HL::FrameBuffer::ScrollRegionData;
|
||||||
|
|
||||||
/* Indicates the active hardware interrupt controller mode */
|
/* APIC mode */
|
||||||
APIC_MODE HL::Pic::ApicMode;
|
APIC_MODE HL::Pic::ApicMode;
|
||||||
|
|
||||||
/* Total number of I/O APIC chips discovered and initialized */
|
|
||||||
ULONG HL::Pic::ControllerCount;
|
|
||||||
|
|
||||||
/* Array containing MMIO bases, IDs, and line counts for all I/O APICs */
|
|
||||||
IOAPIC_DATA HL::Pic::Controllers[IOAPIC_MAX_CONTROLLERS];
|
|
||||||
|
|
||||||
/* Total number of legacy ISA interrupt routing overrides */
|
|
||||||
ULONG HL::Pic::IrqOverrideCount;
|
|
||||||
|
|
||||||
/* Hardware routing definitions mapping legacy ISA interrupts to Global System Interrupts (GSI) */
|
|
||||||
ACPI_MADT_INTERRUPT_OVERRIDE HL::Pic::IrqOverrides[IOAPIC_MAX_OVERRIDES];
|
|
||||||
|
|
||||||
/* Lookup table mapping allocated hardware APIC vectors to their assigned Run Levels */
|
|
||||||
UCHAR HL::Pic::MappedVectors[256];
|
|
||||||
|
|
||||||
/* Accumulated tick value of the ACPI Power Management Timer */
|
|
||||||
ULONG HL::Timer::AcpiPmPerformanceCounter = 0;
|
|
||||||
|
|
||||||
/* Primary hardware timer driving the periodic system clock interrupt */
|
|
||||||
TIMER_TYPE HL::Timer::ClockType;
|
|
||||||
|
|
||||||
/* Fractional remainder used to maintain long-term system clock accuracy */
|
|
||||||
ULONG HL::Timer::FractionalIncrement = 0;
|
|
||||||
|
|
||||||
/* Virtual address mapped to the HPET hardware MMIO registers */
|
|
||||||
PVOID HL::Timer::HpetAddress = NULLPTR;
|
|
||||||
|
|
||||||
/* Operating frequency of the High Precision Event Timer in ticks per second */
|
|
||||||
ULONGLONG HL::Timer::HpetFrequency = 0;
|
|
||||||
|
|
||||||
/* Spinlock protecting concurrent multiprocessor access to the global performance counters */
|
|
||||||
KSPIN_LOCK HL::Timer::PerformanceCounterLock;
|
|
||||||
|
|
||||||
/* The performance counter frequency in ticks per second */
|
|
||||||
ULONGLONG HL::Timer::PerformanceFrequency = 0;
|
|
||||||
|
|
||||||
/* Absolute monotonic tick count driven by the legacy Programmable Interval Timer */
|
|
||||||
ULONGLONG HL::Timer::PitPerformanceCounter;
|
|
||||||
|
|
||||||
/* Programmed hardware divider interval used to increment the PIT performance counter */
|
|
||||||
ULONG HL::Timer::PitRollover;
|
|
||||||
|
|
||||||
/* Flag indicating whether statistical system execution profiling is currently active */
|
|
||||||
BOOLEAN HL::Timer::ProfilingEnabled = FALSE;
|
|
||||||
|
|
||||||
/* Tick interval required to trigger a profile interrupt */
|
|
||||||
ULONG HL::Timer::ProfilingTicks;
|
|
||||||
|
|
||||||
/* Global accumulator for fractional time drift and precision compensation */
|
|
||||||
ULONG HL::Timer::RunningFraction = 0;
|
|
||||||
|
|
||||||
/* System counter driven by the highest precision available hardware */
|
|
||||||
ULONGLONG HL::Timer::SystemPerformanceCounter;
|
|
||||||
|
|
||||||
/* Current base clock increment in standard 100-nanosecond intervals */
|
|
||||||
ULONG HL::Timer::TimeIncrement = 0;
|
|
||||||
|
|
||||||
/* Timer capabilities */
|
|
||||||
TIMER_CAPABILITIES HL::Timer::TimerCapabilities = {0};
|
|
||||||
|
|
||||||
/* APIC timer frequency */
|
|
||||||
ULONG HL::Timer::TimerFrequency;
|
|
||||||
|
|
||||||
/* Function dispatch table for the active hardware timer backend */
|
|
||||||
TIMER_ROUTINES HL::Timer::TimerRoutines = {0};
|
|
||||||
|
|
||||||
/* Identifies the hardware timer backing */
|
|
||||||
TIMER_TYPE HL::Timer::TimerType;
|
|
||||||
|
|||||||
@@ -9,24 +9,6 @@
|
|||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the current value of the high-resolution performance counter.
|
|
||||||
*
|
|
||||||
* @param PerformanceFrequency
|
|
||||||
* Suplies an optional pointer to a variable that receives the performance counter frequency in Hz.
|
|
||||||
*
|
|
||||||
* @return This routine returns the current 64-bit monotonic tick count.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCLINK
|
|
||||||
XTAPI
|
|
||||||
LARGE_INTEGER
|
|
||||||
HlQueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceFrequency)
|
|
||||||
{
|
|
||||||
return HL::Timer::QueryPerformanceCounter(PerformanceFrequency);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the 8-bit data from the specified I/O port.
|
* Reads the 8-bit data from the specified I/O port.
|
||||||
*
|
*
|
||||||
@@ -135,24 +117,6 @@ HlReadRegister32(IN PVOID Register)
|
|||||||
return HL::IoRegister::ReadRegister32(Register);
|
return HL::IoRegister::ReadRegister32(Register);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Requests a dynamic adjustment of the system clock resolution.
|
|
||||||
*
|
|
||||||
* @param Rate
|
|
||||||
* The requested clock rate change in 100-nanosecond units.
|
|
||||||
*
|
|
||||||
* @return This routine returns the actual clock rate granted by the hardware.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCLINK
|
|
||||||
XTAPI
|
|
||||||
ULONG
|
|
||||||
HlSetClockRate(IN ULONG Rate)
|
|
||||||
{
|
|
||||||
return HL::Timer::SetClockRate(Rate);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the 8-bit data to the specified I/O port.
|
* Writes the 8-bit data to the specified I/O port.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -25,9 +25,10 @@ XTAPI
|
|||||||
VOID
|
VOID
|
||||||
HL::FrameBuffer::ClearScreen(IN ULONG Color)
|
HL::FrameBuffer::ClearScreen(IN ULONG Color)
|
||||||
{
|
{
|
||||||
ULONG BackgroundColor, PositionY;
|
ULONG PositionX, PositionY;
|
||||||
PCHAR CurrentLine, TargetBuffer;
|
ULONG BackgroundColor;
|
||||||
UCHAR FillByte;
|
PCHAR CurrentLine;
|
||||||
|
PULONG Pixel;
|
||||||
|
|
||||||
/* Make sure frame buffer is already initialized */
|
/* Make sure frame buffer is already initialized */
|
||||||
if(FrameBufferData.Initialized == FALSE)
|
if(FrameBufferData.Initialized == FALSE)
|
||||||
@@ -36,29 +37,20 @@ HL::FrameBuffer::ClearScreen(IN ULONG Color)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert background color */
|
/* Convert background color and get pointer to frame buffer */
|
||||||
BackgroundColor = GetRGBColor(Color);
|
BackgroundColor = GetRGBColor(Color);
|
||||||
|
CurrentLine = (PCHAR)FrameBufferData.Address;
|
||||||
/* Extract the lower byte for SetMemory */
|
|
||||||
FillByte = (UCHAR)(BackgroundColor & 0xFF);
|
|
||||||
|
|
||||||
/* Determine target buffer */
|
|
||||||
TargetBuffer = (ScreenShadowBuffer != NULLPTR) ? (PCHAR)ScreenShadowBuffer : (PCHAR)FrameBufferData.Address;
|
|
||||||
CurrentLine = TargetBuffer;
|
|
||||||
|
|
||||||
/* Fill the screen with the specified color */
|
/* Fill the screen with the specified color */
|
||||||
for(PositionY = 0; PositionY < FrameBufferData.Height; PositionY++, CurrentLine += FrameBufferData.Pitch)
|
for(PositionY = 0; PositionY < FrameBufferData.Height; PositionY++, CurrentLine += FrameBufferData.Pitch)
|
||||||
{
|
{
|
||||||
/* Fill the current scanline with the background color byte */
|
/* Fill the current line with the specified color */
|
||||||
RTL::Memory::SetMemory(CurrentLine, FillByte, FrameBufferData.Width * FrameBufferData.BytesPerPixel);
|
Pixel = (PULONG)CurrentLine;
|
||||||
}
|
for(PositionX = 0; PositionX < FrameBufferData.Width; PositionX++)
|
||||||
|
{
|
||||||
/* Check if Shadow Buffer is active */
|
/* Set the color of the pixel */
|
||||||
if(ScreenShadowBuffer != NULLPTR)
|
Pixel[PositionX] = BackgroundColor;
|
||||||
{
|
}
|
||||||
/* Flush changes to VRAM */
|
|
||||||
RTL::Memory::CopyMemory(FrameBufferData.Address, ScreenShadowBuffer,
|
|
||||||
FrameBufferData.Pitch * FrameBufferData.Height);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,9 +68,7 @@ XTCDECL
|
|||||||
XTSTATUS
|
XTSTATUS
|
||||||
HL::FrameBuffer::DisplayCharacter(IN WCHAR Character)
|
HL::FrameBuffer::DisplayCharacter(IN WCHAR Character)
|
||||||
{
|
{
|
||||||
ULONG CharacterX, CharacterY;
|
|
||||||
PSSFN_FONT_HEADER FbFont;
|
PSSFN_FONT_HEADER FbFont;
|
||||||
BOOLEAN VisibleCharacter;
|
|
||||||
|
|
||||||
/* Make sure frame buffer is already initialized */
|
/* Make sure frame buffer is already initialized */
|
||||||
if(FrameBufferData.Initialized == FALSE)
|
if(FrameBufferData.Initialized == FALSE)
|
||||||
@@ -90,9 +80,6 @@ HL::FrameBuffer::DisplayCharacter(IN WCHAR Character)
|
|||||||
/* Get font information */
|
/* Get font information */
|
||||||
FbFont = (PSSFN_FONT_HEADER)FrameBufferData.Font;
|
FbFont = (PSSFN_FONT_HEADER)FrameBufferData.Font;
|
||||||
|
|
||||||
/* Assume invisible character */
|
|
||||||
VisibleCharacter = FALSE;
|
|
||||||
|
|
||||||
/* Handle special characters */
|
/* Handle special characters */
|
||||||
switch(Character)
|
switch(Character)
|
||||||
{
|
{
|
||||||
@@ -104,20 +91,15 @@ HL::FrameBuffer::DisplayCharacter(IN WCHAR Character)
|
|||||||
case L'\t':
|
case L'\t':
|
||||||
/* Move cursor to the next tab stop */
|
/* Move cursor to the next tab stop */
|
||||||
ScrollRegionData.CursorX += (8 - (ScrollRegionData.CursorX - ScrollRegionData.Left) / FbFont->Width % 8) * FbFont->Width;
|
ScrollRegionData.CursorX += (8 - (ScrollRegionData.CursorX - ScrollRegionData.Left) / FbFont->Width % 8) * FbFont->Width;
|
||||||
if(ScrollRegionData.CursorX >= ScrollRegionData.Right)
|
if (ScrollRegionData.CursorX >= ScrollRegionData.Right)
|
||||||
{
|
{
|
||||||
ScrollRegionData.CursorX = ScrollRegionData.Left;
|
ScrollRegionData.CursorX = ScrollRegionData.Left;
|
||||||
ScrollRegionData.CursorY += FbFont->Height;
|
ScrollRegionData.CursorY += FbFont->Height;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Save cursor position */
|
/* Draw the character */
|
||||||
CharacterX = ScrollRegionData.CursorX;
|
DrawCharacter(ScrollRegionData.CursorX, ScrollRegionData.CursorY, ScrollRegionData.TextColor, Character);
|
||||||
CharacterY = ScrollRegionData.CursorY;
|
|
||||||
|
|
||||||
/* Draw the character to RAM and mark it as visible */
|
|
||||||
DrawCharacter(CharacterX, CharacterY, ScrollRegionData.TextColor, Character);
|
|
||||||
VisibleCharacter = TRUE;
|
|
||||||
|
|
||||||
/* Advance cursor */
|
/* Advance cursor */
|
||||||
ScrollRegionData.CursorX += FbFont->Width;
|
ScrollRegionData.CursorX += FbFont->Width;
|
||||||
@@ -125,7 +107,6 @@ HL::FrameBuffer::DisplayCharacter(IN WCHAR Character)
|
|||||||
/* Check if cursor reached end of line */
|
/* Check if cursor reached end of line */
|
||||||
if(ScrollRegionData.CursorX >= ScrollRegionData.Right)
|
if(ScrollRegionData.CursorX >= ScrollRegionData.Right)
|
||||||
{
|
{
|
||||||
/* Reset cursor to the left margin and advance to the next line */
|
|
||||||
ScrollRegionData.CursorX = ScrollRegionData.Left;
|
ScrollRegionData.CursorX = ScrollRegionData.Left;
|
||||||
ScrollRegionData.CursorY += FbFont->Height;
|
ScrollRegionData.CursorY += FbFont->Height;
|
||||||
}
|
}
|
||||||
@@ -139,13 +120,6 @@ HL::FrameBuffer::DisplayCharacter(IN WCHAR Character)
|
|||||||
ScrollRegion();
|
ScrollRegion();
|
||||||
ScrollRegionData.CursorY = ScrollRegionData.Bottom - FbFont->Height;
|
ScrollRegionData.CursorY = ScrollRegionData.Bottom - FbFont->Height;
|
||||||
}
|
}
|
||||||
else if(VisibleCharacter == TRUE)
|
|
||||||
{
|
|
||||||
/* Flush visible character to VRAM */
|
|
||||||
UpdateScreenRegion(CharacterX, CharacterY,
|
|
||||||
CharacterX + FbFont->Width,
|
|
||||||
CharacterY + FbFont->Height);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return success */
|
/* Return success */
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
@@ -179,8 +153,9 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
|
|||||||
{
|
{
|
||||||
UINT CurrentFragment, Glyph, GlyphLimit, Index, Line, Mapping;
|
UINT CurrentFragment, Glyph, GlyphLimit, Index, Line, Mapping;
|
||||||
PUCHAR Character, CharacterMapping, Fragment;
|
PUCHAR Character, CharacterMapping, Fragment;
|
||||||
ULONG FontColor, GlyphOffset, PixelOffset;
|
UINT_PTR GlyphPixel, Pixel;
|
||||||
PSSFN_FONT_HEADER FbFont;
|
PSSFN_FONT_HEADER FbFont;
|
||||||
|
ULONG FontColor;
|
||||||
|
|
||||||
/* Make sure frame buffer is already initialized */
|
/* Make sure frame buffer is already initialized */
|
||||||
if(FrameBufferData.Initialized == FALSE)
|
if(FrameBufferData.Initialized == FALSE)
|
||||||
@@ -217,7 +192,7 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* There is a glyph for this character, check if it matches */
|
/* There's a glyph for this character, check if it matches */
|
||||||
if(Index == WideCharacter)
|
if(Index == WideCharacter)
|
||||||
{
|
{
|
||||||
/* Found the character, break loop */
|
/* Found the character, break loop */
|
||||||
@@ -238,7 +213,8 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Find the glyph position on the frame buffer and set font color */
|
/* Find the glyph position on the frame buffer and set font color */
|
||||||
GlyphOffset = (PositionY * FrameBufferData.Pitch) + (PositionX * FrameBufferData.BytesPerPixel);
|
GlyphPixel = (UINT_PTR)FrameBufferData.Address + PositionY * FrameBufferData.Pitch +
|
||||||
|
PositionX * FrameBufferData.BytesPerPixel;
|
||||||
FontColor = GetRGBColor(Color);
|
FontColor = GetRGBColor(Color);
|
||||||
|
|
||||||
/* Check all kerning fragments */
|
/* Check all kerning fragments */
|
||||||
@@ -267,7 +243,7 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get initial glyph line */
|
/* Get initial glyph line */
|
||||||
GlyphOffset += (CharacterMapping[1] - Mapping) * FrameBufferData.Pitch;
|
GlyphPixel += (CharacterMapping[1] - Mapping) * FrameBufferData.Pitch;
|
||||||
Mapping = CharacterMapping[1];
|
Mapping = CharacterMapping[1];
|
||||||
|
|
||||||
/* Extract glyph data from fragments table and advance */
|
/* Extract glyph data from fragments table and advance */
|
||||||
@@ -279,8 +255,7 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
|
|||||||
CurrentFragment = 1;
|
CurrentFragment = 1;
|
||||||
while(GlyphLimit--)
|
while(GlyphLimit--)
|
||||||
{
|
{
|
||||||
/* Set the initial pixel offset for the current glyph fragment */
|
Pixel = GlyphPixel;
|
||||||
PixelOffset = GlyphOffset;
|
|
||||||
for(Line = 0; Line < Glyph; Line++)
|
for(Line = 0; Line < Glyph; Line++)
|
||||||
{
|
{
|
||||||
/* Decode compressed offsets */
|
/* Decode compressed offsets */
|
||||||
@@ -294,26 +269,17 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
|
|||||||
/* Check if pixel should be drawn */
|
/* Check if pixel should be drawn */
|
||||||
if(*Fragment & CurrentFragment)
|
if(*Fragment & CurrentFragment)
|
||||||
{
|
{
|
||||||
/* Route the pixel draw operation to the active buffer */
|
/* Draw glyph pixel */
|
||||||
if(ScreenShadowBuffer != NULLPTR)
|
*((PULONG)Pixel) = FontColor;
|
||||||
{
|
|
||||||
/* Draw glyph pixel to Shadow Buffer */
|
|
||||||
*((PULONG)((PCHAR)ScreenShadowBuffer + PixelOffset)) = FontColor;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Draw glyph pixel directly to VRAM */
|
|
||||||
*((PULONG)((PCHAR)FrameBufferData.Address + PixelOffset)) = FontColor;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Advance pixel pointer */
|
/* Advance pixel pointer */
|
||||||
PixelOffset += FrameBufferData.BytesPerPixel;
|
Pixel += FrameBufferData.BytesPerPixel;
|
||||||
CurrentFragment <<= 1;
|
CurrentFragment <<= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Advance to next line and increase mapping */
|
/* Advance to next line and increase mapping */
|
||||||
GlyphOffset += FrameBufferData.Pitch;
|
GlyphPixel += FrameBufferData.Pitch;
|
||||||
Mapping++;
|
Mapping++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,7 +310,7 @@ HL::FrameBuffer::DrawPixel(IN ULONG PositionX,
|
|||||||
IN ULONG PositionY,
|
IN ULONG PositionY,
|
||||||
IN ULONG Color)
|
IN ULONG Color)
|
||||||
{
|
{
|
||||||
ULONG Offset;
|
PCHAR PixelAddress;
|
||||||
|
|
||||||
/* Make sure frame buffer is already initialized */
|
/* Make sure frame buffer is already initialized */
|
||||||
if(FrameBufferData.Initialized == FALSE)
|
if(FrameBufferData.Initialized == FALSE)
|
||||||
@@ -361,67 +327,11 @@ HL::FrameBuffer::DrawPixel(IN ULONG PositionX,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the address of the pixel in the frame buffer memory */
|
/* Calculate the address of the pixel in the frame buffer memory */
|
||||||
Offset = (PositionY * FrameBufferData.Pitch) + (PositionX * FrameBufferData.BytesPerPixel);
|
PixelAddress = (PCHAR)FrameBufferData.Address + (PositionY * FrameBufferData.Pitch) +
|
||||||
|
(PositionX * FrameBufferData.BytesPerPixel);
|
||||||
|
|
||||||
/* Route the pixel draw operation to the active buffer */
|
/* Set the color of the pixel by writing to the corresponding memory location */
|
||||||
if(ScreenShadowBuffer != NULLPTR)
|
*((PULONG)PixelAddress) = GetRGBColor(Color);
|
||||||
{
|
|
||||||
/* Set the color of the pixel by writing to the corresponding memory location (RAM) */
|
|
||||||
*((PULONG)((PCHAR)ScreenShadowBuffer + Offset)) = GetRGBColor(Color);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Set the color of the pixel by writing to the corresponding memory location (VRAM) */
|
|
||||||
*((PULONG)((PCHAR)FrameBufferData.Address + Offset)) = GetRGBColor(Color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enables the Shadow Buffer (Double Buffering) for high-performance rendering.
|
|
||||||
*
|
|
||||||
* @return This routine returns a status code.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
XTSTATUS
|
|
||||||
HL::FrameBuffer::EnableShadowBuffer(VOID)
|
|
||||||
{
|
|
||||||
ULONG FrameBufferSize;
|
|
||||||
XTSTATUS Status;
|
|
||||||
|
|
||||||
/* Check if the shadow buffer is already enabled */
|
|
||||||
if(ScreenShadowBuffer != NULLPTR)
|
|
||||||
{
|
|
||||||
/* Nothing to do, return success */
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make sure frame buffer is already initialized */
|
|
||||||
if(FrameBufferData.Initialized == FALSE)
|
|
||||||
{
|
|
||||||
/* Unable to operate on non-initialized frame buffer */
|
|
||||||
return STATUS_DEVICE_NOT_READY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calculate the total size of the framebuffer */
|
|
||||||
FrameBufferSize = FrameBufferData.Pitch * FrameBufferData.Height;
|
|
||||||
|
|
||||||
/* Allocate non-paged memory for the shadow buffer */
|
|
||||||
Status = MM::Allocator::AllocatePool(NonPagedPool, FrameBufferSize,
|
|
||||||
&ScreenShadowBuffer, SIGNATURE32('F', 'B', 'U', 'F'));
|
|
||||||
if(Status != STATUS_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Allocation failed, return status code */
|
|
||||||
ScreenShadowBuffer = NULLPTR;
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Synchronize the newly allocated shadow buffer with the current on-screen contents */
|
|
||||||
RTL::Memory::CopyMemory(ScreenShadowBuffer, FrameBufferData.Address, FrameBufferSize);
|
|
||||||
|
|
||||||
/* Return success */
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -634,9 +544,10 @@ XTAPI
|
|||||||
VOID
|
VOID
|
||||||
HL::FrameBuffer::ScrollRegion(VOID)
|
HL::FrameBuffer::ScrollRegion(VOID)
|
||||||
{
|
{
|
||||||
PCHAR TargetBuffer, Destination, Source;
|
PCHAR Destination, Source;
|
||||||
ULONG Line, PositionX, LineBytes;
|
|
||||||
PSSFN_FONT_HEADER FbFont;
|
PSSFN_FONT_HEADER FbFont;
|
||||||
|
ULONG Line, PositionX;
|
||||||
|
ULONG LineBytes;
|
||||||
PULONG Pixel;
|
PULONG Pixel;
|
||||||
|
|
||||||
/* Make sure frame buffer is already initialized */
|
/* Make sure frame buffer is already initialized */
|
||||||
@@ -646,132 +557,37 @@ HL::FrameBuffer::ScrollRegion(VOID)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Retrieve font metrics and calculate line properties for the scroll operation */
|
/* Get font information */
|
||||||
FbFont = (PSSFN_FONT_HEADER)FrameBufferData.Font;
|
FbFont = (PSSFN_FONT_HEADER)FrameBufferData.Font;
|
||||||
|
|
||||||
|
/* Calculate bytes per line in the scroll region */
|
||||||
LineBytes = (ScrollRegionData.Right - ScrollRegionData.Left) * FrameBufferData.BytesPerPixel;
|
LineBytes = (ScrollRegionData.Right - ScrollRegionData.Left) * FrameBufferData.BytesPerPixel;
|
||||||
TargetBuffer = (ScreenShadowBuffer != NULLPTR) ? (PCHAR)ScreenShadowBuffer : (PCHAR)FrameBufferData.Address;
|
|
||||||
|
|
||||||
/* Process every line in the scroll region */
|
/* Scroll up each scan line in the scroll region */
|
||||||
for(Line = ScrollRegionData.Top; Line < ScrollRegionData.Bottom; Line++)
|
for(Line = ScrollRegionData.Top; Line < ScrollRegionData.Bottom - FbFont->Height; Line++)
|
||||||
{
|
{
|
||||||
/* Calculate destination address for the current line */
|
Destination = (PCHAR)FrameBufferData.Address + Line * FrameBufferData.Pitch +
|
||||||
Destination = TargetBuffer + (Line * FrameBufferData.Pitch) +
|
ScrollRegionData.Left * FrameBufferData.BytesPerPixel;
|
||||||
(ScrollRegionData.Left * FrameBufferData.BytesPerPixel);
|
|
||||||
|
|
||||||
/* Check if the current line needs to be copied from below or cleared */
|
/* The source is one full text line (FbFont->Height) below the destination */
|
||||||
if(Line < ScrollRegionData.Bottom - FbFont->Height)
|
Source = (PCHAR)FrameBufferData.Address + (Line + FbFont->Height) * FrameBufferData.Pitch +
|
||||||
|
ScrollRegionData.Left * FrameBufferData.BytesPerPixel;
|
||||||
|
|
||||||
|
/* Move each scan line in the scroll region up */
|
||||||
|
RTL::Memory::MoveMemory(Destination, Source, LineBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear the last text line */
|
||||||
|
for(Line = ScrollRegionData.Bottom - FbFont->Height; Line < ScrollRegionData.Bottom; Line++)
|
||||||
|
{
|
||||||
|
/* Get pointer to the start of the scan line to clear */
|
||||||
|
Pixel = (PULONG)((PCHAR)FrameBufferData.Address + Line * FrameBufferData.Pitch +
|
||||||
|
ScrollRegionData.Left * FrameBufferData.BytesPerPixel);
|
||||||
|
|
||||||
|
/* Clear each pixel in the scan line with the background color */
|
||||||
|
for(PositionX = 0; PositionX < (ScrollRegionData.Right - ScrollRegionData.Left); PositionX++)
|
||||||
{
|
{
|
||||||
/* Copy the line from below */
|
Pixel[PositionX] = ScrollRegionData.BackgroundColor;
|
||||||
Source = Destination + (FbFont->Height * FrameBufferData.Pitch);
|
|
||||||
RTL::Memory::CopyMemory(Destination, Source, LineBytes);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Fill the bottom line(s) with the background color */
|
|
||||||
Pixel = (PULONG)Destination;
|
|
||||||
for(PositionX = 0; PositionX < (ScrollRegionData.Right - ScrollRegionData.Left); PositionX++)
|
|
||||||
{
|
|
||||||
/* Overwrite the pixel with the background color */
|
|
||||||
Pixel[PositionX] = ScrollRegionData.BackgroundColor;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flush changes to VRAM if Shadow Buffer was used */
|
|
||||||
if(ScreenShadowBuffer != NULLPTR)
|
|
||||||
{
|
|
||||||
/* Flush the updated scroll region to VRAM */
|
|
||||||
UpdateScreenRegion(ScrollRegionData.Left,
|
|
||||||
ScrollRegionData.Top,
|
|
||||||
ScrollRegionData.Right,
|
|
||||||
ScrollRegionData.Bottom);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flushes the current content of the Shadow Buffer to the visible FrameBuffer (VRAM).
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
HL::FrameBuffer::UpdateScreen(VOID)
|
|
||||||
{
|
|
||||||
/* Make sure framebuffer is already initialized and shadow buffer is ready */
|
|
||||||
if(FrameBufferData.Initialized == FALSE || ScreenShadowBuffer == NULLPTR)
|
|
||||||
{
|
|
||||||
/* Unable to operate on non-initialized frame buffer */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Flush RAM to VRAM */
|
|
||||||
RTL::Memory::CopyMemory(FrameBufferData.Address,
|
|
||||||
ScreenShadowBuffer,
|
|
||||||
FrameBufferData.Pitch * FrameBufferData.Height);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flushes a specific rectangular region from the Shadow Buffer to the visible FrameBuffer (VRAM).
|
|
||||||
*
|
|
||||||
* @param Left
|
|
||||||
* Supplies the left pixel coordinate of the region to update.
|
|
||||||
*
|
|
||||||
* @param Top
|
|
||||||
* Supplies the top pixel coordinate of the region to update.
|
|
||||||
*
|
|
||||||
* @param Right
|
|
||||||
* Supplies the right pixel coordinate of the region to update.
|
|
||||||
*
|
|
||||||
* @param Bottom
|
|
||||||
* Supplies the bottom pixel coordinate of the region to update.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
HL::FrameBuffer::UpdateScreenRegion(IN ULONG Left,
|
|
||||||
IN ULONG Top,
|
|
||||||
IN ULONG Right,
|
|
||||||
IN ULONG Bottom)
|
|
||||||
{
|
|
||||||
ULONG Line, LineBytes;
|
|
||||||
PCHAR Source, Destination;
|
|
||||||
|
|
||||||
/* Make sure framebuffer is already initialized and shadow buffer is ready */
|
|
||||||
if(FrameBufferData.Initialized == FALSE || ScreenShadowBuffer == NULLPTR)
|
|
||||||
{
|
|
||||||
/* Unable to operate on non-initialized frame buffer */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make sure parameters are valid to prevent memory corruption */
|
|
||||||
if(Left >= Right || Top >= Bottom || Right > FrameBufferData.Width || Bottom > FrameBufferData.Height)
|
|
||||||
{
|
|
||||||
/* Invalid region coordinates provided */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calculate the width of the region */
|
|
||||||
LineBytes = (Right - Left) * FrameBufferData.BytesPerPixel;
|
|
||||||
|
|
||||||
/* Copy the specified region line by line */
|
|
||||||
for(Line = Top; Line < Bottom; Line++)
|
|
||||||
{
|
|
||||||
/* Calculate the source address in the shadow buffer */
|
|
||||||
Source = (PCHAR)ScreenShadowBuffer +
|
|
||||||
(Line * FrameBufferData.Pitch) +
|
|
||||||
(Left * FrameBufferData.BytesPerPixel);
|
|
||||||
|
|
||||||
/* Calculate the destination address in the VRAM */
|
|
||||||
Destination = (PCHAR)FrameBufferData.Address +
|
|
||||||
(Line * FrameBufferData.Pitch) +
|
|
||||||
(Left * FrameBufferData.BytesPerPixel);
|
|
||||||
|
|
||||||
/* Flush RAM to VRAM */
|
|
||||||
RTL::Memory::CopyMemory(Destination, Source, LineBytes);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/hl/i686/firmware.cc
|
|
||||||
* DESCRIPTION: UEFI/BIOS Firmware support
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/* Include common Firmware interface */
|
|
||||||
#include ARCH_COMMON(firmware.cc)
|
|
||||||
@@ -1,259 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/hl/i686/irq.cc
|
|
||||||
* DESCRIPTION: Interrupts support for i686 architecture
|
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
|
||||||
* Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Begins a system interrupt handler by raising the processor's run level and re-enabling
|
|
||||||
* hardware interrupts to allow preemption by higher-priority events.
|
|
||||||
*
|
|
||||||
* @param RunLevel
|
|
||||||
* Supplies the target run level to raise the processor to.
|
|
||||||
*
|
|
||||||
* @param OldRunLevel
|
|
||||||
* Receives the previous run level before the elevation.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
HL::Irq::BeginSystemInterrupt(IN KRUNLEVEL RunLevel,
|
|
||||||
OUT PKRUNLEVEL OldRunLevel)
|
|
||||||
{
|
|
||||||
/* Get the current IRQL */
|
|
||||||
*OldRunLevel = KE::RunLevel::GetCurrentRunLevel();
|
|
||||||
|
|
||||||
/* Raise run level */
|
|
||||||
KE::RunLevel::RaiseRunLevel(RunLevel);
|
|
||||||
|
|
||||||
/* Enable interrupts */
|
|
||||||
AR::CpuFunc::SetInterruptFlag();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Safely concludes an interrupt handler by disabling hardware interrupts.
|
|
||||||
*
|
|
||||||
* @param TrapFrame
|
|
||||||
* Supplies a pointer to the kernel trap frame containing the interrupted execution state.
|
|
||||||
*
|
|
||||||
* @param OldRunLevel
|
|
||||||
* Supplies the previous run level to restore.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
HL::Irq::EndInterrupt(IN PKTRAP_FRAME TrapFrame,
|
|
||||||
IN KRUNLEVEL OldRunLevel)
|
|
||||||
{
|
|
||||||
/* Disable interrupts */
|
|
||||||
AR::CpuFunc::ClearInterruptFlag();
|
|
||||||
|
|
||||||
/* End system interrupt */
|
|
||||||
EndSystemInterrupt(TrapFrame, OldRunLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Concludes a system interrupt by sending an End of Interrupt (EOI) to the hardware
|
|
||||||
* controller and restoring the processor's previous run level.
|
|
||||||
*
|
|
||||||
* @param TrapFrame
|
|
||||||
* Supplies a pointer to the kernel trap frame containing the interrupted execution state.
|
|
||||||
*
|
|
||||||
* @param OldRunLevel
|
|
||||||
* Supplies the previous run level to restore.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
HL::Irq::EndSystemInterrupt(IN PKTRAP_FRAME TrapFrame,
|
|
||||||
IN KRUNLEVEL OldRunLevel)
|
|
||||||
{
|
|
||||||
/* Send EOI */
|
|
||||||
HL::Pic::SendEoi();
|
|
||||||
|
|
||||||
/* Restore previous run level */
|
|
||||||
KE::RunLevel::LowerRunLevel(OldRunLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles profiling interrupt.
|
|
||||||
*
|
|
||||||
* @param TrapFrame
|
|
||||||
* Supplies a kernel trap frame pushed by common interrupt handler.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
HL::Irq::HandleProfileInterrupt(IN PKTRAP_FRAME TrapFrame)
|
|
||||||
{
|
|
||||||
/* Send EOI */
|
|
||||||
HL::Pic::SendEoi();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles unexpected or unmapped system interrupts.
|
|
||||||
*
|
|
||||||
* @param TrapFrame
|
|
||||||
* Supplies a kernel trap frame pushed by common interrupt handler.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
HL::Irq::HandleUnexpectedInterrupt(IN PKTRAP_FRAME TrapFrame)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
|
|
||||||
/* Disable interrupts */
|
|
||||||
AR::CpuFunc::ClearInterruptFlag();
|
|
||||||
|
|
||||||
/* Print debug message and raise kernel panic */
|
|
||||||
DebugPrint(L"ERROR: Caught unexpected interrupt (0x%.2lX)!\n", TrapFrame->Vector);
|
|
||||||
KE::Crash::Panic(0x47, TrapFrame->Vector, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the registered interrupt handler for the specified IDT vector.
|
|
||||||
*
|
|
||||||
* @param Vector
|
|
||||||
* Supplies the interrupt vector number.
|
|
||||||
*
|
|
||||||
* @return This routine returns the pointer to the IDT interrupt handler routine.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PVOID
|
|
||||||
HL::Irq::QueryInterruptHandler(IN ULONG Vector)
|
|
||||||
{
|
|
||||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
|
||||||
PKIDTENTRY IdtEntry;
|
|
||||||
|
|
||||||
/* Get current processor block and IDT entry */
|
|
||||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
|
||||||
IdtEntry = &ProcessorBlock->IdtBase[Vector];
|
|
||||||
|
|
||||||
/* Return address of the interrupt handler */
|
|
||||||
return (PVOID)(((IdtEntry->ExtendedOffset << 16) & 0xFFFF0000) | (IdtEntry->Offset & 0xFFFF));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the registered interrupt handler for the specified vector.
|
|
||||||
*
|
|
||||||
* @param Vector
|
|
||||||
* Supplies the interrupt vector number.
|
|
||||||
*
|
|
||||||
* @return This routine returns the pointer to the interrupt handler routine.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
PVOID
|
|
||||||
HL::Irq::QuerySystemInterruptHandler(IN ULONG Vector)
|
|
||||||
{
|
|
||||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
|
||||||
|
|
||||||
/* Get current processor block */
|
|
||||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
|
||||||
|
|
||||||
return (PVOID)ProcessorBlock->InterruptDispatchTable[Vector];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers new interrupt handler for the existing IDT entry.
|
|
||||||
*
|
|
||||||
* @param HalVector
|
|
||||||
* Supplies the interrupt vector number.
|
|
||||||
*
|
|
||||||
* @param Handler
|
|
||||||
* Supplies the pointer to the interrupt handler routine.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
HL::Irq::RegisterInterruptHandler(IN ULONG Vector,
|
|
||||||
IN PVOID Handler)
|
|
||||||
{
|
|
||||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
|
||||||
|
|
||||||
/* Get current processor block */
|
|
||||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
|
||||||
|
|
||||||
/* Update interrupt handler */
|
|
||||||
AR::ProcSup::SetIdtGate(ProcessorBlock->IdtBase,
|
|
||||||
Vector,
|
|
||||||
Handler,
|
|
||||||
KGDT_R0_CODE,
|
|
||||||
0,
|
|
||||||
KIDT_ACCESS_RING0,
|
|
||||||
I686_INTERRUPT_GATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers the interrupt handler for the specified vector.
|
|
||||||
*
|
|
||||||
* @param HalVector
|
|
||||||
* Supplies the interrupt vector number.
|
|
||||||
*
|
|
||||||
* @param Handler
|
|
||||||
* Supplies the pointer to the interrupt handler routine.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
HL::Irq::RegisterSystemInterruptHandler(IN ULONG Vector,
|
|
||||||
IN PINTERRUPT_HANDLER Handler)
|
|
||||||
{
|
|
||||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
|
||||||
|
|
||||||
/* Get current processor block */
|
|
||||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
|
||||||
|
|
||||||
/* Update interrupt handler in the processor's interrupt dispatch table */
|
|
||||||
ProcessorBlock->InterruptDispatchTable[Vector] = Handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Requests a software interrupt by sending a Self-IPI mapped to the specified run level.
|
|
||||||
*
|
|
||||||
* @param RunLevel
|
|
||||||
* Supplies the target run level for the software interrupt.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTFASTCALL
|
|
||||||
VOID
|
|
||||||
HL::Irq::SendSoftwareInterrupt(IN KRUNLEVEL RunLevel)
|
|
||||||
{
|
|
||||||
/* Request a software interrupt */
|
|
||||||
HL::Pic::SendSelfIpi(HL::RunLevel::TransformRunLevelToSoftwareVector(RunLevel));
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/hl/i686/rtc.cc
|
|
||||||
* DESCRIPTION: Hardware Real-Time Clock (RTC) support
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/* Include common RTC interface */
|
|
||||||
#include ARCH_COMMON(rtc.cc)
|
|
||||||
@@ -20,7 +20,6 @@ XTFASTCALL
|
|||||||
KRUNLEVEL
|
KRUNLEVEL
|
||||||
HL::RunLevel::GetRunLevel(VOID)
|
HL::RunLevel::GetRunLevel(VOID)
|
||||||
{
|
{
|
||||||
/* Read current run level */
|
|
||||||
return TransformApicTprToRunLevel(HL::Pic::ReadApicRegister(APIC_TPR));
|
return TransformApicTprToRunLevel(HL::Pic::ReadApicRegister(APIC_TPR));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +37,6 @@ XTFASTCALL
|
|||||||
VOID
|
VOID
|
||||||
HL::RunLevel::SetRunLevel(IN KRUNLEVEL RunLevel)
|
HL::RunLevel::SetRunLevel(IN KRUNLEVEL RunLevel)
|
||||||
{
|
{
|
||||||
/* Set new run level */
|
|
||||||
HL::Pic::WriteApicRegister(APIC_TPR, TransformRunLevelToApicTpr(RunLevel));
|
HL::Pic::WriteApicRegister(APIC_TPR, TransformRunLevelToApicTpr(RunLevel));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,23 +131,3 @@ HL::RunLevel::TransformRunLevelToApicTpr(IN KRUNLEVEL RunLevel)
|
|||||||
/* Return the TPR corresponding to the run level from the transformation table. */
|
/* Return the TPR corresponding to the run level from the transformation table. */
|
||||||
return TransformationTable[RunLevel];
|
return TransformationTable[RunLevel];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Transforms a given execution run level into a corresponding hardware interrupt vector
|
|
||||||
* suitable for software interrupts.
|
|
||||||
*
|
|
||||||
* @param RunLevel
|
|
||||||
* Supplies the run level to be translated into a software interrupt vector.
|
|
||||||
*
|
|
||||||
* @return This routine returns the 8-bit APIC vector corresponding to the requested software interrupt level.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
XTFASTCALL
|
|
||||||
UCHAR
|
|
||||||
HL::RunLevel::TransformRunLevelToSoftwareVector(IN KRUNLEVEL RunLevel)
|
|
||||||
{
|
|
||||||
/* Transform run level to APIC interrupt vector */
|
|
||||||
return TransformRunLevelToApicTpr(RunLevel);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/hl/i686/timer.cc
|
|
||||||
* DESCRIPTION: Timer support for i686
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/* Include common Timer interface */
|
|
||||||
#include ARCH_COMMON(timer.cc)
|
|
||||||
@@ -23,25 +23,19 @@ HL::Init::InitializeSystem(VOID)
|
|||||||
XTSTATUS Status;
|
XTSTATUS Status;
|
||||||
|
|
||||||
/* Initialize ACPI */
|
/* Initialize ACPI */
|
||||||
Status = HL::Acpi::InitializeAcpi();
|
Status = Acpi::InitializeAcpi();
|
||||||
if(Status != STATUS_SUCCESS)
|
if(Status != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get system information from ACPI */
|
/* Get system information from ACPI */
|
||||||
Status = HL::Acpi::InitializeAcpiSystemInformation();
|
Status = Acpi::InitializeAcpiSystemInformation();
|
||||||
if(Status != STATUS_SUCCESS)
|
if(Status != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize I/O APIC */
|
|
||||||
HL::Pic::InitializeIOApic();
|
|
||||||
|
|
||||||
/* Initialize timer */
|
|
||||||
HL::Timer::InitializeTimer();
|
|
||||||
|
|
||||||
/* Return success */
|
/* Return success */
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,180 +40,8 @@ HL::Cpu::InitializeProcessor(VOID)
|
|||||||
ActiveProcessors |= Affinity;
|
ActiveProcessors |= Affinity;
|
||||||
|
|
||||||
/* Initialize APIC for this processor */
|
/* Initialize APIC for this processor */
|
||||||
HL::Pic::InitializePic();
|
Pic::InitializePic();
|
||||||
|
|
||||||
/* Set the APIC running level */
|
/* Set the APIC running level */
|
||||||
HL::RunLevel::SetRunLevel(KE::Processor::GetCurrentProcessorBlock()->RunLevel);
|
HL::RunLevel::SetRunLevel(KE::Processor::GetCurrentProcessorBlock()->RunLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Wakes up and initializes all Application Processors (APs) and transitions them into the active kernel.
|
|
||||||
*
|
|
||||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
XTSTATUS
|
|
||||||
HL::Cpu::StartAllProcessors(VOID)
|
|
||||||
{
|
|
||||||
ULONG CpuNumber, Index, MaxCpus, SipiVector, Timeout, TrampolinePages;
|
|
||||||
PVOID CpuStructures, TrampolineAddress, TrampolineCode;
|
|
||||||
ULONG_PTR AllocationSize, TrampolineCodeSize;
|
|
||||||
PPROCESSOR_START_BLOCK StartBlock;
|
|
||||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
|
||||||
PACPI_SYSTEM_INFO SysInfo;
|
|
||||||
WCHAR ParameterValue[16];
|
|
||||||
XTSTATUS Status;
|
|
||||||
|
|
||||||
/* Determine the maximum number of CPUs to start */
|
|
||||||
HL::Acpi::GetSystemInformation(&SysInfo);
|
|
||||||
MaxCpus = SysInfo->CpuCount;
|
|
||||||
|
|
||||||
/* Check if user forced a specific CPU limit */
|
|
||||||
if(KE::BootInformation::GetKernelParameterValue(L"MAXCPUS", ParameterValue, 16) == STATUS_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Convert string value to number */
|
|
||||||
Status = RTL::WideString::WideStringToNumber(ParameterValue, 0, &MaxCpus);
|
|
||||||
if(Status == STATUS_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Ensure safe boundaries */
|
|
||||||
if(MaxCpus == 0)
|
|
||||||
{
|
|
||||||
/* Fallback to 1 CPU (BSP) */
|
|
||||||
MaxCpus = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Failed to parse value, fallback to ACPI value */
|
|
||||||
MaxCpus = SysInfo->CpuCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if single core CPU or set a CPU limit */
|
|
||||||
if(MaxCpus == 1 || SysInfo->CpuCount == 1)
|
|
||||||
{
|
|
||||||
/* Single core CPU, return success */
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get trampoline information */
|
|
||||||
AR::ProcSup::GetTrampolineInformation(TrampolineApStartup, &TrampolineCode, &TrampolineCodeSize);
|
|
||||||
|
|
||||||
/* Verify trampoline information */
|
|
||||||
if(TrampolineCode == NULLPTR || TrampolineCodeSize == 0)
|
|
||||||
{
|
|
||||||
/* Failed to get trampoline information, return error */
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compute trampoline memory allocation size (trampoline + processor start block + temporary stack) */
|
|
||||||
AllocationSize = TrampolineCodeSize + sizeof(PROCESSOR_START_BLOCK) + 512;
|
|
||||||
TrampolinePages = (ULONG)(ROUND_UP(AllocationSize, MM_PAGE_SIZE) / MM_PAGE_SIZE);
|
|
||||||
|
|
||||||
/* Allocate real mode memory for AP trampoline */
|
|
||||||
Status = MM::HardwarePool::AllocateRealModeMemory(TrampolinePages, &TrampolineAddress);
|
|
||||||
if(Status != STATUS_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to allocate memory, print error message and return error */
|
|
||||||
DebugPrint(L"Failed to allocate %lu pages for AP Trampoline!\n", TrampolinePages);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy trampoline code to low memory */
|
|
||||||
RTL::Memory::CopyMemory(TrampolineAddress, TrampolineCode, TrampolineCodeSize);
|
|
||||||
|
|
||||||
/* Get start block address relative to trampoline address */
|
|
||||||
StartBlock = (PPROCESSOR_START_BLOCK)((PUCHAR)TrampolineAddress + TrampolineCodeSize);
|
|
||||||
|
|
||||||
/* Get SIPI vector */
|
|
||||||
SipiVector = (ULONG)((ULONG_PTR)TrampolineAddress >> 12);
|
|
||||||
|
|
||||||
/* Loop over all CPUs */
|
|
||||||
CpuNumber = 0;
|
|
||||||
for(Index = 0; Index < SysInfo->CpuCount; Index++)
|
|
||||||
{
|
|
||||||
/* Check if destination CPU is the BSP */
|
|
||||||
if(SysInfo->CpuInfo[Index].ApicId == HL::Pic::GetCpuApicId())
|
|
||||||
{
|
|
||||||
/* Skip current CPU */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Increment CPU number */
|
|
||||||
CpuNumber++;
|
|
||||||
|
|
||||||
/* Verify if the CPU limit has been reached */
|
|
||||||
if((CpuNumber) >= MaxCpus)
|
|
||||||
{
|
|
||||||
/* Maximum allowed CPUs reached, break the loop */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate memory for the processor structures (Stacks, GDT, and Processor Block) */
|
|
||||||
Status = MM::KernelPool::AllocateProcessorStructures(&CpuStructures);
|
|
||||||
if(Status != STATUS_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to allocate memory, unmap memory and return error */
|
|
||||||
MM::HardwarePool::UnmapHardwareMemory(TrampolineAddress, TrampolinePages, TRUE);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get ProcessorBlock and Stack address */
|
|
||||||
AR::ProcSup::InitializeProcessorStructures(CpuStructures, NULLPTR, NULLPTR, &ProcessorBlock,
|
|
||||||
&StartBlock->Stack, NULLPTR, NULLPTR);
|
|
||||||
|
|
||||||
/* Set processor number directly in the processor block */
|
|
||||||
ProcessorBlock->CpuNumber = CpuNumber;
|
|
||||||
|
|
||||||
/* Save processor block in the array */
|
|
||||||
KE::Processor::RegisterProcessorBlock(CpuNumber, ProcessorBlock);
|
|
||||||
|
|
||||||
/* Initialize processor start block */
|
|
||||||
StartBlock->Cr3 = AR::CpuFunc::ReadControlRegister(3);
|
|
||||||
StartBlock->Cr4 = AR::CpuFunc::ReadControlRegister(4);
|
|
||||||
StartBlock->EntryPoint = (PVOID)&KE::KernelInit::BootstrapApplicationProcessor;
|
|
||||||
StartBlock->ProcessorStructures = CpuStructures;
|
|
||||||
StartBlock->Started = FALSE;
|
|
||||||
|
|
||||||
/* Memory barrier */
|
|
||||||
AR::CpuFunc::MemoryBarrier();
|
|
||||||
|
|
||||||
/* Send INIT IPI and wait for 10ms */
|
|
||||||
HL::Pic::SendIpi(SysInfo->CpuInfo[Index].ApicId, 0, APIC_DM_INIT, APIC_DSH_Destination, APIC_TGM_EDGE);
|
|
||||||
HL::Timer::StallExecution(10000);
|
|
||||||
|
|
||||||
/* Send STARTUP IPI (SIPI) and wait for 200us */
|
|
||||||
HL::Pic::SendIpi(SysInfo->CpuInfo[Index].ApicId, SipiVector, APIC_DM_STARTUP, APIC_DSH_Destination, APIC_TGM_EDGE);
|
|
||||||
HL::Timer::StallExecution(200);
|
|
||||||
|
|
||||||
/* Send STARTUP IPI (SIPI) again */
|
|
||||||
HL::Pic::SendIpi(SysInfo->CpuInfo[Index].ApicId, SipiVector, APIC_DM_STARTUP, APIC_DSH_Destination, APIC_TGM_EDGE);
|
|
||||||
|
|
||||||
/* Wait until the processor has started or timeout expires */
|
|
||||||
Timeout = 0;
|
|
||||||
while(!StartBlock->Started && Timeout < 100000)
|
|
||||||
{
|
|
||||||
/* Yield processor and wait for 10us */
|
|
||||||
AR::CpuFunc::YieldProcessor();
|
|
||||||
HL::Timer::StallExecution(10);
|
|
||||||
Timeout++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if the processor has not started */
|
|
||||||
if(!StartBlock->Started)
|
|
||||||
{
|
|
||||||
/* Free processor structures and unregister processor block */
|
|
||||||
MM::KernelPool::FreeProcessorStructures(CpuStructures);
|
|
||||||
KE::Processor::RegisterProcessorBlock(CpuNumber, NULLPTR);
|
|
||||||
|
|
||||||
/* Decrement the CPU counter back */
|
|
||||||
CpuNumber--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unmap trampoline memory and return success */
|
|
||||||
MM::HardwarePool::UnmapHardwareMemory(TrampolineAddress, TrampolinePages, TRUE);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,56 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/hl/x86/firmware.cc
|
|
||||||
* DESCRIPTION: UEFI/BIOS Firmware support
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads a byte from the specified CMOS register.
|
|
||||||
*
|
|
||||||
* @param Register
|
|
||||||
* Supplies the CMOS register index to read from.
|
|
||||||
*
|
|
||||||
* @return This routine returns the data read from the register.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTFASTCALL
|
|
||||||
UCHAR
|
|
||||||
HL::Firmware::ReadCmosRegister(IN UCHAR Register)
|
|
||||||
{
|
|
||||||
/* Select the register (Setting the highest bit disables NMI) */
|
|
||||||
HL::IoPort::WritePort8(CMOS_SELECT_PORT, Register | CMOS_NMI_SELECT);
|
|
||||||
|
|
||||||
/* Read value from the data port */
|
|
||||||
return HL::IoPort::ReadPort8(CMOS_DATA_PORT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes a byte to the specified CMOS register.
|
|
||||||
*
|
|
||||||
* @param Register
|
|
||||||
* Supplies the CMOS register index to write to.
|
|
||||||
*
|
|
||||||
* @param Value
|
|
||||||
* Supplies the value to write to the register.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTFASTCALL
|
|
||||||
VOID
|
|
||||||
HL::Firmware::WriteCmosRegister(IN UCHAR Register,
|
|
||||||
IN UCHAR Value)
|
|
||||||
{
|
|
||||||
/* Select the register (Setting the highest bit disables NMI) */
|
|
||||||
HL::IoPort::WritePort8(CMOS_SELECT_PORT, Register | CMOS_NMI_SELECT);
|
|
||||||
|
|
||||||
/* Write the provided value to the data port */
|
|
||||||
HL::IoPort::WritePort8(CMOS_DATA_PORT, Value);
|
|
||||||
}
|
|
||||||
@@ -4,89 +4,11 @@
|
|||||||
* FILE: xtoskrnl/hl/x86/pic.cc
|
* FILE: xtoskrnl/hl/x86/pic.cc
|
||||||
* DESCRIPTION: Programmable Interrupt Controller (PIC) for x86 (i686/AMD64) support
|
* DESCRIPTION: Programmable Interrupt Controller (PIC) for x86 (i686/AMD64) support
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
* Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocates, maps and commits a requested system interrupt level internally.
|
|
||||||
*
|
|
||||||
* @param RunLevel
|
|
||||||
* Supplies the actual system run level to allocate.
|
|
||||||
*
|
|
||||||
* @param Vector
|
|
||||||
* Supplies the interrupt handler vector assigned to process requests originating on the line.
|
|
||||||
*
|
|
||||||
* @return This routine returns the configured target vector.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
HL::Pic::AllocateSystemInterrupt(IN UCHAR Irq,
|
|
||||||
IN UCHAR RunLevel,
|
|
||||||
IN UCHAR Vector)
|
|
||||||
{
|
|
||||||
IOAPIC_REDIRECTION_REGISTER Register;
|
|
||||||
PIOAPIC_DATA Controller;
|
|
||||||
ULONG EntryNumber, Gsi;
|
|
||||||
XTSTATUS Status;
|
|
||||||
USHORT Flags;
|
|
||||||
|
|
||||||
/* Determine the GSI and flags for the requested IRQ */
|
|
||||||
ResolveInterruptOverride(Irq, &Gsi, &Flags);
|
|
||||||
|
|
||||||
/* Find the APIC controller for the GSI */
|
|
||||||
Status = GetIoApicController(Gsi, &Controller, &EntryNumber);
|
|
||||||
if(Status != STATUS_SUCCESS)
|
|
||||||
{
|
|
||||||
/* GSI maps to an invalid controller, return */
|
|
||||||
DebugPrint(L"ERROR: Hardware IRQ / GSI maps to an invalid controller!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Model a logical connection */
|
|
||||||
Register.LongLong = 0;
|
|
||||||
Register.DeliveryMode = APIC_DM_FIXED;
|
|
||||||
Register.DeliveryStatus = 0;
|
|
||||||
Register.Destination = HL::Pic::ReadApicRegister(APIC_ID) >> 24;
|
|
||||||
Register.DestinationMode = APIC_DM_Physical;
|
|
||||||
Register.Mask = 0;
|
|
||||||
Register.PinPolarity = ((Flags & 0x03) == 0x03) ? 1 : 0;
|
|
||||||
Register.RemoteIRR = 0;
|
|
||||||
Register.Reserved = 0;
|
|
||||||
Register.TriggerMode = (((Flags >> 2) & 0x03) == 0x03) ? APIC_TGM_LEVEL : APIC_TGM_EDGE;
|
|
||||||
Register.Vector = Vector;
|
|
||||||
|
|
||||||
/* Flash logical rules back into the hardware configuration index */
|
|
||||||
WriteRedirectionEntry(Controller, EntryNumber, Register);
|
|
||||||
|
|
||||||
/* Persist the allocated slot so standard routing algorithms don't overlap it */
|
|
||||||
MappedVectors[Vector] = RunLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the APIC is supported by the processor.
|
|
||||||
*
|
|
||||||
* @return This routine returns TRUE if APIC is supported, or FALSE otherwise.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
BOOLEAN
|
|
||||||
HL::Pic::CheckApicSupport(VOID)
|
|
||||||
{
|
|
||||||
PKPROCESSOR_CONTROL_BLOCK Prcb;
|
|
||||||
|
|
||||||
/* Get current processor control block */
|
|
||||||
Prcb = KE::Processor::GetCurrentProcessorControlBlock();
|
|
||||||
|
|
||||||
/* Return APIC status */
|
|
||||||
return (Prcb->CpuId.FeatureBits & KCF_APIC) ? TRUE : FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the x2APIC extension is supported by the processor.
|
* Checks whether the x2APIC extension is supported by the processor.
|
||||||
*
|
*
|
||||||
@@ -101,21 +23,28 @@ XTAPI
|
|||||||
BOOLEAN
|
BOOLEAN
|
||||||
HL::Pic::CheckX2ApicSupport(VOID)
|
HL::Pic::CheckX2ApicSupport(VOID)
|
||||||
{
|
{
|
||||||
PKPROCESSOR_CONTROL_BLOCK Prcb;
|
CPUID_REGISTERS CpuRegisters;
|
||||||
PCWSTR KernelParameter;
|
|
||||||
|
|
||||||
/* Check if the user forced xAPIC via boot parameters */
|
/* Prepare CPUID registers */
|
||||||
if(KE::BootInformation::GetKernelParameter(L"NOX2APIC", &KernelParameter) == STATUS_SUCCESS)
|
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||||
|
CpuRegisters.SubLeaf = 0;
|
||||||
|
CpuRegisters.Eax = 0;
|
||||||
|
CpuRegisters.Ebx = 0;
|
||||||
|
CpuRegisters.Ecx = 0;
|
||||||
|
CpuRegisters.Edx = 0;
|
||||||
|
|
||||||
|
/* Get CPUID */
|
||||||
|
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||||
|
|
||||||
|
/* Check x2APIC status from the CPUID results */
|
||||||
|
if(!(CpuRegisters.Ecx & CPUID_FEATURES_ECX_X2APIC))
|
||||||
{
|
{
|
||||||
/* The NOX2APIC flag is present, explicitly disable x2APIC support */
|
/* x2APIC is not supported */
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get current processor control block */
|
/* x2APIC is supported */
|
||||||
Prcb = KE::Processor::GetCurrentProcessorControlBlock();
|
return TRUE;
|
||||||
|
|
||||||
/* Return x2APIC status */
|
|
||||||
return (Prcb->CpuId.FeatureBits & KCF_X2APIC) ? TRUE : FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -133,105 +62,6 @@ HL::Pic::ClearApicErrors(VOID)
|
|||||||
WriteApicRegister(APIC_ESR, 0);
|
WriteApicRegister(APIC_ESR, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Searches the ACPI MADT tables for the I/O APIC controllers.
|
|
||||||
*
|
|
||||||
* @return This routine returns the status code.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
XTSTATUS
|
|
||||||
HL::Pic::DetectIoApicControllers(VOID)
|
|
||||||
{
|
|
||||||
PACPI_MADT_INTERRUPT_OVERRIDE OverrideDescriptor;
|
|
||||||
PACPI_MADT_IOAPIC IoApicDescriptor;
|
|
||||||
PACPI_SUBTABLE_HEADER SubTable;
|
|
||||||
ULONG_PTR MadtTable;
|
|
||||||
PACPI_MADT Madt;
|
|
||||||
XTSTATUS Status;
|
|
||||||
|
|
||||||
/* Initialize number of I/O APIC Controllers */
|
|
||||||
ControllerCount = 0;
|
|
||||||
|
|
||||||
/* Get Multiple APIC Description Table (MADT) */
|
|
||||||
Status = HL::Acpi::GetAcpiTable(ACPI_MADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Madt);
|
|
||||||
if(Status == STATUS_SUCCESS && Madt != NULLPTR)
|
|
||||||
{
|
|
||||||
/* Set APIC table traverse pointer */
|
|
||||||
MadtTable = (ULONG_PTR)Madt->ApicTables;
|
|
||||||
|
|
||||||
/* Traverse all MADT tables to discover IOAPIC configurations */
|
|
||||||
while(MadtTable < ((ULONG_PTR)Madt + Madt->Header.Length))
|
|
||||||
{
|
|
||||||
/* Extract active header element */
|
|
||||||
SubTable = (PACPI_SUBTABLE_HEADER)MadtTable;
|
|
||||||
|
|
||||||
/* Prevent infinite traversal loops on corrupted firmware definitions */
|
|
||||||
if(SubTable->Length == 0)
|
|
||||||
{
|
|
||||||
/* Invalid MADT table, break loop */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Test specifically for I/O APIC component identity */
|
|
||||||
if(SubTable->Type == ACPI_MADT_TYPE_IOAPIC &&
|
|
||||||
SubTable->Length >= sizeof(ACPI_MADT_IOAPIC))
|
|
||||||
{
|
|
||||||
/* Extract I/O APIC descriptor */
|
|
||||||
IoApicDescriptor = (PACPI_MADT_IOAPIC)MadtTable;
|
|
||||||
|
|
||||||
/* Set information about this I/O APIC Controller */
|
|
||||||
Controllers[ControllerCount].GsiBase = IoApicDescriptor->GlobalIrqBase;
|
|
||||||
Controllers[ControllerCount].Identifier = IoApicDescriptor->IoApicId;
|
|
||||||
Controllers[ControllerCount].PhysicalAddress.QuadPart = IoApicDescriptor->IoApicAddress;
|
|
||||||
|
|
||||||
/* Increment I/O APIC controller index */
|
|
||||||
ControllerCount++;
|
|
||||||
}
|
|
||||||
else if(SubTable->Type == ACPI_MADT_TYPE_INT_OVERRIDE &&
|
|
||||||
SubTable->Length >= sizeof(ACPI_MADT_INTERRUPT_OVERRIDE))
|
|
||||||
{
|
|
||||||
/* Check if maximum number of interrupt overrides has not been reached */
|
|
||||||
if(IrqOverrideCount < IOAPIC_MAX_OVERRIDES)
|
|
||||||
{
|
|
||||||
/* Extract interrupt override descriptor */
|
|
||||||
OverrideDescriptor = (PACPI_MADT_INTERRUPT_OVERRIDE)MadtTable;
|
|
||||||
|
|
||||||
/* Save information about this interrupt override */
|
|
||||||
IrqOverrides[IrqOverrideCount].Bus = OverrideDescriptor->Bus;
|
|
||||||
IrqOverrides[IrqOverrideCount].Flags = OverrideDescriptor->Flags;
|
|
||||||
IrqOverrides[IrqOverrideCount].GlobalSystemInterrupt = OverrideDescriptor->GlobalSystemInterrupt;
|
|
||||||
IrqOverrides[IrqOverrideCount].SourceIrq = OverrideDescriptor->SourceIrq;
|
|
||||||
|
|
||||||
/* Increment interrupt override index */
|
|
||||||
IrqOverrideCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure, maximum number of I/O APIC controllers has not been reached */
|
|
||||||
if(ControllerCount >= IOAPIC_MAX_CONTROLLERS)
|
|
||||||
{
|
|
||||||
/* No more I/O APIC controllers supported, break loop */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Go to the next subtable */
|
|
||||||
MadtTable += SubTable->Length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if any I/O APIC controllers were found */
|
|
||||||
if(ControllerCount == 0)
|
|
||||||
{
|
|
||||||
/* No I/O APIC controllers found, return failure */
|
|
||||||
return STATUS_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return success */
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the local APIC ID of the current processor.
|
* Gets the local APIC ID of the current processor.
|
||||||
*
|
*
|
||||||
@@ -253,52 +83,7 @@ HL::Pic::GetCpuApicId(VOID)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the I/O APIC controller information for the specified GSI.
|
* Allows an APIC spurious interrupts to end up.
|
||||||
*
|
|
||||||
* @param Gsi
|
|
||||||
* Supplies the GSI to get the I/O APIC controller information for.
|
|
||||||
*
|
|
||||||
* @param Controller
|
|
||||||
* Supplies a pointer to the memory area where the I/O APIC controller information will be stored.
|
|
||||||
*
|
|
||||||
* @param EntryNumber
|
|
||||||
* Supplies a pointer to the memory area where the entry number will be stored.
|
|
||||||
*
|
|
||||||
* @return This routine returns the status code.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
XTSTATUS
|
|
||||||
HL::Pic::GetIoApicController(IN ULONG Gsi,
|
|
||||||
OUT PIOAPIC_DATA *Controller,
|
|
||||||
OUT PULONG EntryNumber)
|
|
||||||
{
|
|
||||||
ULONG ControllerIndex;
|
|
||||||
|
|
||||||
/* Iterate over all available I/O APIC controllers */
|
|
||||||
for(ControllerIndex = 0; ControllerIndex < ControllerCount; ControllerIndex++)
|
|
||||||
{
|
|
||||||
/* Check if the GSI belongs to this I/O APIC controller */
|
|
||||||
if(Gsi >= Controllers[ControllerIndex].GsiBase &&
|
|
||||||
Gsi < (Controllers[ControllerIndex].GsiBase + Controllers[ControllerIndex].LineCount))
|
|
||||||
{
|
|
||||||
/* Return I/O APIC controller information */
|
|
||||||
*Controller = &Controllers[ControllerIndex];
|
|
||||||
*EntryNumber = (ULONG)(Gsi - Controllers[ControllerIndex].GsiBase);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* GSI does not belong to any I/O APIC controller, return failure */
|
|
||||||
return STATUS_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Services the APIC Error interrupt, invoked when the APIC detects an internal hardware or message passing error.
|
|
||||||
*
|
|
||||||
* @param TrapFrame
|
|
||||||
* Supplies a pointer to the hardware trap frame representing the interrupted execution context.
|
|
||||||
*
|
*
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
@@ -306,19 +91,21 @@ HL::Pic::GetIoApicController(IN ULONG Gsi,
|
|||||||
*/
|
*/
|
||||||
XTCDECL
|
XTCDECL
|
||||||
VOID
|
VOID
|
||||||
HL::Pic::HandleApicErrorInterrupt(IN PKTRAP_FRAME TrapFrame)
|
HL::Pic::HandleApicSpuriousService(VOID)
|
||||||
{
|
{
|
||||||
ULONG ErrorStatus;
|
}
|
||||||
|
|
||||||
/* Write 0 to the ESR register to trigger an internal state update, then read the latched status */
|
/**
|
||||||
WriteApicRegister(APIC_ESR, 0);
|
* Allows a PIC spurious interrupts to end up.
|
||||||
ErrorStatus = (ULONG)ReadApicRegister(APIC_ESR);
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
/* Log the detected hardware error */
|
*
|
||||||
DebugPrint(L"Caught APIC Error interrupt with ESR = 0x%08X\n", ErrorStatus);
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
/* Acknowledge the interrupt to allow further interrupt delivery */
|
XTCDECL
|
||||||
SendEoi();
|
VOID
|
||||||
|
HL::Pic::HandlePicSpuriousService(VOID)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -337,14 +124,6 @@ HL::Pic::InitializeApic(VOID)
|
|||||||
APIC_LVT_REGISTER LvtRegister;
|
APIC_LVT_REGISTER LvtRegister;
|
||||||
ULONG CpuNumber;
|
ULONG CpuNumber;
|
||||||
|
|
||||||
/* Check APIC support */
|
|
||||||
if(!CheckApicSupport())
|
|
||||||
{
|
|
||||||
/* APIC is not supported, raise kernel panic */
|
|
||||||
DebugPrint(L"ERROR: Local APIC not present.\n");
|
|
||||||
KE::Crash::Panic(0x5D, CPUID_GET_STANDARD1_FEATURES, 0x0, 0x0, CPUID_FEATURES_EDX_APIC);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Determine APIC mode (xAPIC compatibility or x2APIC) */
|
/* Determine APIC mode (xAPIC compatibility or x2APIC) */
|
||||||
if(CheckX2ApicSupport())
|
if(CheckX2ApicSupport())
|
||||||
{
|
{
|
||||||
@@ -380,9 +159,6 @@ HL::Pic::InitializeApic(VOID)
|
|||||||
WriteApicRegister(APIC_LDR, (1UL << CpuNumber) << 24);
|
WriteApicRegister(APIC_LDR, (1UL << CpuNumber) << 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Report the APIC ID to the kernel logic */
|
|
||||||
KE::Processor::RegisterHardwareId(GetCpuApicId());
|
|
||||||
|
|
||||||
/* Configure the spurious interrupt vector */
|
/* Configure the spurious interrupt vector */
|
||||||
SpuriousRegister.Long = ReadApicRegister(APIC_SIVR);
|
SpuriousRegister.Long = ReadApicRegister(APIC_SIVR);
|
||||||
SpuriousRegister.Vector = APIC_VECTOR_SPURIOUS;
|
SpuriousRegister.Vector = APIC_VECTOR_SPURIOUS;
|
||||||
@@ -393,9 +169,13 @@ HL::Pic::InitializeApic(VOID)
|
|||||||
/* Setup the LVT Error entry to deliver APIC errors on a dedicated vector */
|
/* Setup the LVT Error entry to deliver APIC errors on a dedicated vector */
|
||||||
WriteApicRegister(APIC_ERRLVTR, APIC_VECTOR_ERROR);
|
WriteApicRegister(APIC_ERRLVTR, APIC_VECTOR_ERROR);
|
||||||
|
|
||||||
/* Mask the APIC Timer */
|
/* Program the APIC timer for periodic mode */
|
||||||
LvtRegister.Long = 0;
|
LvtRegister.Long = 0;
|
||||||
LvtRegister.Mask = 1;
|
LvtRegister.Mask = 1;
|
||||||
|
LvtRegister.DeliveryMode = APIC_DM_FIXED;
|
||||||
|
LvtRegister.TimerMode = 1;
|
||||||
|
LvtRegister.TriggerMode = APIC_TGM_EDGE;
|
||||||
|
LvtRegister.Vector = APIC_VECTOR_PROFILE;
|
||||||
WriteApicRegister(APIC_TMRLVTR, LvtRegister.Long);
|
WriteApicRegister(APIC_TMRLVTR, LvtRegister.Long);
|
||||||
|
|
||||||
/* Configure the performance counter overflow */
|
/* Configure the performance counter overflow */
|
||||||
@@ -426,9 +206,8 @@ HL::Pic::InitializeApic(VOID)
|
|||||||
WriteApicRegister(APIC_LINT1, LvtRegister.Long);
|
WriteApicRegister(APIC_LINT1, LvtRegister.Long);
|
||||||
|
|
||||||
/* Register interrupt handlers */
|
/* Register interrupt handlers */
|
||||||
HL::Irq::RegisterSystemInterruptHandler(APIC_VECTOR_ERROR, HandleApicErrorInterrupt);
|
KE::Irq::SetInterruptHandler(APIC_VECTOR_SPURIOUS, (PVOID)HandleApicSpuriousService);
|
||||||
HL::Irq::RegisterSystemInterruptHandler(APIC_VECTOR_PROFILE, HL::Irq::HandleProfileInterrupt);
|
KE::Irq::SetInterruptHandler(PIC1_VECTOR_SPURIOUS, (PVOID)HandlePicSpuriousService);
|
||||||
HL::Irq::RegisterInterruptHandler(APIC_VECTOR_SPURIOUS, (PVOID)ArHandleSpuriousInterrupt);
|
|
||||||
|
|
||||||
/* Clear any pre-existing errors */
|
/* Clear any pre-existing errors */
|
||||||
WriteApicRegister(APIC_ESR, 0);
|
WriteApicRegister(APIC_ESR, 0);
|
||||||
@@ -437,90 +216,6 @@ HL::Pic::InitializeApic(VOID)
|
|||||||
WriteApicRegister(APIC_TPR, 0x00);
|
WriteApicRegister(APIC_TPR, 0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the global I/O APIC controller setup over the entire redirection span.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
HL::Pic::InitializeIOApic(VOID)
|
|
||||||
{
|
|
||||||
ULONG ControllerIndex, LineIndex, Vector, VersionRegister;
|
|
||||||
IOAPIC_REDIRECTION_REGISTER Register;
|
|
||||||
XTSTATUS Status;
|
|
||||||
|
|
||||||
/* Detect I/O APIC controllers */
|
|
||||||
Status = DetectIoApicControllers();
|
|
||||||
if(Status != STATUS_SUCCESS)
|
|
||||||
{
|
|
||||||
DebugPrint(L"ERROR: I/O APIC Controller not present.\n");
|
|
||||||
KE::Crash::Panic(0x5D, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Iterate over all I/O APIC controllers */
|
|
||||||
ControllerIndex = 0;
|
|
||||||
while(ControllerIndex < ControllerCount)
|
|
||||||
{
|
|
||||||
/* Map the I/O APIC controller memory into hardware space */
|
|
||||||
Status = MM::HardwarePool::MapHardwareMemory(Controllers[ControllerIndex].PhysicalAddress,
|
|
||||||
1,
|
|
||||||
FALSE,
|
|
||||||
(PVOID*)&Controllers[ControllerIndex].VirtualAddress);
|
|
||||||
if(Status != STATUS_SUCCESS || Controllers[ControllerIndex].VirtualAddress == 0)
|
|
||||||
{
|
|
||||||
DebugPrint(L"ERROR: Failed to map I/O APIC Controller\n");
|
|
||||||
KE::Crash::Panic(0x0E, 0x0, 0x0, 0x0, 0x0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Perform a memory barrier */
|
|
||||||
AR::CpuFunc::MemoryBarrier();
|
|
||||||
AR::CpuFunc::ReadWriteBarrier();
|
|
||||||
|
|
||||||
/* Read the version register and calculate the maximum number of redirection entries */
|
|
||||||
VersionRegister = ReadIOApicRegister(&Controllers[ControllerIndex], IOAPIC_VER);
|
|
||||||
Controllers[ControllerIndex].LineCount = ((VersionRegister >> 16) & 0xFF) + 1;
|
|
||||||
|
|
||||||
/* Set up the default redirection entry for this controller */
|
|
||||||
Register.LongLong = 0;
|
|
||||||
Register.DeliveryMode = APIC_DM_FIXED;
|
|
||||||
Register.DeliveryStatus = 0;
|
|
||||||
Register.Destination = ReadIOApicRegister(&Controllers[ControllerIndex], IOAPIC_ID) >> 24;
|
|
||||||
Register.DestinationMode = 0;
|
|
||||||
Register.Mask = 1;
|
|
||||||
Register.PinPolarity = 0;
|
|
||||||
Register.RemoteIRR = 0;
|
|
||||||
Register.Reserved = 0;
|
|
||||||
Register.TriggerMode = APIC_TGM_EDGE;
|
|
||||||
Register.Vector = IOAPIC_VECTOR_FREE;
|
|
||||||
|
|
||||||
/* Propagate defaults across the array of potential handlers */
|
|
||||||
for(LineIndex = 0; LineIndex < Controllers[ControllerIndex].LineCount; LineIndex++)
|
|
||||||
{
|
|
||||||
/* Write default values into the redirection table */
|
|
||||||
WriteRedirectionEntry(&Controllers[ControllerIndex], LineIndex, Register);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print information about the I/O APIC controller */
|
|
||||||
DebugPrint(L"Initialized I/O APIC Controller #%lu at 0x%llX (ID: %lu, GSI Base: %lu, Line Count: %lu)\n",
|
|
||||||
ControllerIndex, Controllers[ControllerIndex].VirtualAddress,
|
|
||||||
Controllers[ControllerIndex].Identifier, Controllers[ControllerIndex].GsiBase,
|
|
||||||
Controllers[ControllerIndex].LineCount);
|
|
||||||
|
|
||||||
/* Go to the next I/O APIC controller */
|
|
||||||
ControllerIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Assign initial clean state for mapping translations */
|
|
||||||
for(Vector = 0; Vector <= 255; Vector++)
|
|
||||||
{
|
|
||||||
/* Set vector to free */
|
|
||||||
MappedVectors[Vector] = IOAPIC_VECTOR_FREE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the legacy PIC interrupt controller.
|
* Initializes the legacy PIC interrupt controller.
|
||||||
*
|
*
|
||||||
@@ -594,9 +289,6 @@ HL::Pic::InitializeLegacyPic(VOID)
|
|||||||
|
|
||||||
/* Mask all interrupts on PIC2 port */
|
/* Mask all interrupts on PIC2 port */
|
||||||
HL::IoPort::WritePort8(PIC2_DATA_PORT, 0xFF);
|
HL::IoPort::WritePort8(PIC2_DATA_PORT, 0xFF);
|
||||||
|
|
||||||
/* Register interrupt handler */
|
|
||||||
HL::Irq::RegisterInterruptHandler(PIC1_VECTOR_SPURIOUS, (PVOID)ArHandleSpuriousInterrupt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -641,181 +333,7 @@ HL::Pic::ReadApicRegister(IN APIC_REGISTER Register)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Read from xAPIC */
|
/* Read from xAPIC */
|
||||||
return HL::IoRegister::ReadRegister32((PULONG)(APIC_BASE + (Register << 4)));
|
return IoRegister::ReadRegister32((PULONG)(APIC_BASE + (Register << 4)));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads from the I/O APIC register.
|
|
||||||
*
|
|
||||||
* @param Controller
|
|
||||||
* Supplies the I/O APIC controller to read from.
|
|
||||||
*
|
|
||||||
* @param Register
|
|
||||||
* Supplies the I/O APIC register to read from.
|
|
||||||
*
|
|
||||||
* @return This routine returns the value read from the given IO APIC register.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTFASTCALL
|
|
||||||
ULONG
|
|
||||||
HL::Pic::ReadIOApicRegister(IN PIOAPIC_DATA Controller,
|
|
||||||
IN UCHAR Register)
|
|
||||||
{
|
|
||||||
/* Write the target address into the index register */
|
|
||||||
HL::IoRegister::WriteRegister32((PULONG)(Controller->VirtualAddress + IOAPIC_IOREGSEL), Register);
|
|
||||||
|
|
||||||
/* Fetch the resultant value from the data window */
|
|
||||||
return HL::IoRegister::ReadRegister32((PULONG)(Controller->VirtualAddress + IOAPIC_IOWIN));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads a configuration entry from the I/O APIC redirection table.
|
|
||||||
*
|
|
||||||
* @param Controller
|
|
||||||
* Supplies the I/O APIC controller to read from.
|
|
||||||
*
|
|
||||||
* @param EntryNumber
|
|
||||||
* Supplies the redirection table entry number to read.
|
|
||||||
*
|
|
||||||
* @return This routine returns the populated redirection table entry.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTFASTCALL
|
|
||||||
IOAPIC_REDIRECTION_REGISTER
|
|
||||||
HL::Pic::ReadRedirectionEntry(IN PIOAPIC_DATA Controller,
|
|
||||||
IN ULONG EntryNumber)
|
|
||||||
{
|
|
||||||
IOAPIC_REDIRECTION_REGISTER Register;
|
|
||||||
ULONG Offset;
|
|
||||||
|
|
||||||
/* Derive the offset corresponding to the index */
|
|
||||||
Offset = IOAPIC_REDTBL + (EntryNumber * IOAPIC_RTE_SIZE);
|
|
||||||
|
|
||||||
/* Read the low and high portions mapping to the 64-bit construct */
|
|
||||||
Register.Base = ReadIOApicRegister(Controller, Offset);
|
|
||||||
Register.Extended = ReadIOApicRegister(Controller, Offset + 1);
|
|
||||||
|
|
||||||
/* Return the redirection table entry */
|
|
||||||
return Register;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolves the GSI and flags for the specified IRQ.
|
|
||||||
*
|
|
||||||
* @param Irq
|
|
||||||
* Supplies the IRQ number to get the GSI and flags for.
|
|
||||||
*
|
|
||||||
* @param Gsi
|
|
||||||
* Supplies a pointer to the memory area where the GSI will be stored.
|
|
||||||
*
|
|
||||||
* @param Flags
|
|
||||||
* Supplies a pointer to the memory area where the flags will be stored.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
HL::Pic::ResolveInterruptOverride(IN UCHAR Irq,
|
|
||||||
OUT PULONG Gsi,
|
|
||||||
OUT PUSHORT Flags)
|
|
||||||
{
|
|
||||||
ULONG Index;
|
|
||||||
|
|
||||||
/* Iterate over all I/O APIC overrides */
|
|
||||||
for(Index = 0; Index < IrqOverrideCount; Index++)
|
|
||||||
{
|
|
||||||
/* Check if this IRQ has been overridden */
|
|
||||||
if(IrqOverrides[Index].SourceIrq == Irq)
|
|
||||||
{
|
|
||||||
/* Return overridden GSI and flags */
|
|
||||||
*Flags = IrqOverrides[Index].Flags;
|
|
||||||
*Gsi = IrqOverrides[Index].GlobalSystemInterrupt;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return original IRQ number as GSI and no flags */
|
|
||||||
*Flags = 0;
|
|
||||||
*Gsi = (ULONG)Irq;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends a Broadcast IPI (Inter-Processor Interrupt) to all processors in the system.
|
|
||||||
*
|
|
||||||
* @param Vector
|
|
||||||
* Supplies the hardware interrupt vector to trigger on the target processors.
|
|
||||||
*
|
|
||||||
* @param Self
|
|
||||||
* Supplies a boolean value indicating the broadcast scope.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
HL::Pic::SendBroadcastIpi(IN ULONG Vector,
|
|
||||||
IN BOOLEAN Self)
|
|
||||||
{
|
|
||||||
PKPROCESSOR_BLOCK CurrentProcessorBlock, TargetProcessorBlock;
|
|
||||||
PACPI_SYSTEM_INFO SysInfo;
|
|
||||||
BOOLEAN Interrupts;
|
|
||||||
ULONG Index;
|
|
||||||
|
|
||||||
/* Get the current processor block */
|
|
||||||
CurrentProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
|
||||||
if(CurrentProcessorBlock == NULLPTR)
|
|
||||||
{
|
|
||||||
/* Processor block not available, return */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the ACPI system information */
|
|
||||||
HL::Acpi::GetSystemInformation(&SysInfo);
|
|
||||||
|
|
||||||
/* Check whether interrupts are enabled */
|
|
||||||
Interrupts = AR::CpuFunc::InterruptsEnabled();
|
|
||||||
|
|
||||||
/* Disable interrupts */
|
|
||||||
AR::CpuFunc::ClearInterruptFlag();
|
|
||||||
|
|
||||||
/* Iterate over all logical CPUs */
|
|
||||||
for(Index = 0; Index < SysInfo->CpuCount; Index++)
|
|
||||||
{
|
|
||||||
/* Retrieve the target processor block by its Logical CPU Number */
|
|
||||||
TargetProcessorBlock = KE::Processor::GetProcessorBlock(Index);
|
|
||||||
|
|
||||||
/* Only send to processors that exist and have successfully started */
|
|
||||||
if(TargetProcessorBlock != NULLPTR && TargetProcessorBlock->Started)
|
|
||||||
{
|
|
||||||
/* Check if this processor originated the broadcast */
|
|
||||||
if(TargetProcessorBlock->HardwareId == CurrentProcessorBlock->HardwareId)
|
|
||||||
{
|
|
||||||
/* Check if this is a self broadcast */
|
|
||||||
if(Self)
|
|
||||||
{
|
|
||||||
/* Dispatch the IPI to the current processor */
|
|
||||||
SendSelfIpi(Vector);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Dispatch the IPI to the target processor */
|
|
||||||
SendIpi(TargetProcessorBlock->HardwareId, Vector, APIC_DM_FIXED, APIC_DSH_Destination, APIC_TGM_EDGE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check whether interrupts need to be re-enabled */
|
|
||||||
if(Interrupts)
|
|
||||||
{
|
|
||||||
/* Re-enable interrupts */
|
|
||||||
AR::CpuFunc::SetInterruptFlag();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -843,153 +361,27 @@ HL::Pic::SendEoi(VOID)
|
|||||||
* @param Vector
|
* @param Vector
|
||||||
* Supplies the IPI vector to send.
|
* Supplies the IPI vector to send.
|
||||||
*
|
*
|
||||||
* @param DeliveryMode
|
|
||||||
* Supplies the delivery mode for the IPI.
|
|
||||||
*
|
|
||||||
* @param DestinationShorthand
|
|
||||||
* Supplies the shorthand.
|
|
||||||
*
|
|
||||||
* @param TriggerMode
|
|
||||||
* Supplies the trigger mode (Edge or Level).
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
* @since XT 1.0
|
* @since XT 1.0
|
||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
VOID
|
VOID
|
||||||
HL::Pic::SendIpi(IN ULONG ApicId,
|
HL::Pic::SendIpi(ULONG ApicId,
|
||||||
IN ULONG Vector,
|
ULONG Vector)
|
||||||
IN APIC_DM DeliveryMode,
|
|
||||||
IN APIC_DSH DestinationShortHand,
|
|
||||||
IN ULONG TriggerMode)
|
|
||||||
{
|
{
|
||||||
APIC_COMMAND_REGISTER Register;
|
|
||||||
BOOLEAN Interrupts;
|
|
||||||
|
|
||||||
/* Check whether interrupts are enabled */
|
|
||||||
Interrupts = AR::CpuFunc::InterruptsEnabled();
|
|
||||||
|
|
||||||
/* Disable interrupts */
|
|
||||||
AR::CpuFunc::ClearInterruptFlag();
|
|
||||||
|
|
||||||
/* Check current APIC mode and destination */
|
|
||||||
if(ApicMode == APIC_MODE_X2APIC && DestinationShortHand == APIC_DSH_Self)
|
|
||||||
{
|
|
||||||
/* In x2APIC mode, a dedicated Self-IPI register is used */
|
|
||||||
WriteApicRegister(APIC_SIPI, Vector);
|
|
||||||
|
|
||||||
/* Check whether interrupts need to be re-enabled */
|
|
||||||
if(Interrupts)
|
|
||||||
{
|
|
||||||
/* Check whether interrupts need to be re-enabled */
|
|
||||||
AR::CpuFunc::SetInterruptFlag();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Nothing more to do */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prepare APIC command register struct */
|
|
||||||
Register.LongLong = 0;
|
|
||||||
Register.DeliveryMode = DeliveryMode;
|
|
||||||
Register.Destination = ApicId;
|
|
||||||
Register.DestinationShortHand = DestinationShortHand;
|
|
||||||
Register.Level = 1;
|
|
||||||
Register.TriggerMode = TriggerMode;
|
|
||||||
Register.Vector = Vector;
|
|
||||||
|
|
||||||
/* Check current APIC mode */
|
/* Check current APIC mode */
|
||||||
if(ApicMode == APIC_MODE_X2APIC)
|
if(ApicMode == APIC_MODE_X2APIC)
|
||||||
{
|
{
|
||||||
/* Set destination APIC ID */
|
|
||||||
Register.Long1 = ApicId;
|
|
||||||
|
|
||||||
/* Send IPI using x2APIC mode */
|
/* Send IPI using x2APIC mode */
|
||||||
WriteApicRegister(APIC_ICR0, Register.LongLong);
|
WriteApicRegister(APIC_ICR0, ((ULONGLONG)ApicId << 32) | Vector);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Wait for the APIC to clear the delivery status */
|
/* Send IPI using xAPIC compatibility mode */
|
||||||
while((ReadApicRegister(APIC_ICR0) & 0x1000) != 0)
|
WriteApicRegister(APIC_ICR1, ApicId << 24);
|
||||||
{
|
WriteApicRegister(APIC_ICR0, Vector);
|
||||||
/* Yield the processor */
|
|
||||||
AR::CpuFunc::YieldProcessor();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* In xAPIC compatibility mode, write the command to the ICR registers */
|
|
||||||
WriteApicRegister(APIC_ICR1, Register.Long1);
|
|
||||||
WriteApicRegister(APIC_ICR0, Register.Long0);
|
|
||||||
|
|
||||||
/* Check if this is a Self-IPI */
|
|
||||||
if(DestinationShortHand == APIC_DSH_Self)
|
|
||||||
{
|
|
||||||
/* Wait until the interrupt physically arrives in the requested state */
|
|
||||||
while((ReadApicRegister((APIC_REGISTER)(APIC_IRR + (Vector / 32))) & (1UL << (Vector % 32))) == 0)
|
|
||||||
{
|
|
||||||
/* Yield the processor */
|
|
||||||
AR::CpuFunc::YieldProcessor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check whether interrupts need to be re-enabled */
|
|
||||||
if(Interrupts)
|
|
||||||
{
|
|
||||||
/* Re-enable interrupts */
|
|
||||||
AR::CpuFunc::SetInterruptFlag();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends a Self-IPI (Inter-Processor Interrupt) to the current CPU.
|
|
||||||
*
|
|
||||||
* @param Vector
|
|
||||||
* Supplies the IPI vector to send.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
VOID
|
|
||||||
HL::Pic::SendSelfIpi(IN ULONG Vector)
|
|
||||||
{
|
|
||||||
SendIpi(0, Vector, APIC_DM_FIXED, APIC_DSH_Self, APIC_TGM_EDGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Translates a given Global System Interrupt (GSI) into an active system interrupt vector.
|
|
||||||
*
|
|
||||||
* @param Gsi
|
|
||||||
* Supplies the GSI to translate.
|
|
||||||
*
|
|
||||||
* @return This routine returns the underlying associated system vector mapping.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTFASTCALL
|
|
||||||
UCHAR
|
|
||||||
HL::Pic::TranslateGsiToVector(IN ULONG Gsi)
|
|
||||||
{
|
|
||||||
IOAPIC_REDIRECTION_REGISTER Register;
|
|
||||||
PIOAPIC_DATA Controller;
|
|
||||||
ULONG EntryNumber;
|
|
||||||
XTSTATUS Status;
|
|
||||||
|
|
||||||
/* Find the APIC controller for the GSI */
|
|
||||||
Status = GetIoApicController(Gsi, &Controller, &EntryNumber);
|
|
||||||
if(Status != STATUS_SUCCESS)
|
|
||||||
{
|
|
||||||
/* GSI maps to an invalid controller, return free */
|
|
||||||
return IOAPIC_VECTOR_FREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read the redirection table entry */
|
|
||||||
Register.Base = ReadIOApicRegister(Controller, IOAPIC_REDTBL + (EntryNumber * IOAPIC_RTE_SIZE));
|
|
||||||
|
|
||||||
/* Return the vector */
|
|
||||||
return (UCHAR)Register.Vector;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1018,70 +410,6 @@ HL::Pic::WriteApicRegister(IN APIC_REGISTER Register,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Write to xAPIC */
|
/* Write to xAPIC */
|
||||||
HL::IoRegister::WriteRegister32((PULONG)(APIC_BASE + (Register << 4)), Value);
|
IoRegister::WriteRegister32((PULONG)(APIC_BASE + (Register << 4)), Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes a value to the I/O APIC register.
|
|
||||||
*
|
|
||||||
* @param Controller
|
|
||||||
* Supplies the I/O APIC controller to write to.
|
|
||||||
*
|
|
||||||
* @param Register
|
|
||||||
* Supplies the I/O APIC register to write to.
|
|
||||||
*
|
|
||||||
* @param DataValue
|
|
||||||
* Supplies the value to write to the designated I/O APIC register.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTFASTCALL
|
|
||||||
VOID
|
|
||||||
HL::Pic::WriteIOApicRegister(IN PIOAPIC_DATA Controller,
|
|
||||||
IN UCHAR Register,
|
|
||||||
IN ULONG DataValue)
|
|
||||||
{
|
|
||||||
/* Provide the index to the control port */
|
|
||||||
HL::IoRegister::WriteRegister32((PULONG)(Controller->VirtualAddress + IOAPIC_IOREGSEL), Register);
|
|
||||||
|
|
||||||
/* Commit the value via the data port */
|
|
||||||
HL::IoRegister::WriteRegister32((PULONG)(Controller->VirtualAddress + IOAPIC_IOWIN), DataValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes a configuration entry into the I/O APIC redirection table.
|
|
||||||
*
|
|
||||||
* @param Controller
|
|
||||||
* Supplies the I/O APIC controller to write to.
|
|
||||||
*
|
|
||||||
* @param EntryNumber
|
|
||||||
* Supplies the redirection table entry number to write.
|
|
||||||
*
|
|
||||||
* @param EntryData
|
|
||||||
* Supplies the redirection table entry data to write.
|
|
||||||
*
|
|
||||||
* @return This routine does not return any value.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTFASTCALL
|
|
||||||
VOID
|
|
||||||
HL::Pic::WriteRedirectionEntry(IN PIOAPIC_DATA Controller,
|
|
||||||
IN ULONG EntryNumber,
|
|
||||||
IN IOAPIC_REDIRECTION_REGISTER EntryData)
|
|
||||||
{
|
|
||||||
ULONG Offset;
|
|
||||||
|
|
||||||
/* Calculate the offset of the redirection entry */
|
|
||||||
Offset = IOAPIC_REDTBL + (EntryNumber * IOAPIC_RTE_SIZE);
|
|
||||||
|
|
||||||
/* Mask the entry to prevent spurious interrupts */
|
|
||||||
WriteIOApicRegister(Controller, Offset, IOAPIC_RTE_MASKED);
|
|
||||||
|
|
||||||
/* Write the lower and upper chunks of the entry */
|
|
||||||
WriteIOApicRegister(Controller, Offset + 1, EntryData.Extended);
|
|
||||||
WriteIOApicRegister(Controller, Offset, EntryData.Base);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,328 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/hl/x86/rtc.cc
|
|
||||||
* DESCRIPTION: Hardware Real-Time Clock (RTC) support
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Queries the hardware Real-Time Clock (RTC) for the current date and time.
|
|
||||||
*
|
|
||||||
* @param Time
|
|
||||||
* Supplies a pointer to a structure to receive the system time.
|
|
||||||
*
|
|
||||||
* @return This routine returns the status code.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
XTSTATUS
|
|
||||||
HL::Rtc::GetRealTimeClock(OUT PTIME_FIELDS Time)
|
|
||||||
{
|
|
||||||
UCHAR Century1, Century2, CenturyRegister, RegisterB;
|
|
||||||
TIME_FIELDS TimeProbe1, TimeProbe2;
|
|
||||||
PACPI_FADT FadtTable;
|
|
||||||
BOOLEAN PostMeridiem;
|
|
||||||
XTSTATUS Status;
|
|
||||||
ULONG Index;
|
|
||||||
|
|
||||||
/* Locate the ACPI FADT table */
|
|
||||||
Status = HL::Acpi::GetAcpiTable(ACPI_FADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&FadtTable);
|
|
||||||
if(Status == STATUS_SUCCESS && FadtTable && FadtTable->CenturyAlarmIndex)
|
|
||||||
{
|
|
||||||
/* Cache the dynamically provided Century register index */
|
|
||||||
CenturyRegister = FadtTable->CenturyAlarmIndex;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Century register is unavailable */
|
|
||||||
CenturyRegister = 0;
|
|
||||||
Century1 = 0;
|
|
||||||
Century2 = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read the RTC Status Register B to determine hardware data formats */
|
|
||||||
RegisterB = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_B);
|
|
||||||
|
|
||||||
/* Assume failure */
|
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
|
||||||
|
|
||||||
/* Execute a maximum of 100 retries to obtain a stable RTC snapshot */
|
|
||||||
for(Index = 0; Index < 100; Index++)
|
|
||||||
{
|
|
||||||
/* Wait until the RTC hardware finishes any ongoing background updates */
|
|
||||||
while(HL::Firmware::ReadCmosRegister(CMOS_REGISTER_A) & CMOS_REGISTER_A_UPDATE_IN_PROGRESS)
|
|
||||||
{
|
|
||||||
/* Yield the processor */
|
|
||||||
AR::CpuFunc::YieldProcessor();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Latch the first sequential hardware time snapshot */
|
|
||||||
TimeProbe1.Hour = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_HOUR);
|
|
||||||
TimeProbe1.Minute = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_MINUTE);
|
|
||||||
TimeProbe1.Second = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_SECOND);
|
|
||||||
TimeProbe1.Day = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_DAY);
|
|
||||||
TimeProbe1.Month = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_MONTH);
|
|
||||||
TimeProbe1.Year = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_YEAR);
|
|
||||||
TimeProbe1.Weekday = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_WEEKDAY);
|
|
||||||
|
|
||||||
/* Check if Century register is available */
|
|
||||||
if(CenturyRegister)
|
|
||||||
{
|
|
||||||
/* Read the corresponding Century register */
|
|
||||||
Century1 = HL::Firmware::ReadCmosRegister(CenturyRegister);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wait until the RTC hardware finishes any ongoing background updates */
|
|
||||||
while(HL::Firmware::ReadCmosRegister(CMOS_REGISTER_A) & CMOS_REGISTER_A_UPDATE_IN_PROGRESS)
|
|
||||||
{
|
|
||||||
/* Yield the processor */
|
|
||||||
AR::CpuFunc::YieldProcessor();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Latch the second sequential hardware time snapshot for verification */
|
|
||||||
TimeProbe2.Hour = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_HOUR);
|
|
||||||
TimeProbe2.Minute = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_MINUTE);
|
|
||||||
TimeProbe2.Second = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_SECOND);
|
|
||||||
TimeProbe2.Day = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_DAY);
|
|
||||||
TimeProbe2.Month = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_MONTH);
|
|
||||||
TimeProbe2.Year = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_YEAR);
|
|
||||||
TimeProbe2.Weekday = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_WEEKDAY);
|
|
||||||
|
|
||||||
/* Check if Century register is available */
|
|
||||||
if(CenturyRegister)
|
|
||||||
{
|
|
||||||
/* Read the corresponding Century register */
|
|
||||||
Century2 = HL::Firmware::ReadCmosRegister(CenturyRegister);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compare both snapshots to guarantee data consistency */
|
|
||||||
if((TimeProbe1.Hour == TimeProbe2.Hour) &&
|
|
||||||
(TimeProbe1.Minute == TimeProbe2.Minute) &&
|
|
||||||
(TimeProbe1.Second == TimeProbe2.Second) &&
|
|
||||||
(TimeProbe1.Day == TimeProbe2.Day) &&
|
|
||||||
(TimeProbe1.Month == TimeProbe2.Month) &&
|
|
||||||
(TimeProbe1.Year == TimeProbe2.Year) &&
|
|
||||||
(TimeProbe1.Weekday == TimeProbe2.Weekday) &&
|
|
||||||
(Century1 == Century2))
|
|
||||||
{
|
|
||||||
/* A stable time sample was acquired, break the loop */
|
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy the validated data into the output buffer */
|
|
||||||
Time->Hour = TimeProbe1.Hour;
|
|
||||||
Time->Minute = TimeProbe1.Minute;
|
|
||||||
Time->Second = TimeProbe1.Second;
|
|
||||||
Time->Milliseconds = 0;
|
|
||||||
Time->Day = TimeProbe1.Day;
|
|
||||||
Time->Month = TimeProbe1.Month;
|
|
||||||
Time->Year = TimeProbe1.Year;
|
|
||||||
Time->Weekday = TimeProbe1.Weekday;
|
|
||||||
|
|
||||||
/* Check if RTC is operating in 12-hour mode */
|
|
||||||
if(!(RegisterB & CMOS_REGISTER_B_24_HOUR))
|
|
||||||
{
|
|
||||||
/* Cache the PM status and strip the hardware flag */
|
|
||||||
PostMeridiem = (Time->Hour & CMOS_RTC_POST_MERIDIEM) != 0;
|
|
||||||
Time->Hour &= ~CMOS_RTC_POST_MERIDIEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert Binary-Coded Decimal (BCD) values to standard integers if necessary */
|
|
||||||
if(!(RegisterB & CMOS_REGISTER_B_BINARY))
|
|
||||||
{
|
|
||||||
/* Decode all standard time fields */
|
|
||||||
Time->Hour = BCD_TO_DECIMAL(Time->Hour);
|
|
||||||
Time->Minute = BCD_TO_DECIMAL(Time->Minute);
|
|
||||||
Time->Second = BCD_TO_DECIMAL(Time->Second);
|
|
||||||
Time->Day = BCD_TO_DECIMAL(Time->Day);
|
|
||||||
Time->Month = BCD_TO_DECIMAL(Time->Month);
|
|
||||||
Time->Year = BCD_TO_DECIMAL(Time->Year);
|
|
||||||
Time->Weekday = BCD_TO_DECIMAL(Time->Weekday);
|
|
||||||
|
|
||||||
/* Check if Century byte is available */
|
|
||||||
if(CenturyRegister)
|
|
||||||
{
|
|
||||||
/* Convert Century byte */
|
|
||||||
Century1 = BCD_TO_DECIMAL(Century1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Standardize hours into a strict 24-hour format */
|
|
||||||
if(!(RegisterB & CMOS_REGISTER_B_24_HOUR))
|
|
||||||
{
|
|
||||||
/* Adjust for midnight and noon boundary cases */
|
|
||||||
if(Time->Hour == 12)
|
|
||||||
{
|
|
||||||
/* 12 AM evaluates to 00:00, 12 PM evaluates to 12:00 */
|
|
||||||
Time->Hour = PostMeridiem ? 12 : 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Add 12 hours for PM times */
|
|
||||||
Time->Hour += PostMeridiem ? 12 : 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Merge the century offset with the 2-digit hardware year */
|
|
||||||
if(Century1 >= 19 && Century1 <= 30)
|
|
||||||
{
|
|
||||||
/* Utilize the hardware-provided century base */
|
|
||||||
Time->Year += (Century1 * 100);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Century byte is invalid; apply the sliding window */
|
|
||||||
Time->Year += (Time->Year > 80) ? 1900 : 2000;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return status code */
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the hardware Real-Time Clock (RTC) with the provided date and time.
|
|
||||||
*
|
|
||||||
* @param Time
|
|
||||||
* Supplies a pointer to a structure with populated data and time.
|
|
||||||
*
|
|
||||||
* @return This routine returns the status code.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTAPI
|
|
||||||
XTSTATUS
|
|
||||||
HL::Rtc::SetRealTimeClock(IN PTIME_FIELDS Time)
|
|
||||||
{
|
|
||||||
UCHAR Century, CenturyRegister, RegisterB;
|
|
||||||
TIME_FIELDS SystemTime;
|
|
||||||
BOOLEAN PostMeridiem;
|
|
||||||
PACPI_FADT FadtTable;
|
|
||||||
XTSTATUS Status;
|
|
||||||
|
|
||||||
/* Validate the input time boundaries against calendar limits */
|
|
||||||
if(Time->Hour > 23 || Time->Minute > 59 || Time->Second > 59 ||
|
|
||||||
Time->Day == 0 || Time->Day > 31 || Time->Month == 0 ||
|
|
||||||
Time->Month > 12 || Time->Weekday == 0 || Time->Weekday > 7)
|
|
||||||
{
|
|
||||||
/* Invalid time parameters, return error code */
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Assume Ante Meridiem */
|
|
||||||
PostMeridiem = FALSE;
|
|
||||||
|
|
||||||
/* Extract local copy */
|
|
||||||
SystemTime.Hour = Time->Hour;
|
|
||||||
SystemTime.Minute = Time->Minute;
|
|
||||||
SystemTime.Second = Time->Second;
|
|
||||||
SystemTime.Day = Time->Day;
|
|
||||||
SystemTime.Month = Time->Month;
|
|
||||||
SystemTime.Year = (Time->Year % 100);
|
|
||||||
SystemTime.Weekday = Time->Weekday;
|
|
||||||
Century = (UCHAR)(Time->Year / 100);
|
|
||||||
|
|
||||||
/* Locate the ACPI FADT table */
|
|
||||||
Status = HL::Acpi::GetAcpiTable(ACPI_FADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&FadtTable);
|
|
||||||
if(Status == STATUS_SUCCESS && FadtTable && FadtTable->CenturyAlarmIndex)
|
|
||||||
{
|
|
||||||
/* Cache the dynamically provided Century register index */
|
|
||||||
CenturyRegister = FadtTable->CenturyAlarmIndex;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Century register is unavailable */
|
|
||||||
CenturyRegister = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read the RTC Status Register B to determine hardware data formats */
|
|
||||||
RegisterB = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_B);
|
|
||||||
|
|
||||||
/* Format hours if the hardware is running in 12-hour mode */
|
|
||||||
if(!(RegisterB & CMOS_REGISTER_B_24_HOUR))
|
|
||||||
{
|
|
||||||
/* Determine if the time is PM */
|
|
||||||
PostMeridiem = (SystemTime.Hour >= 12);
|
|
||||||
|
|
||||||
/* Adjust for midnight and noon boundary cases */
|
|
||||||
if(SystemTime.Hour == 0)
|
|
||||||
{
|
|
||||||
/* Midnight evaluates to 12 AM */
|
|
||||||
SystemTime.Hour = 12;
|
|
||||||
}
|
|
||||||
else if(SystemTime.Hour > 12)
|
|
||||||
{
|
|
||||||
/* Post-noon hour */
|
|
||||||
SystemTime.Hour -= 12;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert to BCD first if needed and apply the hardware PM flag */
|
|
||||||
if(!(RegisterB & CMOS_REGISTER_B_BINARY))
|
|
||||||
{
|
|
||||||
/* Encode to BCD */
|
|
||||||
SystemTime.Hour = DECIMAL_TO_BCD(SystemTime.Hour);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Apply the hardware PM flag to the highest bit */
|
|
||||||
if(PostMeridiem)
|
|
||||||
{
|
|
||||||
/* Set PM flag */
|
|
||||||
SystemTime.Hour |= CMOS_RTC_POST_MERIDIEM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* 24-hour mode, simply encode to BCD if necessary */
|
|
||||||
if(!(RegisterB & CMOS_REGISTER_B_BINARY))
|
|
||||||
{
|
|
||||||
/* Encode to BCD */
|
|
||||||
SystemTime.Hour = DECIMAL_TO_BCD(SystemTime.Hour);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert remaining standard fields to BCD if necessary */
|
|
||||||
if(!(RegisterB & CMOS_REGISTER_B_BINARY))
|
|
||||||
{
|
|
||||||
/* Encode all standard time fields */
|
|
||||||
SystemTime.Minute = DECIMAL_TO_BCD(SystemTime.Minute);
|
|
||||||
SystemTime.Second = DECIMAL_TO_BCD(SystemTime.Second);
|
|
||||||
SystemTime.Day = DECIMAL_TO_BCD(SystemTime.Day);
|
|
||||||
SystemTime.Month = DECIMAL_TO_BCD(SystemTime.Month);
|
|
||||||
SystemTime.Year = DECIMAL_TO_BCD(SystemTime.Year);
|
|
||||||
SystemTime.Weekday = DECIMAL_TO_BCD((UCHAR)SystemTime.Weekday);
|
|
||||||
|
|
||||||
/* Encode the Century byte */
|
|
||||||
Century = DECIMAL_TO_BCD(Century);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Freeze the RTC to prevent data tearing */
|
|
||||||
HL::Firmware::WriteCmosRegister(CMOS_REGISTER_B, RegisterB | CMOS_REGISTER_B_SET_CLOCK);
|
|
||||||
|
|
||||||
/* Push the formatted time values into the hardware registers */
|
|
||||||
HL::Firmware::WriteCmosRegister(CMOS_REGISTER_HOUR, SystemTime.Hour);
|
|
||||||
HL::Firmware::WriteCmosRegister(CMOS_REGISTER_MINUTE, SystemTime.Minute);
|
|
||||||
HL::Firmware::WriteCmosRegister(CMOS_REGISTER_SECOND, SystemTime.Second);
|
|
||||||
HL::Firmware::WriteCmosRegister(CMOS_REGISTER_DAY, SystemTime.Day);
|
|
||||||
HL::Firmware::WriteCmosRegister(CMOS_REGISTER_MONTH, SystemTime.Month);
|
|
||||||
HL::Firmware::WriteCmosRegister(CMOS_REGISTER_YEAR, SystemTime.Year);
|
|
||||||
HL::Firmware::WriteCmosRegister(CMOS_REGISTER_WEEKDAY, SystemTime.Weekday);
|
|
||||||
|
|
||||||
/* Check if Century register is available */
|
|
||||||
if(CenturyRegister)
|
|
||||||
{
|
|
||||||
/* Write the corresponding Century register */
|
|
||||||
HL::Firmware::WriteCmosRegister(CenturyRegister, Century);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unfreeze the RTC */
|
|
||||||
HL::Firmware::WriteCmosRegister(CMOS_REGISTER_B, RegisterB);
|
|
||||||
|
|
||||||
/* Return success status code */
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
#include XTOS_ARCH_HEADER(ar, asmsup.hh)
|
#include XTOS_ARCH_HEADER(ar, assembly.hh)
|
||||||
#include XTOS_ARCH_HEADER(ar, cpufunc.hh)
|
#include XTOS_ARCH_HEADER(ar, cpufunc.hh)
|
||||||
#include XTOS_ARCH_HEADER(ar, procsup.hh)
|
#include XTOS_ARCH_HEADER(ar, procsup.hh)
|
||||||
#include XTOS_ARCH_HEADER(ar, traps.hh)
|
#include XTOS_ARCH_HEADER(ar, traps.hh)
|
||||||
|
|||||||
66
xtoskrnl/includes/ar/amd64/asmsup.h
Normal file
66
xtoskrnl/includes/ar/amd64/asmsup.h
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/**
|
||||||
|
* PROJECT: ExectOS
|
||||||
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
|
* FILE: xtoskrnl/includes/amd64/asm.h
|
||||||
|
* DESCRIPTION: AMD64 architecture assembly definitions
|
||||||
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __XTOSKRNL_AMD64_ASMSUP_H
|
||||||
|
#define __XTOSKRNL_AMD64_ASMSUP_H
|
||||||
|
|
||||||
|
|
||||||
|
/* Control Register bit definitions */
|
||||||
|
#define CR0_PG 0x80000000
|
||||||
|
#define CR4_PGE 0x00000080
|
||||||
|
#define CR4_LA57 0x00001000
|
||||||
|
#define CR4_PCIDE 0x00020000
|
||||||
|
|
||||||
|
/* GDT selectors */
|
||||||
|
#define GDT_R0_CMCODE 0x08
|
||||||
|
#define GDT_R0_CODE 0x10
|
||||||
|
#define GDT_R0_DATA 0x18
|
||||||
|
|
||||||
|
/* MSR registers */
|
||||||
|
#define X86_MSR_EFER 0xC0000080
|
||||||
|
#define X86_MSR_EFER_LME (1 << 8)
|
||||||
|
|
||||||
|
/* KTRAP_FRAME structure offsets */
|
||||||
|
#define TrapXmm0 0
|
||||||
|
#define TrapXmm1 16
|
||||||
|
#define TrapXmm2 32
|
||||||
|
#define TrapXmm3 48
|
||||||
|
#define TrapXmm4 64
|
||||||
|
#define TrapXmm5 80
|
||||||
|
#define TrapXmm6 96
|
||||||
|
#define TrapXmm7 112
|
||||||
|
#define TrapXmm8 128
|
||||||
|
#define TrapXmm9 144
|
||||||
|
#define TrapXmm10 160
|
||||||
|
#define TrapXmm11 176
|
||||||
|
#define TrapXmm12 192
|
||||||
|
#define TrapXmm13 208
|
||||||
|
#define TrapXmm14 224
|
||||||
|
#define TrapXmm15 240
|
||||||
|
#define TrapMxCsr 256
|
||||||
|
#define TrapPreviousMode 260
|
||||||
|
#define TrapCr2 264
|
||||||
|
#define TrapCr3 272
|
||||||
|
#define TrapDr0 280
|
||||||
|
#define TrapDr1 288
|
||||||
|
#define TrapDr2 296
|
||||||
|
#define TrapDr3 304
|
||||||
|
#define TrapDr6 312
|
||||||
|
#define TrapDr7 320
|
||||||
|
#define TrapSegDs 328
|
||||||
|
#define TrapSegEs 330
|
||||||
|
#define TrapSegFs 332
|
||||||
|
#define TrapSegGs 334
|
||||||
|
#define TrapRsp 496
|
||||||
|
#define TrapSegSs 504
|
||||||
|
|
||||||
|
/* KTRAP_FRAME length related definitions */
|
||||||
|
#define TRAP_FRAME_SIZE 512
|
||||||
|
#define TRAP_REGISTERS_SIZE 176
|
||||||
|
|
||||||
|
#endif /* __XTOSKRNL_AMD64_ASMSUP_H */
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/includes/ar/amd64/asmsup.hh
|
|
||||||
* DESCRIPTION: Architecture-specific assembler prototypes
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __XTOSKRNL_AR_ASMSUP_HH
|
|
||||||
#define __XTOSKRNL_AR_ASMSUP_HH
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/* TrampolineEnableXpa end address to calculate trampoline size */
|
|
||||||
XTCLINK PVOID ArEnableExtendedPhysicalAddressingEnd[];
|
|
||||||
|
|
||||||
/* External array of pointers to the interrupt handlers */
|
|
||||||
XTCLINK ULONG_PTR ArInterruptEntry[256];
|
|
||||||
|
|
||||||
/* TrampolineApStartup end address to calculate trampoline size */
|
|
||||||
XTCLINK PVOID ArStartApplicationProcessorEnd[];
|
|
||||||
|
|
||||||
/* External array of pointers to the trap handlers */
|
|
||||||
XTCLINK ULONG_PTR ArTrapEntry[256];
|
|
||||||
|
|
||||||
/* Forward reference for assembler code */
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArEnableExtendedPhysicalAddressing(IN ULONG_PTR PageMap);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArHandleSpuriousInterrupt(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArStartApplicationProcessor(VOID);
|
|
||||||
|
|
||||||
#endif /* __XTOSKRNL_AR_ASMSUP_HH */
|
|
||||||
158
xtoskrnl/includes/ar/amd64/assembly.hh
Normal file
158
xtoskrnl/includes/ar/amd64/assembly.hh
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
/**
|
||||||
|
* PROJECT: ExectOS
|
||||||
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
|
* FILE: xtoskrnl/includes/ar/amd64/assembly.hh
|
||||||
|
* DESCRIPTION: Architecture-specific assembler prototypes
|
||||||
|
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __XTOSKRNL_AR_ASSEMBLY_HH
|
||||||
|
#define __XTOSKRNL_AR_ASSEMBLY_HH
|
||||||
|
|
||||||
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
|
/* TrampolineEnableXpa end address to calculate trampoline size */
|
||||||
|
XTCLINK PVOID ArEnableExtendedPhysicalAddressingEnd[];
|
||||||
|
|
||||||
|
/* TrampolineApStartup end address to calculate trampoline size */
|
||||||
|
XTCLINK PVOID ArStartApplicationProcessorEnd[];
|
||||||
|
|
||||||
|
|
||||||
|
/* Forward reference for assembler code */
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArEnableExtendedPhysicalAddressing(IN ULONG_PTR PageMap);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArStartApplicationProcessor(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x00(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x01(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x02(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x03(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x04(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x05(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x06(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x07(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x08(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x09(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x0A(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x0B(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x0C(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x0D(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x0E(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x10(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x11(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x12(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x13(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x1F(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x2C(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x2D(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x2F(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0xE1(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0xFF(VOID);
|
||||||
|
|
||||||
|
#endif /* __XTOSKRNL_AR_ASSEMBLY_HH */
|
||||||
@@ -40,7 +40,6 @@ namespace AR
|
|||||||
STATIC XTCDECL ULONGLONG ReadModelSpecificRegister(IN ULONG Register);
|
STATIC XTCDECL ULONGLONG ReadModelSpecificRegister(IN ULONG Register);
|
||||||
STATIC XTCDECL UINT ReadMxCsrRegister(VOID);
|
STATIC XTCDECL UINT ReadMxCsrRegister(VOID);
|
||||||
STATIC XTCDECL ULONGLONG ReadTimeStampCounter(VOID);
|
STATIC XTCDECL ULONGLONG ReadTimeStampCounter(VOID);
|
||||||
STATIC XTCDECL ULONGLONG ReadTimeStampCounterProcessor(OUT PULONG TscAux);
|
|
||||||
STATIC XTCDECL VOID ReadWriteBarrier(VOID);
|
STATIC XTCDECL VOID ReadWriteBarrier(VOID);
|
||||||
STATIC XTCDECL VOID SetInterruptFlag(VOID);
|
STATIC XTCDECL VOID SetInterruptFlag(VOID);
|
||||||
STATIC XTCDECL VOID StoreGlobalDescriptorTable(OUT PVOID Destination);
|
STATIC XTCDECL VOID StoreGlobalDescriptorTable(OUT PVOID Destination);
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ namespace AR
|
|||||||
STATIC KIDTENTRY InitialIdt[IDT_ENTRIES];
|
STATIC KIDTENTRY InitialIdt[IDT_ENTRIES];
|
||||||
STATIC KPROCESSOR_BLOCK InitialProcessorBlock;
|
STATIC KPROCESSOR_BLOCK InitialProcessorBlock;
|
||||||
STATIC KTSS InitialTss;
|
STATIC KTSS InitialTss;
|
||||||
STATIC UCHAR NmiStack[KERNEL_STACK_SIZE];
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
STATIC XTAPI PVOID GetBootStack(VOID);
|
STATIC XTAPI PVOID GetBootStack(VOID);
|
||||||
@@ -32,24 +31,9 @@ namespace AR
|
|||||||
OUT PVOID *TrampolineCode,
|
OUT PVOID *TrampolineCode,
|
||||||
OUT PULONG_PTR TrampolineSize);
|
OUT PULONG_PTR TrampolineSize);
|
||||||
STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures);
|
STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures);
|
||||||
STATIC XTAPI VOID InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
|
||||||
OUT PKGDTENTRY *Gdt,
|
|
||||||
OUT PKTSS *Tss,
|
|
||||||
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
|
||||||
OUT PVOID *KernelBootStack,
|
|
||||||
OUT PVOID *KernelFaultStack,
|
|
||||||
OUT PVOID *KernelNmiStack);
|
|
||||||
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
|
|
||||||
IN USHORT Vector,
|
|
||||||
IN PVOID Handler,
|
|
||||||
IN USHORT Selector,
|
|
||||||
IN USHORT Ist,
|
|
||||||
IN USHORT Dpl,
|
|
||||||
IN USHORT Type);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
STATIC XTAPI VOID IdentifyProcessor(VOID);
|
STATIC XTAPI VOID IdentifyProcessor(VOID);
|
||||||
STATIC XTAPI VOID IdentifyProcessorFeatures(VOID);
|
|
||||||
STATIC XTAPI VOID InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock);
|
STATIC XTAPI VOID InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock);
|
||||||
STATIC XTAPI VOID InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock);
|
STATIC XTAPI VOID InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock);
|
||||||
STATIC XTAPI VOID InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
|
STATIC XTAPI VOID InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
|
||||||
@@ -58,11 +42,16 @@ namespace AR
|
|||||||
IN PKTSS Tss,
|
IN PKTSS Tss,
|
||||||
IN PVOID DpcStack);
|
IN PVOID DpcStack);
|
||||||
STATIC XTAPI VOID InitializeProcessorRegisters(VOID);
|
STATIC XTAPI VOID InitializeProcessorRegisters(VOID);
|
||||||
|
STATIC XTAPI VOID InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
||||||
|
OUT PKGDTENTRY *Gdt,
|
||||||
|
OUT PKTSS *Tss,
|
||||||
|
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
||||||
|
OUT PVOID *KernelBootStack,
|
||||||
|
OUT PVOID *KernelFaultStack);
|
||||||
STATIC XTAPI VOID InitializeSegments(VOID);
|
STATIC XTAPI VOID InitializeSegments(VOID);
|
||||||
STATIC XTAPI VOID InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
STATIC XTAPI VOID InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||||
IN PVOID KernelBootStack,
|
IN PVOID KernelBootStack,
|
||||||
IN PVOID KernelFaultStack,
|
IN PVOID KernelFaultStack);
|
||||||
IN PVOID KernelNmiStack);
|
|
||||||
STATIC XTAPI VOID SetGdtEntry(IN PKGDTENTRY Gdt,
|
STATIC XTAPI VOID SetGdtEntry(IN PKGDTENTRY Gdt,
|
||||||
IN USHORT Selector,
|
IN USHORT Selector,
|
||||||
IN ULONG_PTR Base,
|
IN ULONG_PTR Base,
|
||||||
@@ -73,6 +62,13 @@ namespace AR
|
|||||||
STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
||||||
IN USHORT Selector,
|
IN USHORT Selector,
|
||||||
IN ULONG_PTR Base);
|
IN ULONG_PTR Base);
|
||||||
|
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
|
||||||
|
IN USHORT Vector,
|
||||||
|
IN PVOID Handler,
|
||||||
|
IN USHORT Selector,
|
||||||
|
IN USHORT Ist,
|
||||||
|
IN USHORT Dpl,
|
||||||
|
IN USHORT Type);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,14 +17,9 @@ namespace AR
|
|||||||
{
|
{
|
||||||
class Traps
|
class Traps
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
STATIC PINTERRUPT_HANDLER UnhandledInterruptRoutine;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
STATIC XTCDECL VOID DispatchInterrupt(IN PKTRAP_FRAME TrapFrame) XTSYMBOL("ArDispatchInterrupt");
|
STATIC XTCDECL VOID DispatchTrap(IN PKTRAP_FRAME TrapFrame);
|
||||||
STATIC XTCDECL VOID DispatchTrap(IN PKTRAP_FRAME TrapFrame) XTSYMBOL("ArDispatchTrap");
|
|
||||||
STATIC XTCDECL VOID InitializeSystemCallMsrs(VOID);
|
STATIC XTCDECL VOID InitializeSystemCallMsrs(VOID);
|
||||||
STATIC XTCDECL VOID SetUnhandledInterruptRoutine(PINTERRUPT_HANDLER Handler);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
STATIC XTCDECL VOID HandleSystemCall32(VOID);
|
STATIC XTCDECL VOID HandleSystemCall32(VOID);
|
||||||
|
|||||||
34
xtoskrnl/includes/ar/i686/asmsup.h
Normal file
34
xtoskrnl/includes/ar/i686/asmsup.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* PROJECT: ExectOS
|
||||||
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
|
* FILE: xtoskrnl/includes/i686/asm.h
|
||||||
|
* DESCRIPTION: i686 architecture assembly definitions
|
||||||
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __XTOSKRNL_I686_ASMSUP_H
|
||||||
|
#define __XTOSKRNL_I686_ASMSUP_H
|
||||||
|
|
||||||
|
|
||||||
|
/* KTRAP_FRAME structure offsets */
|
||||||
|
#define TrapPreviousMode 0
|
||||||
|
#define TrapCr2 4
|
||||||
|
#define TrapCr3 8
|
||||||
|
#define TrapDr0 12
|
||||||
|
#define TrapDr1 16
|
||||||
|
#define TrapDr2 20
|
||||||
|
#define TrapDr3 24
|
||||||
|
#define TrapDr6 28
|
||||||
|
#define TrapDr7 32
|
||||||
|
#define TrapSegDs 36
|
||||||
|
#define TrapSegEs 38
|
||||||
|
#define TrapSegFs 40
|
||||||
|
#define TrapSegGs 42
|
||||||
|
#define TrapEsp 92
|
||||||
|
#define TrapSegSs 96
|
||||||
|
|
||||||
|
/* KTRAP_FRAME length related definitions */
|
||||||
|
#define TRAP_FRAME_SIZE 100
|
||||||
|
#define TRAP_REGISTERS_SIZE 56
|
||||||
|
|
||||||
|
#endif /* __XTOSKRNL_I686_ASMSUP_H */
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtoskrnl/includes/ar/i686/asmsup.hh
|
|
||||||
* DESCRIPTION: Architecture-specific assembler prototypes
|
|
||||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __XTOSKRNL_AR_ASMSUP_HH
|
|
||||||
#define __XTOSKRNL_AR_ASMSUP_HH
|
|
||||||
|
|
||||||
#include <xtos.hh>
|
|
||||||
|
|
||||||
|
|
||||||
/* TrampolineEnableXpa end address to calculate trampoline size */
|
|
||||||
XTCLINK PVOID ArEnableExtendedPhysicalAddressingEnd[];
|
|
||||||
|
|
||||||
/* External array of pointers to the interrupt handlers */
|
|
||||||
XTCLINK ULONG_PTR ArInterruptEntry[256];
|
|
||||||
|
|
||||||
/* TrampolineApStartup end address to calculate trampoline size */
|
|
||||||
XTCLINK PVOID ArStartApplicationProcessorEnd[];
|
|
||||||
|
|
||||||
/* External array of pointers to the trap handlers */
|
|
||||||
XTCLINK ULONG_PTR ArTrapEntry[256];
|
|
||||||
|
|
||||||
/* Forward reference for assembler code */
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArEnableExtendedPhysicalAddressing(IN ULONG_PTR PageMap);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArHandleSpuriousInterrupt(VOID);
|
|
||||||
|
|
||||||
XTCLINK
|
|
||||||
XTCDECL
|
|
||||||
VOID
|
|
||||||
ArStartApplicationProcessor(VOID);
|
|
||||||
|
|
||||||
#endif /* __XTOSKRNL_AR_ASMSUP_HH */
|
|
||||||
151
xtoskrnl/includes/ar/i686/assembly.hh
Normal file
151
xtoskrnl/includes/ar/i686/assembly.hh
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
/**
|
||||||
|
* PROJECT: ExectOS
|
||||||
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
|
* FILE: xtoskrnl/includes/ar/i686/assembly.hh
|
||||||
|
* DESCRIPTION: Architecture-specific assembler prototypes
|
||||||
|
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __XTOSKRNL_AR_ASSEMBLY_HH
|
||||||
|
#define __XTOSKRNL_AR_ASSEMBLY_HH
|
||||||
|
|
||||||
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
|
/* TrampolineApStartup end address to calculate trampoline size */
|
||||||
|
XTCLINK PVOID ArStartApplicationProcessorEnd[];
|
||||||
|
|
||||||
|
|
||||||
|
/* Forward reference for assembler code */
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArStartApplicationProcessor(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x00(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x01(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x02(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x03(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x04(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x05(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x06(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x07(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x08(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x09(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x0A(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x0B(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x0C(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x0D(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x0E(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x10(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x11(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x12(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x13(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x2A(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x2B(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x2C(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x2D(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0x2E(VOID);
|
||||||
|
|
||||||
|
XTCLINK
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
ArTrap0xFF(VOID);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __XTOSKRNL_AR_ASSEMBLY_HH */
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user