Compare commits
211 Commits
master
...
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_BINARY_DIR="${EXECTOS_BINARY_DIR}")
|
||||
|
||||
# Add assembler flags
|
||||
add_compiler_asmflags(-D__XTOS_ASSEMBLER__)
|
||||
|
||||
# Compute __FILE__ definition
|
||||
file(RELATIVE_PATH _PATH_PREFIX ${EXECTOS_BINARY_DIR} ${EXECTOS_SOURCE_DIR})
|
||||
add_compiler_flags(-D__RELFILE__="&__FILE__[__FILE__[0] == '.' ? sizeof \\\"${_PATH_PREFIX}\\\" - 1 : sizeof XTOS_SOURCE_DIR]")
|
||||
|
||||
@@ -221,15 +221,10 @@ Console::QueryMode(OUT PUINT_PTR ResX,
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
VOID
|
||||
Console::ReadKeyStroke(OUT PEFI_INPUT_KEY Key)
|
||||
{
|
||||
/* Clear the key structure to prevent ghost keystrokes */
|
||||
Key->ScanCode = 0;
|
||||
Key->UnicodeChar = 0;
|
||||
|
||||
/* Read the keystroke from the EFI input console */
|
||||
return XtLoader::GetEfiSystemTable()->ConIn->ReadKeyStroke(XtLoader::GetEfiSystemTable()->ConIn, Key);
|
||||
XtLoader::GetEfiSystemTable()->ConIn->ReadKeyStroke(XtLoader::GetEfiSystemTable()->ConIn, Key);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -56,21 +56,6 @@ XTBL_LOADER_PROTOCOL Protocol::LoaderProtocol;
|
||||
/* XT Boot Loader loaded modules list */
|
||||
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_ENTRY Volume::EfiBlockDevices;
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ class Console
|
||||
STATIC XTCDECL XTSTATUS PutChar(IN WCHAR Character);
|
||||
STATIC XTCDECL VOID QueryMode(OUT PUINT_PTR ResX,
|
||||
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 SetAttributes(IN ULONGLONG Attributes);
|
||||
STATIC XTCDECL VOID SetCursorPosition(IN ULONGLONG PosX,
|
||||
@@ -253,47 +253,11 @@ class Protocol
|
||||
|
||||
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:
|
||||
STATIC XTCDECL EFI_STATUS RegisterCommand(IN PCWSTR Command,
|
||||
IN PCWSTR Description,
|
||||
IN PBL_SHELL_COMMAND Handler);
|
||||
STATIC XTCDECL VOID StartLoaderShell();
|
||||
|
||||
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 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
|
||||
|
||||
@@ -302,7 +302,6 @@ Protocol::LoadModule(IN PWCHAR ModuleName)
|
||||
PXTBL_MODULE_DEPS ModuleDependency;
|
||||
PXTBL_MODULE_INFO ModuleInfo;
|
||||
WCHAR ModuleFileName[24];
|
||||
ULONG ModuleNameLength;
|
||||
USHORT SectionIndex;
|
||||
PWCHAR SectionData;
|
||||
SIZE_T ModuleSize;
|
||||
@@ -329,11 +328,8 @@ Protocol::LoadModule(IN PWCHAR ModuleName)
|
||||
/* Print debug message */
|
||||
Debug::Print(L"Loading module '%S' ...\n", ModuleName);
|
||||
|
||||
/* Calculate module name length */
|
||||
ModuleNameLength = RTL::WideString::WideStringLength(ModuleName, 0) + 1;
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Open EFI volume */
|
||||
@@ -442,8 +438,7 @@ Protocol::LoadModule(IN PWCHAR ModuleName)
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to load module, print error message and return status code */
|
||||
Debug::Print(L"Failed to load dependency module '%S' (Status Code: 0x%zX)\n",
|
||||
ModuleDependency->ModuleName, Status);
|
||||
Debug::Print(L"Failed to load dependency module '%S' (Status Code: 0x%zX)\n", ModuleDependency->ModuleName, Status);
|
||||
return STATUS_EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@@ -506,19 +501,8 @@ Protocol::LoadModule(IN PWCHAR ModuleName)
|
||||
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 */
|
||||
ModuleInfo->ModuleName = ModuleName;
|
||||
ModuleInfo->ModuleBase = LoadedImage->ImageBase;
|
||||
ModuleInfo->ModuleSize = LoadedImage->ImageSize;
|
||||
ModuleInfo->Revision = LoadedImage->Revision;
|
||||
@@ -1093,7 +1077,6 @@ Protocol::InstallXtLoaderProtocol()
|
||||
LoaderProtocol.Protocol.LocateHandles = LocateProtocolHandles;
|
||||
LoaderProtocol.Protocol.Open = OpenProtocol;
|
||||
LoaderProtocol.Protocol.OpenHandle = OpenProtocolHandle;
|
||||
LoaderProtocol.Shell.RegisterCommand = Shell::RegisterCommand;
|
||||
LoaderProtocol.String.Compare = RTL::String::CompareString;
|
||||
LoaderProtocol.String.Length = RTL::String::StringLength;
|
||||
LoaderProtocol.String.ToWideString = RTL::String::StringToWideString;
|
||||
|
||||
@@ -4,21 +4,13 @@
|
||||
* FILE: xtldr/shell.cc
|
||||
* DESCRIPTION: XT Boot Loader shell
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtldr.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Implements the built-in `exit` command. Sets the exit flag to signal the main
|
||||
* 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.
|
||||
* Starts XTLDR shell.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
@@ -26,410 +18,14 @@
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
Shell::CommandExit(IN ULONG Argc,
|
||||
IN PWCHAR *Argv)
|
||||
Shell::StartLoaderShell()
|
||||
{
|
||||
/* Signal the main shell loop to stop and return to the boot menu */
|
||||
ExitRequest = TRUE;
|
||||
}
|
||||
/* Initialize console */
|
||||
Console::InitializeConsole();
|
||||
|
||||
/**
|
||||
* Implements the built-in `help` command. Prints a list of available commands alongside their descriptions.
|
||||
*
|
||||
* @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;
|
||||
/* Print prompt */
|
||||
PrintPrompt();
|
||||
for(;;);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -446,486 +42,9 @@ Shell::PrintPrompt()
|
||||
/* Set prompt color */
|
||||
Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_YELLOW);
|
||||
|
||||
/* Print prompt at the start of the line */
|
||||
Console::Print(L"\rXTLDR> ");
|
||||
/* Print prompt */
|
||||
Console::Print(L"XTLDR> ");
|
||||
|
||||
/* Reset standard shell colors */
|
||||
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;
|
||||
}
|
||||
}
|
||||
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::ClearLine(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::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
|
||||
Console::Print(L" Use cursors to change the selection. Press ENTER key to edit the chosen\n"
|
||||
L" option, ESC to return to the main boot menu or 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")
|
||||
|
||||
@@ -59,86 +59,6 @@ function(add_module_linker_flags MODULE FLAGS)
|
||||
set_module_property(${MODULE} LINK_FLAGS ${FLAGS})
|
||||
endfunction()
|
||||
|
||||
# This function compiles XT Assembly Development Kit
|
||||
function(generate_xtadk TARGET_NAME SOURCE_FILES)
|
||||
# Define the absolute destination path for the generated header file
|
||||
set(HEADER_OUTPUT "${EXECTOS_BINARY_DIR}/sdk/includes/${TARGET_NAME}.h")
|
||||
get_filename_component(HEADER_OUTPUT_DIRECTORY "${HEADER_OUTPUT}" DIRECTORY)
|
||||
|
||||
# Tokenize global CXX flags into a list to ensure correct argument expansion
|
||||
separate_arguments(COMPILER_FLAGS NATIVE_COMMAND "${CMAKE_CXX_FLAGS}")
|
||||
|
||||
# Resolve and tokenize build-configuration specific flags
|
||||
string(TOUPPER "${CMAKE_BUILD_TYPE}" BUILD_TYPE)
|
||||
if(BUILD_TYPE)
|
||||
separate_arguments(BUILD_TYPE_SPECIFIC_FLAGS NATIVE_COMMAND "${CMAKE_CXX_FLAGS_${BUILD_TYPE}}")
|
||||
endif()
|
||||
|
||||
# Retrieve compiler definitions, include paths, and options
|
||||
get_directory_property(COMPILE_DEFINITIONS COMPILE_DEFINITIONS)
|
||||
get_directory_property(INCLUDE_DIRECTORIES INCLUDE_DIRECTORIES)
|
||||
get_directory_property(COMPILE_OPTIONS COMPILE_OPTIONS)
|
||||
|
||||
# Initialize the final compiler argument list
|
||||
set(COMPILER_ARGUMENTS "")
|
||||
list(APPEND COMPILER_ARGUMENTS ${COMPILER_FLAGS} ${BUILD_TYPE_SPECIFIC_FLAGS})
|
||||
|
||||
# Transform definitions into MSVC-style
|
||||
foreach(DEFINITION ${COMPILE_DEFINITIONS})
|
||||
list(APPEND COMPILER_ARGUMENTS "/D${DEFINITION}")
|
||||
endforeach()
|
||||
|
||||
# Transform include paths into MSVC-style
|
||||
foreach(INCLUDE_PATH ${INCLUDE_DIRECTORIES})
|
||||
list(APPEND COMPILER_ARGUMENTS "/I${INCLUDE_PATH}")
|
||||
endforeach()
|
||||
|
||||
# Append all supplemental compiler options
|
||||
list(APPEND COMPILER_ARGUMENTS ${COMPILE_OPTIONS})
|
||||
set(COLLECTED_ASSEMBLY_OUTPUTS "")
|
||||
|
||||
# Iterate through each source file to create individual assembly generation rules
|
||||
foreach(SOURCE_FILE_PATH ${SOURCE_FILES})
|
||||
# Extract the base filename
|
||||
get_filename_component(FILENAME_WITHOUT_EXTENSION "${SOURCE_FILE_PATH}" NAME_WE)
|
||||
|
||||
# Define the unique output path for the intermediate assembly file
|
||||
set(CURRENT_ASSEMBLY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FILENAME_WITHOUT_EXTENSION}.S")
|
||||
list(APPEND COLLECTED_ASSEMBLY_OUTPUTS "${CURRENT_ASSEMBLY_OUTPUT}")
|
||||
get_filename_component(CURRENT_ASSEMBLY_DIRECTORY "${CURRENT_ASSEMBLY_OUTPUT}" DIRECTORY)
|
||||
|
||||
# Execute the compiler to generate assembly code
|
||||
add_custom_command(
|
||||
OUTPUT "${CURRENT_ASSEMBLY_OUTPUT}"
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${CURRENT_ASSEMBLY_DIRECTORY}"
|
||||
COMMAND ${CMAKE_CXX_COMPILER}
|
||||
${COMPILER_ARGUMENTS}
|
||||
/c /FAs /Fa${CURRENT_ASSEMBLY_OUTPUT}
|
||||
-- ${SOURCE_FILE_PATH}
|
||||
DEPENDS "${SOURCE_FILE_PATH}"
|
||||
COMMENT "Generating XTADK Assembly: ${FILENAME_WITHOUT_EXTENSION}"
|
||||
VERBATIM
|
||||
COMMAND_EXPAND_LISTS
|
||||
)
|
||||
endforeach()
|
||||
|
||||
# Aggregate all generated assembly units into a single consolidated XTADK header
|
||||
add_custom_command(
|
||||
OUTPUT "${HEADER_OUTPUT}"
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${HEADER_OUTPUT_DIRECTORY}"
|
||||
COMMAND xtadkgen ${COLLECTED_ASSEMBLY_OUTPUTS} -O "${HEADER_OUTPUT}"
|
||||
DEPENDS ${COLLECTED_ASSEMBLY_OUTPUTS}
|
||||
COMMENT "Generating XTADK header: ${TARGET_NAME}"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# Establish the generation target and expose the header directory via an interface library
|
||||
add_custom_target(${TARGET_NAME}_gen DEPENDS "${HEADER_OUTPUT}")
|
||||
add_library(${TARGET_NAME} INTERFACE)
|
||||
add_dependencies(${TARGET_NAME} ${TARGET_NAME}_gen)
|
||||
target_include_directories(${TARGET_NAME} INTERFACE "${EXECTOS_BINARY_DIR}/sdk/includes")
|
||||
endfunction()
|
||||
|
||||
# This function compiles an assembly bootsector file into a flat binary
|
||||
function(compile_bootsector NAME SOURCE BASEADDR ENTRYPOINT)
|
||||
set(BINARY_NAME "${NAME}.bin")
|
||||
|
||||
@@ -13,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
|
||||
a virtual machine, allowing it to maintain its configuration across multiple boot sessions.
|
||||
|
||||
## BOCHS ROM BIOS
|
||||
The rombios.bin file contains the ROM BIOS image for Bochs. This image is distributed under the GNU Lesser General Public
|
||||
License (LGPL).
|
||||
|
||||
## Video BIOS (LGPL'd VGABios)
|
||||
The vgabios.bin file contains the Video Bios for Bochs and QEMU. This VGA Bios is very specific to the emulated VGA card.
|
||||
It is NOT meant to drive a physical vga card. It also implements support for VBE version 2.0.
|
||||
|
||||
@@ -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,83 +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);
|
||||
}
|
||||
@@ -1,57 +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);
|
||||
}
|
||||
@@ -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 <xtstruct.h>
|
||||
#include <xttypes.h>
|
||||
#include ARCH_HEADER(xtstruct.h)
|
||||
|
||||
|
||||
/* Control Register 0 constants */
|
||||
@@ -128,10 +127,6 @@
|
||||
#define X86_EFLAGS_VIP_MASK 0x00100000 /* Virtual Interrupt Pending */
|
||||
#define X86_EFLAGS_ID_MASK 0x00200000 /* Identification */
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* CPU vendor enumeration list */
|
||||
typedef enum _CPU_VENDOR
|
||||
{
|
||||
@@ -140,18 +135,6 @@ typedef enum _CPU_VENDOR
|
||||
CPU_VENDOR_UNKNOWN = 0xFFFFFFFF
|
||||
} CPU_VENDOR, *PCPU_VENDOR;
|
||||
|
||||
/* CPUID advanced power management features (0x80000007) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT
|
||||
{
|
||||
CPUID_FEATURES_EDX_TS = 1 << 0, /* Temperature Sensor */
|
||||
CPUID_FEATURES_EDX_FIS = 1 << 1, /* Frequency ID Selection */
|
||||
CPUID_FEATURES_EDX_VIS = 1 << 2, /* Voltage ID Selection */
|
||||
CPUID_FEATURES_EDX_TTS = 1 << 3, /* ThermaTrip Support */
|
||||
CPUID_FEATURES_EDX_HTC = 1 << 4, /* Hardware Thermal Throttling */
|
||||
CPUID_FEATURES_EDX_STC = 1 << 5, /* Software Thermal Throttling */
|
||||
CPUID_FEATURES_EDX_TSCI = 1 << 8 /* TSC Invariant */
|
||||
} CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT, *PCPUID_FEATURES_ADVANCED_POWER_MANAGEMENT;
|
||||
|
||||
/* CPUID extended features (0x80000001) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_EXTENDED
|
||||
{
|
||||
@@ -193,23 +176,6 @@ typedef enum _CPUID_FEATURES_EXTENDED
|
||||
CPUID_FEATURES_EDX_3DNOW = 1 << 31
|
||||
} CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
|
||||
|
||||
/* CPUID Thermal and Power Management features (0x00000006) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_POWER_MANAGEMENT
|
||||
{
|
||||
CPUID_FEATURES_EAX_DTHERM = 1 << 0,
|
||||
CPUID_FEATURES_EAX_IDA = 1 << 1,
|
||||
CPUID_FEATURES_EAX_ARAT = 1 << 2,
|
||||
CPUID_FEATURES_EAX_PLN = 1 << 4,
|
||||
CPUID_FEATURES_EAX_PTS = 1 << 6,
|
||||
CPUID_FEATURES_EAX_HWP = 1 << 7,
|
||||
CPUID_FEATURES_EAX_HWP_NOTIFY = 1 << 8,
|
||||
CPUID_FEATURES_EAX_HWP_ACT_WINDOW = 1 << 9,
|
||||
CPUID_FEATURES_EAX_HWP_EPP = 1 << 10,
|
||||
CPUID_FEATURES_EAX_HWP_PKG_REQ = 1 << 11,
|
||||
CPUID_FEATURES_EAX_HWP_HIGHEST_PERF_CHANGE = 1 << 15,
|
||||
CPUID_FEATURES_EAX_HFI = 1 << 19
|
||||
} CPUID_FEATURES_LEAF6, *PCPUID_FEATURES_LEAF6;
|
||||
|
||||
/* CPUID STD1 features (0x00000001) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_STANDARD1
|
||||
{
|
||||
@@ -236,7 +202,7 @@ typedef enum _CPUID_FEATURES_STANDARD1
|
||||
CPUID_FEATURES_ECX_X2APIC = 1 << 21,
|
||||
CPUID_FEATURES_ECX_MOVBE = 1 << 22,
|
||||
CPUID_FEATURES_ECX_POPCNT = 1 << 23,
|
||||
CPUID_FEATURES_ECX_TSC_DEADLINE = 1 << 24,
|
||||
CPUID_FEATURES_ECX_TSC = 1 << 24,
|
||||
CPUID_FEATURES_ECX_AES = 1 << 25,
|
||||
CPUID_FEATURES_ECX_XSAVE = 1 << 26,
|
||||
CPUID_FEATURES_ECX_OSXSAVE = 1 << 27,
|
||||
@@ -410,23 +376,16 @@ typedef enum _CPUID_FEATURES_STANDARD7_LEAF1
|
||||
/* CPUID requests */
|
||||
typedef enum _CPUID_REQUESTS
|
||||
{
|
||||
CPUID_GET_VENDOR_STRING = 0x00000000,
|
||||
CPUID_GET_STANDARD1_FEATURES = 0x00000001,
|
||||
CPUID_GET_TLB_CACHE = 0x00000002,
|
||||
CPUID_GET_SERIAL = 0x00000003,
|
||||
CPUID_GET_CACHE_TOPOLOGY = 0x00000004,
|
||||
CPUID_GET_MONITOR_MWAIT = 0x00000005,
|
||||
CPUID_GET_POWER_MANAGEMENT = 0x00000006,
|
||||
CPUID_GET_STANDARD7_FEATURES = 0x00000007,
|
||||
CPUID_GET_TSC_CRYSTAL_CLOCK = 0x00000015,
|
||||
CPUID_GET_EXTENDED_MAX = 0x80000000,
|
||||
CPUID_GET_EXTENDED_FEATURES = 0x80000001,
|
||||
CPUID_GET_ADVANCED_POWER_MANAGEMENT = 0x80000007
|
||||
CPUID_GET_VENDOR_STRING,
|
||||
CPUID_GET_STANDARD1_FEATURES,
|
||||
CPUID_GET_TLB_CACHE,
|
||||
CPUID_GET_SERIAL,
|
||||
CPUID_GET_CACHE_TOPOLOGY,
|
||||
CPUID_GET_MONITOR_MWAIT,
|
||||
CPUID_GET_POWER_MANAGEMENT,
|
||||
CPUID_GET_STANDARD7_FEATURES
|
||||
} CPUID_REQUESTS, *PCPUID_REQUESTS;
|
||||
|
||||
/* Interrupt handler */
|
||||
typedef VOID (*PINTERRUPT_HANDLER)(PKTRAP_FRAME TrapFrame);
|
||||
|
||||
/* Processor identification information */
|
||||
typedef struct _CPU_IDENTIFICATION
|
||||
{
|
||||
@@ -467,5 +426,4 @@ typedef enum _TRAMPOLINE_TYPE
|
||||
TrampolineEnableXpa
|
||||
} TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_AMD64_ARTYPES_H */
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
#include <amd64/xtstruct.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Hardware layer routines forward references */
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
@@ -52,5 +49,4 @@ VOID
|
||||
HlWritePort32(IN USHORT Port,
|
||||
IN ULONG Value);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_AMD64_HLFUNCS_H */
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#ifndef __XTDK_AMD64_HLTYPES_H
|
||||
#define __XTDK_AMD64_HLTYPES_H
|
||||
|
||||
#include <xtbase.h>
|
||||
#include <xtdefs.h>
|
||||
#include <xtstruct.h>
|
||||
#include <xttypes.h>
|
||||
@@ -54,27 +53,6 @@
|
||||
/* Maximum number of I/O APICs */
|
||||
#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 */
|
||||
#define PIC1_CONTROL_PORT 0x20
|
||||
#define PIC1_DATA_PORT 0x21
|
||||
@@ -84,87 +62,6 @@
|
||||
/* PIC vector definitions */
|
||||
#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 */
|
||||
#define COMPORT_ADDRESS {0x3F8, 0x2F8, 0x3E8, 0x2E8, 0x5F8, 0x4F8, 0x5E8, 0x4E8}
|
||||
#define COMPORT_COUNT 8
|
||||
@@ -172,17 +69,6 @@
|
||||
/* Initial stall factor */
|
||||
#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 */
|
||||
typedef enum _APIC_DM
|
||||
{
|
||||
@@ -240,7 +126,6 @@ typedef enum _APIC_REGISTER
|
||||
APIC_TICR = 0x38, /* Initial Count Register for Timer */
|
||||
APIC_TCCR = 0x39, /* Current Count Register for Timer */
|
||||
APIC_TDCR = 0x3E, /* Timer Divide Configuration Register */
|
||||
APIC_SIPI = 0x3F, /* Self-IPI Register */
|
||||
APIC_EAFR = 0x40, /* extended APIC Feature register */
|
||||
APIC_EACR = 0x41, /* Extended APIC Control Register */
|
||||
APIC_SEOI = 0x42, /* Specific End Of Interrupt Register */
|
||||
@@ -250,19 +135,6 @@ typedef enum _APIC_REGISTER
|
||||
APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */
|
||||
} APIC_REGISTER, *PAPIC_REGISTER;
|
||||
|
||||
/* APIC Timer Divide enumeration list */
|
||||
typedef enum _APIC_TIMER_DIVISOR
|
||||
{
|
||||
TIMER_DivideBy2 = 0,
|
||||
TIMER_DivideBy4 = 1,
|
||||
TIMER_DivideBy8 = 2,
|
||||
TIMER_DivideBy16 = 3,
|
||||
TIMER_DivideBy32 = 8,
|
||||
TIMER_DivideBy64 = 9,
|
||||
TIMER_DivideBy128 = 10,
|
||||
TIMER_DivideBy1 = 11,
|
||||
} APIC_TIMER_DIVISOR, *PAPIC_TIMER_DIVISOR;
|
||||
|
||||
/* I8259 PIC interrupt mode enumeration list */
|
||||
typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE
|
||||
{
|
||||
@@ -380,40 +252,6 @@ typedef union _APIC_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 */
|
||||
typedef union _PIC_I8259_ICW1
|
||||
{
|
||||
@@ -479,38 +317,4 @@ typedef union _PIC_I8259_ICW4
|
||||
UCHAR Bits;
|
||||
} 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;
|
||||
|
||||
typedef struct _TIMER_CAPABILITIES
|
||||
{
|
||||
BOOLEAN Arat;
|
||||
BOOLEAN Art;
|
||||
BOOLEAN InvariantTsc;
|
||||
BOOLEAN RDTSCP;
|
||||
ULONG TimerFrequency;
|
||||
BOOLEAN TscDeadline;
|
||||
ULONG TscDenominator;
|
||||
ULONG TscNumerator;
|
||||
} TIMER_CAPABILITIES, *PTIMER_CAPABILITIES;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_AMD64_HLTYPES_H */
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
/* GDT selector names */
|
||||
#define KGDT_NULL 0x0000
|
||||
#define KGDT_R0_CMCODE 0x0008
|
||||
#define KGDT_R0_CODE 0x0010
|
||||
#define KGDT_R0_DATA 0x0018
|
||||
#define KGDT_R3_CMCODE 0x0020
|
||||
@@ -47,7 +46,7 @@
|
||||
#define KGDT_DESCRIPTOR_CODE 0x08
|
||||
|
||||
/* 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_DATA (0x10 | KGDT_DESCRIPTOR_READ_WRITE)
|
||||
|
||||
@@ -59,7 +58,6 @@
|
||||
#define KIDT_IST_RESERVED 0
|
||||
#define KIDT_IST_PANIC 1
|
||||
#define KIDT_IST_MCA 2
|
||||
#define KIDT_IST_NMI 3
|
||||
|
||||
/* AMD64 Segment Types */
|
||||
#define AMD64_TASK_GATE 0x5
|
||||
@@ -112,7 +110,6 @@
|
||||
|
||||
/* XTOS Kernel stack size */
|
||||
#define KERNEL_STACK_SIZE 0x8000
|
||||
#define KERNEL_STACKS 3
|
||||
|
||||
/* XTOS Kernel stack guard pages */
|
||||
#define KERNEL_STACK_GUARD_PAGES 1
|
||||
@@ -138,10 +135,6 @@
|
||||
#define NPX_STATE_SCRUB 0x1
|
||||
#define NPX_STATE_SWITCH 0x2
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Floating point state storing structure */
|
||||
typedef struct _FLOATING_SAVE_AREA
|
||||
{
|
||||
@@ -523,7 +516,6 @@ typedef struct _KPROCESSOR_BLOCK
|
||||
KAFFINITY SetMember;
|
||||
ULONG StallScaleFactor;
|
||||
UCHAR CpuNumber;
|
||||
PINTERRUPT_HANDLER InterruptDispatchTable[256];
|
||||
} KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK;
|
||||
|
||||
/* Thread Environment Block (TEB) structure definition */
|
||||
@@ -532,5 +524,4 @@ typedef struct _THREAD_ENVIRONMENT_BLOCK
|
||||
THREAD_INFORMATION_BLOCK InformationBlock;
|
||||
} THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_AMD64_KETYPES_H */
|
||||
|
||||
@@ -101,9 +101,6 @@
|
||||
/* HAL memory pool virtual address start */
|
||||
#define MM_HARDWARE_VA_START 0xFFFFFFFFFFC00000ULL
|
||||
|
||||
/* Kernel shared data address */
|
||||
#define MM_KERNEL_SHARED_DATA_ADDRESS 0xFFFFFFFFFFDF0000ULL
|
||||
|
||||
/* Maximum physical address used by HAL allocations */
|
||||
#define MM_MAXIMUM_PHYSICAL_ADDRESS 0x00000000FFFFFFFFULL
|
||||
|
||||
@@ -122,10 +119,6 @@
|
||||
/* Number of pool tracking tables */
|
||||
#define MM_POOL_TRACKING_TABLES 64
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Page size enumeration list */
|
||||
typedef enum _PAGE_SIZE
|
||||
{
|
||||
@@ -351,5 +344,4 @@ typedef struct _POOL_DESCRIPTOR
|
||||
SIZE_T Reserved;
|
||||
} POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_AMD64_MMTYPES_H */
|
||||
|
||||
@@ -12,20 +12,13 @@
|
||||
#include <xtdefs.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* 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_DSH APIC_DSH, *PAPIC_DSH;
|
||||
typedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE;
|
||||
typedef enum _APIC_REGISTER APIC_REGISTER, *PAPIC_REGISTER;
|
||||
typedef enum _APIC_TIMER_DIVISOR APIC_TIMER_DIVISOR, *PAPIC_TIMER_DIVISOR;
|
||||
typedef enum _CPU_VENDOR CPU_VENDOR, *PCPU_VENDOR;
|
||||
typedef enum _CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT, *PCPUID_FEATURES_ADVANCED_POWER_MANAGEMENT;
|
||||
typedef enum _CPUID_FEATURES_EXTENDED CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
|
||||
typedef enum _CPUID_FEATURES_POWER_MANAGEMENT CPUID_FEATURES_POWER_MANAGEMENT, *PCPUID_FEATURES_POWER_MANAGEMENT;
|
||||
typedef enum _CPUID_FEATURES_STANDARD1 CPUID_FEATURES_STANDARD1, *PCPUID_FEATURES_STANDARD1;
|
||||
typedef enum _CPUID_FEATURES_STANDARD7_LEAF0 CPUID_FEATURES_STANDARD7_LEAF0, *PCPUID_FEATURES_STANDARD7_LEAF0;
|
||||
typedef enum _CPUID_FEATURES_STANDARD7_LEAF1 CPUID_FEATURES_STANDARD7_LEAF1, *PCPUID_FEATURES_STANDARD7_LEAF1;
|
||||
@@ -46,8 +39,6 @@ typedef struct _CPUID_REGISTERS CPUID_REGISTERS, *PCPUID_REGISTERS;
|
||||
typedef struct _CPUID_SIGNATURE CPUID_SIGNATURE, *PCPUID_SIGNATURE;
|
||||
typedef struct _FLOATING_SAVE_AREA FLOATING_SAVE_AREA, *PFLOATING_SAVE_AREA;
|
||||
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 _KEXCEPTION_FRAME KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;
|
||||
typedef struct _KGDTENTRY KGDTENTRY, *PKGDTENTRY;
|
||||
@@ -72,14 +63,12 @@ typedef struct _MMPTE_SUBSECTION MMPTE_SUBSECTION, *PMMPTE_SUBSECTION;
|
||||
typedef struct _MMPTE_TRANSITION MMPTE_TRANSITION, *PMMPTE_TRANSITION;
|
||||
typedef struct _POOL_DESCRIPTOR POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
||||
typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
||||
typedef struct _TIMER_CAPABILITIES TIMER_CAPABILITIES, *PTIMER_CAPABILITIES;
|
||||
|
||||
/* Unions forward references */
|
||||
typedef union _APIC_BASE_REGISTER APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER;
|
||||
typedef union _APIC_COMMAND_REGISTER APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGISTER;
|
||||
typedef union _APIC_LVT_REGISTER APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER;
|
||||
typedef union _APIC_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
|
||||
typedef union _IOAPIC_REDIRECTION_REGISTER IOAPIC_REDIRECTION_REGISTER, *PIOAPIC_REDIRECTION_REGISTER;
|
||||
typedef union _MMPTE MMP5E, *PMMP5E;
|
||||
typedef union _MMPTE MMPDE, *PMMPDE;
|
||||
typedef union _MMPTE MMPPE, *PMMPPE;
|
||||
@@ -90,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_ICW4 PIC_I8259_ICW4, *PPIC_I8259_ICW4;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_AMD64_XTSTRUCT_H */
|
||||
|
||||
@@ -13,9 +13,6 @@
|
||||
#include <xtuefi.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef D__XTOS_ASSEMBLER__
|
||||
|
||||
/* XT BootLoader routines forward references */
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
@@ -24,5 +21,4 @@ BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable,
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
OUT PXTBL_LOADER_PROTOCOL *ProtocolHandler);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_BLFUNCS_H */
|
||||
|
||||
@@ -29,10 +29,6 @@
|
||||
#define XTBL_DEBUGPORT_SCREEN 1
|
||||
#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 */
|
||||
#define XTBL_TUI_DIALOG_GENERIC_BOX 1
|
||||
#define XTBL_TUI_DIALOG_ERROR_BOX 2
|
||||
@@ -45,10 +41,6 @@
|
||||
/* TUI dialog box maximum width */
|
||||
#define XTBL_TUI_MAX_DIALOG_WIDTH 100
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef D__XTOS_ASSEMBLER__
|
||||
|
||||
/* XTLDR Routine pointers */
|
||||
typedef LOADER_MEMORY_TYPE (XTCDECL *PBL_GET_MEMTYPE_ROUTINE)(IN EFI_MEMORY_TYPE EfiMemoryType);
|
||||
|
||||
@@ -77,7 +69,7 @@ typedef VOID (XTCDECL *PBL_CONSOLE_DISABLE_CURSOR)();
|
||||
typedef VOID (XTCDECL *PBL_CONSOLE_ENABLE_CURSOR)();
|
||||
typedef VOID (XTCDECL *PBL_CONSOLE_PRINT)(IN PCWSTR Format, IN ...);
|
||||
typedef VOID (XTCDECL *PBL_CONSOLE_QUERY_MODE)(OUT PUINT_PTR ResX, OUT PUINT_PTR ResY);
|
||||
typedef 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_SET_ATTRIBUTES)(IN ULONGLONG Attributes);
|
||||
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 PWCHAR (XTAPI *PBL_WIDESTRING_TOKENIZE)(IN PWCHAR String, IN PCWSTR Delimiter, IN OUT PWCHAR *SavePtr);
|
||||
typedef EFI_STATUS (XTCDECL *PBL_WAIT_FOR_EFI_EVENT)(IN UINT_PTR NumberOfEvents, IN PEFI_EVENT Event, OUT PUINT_PTR Index);
|
||||
typedef VOID (XTCDECL *PBL_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 (XTAPI *PBL_ZERO_MEMORY)(OUT PVOID Destination, IN SIZE_T Length);
|
||||
|
||||
@@ -239,15 +229,6 @@ typedef struct _XTBL_KNOWN_BOOT_PROTOCOL
|
||||
EFI_GUID Guid;
|
||||
} 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 */
|
||||
typedef struct _XTBL_MEMORY_MAPPING
|
||||
{
|
||||
@@ -497,10 +478,6 @@ typedef struct _XTBL_LOADER_PROTOCOL
|
||||
PBL_OPEN_PROTOCOL_HANDLE OpenHandle;
|
||||
} Protocol;
|
||||
struct
|
||||
{
|
||||
PBL_REGISTER_SHELL_COMMAND RegisterCommand;
|
||||
} Shell;
|
||||
struct
|
||||
{
|
||||
PBL_STRING_COMPARE Compare;
|
||||
PBL_STRING_LENGTH Length;
|
||||
@@ -543,5 +520,4 @@ typedef struct _XTBL_LOADER_PROTOCOL
|
||||
} WideString;
|
||||
} XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_BLTYPES_H */
|
||||
|
||||
@@ -13,9 +13,6 @@
|
||||
#include <xttypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Kernel Executive routines forward references */
|
||||
XTCLINK
|
||||
XTFASTCALL
|
||||
@@ -47,5 +44,4 @@ XTFASTCALL
|
||||
VOID
|
||||
ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_EXFUNCS_H */
|
||||
|
||||
@@ -17,10 +17,6 @@
|
||||
/* Rundown protection flags */
|
||||
#define EX_RUNDOWN_ACTIVE 0x1
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Executive rundown protection structure definition */
|
||||
typedef struct _EX_RUNDOWN_REFERENCE
|
||||
{
|
||||
@@ -38,5 +34,4 @@ typedef struct _EX_RUNDOWN_WAIT_BLOCK
|
||||
KEVENT WakeEvent;
|
||||
} EX_RUNDOWN_WAIT_BLOCK, *PEX_RUNDOWN_WAIT_BLOCK;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_EXTYPES_H */
|
||||
|
||||
@@ -14,9 +14,6 @@
|
||||
#include <xttypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Hardware layer routines forward references */
|
||||
XTCLINK
|
||||
XTAPI
|
||||
@@ -51,5 +48,4 @@ VOID
|
||||
HlWriteRegister32(IN PVOID Register,
|
||||
IN ULONG Value);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_HLFUNCS_H */
|
||||
|
||||
@@ -64,8 +64,8 @@
|
||||
#define ACPI_FADT_32BIT_TIMER (1<<8)
|
||||
|
||||
/* ACPI Timer bit masks */
|
||||
#define ACPI_FADT_TIMER_32BIT 0xFFFFFFFF
|
||||
#define ACPI_FADT_TIMER_24BIT 0x00FFFFFF
|
||||
#define ACPI_FADT_TIMER_32BIT 0x80000000
|
||||
#define ACPI_FADT_TIMER_24BIT 0x00800000
|
||||
|
||||
/* ACPI MADT subtable type definitions */
|
||||
#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_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 */
|
||||
#define COMPORT_CLOCK_RATE 0x1C200
|
||||
#define COMPORT_WAIT_TIMEOUT 204800
|
||||
@@ -188,14 +179,6 @@
|
||||
#define COMPORT_REG_MSR 0x06 /* Modem Status Register */
|
||||
#define COMPORT_REG_SR 0x07 /* Scratch Register */
|
||||
|
||||
/* Minimum and maximum profile intervals */
|
||||
#define MIN_PROFILE_INTERVAL 10000
|
||||
#define MAX_PROFILE_INTERVAL 10000000
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Generic Address structure */
|
||||
typedef struct _GENERIC_ADDRESS
|
||||
{
|
||||
@@ -231,7 +214,7 @@ typedef struct _ACPI_SUBTABLE_HEADER
|
||||
typedef struct _ACPI_CACHE_LIST
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
PACPI_DESCRIPTION_HEADER Table;
|
||||
ACPI_DESCRIPTION_HEADER Header;
|
||||
} ACPI_CACHE_LIST, *PACPI_CACHE_LIST;
|
||||
|
||||
/* ACPI Root System Description Table Pointer (RSDP) structure */
|
||||
@@ -322,17 +305,6 @@ typedef struct _ACPI_FADT
|
||||
GENERIC_ADDRESS SleepStatusReg;
|
||||
} 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 */
|
||||
typedef struct _ACPI_MADT
|
||||
{
|
||||
@@ -342,26 +314,6 @@ typedef struct _ACPI_MADT
|
||||
ULONG ApicTables[];
|
||||
} 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 */
|
||||
typedef struct _ACPI_MADT_LOCAL_APIC
|
||||
{
|
||||
@@ -498,5 +450,4 @@ typedef struct _SMBIOS3_TABLE_HEADER
|
||||
ULONGLONG TableAddress;
|
||||
} SMBIOS3_TABLE_HEADER, *PSMBIOS3_TABLE_HEADER;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_HLTYPES_H */
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include <xtdefs.h>
|
||||
#include <xtstruct.h>
|
||||
#include <xttypes.h>
|
||||
#include ARCH_HEADER(xtstruct.h)
|
||||
|
||||
|
||||
/* Control Register 0 constants */
|
||||
@@ -93,10 +92,6 @@
|
||||
#define X86_EFLAGS_VIP_MASK 0x00100000 /* Virtual Interrupt Pending */
|
||||
#define X86_EFLAGS_ID_MASK 0x00200000 /* Identification */
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* CPU vendor enumeration list */
|
||||
typedef enum _CPU_VENDOR
|
||||
{
|
||||
@@ -105,18 +100,6 @@ typedef enum _CPU_VENDOR
|
||||
CPU_VENDOR_UNKNOWN = 0xFFFFFFFF
|
||||
} CPU_VENDOR, *PCPU_VENDOR;
|
||||
|
||||
/* CPUID advanced power management features (0x80000007) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT
|
||||
{
|
||||
CPUID_FEATURES_EDX_TS = 1 << 0, /* Temperature Sensor */
|
||||
CPUID_FEATURES_EDX_FIS = 1 << 1, /* Frequency ID Selection */
|
||||
CPUID_FEATURES_EDX_VIS = 1 << 2, /* Voltage ID Selection */
|
||||
CPUID_FEATURES_EDX_TTS = 1 << 3, /* ThermaTrip Support */
|
||||
CPUID_FEATURES_EDX_HTC = 1 << 4, /* Hardware Thermal Throttling */
|
||||
CPUID_FEATURES_EDX_STC = 1 << 5, /* Software Thermal Throttling */
|
||||
CPUID_FEATURES_EDX_TSCI = 1 << 8 /* TSC Invariant */
|
||||
} CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT, *PCPUID_FEATURES_ADVANCED_POWER_MANAGEMENT;
|
||||
|
||||
/* CPUID extended features (0x80000001) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_EXTENDED
|
||||
{
|
||||
@@ -158,23 +141,6 @@ typedef enum _CPUID_FEATURES_EXTENDED
|
||||
CPUID_FEATURES_EDX_3DNOW = 1 << 31
|
||||
} CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
|
||||
|
||||
/* CPUID Thermal and Power Management features (0x00000006) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_POWER_MANAGEMENT
|
||||
{
|
||||
CPUID_FEATURES_EAX_DTHERM = 1 << 0,
|
||||
CPUID_FEATURES_EAX_IDA = 1 << 1,
|
||||
CPUID_FEATURES_EAX_ARAT = 1 << 2,
|
||||
CPUID_FEATURES_EAX_PLN = 1 << 4,
|
||||
CPUID_FEATURES_EAX_PTS = 1 << 6,
|
||||
CPUID_FEATURES_EAX_HWP = 1 << 7,
|
||||
CPUID_FEATURES_EAX_HWP_NOTIFY = 1 << 8,
|
||||
CPUID_FEATURES_EAX_HWP_ACT_WINDOW = 1 << 9,
|
||||
CPUID_FEATURES_EAX_HWP_EPP = 1 << 10,
|
||||
CPUID_FEATURES_EAX_HWP_PKG_REQ = 1 << 11,
|
||||
CPUID_FEATURES_EAX_HWP_HIGHEST_PERF_CHANGE = 1 << 15,
|
||||
CPUID_FEATURES_EAX_HFI = 1 << 19
|
||||
} CPUID_FEATURES_LEAF6, *PCPUID_FEATURES_LEAF6;
|
||||
|
||||
/* CPUID STD1 features (0x00000001) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_STANDARD1
|
||||
{
|
||||
@@ -201,7 +167,7 @@ typedef enum _CPUID_FEATURES_STANDARD1
|
||||
CPUID_FEATURES_ECX_X2APIC = 1 << 21,
|
||||
CPUID_FEATURES_ECX_MOVBE = 1 << 22,
|
||||
CPUID_FEATURES_ECX_POPCNT = 1 << 23,
|
||||
CPUID_FEATURES_ECX_TSC_DEADLINE = 1 << 24,
|
||||
CPUID_FEATURES_ECX_TSC = 1 << 24,
|
||||
CPUID_FEATURES_ECX_AES = 1 << 25,
|
||||
CPUID_FEATURES_ECX_XSAVE = 1 << 26,
|
||||
CPUID_FEATURES_ECX_OSXSAVE = 1 << 27,
|
||||
@@ -375,23 +341,16 @@ typedef enum _CPUID_FEATURES_STANDARD7_LEAF1
|
||||
/* CPUID requests */
|
||||
typedef enum _CPUID_REQUESTS
|
||||
{
|
||||
CPUID_GET_VENDOR_STRING = 0x00000000,
|
||||
CPUID_GET_STANDARD1_FEATURES = 0x00000001,
|
||||
CPUID_GET_TLB_CACHE = 0x00000002,
|
||||
CPUID_GET_SERIAL = 0x00000003,
|
||||
CPUID_GET_CACHE_TOPOLOGY = 0x00000004,
|
||||
CPUID_GET_MONITOR_MWAIT = 0x00000005,
|
||||
CPUID_GET_POWER_MANAGEMENT = 0x00000006,
|
||||
CPUID_GET_STANDARD7_FEATURES = 0x00000007,
|
||||
CPUID_GET_TSC_CRYSTAL_CLOCK = 0x00000015,
|
||||
CPUID_GET_EXTENDED_MAX = 0x80000000,
|
||||
CPUID_GET_EXTENDED_FEATURES = 0x80000001,
|
||||
CPUID_GET_ADVANCED_POWER_MANAGEMENT = 0x80000007
|
||||
CPUID_GET_VENDOR_STRING,
|
||||
CPUID_GET_STANDARD1_FEATURES,
|
||||
CPUID_GET_TLB_CACHE,
|
||||
CPUID_GET_SERIAL,
|
||||
CPUID_GET_CACHE_TOPOLOGY,
|
||||
CPUID_GET_MONITOR_MWAIT,
|
||||
CPUID_GET_POWER_MANAGEMENT,
|
||||
CPUID_GET_STANDARD7_FEATURES
|
||||
} CPUID_REQUESTS, *PCPUID_REQUESTS;
|
||||
|
||||
/* Interrupt handler */
|
||||
typedef VOID (*PINTERRUPT_HANDLER)(PKTRAP_FRAME TrapFrame);
|
||||
|
||||
/* Processor identification information */
|
||||
typedef struct _CPU_IDENTIFICATION
|
||||
{
|
||||
@@ -431,5 +390,4 @@ typedef enum _TRAMPOLINE_TYPE
|
||||
TrampolineApStartup
|
||||
} TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_I686_ARTYPES_H */
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
#include <i686/xtstruct.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Hardware layer routines forward references */
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
@@ -52,5 +49,4 @@ VOID
|
||||
HlWritePort32(IN USHORT Port,
|
||||
IN ULONG Value);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_I686_HLFUNCS_H */
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#ifndef __XTDK_I686_HLTYPES_H
|
||||
#define __XTDK_I686_HLTYPES_H
|
||||
|
||||
#include <xtbase.h>
|
||||
#include <xtdefs.h>
|
||||
#include <xtstruct.h>
|
||||
#include <xttypes.h>
|
||||
@@ -37,7 +36,6 @@
|
||||
#define APIC_VECTOR_GENERIC 0xC1
|
||||
#define APIC_VECTOR_SYNC 0xC1
|
||||
#define APIC_VECTOR_CLOCK 0xD1
|
||||
#define APIC_VECTOR_CLOCK_IPI 0xD2
|
||||
#define APIC_VECTOR_IPI 0xE1
|
||||
#define APIC_VECTOR_ERROR 0xE3
|
||||
#define APIC_VECTOR_POWERFAIL 0xEF
|
||||
@@ -60,27 +58,6 @@
|
||||
/* Maximum number of I/O APICs */
|
||||
#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 */
|
||||
#define PIC1_CONTROL_PORT 0x20
|
||||
#define PIC1_DATA_PORT 0x21
|
||||
@@ -92,87 +69,6 @@
|
||||
/* PIC vector definitions */
|
||||
#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 */
|
||||
#define COMPORT_ADDRESS {0x3F8, 0x2F8, 0x3E8, 0x2E8, 0x5F8, 0x4F8, 0x5E8, 0x4E8}
|
||||
#define COMPORT_COUNT 8
|
||||
@@ -180,17 +76,6 @@
|
||||
/* Initial stall factor */
|
||||
#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 */
|
||||
typedef enum _APIC_DM
|
||||
{
|
||||
@@ -248,7 +133,6 @@ typedef enum _APIC_REGISTER
|
||||
APIC_TICR = 0x38, /* Initial Count Register for Timer */
|
||||
APIC_TCCR = 0x39, /* Current Count Register for Timer */
|
||||
APIC_TDCR = 0x3E, /* Timer Divide Configuration Register */
|
||||
APIC_SIPI = 0x3F, /* Self-IPI Register */
|
||||
APIC_EAFR = 0x40, /* extended APIC Feature register */
|
||||
APIC_EACR = 0x41, /* Extended APIC Control Register */
|
||||
APIC_SEOI = 0x42, /* Specific End Of Interrupt Register */
|
||||
@@ -258,19 +142,6 @@ typedef enum _APIC_REGISTER
|
||||
APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */
|
||||
} APIC_REGISTER, *PAPIC_REGISTER;
|
||||
|
||||
/* APIC Timer Divide enumeration list */
|
||||
typedef enum _APIC_TIMER_DIVISOR
|
||||
{
|
||||
TIMER_DivideBy2 = 0,
|
||||
TIMER_DivideBy4 = 1,
|
||||
TIMER_DivideBy8 = 2,
|
||||
TIMER_DivideBy16 = 3,
|
||||
TIMER_DivideBy32 = 8,
|
||||
TIMER_DivideBy64 = 9,
|
||||
TIMER_DivideBy128 = 10,
|
||||
TIMER_DivideBy1 = 11,
|
||||
} APIC_TIMER_DIVISOR, *PAPIC_TIMER_DIVISOR;
|
||||
|
||||
/* I8259 PIC interrupt mode enumeration list */
|
||||
typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE
|
||||
{
|
||||
@@ -388,40 +259,6 @@ typedef union _APIC_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 */
|
||||
typedef union _PIC_I8259_ICW1
|
||||
{
|
||||
@@ -487,39 +324,4 @@ typedef union _PIC_I8259_ICW4
|
||||
UCHAR Bits;
|
||||
} 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;
|
||||
|
||||
/* Timer Capabilities */
|
||||
typedef struct _TIMER_CAPABILITIES
|
||||
{
|
||||
BOOLEAN Arat;
|
||||
BOOLEAN Art;
|
||||
BOOLEAN InvariantTsc;
|
||||
BOOLEAN RDTSCP;
|
||||
ULONG TimerFrequency;
|
||||
BOOLEAN TscDeadline;
|
||||
ULONG TscDenominator;
|
||||
ULONG TscNumerator;
|
||||
} TIMER_CAPABILITIES, *PTIMER_CAPABILITIES;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_I686_HLTYPES_H */
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
#define KGDT_DESCRIPTOR_CODE 0x08
|
||||
|
||||
/* GDT descriptor type codes */
|
||||
#define KGDT_TYPE_NONE 0x00
|
||||
#define KGDT_TYPE_NONE 0x0
|
||||
#define KGDT_TYPE_CODE (0x10 | KGDT_DESCRIPTOR_CODE | KGDT_DESCRIPTOR_EXECUTE_READ)
|
||||
#define KGDT_TYPE_DATA (0x10 | KGDT_DESCRIPTOR_READ_WRITE)
|
||||
|
||||
@@ -82,7 +82,6 @@
|
||||
#define KTSS_IO_MAPS 0x68
|
||||
|
||||
/* I686 Segment Types */
|
||||
#define I686_LDT 0x2
|
||||
#define I686_TASK_GATE 0x5
|
||||
#define I686_TSS 0x9
|
||||
#define I686_ACTIVE_TSS 0xB
|
||||
@@ -131,7 +130,6 @@
|
||||
|
||||
/* XTOS Kernel stack size */
|
||||
#define KERNEL_STACK_SIZE 0x4000
|
||||
#define KERNEL_STACKS 3
|
||||
|
||||
/* XTOS Kernel stack guard pages */
|
||||
#define KERNEL_STACK_GUARD_PAGES 1
|
||||
@@ -159,10 +157,6 @@
|
||||
#define NPX_STATE_LOADED 0x0
|
||||
#define NPX_STATE_UNLOADED 0xA
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Floating point state storing structure */
|
||||
typedef struct _FN_SAVE_FORMAT
|
||||
{
|
||||
@@ -478,7 +472,6 @@ typedef struct _KPROCESSOR_BLOCK
|
||||
KAFFINITY SetMember;
|
||||
ULONG StallScaleFactor;
|
||||
UCHAR CpuNumber;
|
||||
PINTERRUPT_HANDLER InterruptDispatchTable[256];
|
||||
} KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK;
|
||||
|
||||
/* Thread Environment Block (TEB) structure definition */
|
||||
@@ -487,5 +480,4 @@ typedef struct _THREAD_ENVIRONMENT_BLOCK
|
||||
THREAD_INFORMATION_BLOCK InformationBlock;
|
||||
} THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_I686_KETYPES_H */
|
||||
|
||||
@@ -99,9 +99,6 @@
|
||||
/* HAL memory pool virtual address start */
|
||||
#define MM_HARDWARE_VA_START 0xFFC00000
|
||||
|
||||
/* Kernel shared data address */
|
||||
#define MM_KERNEL_SHARED_DATA_ADDRESS 0xFFDF0000
|
||||
|
||||
/* Maximum physical address used by HAL allocations */
|
||||
#define MM_MAXIMUM_PHYSICAL_ADDRESS 0xFFFFFFFF
|
||||
|
||||
@@ -120,10 +117,6 @@
|
||||
/* Number of pool tracking tables */
|
||||
#define MM_POOL_TRACKING_TABLES 32
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Page size enumeration list */
|
||||
typedef enum _PAGE_SIZE
|
||||
{
|
||||
@@ -444,5 +437,4 @@ typedef struct _POOL_DESCRIPTOR
|
||||
SIZE_T Reserved;
|
||||
} POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_I686_MMTYPES_H */
|
||||
|
||||
@@ -12,20 +12,13 @@
|
||||
#include <xtdefs.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* 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_DSH APIC_DSH, *PAPIC_DSH;
|
||||
typedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE;
|
||||
typedef enum _APIC_REGISTER APIC_REGISTER, *PAPIC_REGISTER;
|
||||
typedef enum _APIC_TIMER_DIVISOR APIC_TIMER_DIVISOR, *PAPIC_TIMER_DIVISOR;
|
||||
typedef enum _CPU_VENDOR CPU_VENDOR, *PCPU_VENDOR;
|
||||
typedef enum _CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT, *PCPUID_FEATURES_ADVANCED_POWER_MANAGEMENT;
|
||||
typedef enum _CPUID_FEATURES_EXTENDED CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
|
||||
typedef enum _CPUID_FEATURES_POWER_MANAGEMENT CPUID_FEATURES_POWER_MANAGEMENT, *PCPUID_FEATURES_POWER_MANAGEMENT;
|
||||
typedef enum _CPUID_FEATURES_STANDARD1 CPUID_FEATURES_STANDARD1, *PCPUID_FEATURES_STANDARD1;
|
||||
typedef enum _CPUID_FEATURES_STANDARD7_LEAF0 CPUID_FEATURES_STANDARD7_LEAF0, *PCPUID_FEATURES_STANDARD7_LEAF0;
|
||||
typedef enum _CPUID_FEATURES_STANDARD7_LEAF1 CPUID_FEATURES_STANDARD7_LEAF1, *PCPUID_FEATURES_STANDARD7_LEAF1;
|
||||
@@ -49,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 _HARDWARE_LEGACY_PTE HARDWARE_LEGACY_PTE, *PHARDWARE_LEGACY_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 _KEXCEPTION_FRAME KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;
|
||||
typedef struct _KGDTENTRY KGDTENTRY, *PKGDTENTRY;
|
||||
@@ -81,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 _POOL_DESCRIPTOR POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
||||
typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
||||
typedef struct _TIMER_CAPABILITIES TIMER_CAPABILITIES, *PTIMER_CAPABILITIES;
|
||||
|
||||
/* Unions forward references */
|
||||
typedef union _APIC_BASE_REGISTER APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER;
|
||||
@@ -89,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_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
|
||||
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 _MMPML3_PTE MMPML3_PTE, *PMMPML3_PTE;
|
||||
typedef union _MMPTE MMPDE, *PMMPDE;
|
||||
@@ -100,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_ICW4 PIC_I8259_ICW4, *PPIC_I8259_ICW4;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_I686_XTSTRUCT_H */
|
||||
|
||||
@@ -58,10 +58,6 @@
|
||||
#define PCI_STATUS_SIGNALED_SYSTEM_ERROR 0x4000
|
||||
#define PCI_STATUS_DETECTED_PARITY_ERROR 0x8000
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* PCI bridge control registers */
|
||||
typedef struct _PCI_BRIDGE_CONTROL_REGISTER
|
||||
{
|
||||
@@ -218,5 +214,4 @@ typedef struct _PCI_TYPE1_DEVICE
|
||||
PCI_BRIDGE_CONTROL_REGISTER Bridge;
|
||||
} PCI_TYPE1_DEVICE, *PPCI_TYPE1_DEVICE;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_IOTYPES_H */
|
||||
|
||||
@@ -13,9 +13,6 @@
|
||||
#include <xttypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Kernel debugger routines forward references */
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
@@ -23,5 +20,4 @@ VOID
|
||||
DbgPrint(PCWSTR Format,
|
||||
...);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_KDFUNCS_H */
|
||||
|
||||
@@ -21,10 +21,6 @@
|
||||
#define DEBUG_PROVIDER_COMPORT 0x00000001
|
||||
#define DEBUG_PROVIDER_FRAMEBUFFER 0x00000002
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Kernel routine callbacks */
|
||||
typedef XTSTATUS (XTAPI *PKD_INIT_ROUTINE)();
|
||||
typedef VOID (*PKD_PRINT_ROUTINE)(IN PCWSTR Format, IN ...);
|
||||
@@ -46,5 +42,4 @@ typedef struct _KD_DISPATCH_TABLE
|
||||
RTL_PRINT_CONTEXT PrintContext;
|
||||
} KD_DISPATCH_TABLE, *PKD_DISPATCH_TABLE;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_KDTYPES_H */
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
#include <ketypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Kernel services routines forward references */
|
||||
XTCLINK
|
||||
XTFASTCALL
|
||||
@@ -162,5 +159,4 @@ XTAPI
|
||||
BOOLEAN
|
||||
KeSignalCallDpcSynchronize(IN PVOID SystemArgument);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_KEFUNCS_H */
|
||||
|
||||
@@ -49,10 +49,6 @@
|
||||
#define THREAD_HIGH_PRIORITY 31
|
||||
#define THREAD_MAXIMUM_PRIORITY 32
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Adjust reason */
|
||||
typedef enum _ADJUST_REASON
|
||||
{
|
||||
@@ -137,37 +133,6 @@ typedef enum _KPROCESS_STATE
|
||||
ProcessOutSwap
|
||||
} KPROCESS_STATE, *PKPROCESS_STATE;
|
||||
|
||||
/* Kernel profiling sources */
|
||||
typedef enum _KPROFILE_SOURCE
|
||||
{
|
||||
ProfileTime,
|
||||
ProfileAlignmentFixup,
|
||||
ProfileTotalIssues,
|
||||
ProfilePipelineDry,
|
||||
ProfileLoadInstructions,
|
||||
ProfilePipelineFrozen,
|
||||
ProfileBranchInstructions,
|
||||
ProfileTotalNonissues,
|
||||
ProfileDcacheMisses,
|
||||
ProfileIcacheMisses,
|
||||
ProfileCacheMisses,
|
||||
ProfileBranchMispredictions,
|
||||
ProfileStoreInstructions,
|
||||
ProfileFpInstructions,
|
||||
ProfileIntegerInstructions,
|
||||
Profile2Issue,
|
||||
Profile3Issue,
|
||||
Profile4Issue,
|
||||
ProfileSpecialInstructions,
|
||||
ProfileTotalCycles,
|
||||
ProfileIcacheIssues,
|
||||
ProfileDcacheAccesses,
|
||||
ProfileMemoryBarrierCycles,
|
||||
ProfileLoadLinkedIssues,
|
||||
ProfileXtKernel,
|
||||
ProfileMaximum
|
||||
} KPROFILE_SOURCE, *PKPROFILE_SOURCE;
|
||||
|
||||
/* Thread state */
|
||||
typedef enum _KTHREAD_STATE
|
||||
{
|
||||
@@ -449,28 +414,6 @@ typedef struct _KPROCESS
|
||||
UCHAR Spare;
|
||||
} 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;
|
||||
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 */
|
||||
typedef struct _KTHREAD
|
||||
{
|
||||
@@ -704,5 +647,4 @@ typedef struct _KUBSAN_TYPE_MISMATCH_DATA_V1
|
||||
UCHAR TypeCheckKind;
|
||||
} KUBSAN_TYPE_MISMATCH_DATA_V1, *PKUBSAN_TYPE_MISMATCH_DATA_V1;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_KEFUNCS_H */
|
||||
|
||||
@@ -38,10 +38,6 @@
|
||||
#define LDR_DTE_MM_LOADED 0x40000000
|
||||
#define LDR_DTE_COMPAT_DATABASE_PROCESSED 0x80000000
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Loader data table entry */
|
||||
typedef struct _LDR_DATA_TABLE_ENTRY
|
||||
{
|
||||
@@ -74,5 +70,4 @@ typedef struct _LDR_DATA_TABLE_ENTRY
|
||||
PVOID PatchInformation;
|
||||
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#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 */
|
||||
#define MM_PROTECT_FIELD_SHIFT 5
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Memory manager page lists */
|
||||
typedef enum _MMPAGELISTS
|
||||
{
|
||||
@@ -262,5 +258,4 @@ typedef struct _POOL_TRACKING_TABLE
|
||||
ULONG Tag;
|
||||
} POOL_TRACKING_TABLE, *PPOOL_TRACKING_TABLE;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_MMTYPES_H */
|
||||
|
||||
@@ -14,9 +14,6 @@
|
||||
#include <ketypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Power Manager routine callbacks */
|
||||
typedef VOID (XTFASTCALL *PPROCESSOR_IDLE_FUNCTION)(IN PPROCESSOR_POWER_STATE PowerState);
|
||||
typedef XTSTATUS (XTFASTCALL *PSET_PROCESSOR_THROTTLE)(IN UCHAR Throttle);
|
||||
@@ -91,5 +88,4 @@ typedef struct _PROCESSOR_POWER_STATE
|
||||
ULONG LastC3UserTime;
|
||||
} PROCESSOR_POWER_STATE, *PPROCESSOR_POWER_STATE;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_POTYPES_H */
|
||||
|
||||
@@ -13,9 +13,6 @@
|
||||
#include <ketypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Kernel's representation of a process object */
|
||||
typedef struct _EPROCESS
|
||||
{
|
||||
@@ -30,5 +27,4 @@ typedef struct _ETHREAD
|
||||
UINT Reserved0;
|
||||
} ETHREAD, *PETHREAD;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_PSTYPES_H */
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
#include <rtltypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Runtime Library routines forward references */
|
||||
XTCLINK
|
||||
XTAPI
|
||||
@@ -297,18 +294,6 @@ BOOLEAN
|
||||
RtlTestBit(IN PRTL_BITMAP BitMap,
|
||||
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
|
||||
XTAPI
|
||||
PCHAR
|
||||
@@ -385,5 +370,4 @@ VOID
|
||||
RtlZeroMemory(OUT PVOID Destination,
|
||||
IN SIZE_T Length);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_RTLFUNCS_H */
|
||||
|
||||
@@ -53,17 +53,6 @@
|
||||
#define SHA1_BLOCK_SIZE 64
|
||||
#define SHA1_DIGEST_SIZE 20
|
||||
|
||||
/* Time related definitions */
|
||||
#define TIME_SECONDS_PER_MINUTE 60ULL
|
||||
#define TIME_SECONDS_PER_HOUR 3600ULL
|
||||
#define TIME_SECONDS_PER_DAY 86400ULL
|
||||
#define TIME_TICKS_PER_SECOND 10000000ULL
|
||||
#define TIME_TICKS_PER_MILLISECOND 10000ULL
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Runtime Library routine callbacks */
|
||||
typedef XTSTATUS (*PWRITE_CHARACTER)(IN CHAR Character);
|
||||
typedef XTSTATUS (*PWRITE_WIDE_CHARACTER)(IN WCHAR Character);
|
||||
@@ -118,18 +107,4 @@ typedef struct _RTL_SHA1_CONTEXT
|
||||
UCHAR Buffer[SHA1_BLOCK_SIZE];
|
||||
} 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 */
|
||||
|
||||
@@ -14,9 +14,6 @@
|
||||
#include <xttypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Kernel affinity */
|
||||
typedef ULONG_PTR KAFFINITY, *PKAFFINITY;
|
||||
|
||||
@@ -111,5 +108,4 @@ typedef struct _DISPATCHER_HEADER
|
||||
LIST_ENTRY WaitListHead;
|
||||
} DISPATCHER_HEADER, *PDISPATCHER_HEADER;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER_ */
|
||||
#endif /* __XTDK_XTBASE_H */
|
||||
|
||||
@@ -10,15 +10,11 @@
|
||||
#define __XTDK_XTCOMPAT_H
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* C++ definitions */
|
||||
#define NULLPTR nullptr
|
||||
#define VIRTUAL virtual
|
||||
#define XTCLINK extern "C"
|
||||
#define XTSYMBOL(Name) __asm__(Name)
|
||||
|
||||
/* C++ boolean type */
|
||||
typedef bool BOOLEAN, *PBOOLEAN;
|
||||
@@ -32,7 +28,6 @@
|
||||
#define NULLPTR ((void *)0)
|
||||
#define VIRTUAL
|
||||
#define XTCLINK
|
||||
#define XTSYMBOL(Name)
|
||||
|
||||
/* C boolean type */
|
||||
typedef enum _BOOLEAN
|
||||
@@ -45,5 +40,4 @@
|
||||
typedef unsigned short wchar;
|
||||
#endif
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_XTCOMPAT_H */
|
||||
|
||||
@@ -58,10 +58,6 @@
|
||||
/* Macro for calculating size of an 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 */
|
||||
#define CONCAT_STRING(Str1, Str2) Str1##Str2
|
||||
#define CONCATENATE(Str1, Str2) CONCAT_STRING(Str1, Str2)
|
||||
@@ -115,6 +111,7 @@
|
||||
#define UNIQUE(Prefix) CONCATENATE(CONCATENATE(__UNIQUE_ID_, Prefix), __COUNTER__)
|
||||
|
||||
/* Variadic ABI functions */
|
||||
typedef __builtin_va_list VA_LIST, *PVA_LIST;
|
||||
#define VA_ARG(Marker, Type) ((sizeof(Type) < sizeof(UINT_PTR)) ? \
|
||||
(Type)(__builtin_va_arg(Marker, UINT_PTR)) : \
|
||||
(Type)(__builtin_va_arg(Marker, Type)))
|
||||
|
||||
@@ -13,9 +13,6 @@
|
||||
#include <xtdefs.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef D__XTOS_ASSEMBLER__
|
||||
|
||||
/* SSF2 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,
|
||||
0x82, 0x32, 0x4E, 0x46, 0x53};
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_XTFONT_H */
|
||||
|
||||
@@ -19,10 +19,6 @@
|
||||
/* Version number of the current XTOS loader protocol */
|
||||
#define BOOT_PROTOCOL_VERSION 1
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Memory allocation structures */
|
||||
typedef enum _LOADER_MEMORY_TYPE
|
||||
{
|
||||
@@ -120,5 +116,4 @@ typedef struct _KERNEL_INITIALIZATION_BLOCK
|
||||
FIRMWARE_INFORMATION_BLOCK FirmwareInformation;
|
||||
} KERNEL_INITIALIZATION_BLOCK, *PKERNEL_INITIALIZATION_BLOCK;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER_ */
|
||||
#endif /* __XTDK_XTFW_H */
|
||||
|
||||
@@ -12,9 +12,6 @@
|
||||
#include <xttypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef D__XTOS_ASSEMBLER__
|
||||
|
||||
CHAR XTGLYPH_EXECTOS_LOGO[] =
|
||||
{
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x25, 0x23,
|
||||
@@ -64,5 +61,4 @@ CHAR XTGLYPH_EXECTOS_LOGO[] =
|
||||
0x28, 0x0d, 0x0a
|
||||
};
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_XTGLYPH_H */
|
||||
|
||||
@@ -202,10 +202,6 @@
|
||||
#define PECOFF_IMAGE_SCN_MEM_READ 0x40000000
|
||||
#define PECOFF_IMAGE_SCN_MEM_WRITE 0x80000000
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* PE/COFF image representation structure */
|
||||
typedef struct _PECOFF_IMAGE_CONTEXT
|
||||
{
|
||||
@@ -642,5 +638,4 @@ typedef struct _PECOFF_IMAGE_RESOURCE_DATA_ENTRY
|
||||
ULONG Reserved;
|
||||
} PECOFF_IMAGE_RESOURCE_DATA_ENTRY, *PPECOFF_IMAGE_RESOURCE_DATA_ENTRY;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_XTIMAGE_H */
|
||||
|
||||
@@ -50,7 +50,6 @@
|
||||
#include <hlfuncs.h>
|
||||
#include <kdfuncs.h>
|
||||
#include <kefuncs.h>
|
||||
#include <mmfuncs.h>
|
||||
#include <rtlfuncs.h>
|
||||
|
||||
/* Architecture specific XT routines */
|
||||
|
||||
@@ -12,9 +12,6 @@
|
||||
#include <xtdefs.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Enumeration lists forward references */
|
||||
typedef enum _ADJUST_REASON ADJUST_REASON, *PADJUST_REASON;
|
||||
typedef enum _EXCEPTION_DISPOSITION EXCEPTION_DISPOSITION, *PEXCEPTION_DISPOSITION;
|
||||
@@ -47,7 +44,6 @@ typedef enum _KDPC_IMPORTANCE KDPC_IMPORTANCE, *PKDPC_IMPORTANCE;
|
||||
typedef enum _KEVENT_TYPE KEVENT_TYPE, *PKEVENT_TYPE;
|
||||
typedef enum _KOBJECTS KOBJECTS, *PKOBJECTS;
|
||||
typedef enum _KPROCESS_STATE KPROCESS_STATE, *PKPROCESS_STATE;
|
||||
typedef enum _KPROFILE_SOURCE KPROFILE_SOURCE, *PKPROFILE_SOURCE;
|
||||
typedef enum _KTHREAD_STATE KTHREAD_STATE, *PKTHREAD_STATE;
|
||||
typedef enum _KTIMER_TYPE KTIMER_TYPE, *PKTIMER_TYPE;
|
||||
typedef enum _KUBSAN_DATA_TYPE KUBSAN_DATA_TYPE, *PKUBSAN_DATA_TYPE;
|
||||
@@ -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_DESCRIPTION_HEADER ACPI_DESCRIPTION_HEADER, *PACPI_DESCRIPTION_HEADER;
|
||||
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_INTERRUPT_OVERRIDE ACPI_MADT_INTERRUPT_OVERRIDE, *PACPI_MADT_INTERRUPT_OVERRIDE;
|
||||
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_MADT_TABLE_LOCAL_APIC ACPI_MADT_TABLE_LOCAL_APIC, *PACPI_MADT_TABLE_LOCAL_APIC;
|
||||
typedef struct _ACPI_RSDP ACPI_RSDP, *PACPI_RSDP;
|
||||
typedef struct _ACPI_RSDT ACPI_RSDT, *PACPI_RSDT;
|
||||
typedef struct _ACPI_SUBTABLE_HEADER ACPI_SUBTABLE_HEADER, *PACPI_SUBTABLE_HEADER;
|
||||
@@ -263,9 +255,7 @@ typedef struct _KPROCESS KPROCESS, *PKPROCESS;
|
||||
typedef struct _KQUEUE KQUEUE, *PKQUEUE;
|
||||
typedef struct _KSEMAPHORE KSEMAPHORE, *PKSEMAPHORE;
|
||||
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 _KSYSTEM_TIME KSYSTEM_TIME, *PKSYSTEM_TIME;
|
||||
typedef struct _KTHREAD KTHREAD, *PKTHREAD;
|
||||
typedef struct _KTIMER KTIMER, *PKTIMER;
|
||||
typedef struct _KUBSAN_FLOAT_CAST_OVERFLOW_DATA KUBSAN_FLOAT_CAST_OVERFLOW_DATA, *PKUBSAN_FLOAT_CAST_OVERFLOW_DATA;
|
||||
@@ -337,7 +327,6 @@ typedef struct _STRING STRING, *PSTRING;
|
||||
typedef struct _STRING32 STRING32, *PSTRING32;
|
||||
typedef struct _STRING64 STRING64, *PSTRING64;
|
||||
typedef struct _THREAD_INFORMATION_BLOCK THREAD_INFORMATION_BLOCK, *PTHREAD_INFORMATION_BLOCK;
|
||||
typedef struct _TIME_FIELDS TIME_FIELDS, *PTIME_FIELDS;
|
||||
typedef struct _UEFI_FIRMWARE_INFORMATION UEFI_FIRMWARE_INFORMATION, *PUEFI_FIRMWARE_INFORMATION;
|
||||
typedef struct _UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING;
|
||||
typedef struct _UNICODE_STRING32 UNICODE_STRING32, *PUNICODE_STRING32;
|
||||
@@ -359,7 +348,6 @@ typedef struct _XTBL_MODULE_AUTHORS XTBL_MODULE_AUTHORS, *PXTBL_MODULE_AUTHORS;
|
||||
typedef struct _XTBL_MODULE_DEPS XTBL_MODULE_DEPS, *PXTBL_MODULE_DEPS;
|
||||
typedef struct _XTBL_MODULE_INFO XTBL_MODULE_INFO, *PXTBL_MODULE_INFO;
|
||||
typedef struct _XTBL_PAGE_MAPPING XTBL_PAGE_MAPPING, *PXTBL_PAGE_MAPPING;
|
||||
typedef struct _XTBL_SHELL_COMMAND XTBL_SHELL_COMMAND, *PXTBL_SHELL_COMMAND;
|
||||
typedef struct _XTBL_STATUS XTBL_STATUS, *PXTBL_STATUS;
|
||||
|
||||
/* Unions forward references */
|
||||
@@ -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 _ULARGE_INTEGER ULARGE_INTEGER, *PULARGE_INTEGER;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_XTSTRUCT_H */
|
||||
|
||||
@@ -13,9 +13,6 @@
|
||||
#include <xtcompat.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Standard C types */
|
||||
typedef unsigned char BYTE, *PBYTE, *LPBYTE;
|
||||
typedef char CHAR, *PCHAR, *LPCHAR;
|
||||
@@ -153,9 +150,6 @@ typedef LPCWSTR PCTSTR, LPCTSTR;
|
||||
typedef LPUWSTR PUTSTR, LPUTSTR;
|
||||
typedef LPCUWSTR PCUTSTR, LPCUTSTR;
|
||||
|
||||
/* Variadic ABI types */
|
||||
typedef __builtin_va_list VA_LIST, *PVA_LIST;
|
||||
|
||||
/* 128-bit floats structure */
|
||||
typedef struct _FLOAT128
|
||||
{
|
||||
@@ -293,5 +287,4 @@ typedef struct _UNICODE_STRING64
|
||||
} UNICODE_STRING64, *PUNICODE_STRING64;
|
||||
typedef const UNICODE_STRING64 *PCUNICODE_STRING64;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#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_SMBIOS3_TABLE_GUID {0xF2FD1544, 0x9794, 0x4A2C, {0x99, 0x2E, 0xE5, 0xBB, 0xCf, 0x20, 0xE3, 0x94}}
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Basic UEFI types */
|
||||
typedef PVOID EFI_EVENT, *PEFI_EVENT;
|
||||
typedef PVOID EFI_HANDLE, *PEFI_HANDLE;
|
||||
@@ -2727,5 +2723,4 @@ typedef struct _EFI_PROCESSOR_INFORMATION
|
||||
EFI_PROCESSOR_PHYSICAL_LOCATION Location;
|
||||
} EFI_PROCESSOR_INFORMATION, *PEFI_PROCESSOR_INFORMATION;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_XTUEFI_H */
|
||||
|
||||
@@ -10,6 +10,7 @@ include_directories(
|
||||
# Specify list of kernel source code files
|
||||
list(APPEND XTOSKRNL_SOURCE
|
||||
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/archsup.S
|
||||
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/boot.S
|
||||
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/data.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/procsup.cc
|
||||
@@ -17,13 +18,9 @@ list(APPEND XTOSKRNL_SOURCE
|
||||
${XTOSKRNL_SOURCE_DIR}/ex/exports.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ex/rundown.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}/rtc.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/runlevel.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/timer.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/hl/acpi.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/hl/cport.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/hl/data.cc
|
||||
@@ -34,6 +31,7 @@ list(APPEND XTOSKRNL_SOURCE
|
||||
${XTOSKRNL_SOURCE_DIR}/kd/data.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/kd/dbgio.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/kd/exports.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/irq.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/krnlinit.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/kthread.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/proc.cc
|
||||
@@ -41,7 +39,6 @@ list(APPEND XTOSKRNL_SOURCE
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/bootinfo.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/crash.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/data.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/dispatch.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/dpc.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/event.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/exports.cc
|
||||
@@ -51,10 +48,8 @@ list(APPEND XTOSKRNL_SOURCE
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/kubsan.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/runlevel.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/semphore.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/shdata.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/spinlock.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/sysres.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/systime.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/timer.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/mmgr.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pagemap.cc
|
||||
@@ -66,7 +61,6 @@ list(APPEND XTOSKRNL_SOURCE
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/alloc.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/colors.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/data.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/exports.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/hlpool.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/kpool.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/mmgr.cc
|
||||
@@ -77,7 +71,6 @@ list(APPEND XTOSKRNL_SOURCE
|
||||
${XTOSKRNL_SOURCE_DIR}/po/idle.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/dispatch.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/bitmap.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/data.cc
|
||||
@@ -90,7 +83,6 @@ list(APPEND XTOSKRNL_SOURCE
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/sha1.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/slist.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/string.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/time.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/widestr.cc)
|
||||
|
||||
# Set module definition SPEC file
|
||||
@@ -98,13 +90,15 @@ set_specfile(xtoskrnl.spec xtoskrnl.exe)
|
||||
|
||||
# Link static XTOS library
|
||||
add_library(libxtos ${XTOSKRNL_SOURCE})
|
||||
target_link_libraries(libxtos PRIVATE xtadk)
|
||||
|
||||
# Link kernel executable
|
||||
add_executable(xtoskrnl ${CMAKE_CURRENT_BINARY_DIR}/xtoskrnl.def)
|
||||
add_executable(xtoskrnl
|
||||
${CMAKE_CURRENT_BINARY_DIR}/xtoskrnl.def)
|
||||
|
||||
# Add linker libraries
|
||||
target_link_libraries(xtoskrnl PRIVATE libxtos)
|
||||
target_link_libraries(xtoskrnl
|
||||
PRIVATE
|
||||
libxtos)
|
||||
|
||||
# Set proper binary name and install target
|
||||
set_target_properties(xtoskrnl PROPERTIES SUFFIX .exe)
|
||||
|
||||
@@ -4,40 +4,29 @@
|
||||
* FILE: xtoskrnl/ar/amd64/archsup.S
|
||||
* DESCRIPTION: Provides AMD64 architecture features not implementable in C
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtkmapi.h>
|
||||
#include <xtadk.h>
|
||||
#include <ar/amd64/asmsup.h>
|
||||
|
||||
.altmacro
|
||||
.text
|
||||
|
||||
|
||||
/**
|
||||
* Creates a trap or interrupt handler for the specified vector.
|
||||
* Creates a trap handler for the specified vector.
|
||||
*
|
||||
* @param Vector
|
||||
* Supplies a trap/interrupt vector number.
|
||||
*
|
||||
* @param Type
|
||||
* Specifies whether the handler is designed to handle an interrupt or a trap.
|
||||
* Supplies a trap vector number.
|
||||
*
|
||||
* @return This macro does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.macro ArCreateHandler Vector Type
|
||||
.global Ar\Type\Vector
|
||||
Ar\Type\Vector:
|
||||
/* Check handler type */
|
||||
.ifc \Type,Trap
|
||||
/* Push fake error code for non-error vector traps */
|
||||
.if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
|
||||
push $0
|
||||
.endif
|
||||
.else
|
||||
/* Push fake error code for interrupts */
|
||||
.macro ArCreateTrapHandler Vector
|
||||
.global ArTrap\Vector
|
||||
ArTrap\Vector:
|
||||
/* Push fake error code for non-error vectors */
|
||||
.if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
|
||||
push $0
|
||||
.endif
|
||||
|
||||
@@ -62,122 +51,113 @@ Ar\Type\Vector:
|
||||
push %rax
|
||||
|
||||
/* 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
|
||||
|
||||
/* Store segment selectors */
|
||||
mov %gs, KTRAP_FRAME_SegGs(%rbp)
|
||||
mov %fs, KTRAP_FRAME_SegFs(%rbp)
|
||||
mov %es, KTRAP_FRAME_SegEs(%rbp)
|
||||
mov %ds, KTRAP_FRAME_SegDs(%rbp)
|
||||
mov %gs, TrapSegGs(%rbp)
|
||||
mov %fs, TrapSegFs(%rbp)
|
||||
mov %es, TrapSegEs(%rbp)
|
||||
mov %ds, TrapSegDs(%rbp)
|
||||
|
||||
/* Store debug registers */
|
||||
mov %dr7, %rax
|
||||
mov %rax, KTRAP_FRAME_Dr7(%rbp)
|
||||
mov %rax, TrapDr7(%rbp)
|
||||
mov %dr6, %rax
|
||||
mov %rax, KTRAP_FRAME_Dr6(%rbp)
|
||||
mov %rax, TrapDr6(%rbp)
|
||||
mov %dr3, %rax
|
||||
mov %rax, KTRAP_FRAME_Dr3(%rbp)
|
||||
mov %rax, TrapDr3(%rbp)
|
||||
mov %dr2, %rax
|
||||
mov %rax, KTRAP_FRAME_Dr2(%rbp)
|
||||
mov %rax, TrapDr2(%rbp)
|
||||
mov %dr1, %rax
|
||||
mov %rax, KTRAP_FRAME_Dr1(%rbp)
|
||||
mov %rax, TrapDr1(%rbp)
|
||||
mov %dr0, %rax
|
||||
mov %rax, KTRAP_FRAME_Dr0(%rbp)
|
||||
mov %rax, TrapDr0(%rbp)
|
||||
|
||||
/* Store CR2 and CR3 */
|
||||
mov %cr3, %rax
|
||||
mov %rax, KTRAP_FRAME_Cr3(%rbp)
|
||||
mov %rax, TrapCr3(%rbp)
|
||||
mov %cr2, %rax
|
||||
mov %rax, KTRAP_FRAME_Cr2(%rbp)
|
||||
mov %rax, TrapCr2(%rbp)
|
||||
|
||||
/* Store MxCsr register */
|
||||
stmxcsr KTRAP_FRAME_MxCsr(%rbp)
|
||||
stmxcsr TrapMxCsr(%rbp)
|
||||
|
||||
/* Store XMM registers */
|
||||
movdqa %xmm15, KTRAP_FRAME_Xmm15(%rbp)
|
||||
movdqa %xmm14, KTRAP_FRAME_Xmm14(%rbp)
|
||||
movdqa %xmm13, KTRAP_FRAME_Xmm13(%rbp)
|
||||
movdqa %xmm12, KTRAP_FRAME_Xmm12(%rbp)
|
||||
movdqa %xmm11, KTRAP_FRAME_Xmm11(%rbp)
|
||||
movdqa %xmm10, KTRAP_FRAME_Xmm10(%rbp)
|
||||
movdqa %xmm9, KTRAP_FRAME_Xmm9(%rbp)
|
||||
movdqa %xmm8, KTRAP_FRAME_Xmm8(%rbp)
|
||||
movdqa %xmm7, KTRAP_FRAME_Xmm7(%rbp)
|
||||
movdqa %xmm6, KTRAP_FRAME_Xmm6(%rbp)
|
||||
movdqa %xmm5, KTRAP_FRAME_Xmm5(%rbp)
|
||||
movdqa %xmm4, KTRAP_FRAME_Xmm4(%rbp)
|
||||
movdqa %xmm3, KTRAP_FRAME_Xmm3(%rbp)
|
||||
movdqa %xmm2, KTRAP_FRAME_Xmm2(%rbp)
|
||||
movdqa %xmm1, KTRAP_FRAME_Xmm1(%rbp)
|
||||
movdqa %xmm0, KTRAP_FRAME_Xmm0(%rbp)
|
||||
movdqa %xmm15, TrapXmm15(%rbp)
|
||||
movdqa %xmm14, TrapXmm14(%rbp)
|
||||
movdqa %xmm13, TrapXmm13(%rbp)
|
||||
movdqa %xmm12, TrapXmm12(%rbp)
|
||||
movdqa %xmm11, TrapXmm11(%rbp)
|
||||
movdqa %xmm10, TrapXmm10(%rbp)
|
||||
movdqa %xmm9, TrapXmm9(%rbp)
|
||||
movdqa %xmm8, TrapXmm8(%rbp)
|
||||
movdqa %xmm7, TrapXmm7(%rbp)
|
||||
movdqa %xmm6, TrapXmm6(%rbp)
|
||||
movdqa %xmm5, TrapXmm5(%rbp)
|
||||
movdqa %xmm4, TrapXmm4(%rbp)
|
||||
movdqa %xmm3, TrapXmm3(%rbp)
|
||||
movdqa %xmm2, TrapXmm2(%rbp)
|
||||
movdqa %xmm1, TrapXmm1(%rbp)
|
||||
movdqa %xmm0, TrapXmm0(%rbp)
|
||||
|
||||
/* Test previous mode and swap GS if needed */
|
||||
movl $0, KTRAP_FRAME_PreviousMode(%rbp)
|
||||
mov KTRAP_FRAME_SegCs(%rbp), %ax
|
||||
movl $0, TrapPreviousMode(%rbp)
|
||||
mov %cs, %ax
|
||||
and $3, %al
|
||||
mov %al, KTRAP_FRAME_PreviousMode(%rbp)
|
||||
|
||||
/* Skip swapgs as the interrupt originated from kernel mode */
|
||||
jz Dispatch\Type\Vector
|
||||
|
||||
mov %al, TrapPreviousMode(%rbp)
|
||||
jz KernelMode$\Vector
|
||||
swapgs
|
||||
jmp UserMode$\Vector
|
||||
|
||||
Dispatch\Type\Vector:
|
||||
/* Set up trap frame pointer for the dispatcher and clear the direction flag */
|
||||
KernelMode$\Vector:
|
||||
/* Save kernel stack pointer (SS:RSP) */
|
||||
movl %ss, %eax
|
||||
mov %eax, TrapSegSs(%rbp)
|
||||
lea TRAP_FRAME_SIZE(%rbp), %rax
|
||||
mov %rax, TrapRsp(%rbp)
|
||||
|
||||
UserMode$\Vector:
|
||||
/* Push Frame Pointer, clear direction flag and pass to trap dispatcher */
|
||||
mov %rsp, %rcx
|
||||
cld
|
||||
|
||||
/* Preserve the original stack pointer */
|
||||
mov %rsp, %rbx
|
||||
|
||||
/* Force stack alignment */
|
||||
and $-16, %rsp
|
||||
|
||||
/* Allocate 32 bytes of shadow space */
|
||||
sub $32, %rsp
|
||||
|
||||
.ifc \Type,Trap
|
||||
/* Pass to the trap dispatcher */
|
||||
call ArDispatchTrap
|
||||
.else
|
||||
/* Pass to the interrupt dispatcher */
|
||||
call ArDispatchInterrupt
|
||||
.endif
|
||||
|
||||
/* Restore the original trap frame stack pointer */
|
||||
mov %rbx, %rsp
|
||||
call ArDispatchTrap
|
||||
|
||||
/* Test previous mode and swapgs if needed */
|
||||
testb $1, KTRAP_FRAME_PreviousMode(%rbp)
|
||||
jz RestoreState\Type\Vector
|
||||
testb $1, TrapPreviousMode(%rbp)
|
||||
jz KernelModeReturn$\Vector
|
||||
cli
|
||||
swapgs
|
||||
|
||||
RestoreState\Type\Vector:
|
||||
KernelModeReturn$\Vector:
|
||||
/* Restore XMM registers */
|
||||
movdqa KTRAP_FRAME_Xmm0(%rbp), %xmm0
|
||||
movdqa KTRAP_FRAME_Xmm1(%rbp), %xmm1
|
||||
movdqa KTRAP_FRAME_Xmm2(%rbp), %xmm2
|
||||
movdqa KTRAP_FRAME_Xmm3(%rbp), %xmm3
|
||||
movdqa KTRAP_FRAME_Xmm4(%rbp), %xmm4
|
||||
movdqa KTRAP_FRAME_Xmm5(%rbp), %xmm5
|
||||
movdqa KTRAP_FRAME_Xmm6(%rbp), %xmm6
|
||||
movdqa KTRAP_FRAME_Xmm7(%rbp), %xmm7
|
||||
movdqa KTRAP_FRAME_Xmm8(%rbp), %xmm8
|
||||
movdqa KTRAP_FRAME_Xmm9(%rbp), %xmm9
|
||||
movdqa KTRAP_FRAME_Xmm10(%rbp), %xmm10
|
||||
movdqa KTRAP_FRAME_Xmm11(%rbp), %xmm11
|
||||
movdqa KTRAP_FRAME_Xmm12(%rbp), %xmm12
|
||||
movdqa KTRAP_FRAME_Xmm13(%rbp), %xmm13
|
||||
movdqa KTRAP_FRAME_Xmm14(%rbp), %xmm14
|
||||
movdqa KTRAP_FRAME_Xmm15(%rbp), %xmm15
|
||||
movdqa TrapXmm0(%rbp), %xmm0
|
||||
movdqa TrapXmm1(%rbp), %xmm1
|
||||
movdqa TrapXmm2(%rbp), %xmm2
|
||||
movdqa TrapXmm3(%rbp), %xmm3
|
||||
movdqa TrapXmm4(%rbp), %xmm4
|
||||
movdqa TrapXmm5(%rbp), %xmm5
|
||||
movdqa TrapXmm6(%rbp), %xmm6
|
||||
movdqa TrapXmm7(%rbp), %xmm7
|
||||
movdqa TrapXmm8(%rbp), %xmm8
|
||||
movdqa TrapXmm9(%rbp), %xmm9
|
||||
movdqa TrapXmm10(%rbp), %xmm10
|
||||
movdqa TrapXmm11(%rbp), %xmm11
|
||||
movdqa TrapXmm12(%rbp), %xmm12
|
||||
movdqa TrapXmm13(%rbp), %xmm13
|
||||
movdqa TrapXmm14(%rbp), %xmm14
|
||||
movdqa TrapXmm15(%rbp), %xmm15
|
||||
|
||||
/* 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 */
|
||||
add $(KTRAP_FRAME_SIZE - KTRAP_FRAME_REGISTERS_SIZE), %rsp
|
||||
add $(TRAP_FRAME_SIZE - TRAP_REGISTERS_SIZE), %rsp
|
||||
|
||||
/* Pop General Purpose Registers */
|
||||
pop %rax
|
||||
@@ -201,172 +181,9 @@ RestoreState\Type\Vector:
|
||||
iretq
|
||||
.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 j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
ArCreateHandler 0x\i\j Interrupt
|
||||
ArCreateHandler 0x\i\j Trap
|
||||
ArCreateTrapHandler 0x\i\j
|
||||
.endr
|
||||
.endr
|
||||
|
||||
/* Define array of pointers to the interrupt handlers */
|
||||
.global ArInterruptEntry
|
||||
ArInterruptEntry:
|
||||
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.quad ArInterrupt0x\i\j
|
||||
.endr
|
||||
.endr
|
||||
|
||||
/* Define array of pointers to the trap handlers */
|
||||
.global ArTrapEntry
|
||||
ArTrapEntry:
|
||||
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.quad ArTrap0x\i\j
|
||||
.endr
|
||||
.endr
|
||||
|
||||
/**
|
||||
* Enables eXtended Physical Addressing (XPA).
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page map to be used.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.global ArEnableExtendedPhysicalAddressing
|
||||
ArEnableExtendedPhysicalAddressing:
|
||||
/* Save the original CR4 register */
|
||||
movq %cr4, %rax
|
||||
|
||||
/* Save the state of stack pointer and non-volatile registers */
|
||||
movq %rsp, XpaRegisterSaveArea(%rip)
|
||||
movq %rbp, XpaRegisterSaveArea+0x08(%rip)
|
||||
movq %rax, XpaRegisterSaveArea+0x10(%rip)
|
||||
movq %rbx, XpaRegisterSaveArea+0x18(%rip)
|
||||
|
||||
/* Save the original CR0 register */
|
||||
movq %cr0, %rbp
|
||||
|
||||
/* Load temporary GDT required for mode transitions */
|
||||
leaq XpaTemporaryGdtDesc(%rip), %rax
|
||||
movq %rax, XpaTemporaryGdtBase(%rip)
|
||||
lgdtq XpaTemporaryGdtSize(%rip)
|
||||
|
||||
/* Load addresses for entering compatibility mode and re-entering long mode */
|
||||
leaq XpaEnterCompatMode(%rip), %rax
|
||||
leaq XpaEnterLongMode(%rip), %rbx
|
||||
|
||||
/* Push the 32-bit code segment selector and the target address for a far jump */
|
||||
pushq $KGDT_R0_CMCODE
|
||||
pushq %rax
|
||||
|
||||
/* Perform a far return to switch to 32-bit compatibility mode */
|
||||
lretq
|
||||
|
||||
XpaEnterCompatMode:
|
||||
/* Enter 32-bit compatibility mode */
|
||||
.code32
|
||||
|
||||
/* Store the PageMap pointer on the stack for future use */
|
||||
pushl %ecx
|
||||
|
||||
/* Set the stack segment to the 32-bit data segment selector */
|
||||
movl $KGDT_R0_DATA, %eax
|
||||
movl %eax, %ss
|
||||
|
||||
/* Disable PGE and PCIDE to ensure all TLB entries will be flushed */
|
||||
movl %cr4, %eax
|
||||
andl $~(CR4_PGE | CR4_PCIDE), %eax
|
||||
movl %eax, %cr4
|
||||
|
||||
/* Temporarily disable paging */
|
||||
movl %ebp, %eax
|
||||
andl $~CR0_PG, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
/* Disable Long Mode as prerequisite for enabling 5-level paging */
|
||||
movl $X86_MSR_EFER, %ecx
|
||||
rdmsr
|
||||
andl $~X86_MSR_EFER_LME, %eax
|
||||
wrmsr
|
||||
|
||||
/* Transition to 5-level paging (PML5/LA57) */
|
||||
movl %cr4, %eax
|
||||
orl $CR4_LA57, %eax
|
||||
movl %eax, %cr4
|
||||
|
||||
/* Restore the PageMap pointer from the stack and load it into CR3 */
|
||||
popl %ecx
|
||||
movl %ecx, %cr3
|
||||
|
||||
/* Re-enable Long Mode */
|
||||
movl $X86_MSR_EFER, %ecx
|
||||
rdmsr
|
||||
orl $X86_MSR_EFER_LME, %eax
|
||||
wrmsr
|
||||
|
||||
/* Restore CR0 with paging enabled and flush the instruction pipeline */
|
||||
movl %ebp, %cr0
|
||||
call XpaFlushInstructions
|
||||
|
||||
XpaFlushInstructions:
|
||||
/* Push the 64-bit code segment selector and the target address for a far jump */
|
||||
pushl $KGDT_R0_CODE
|
||||
pushl %ebx
|
||||
|
||||
/* Perform a far return to switch to 64-bit long mode */
|
||||
lretl
|
||||
|
||||
XpaEnterLongMode:
|
||||
/* Enter 64-bit long mode */
|
||||
.code64
|
||||
|
||||
/* Restore the stack pointer and non-volatile registers */
|
||||
movq XpaRegisterSaveArea(%rip), %rsp
|
||||
movq XpaRegisterSaveArea+8(%rip), %rbp
|
||||
movq XpaRegisterSaveArea+0x10(%rip), %rax
|
||||
movq XpaRegisterSaveArea+0x18(%rip), %rbx
|
||||
|
||||
/* Restore the original CR4 register with LA57 bit set */
|
||||
orq $CR4_LA57, %rax
|
||||
movq %rax, %cr4
|
||||
|
||||
/* Return to the caller */
|
||||
retq
|
||||
|
||||
/* Data section for saving registers and temporary GDT */
|
||||
XpaRegisterSaveArea: .quad 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000
|
||||
XpaTemporaryGdtSize: .short ArEnableExtendedPhysicalAddressingEnd - XpaTemporaryGdtDesc - 1
|
||||
XpaTemporaryGdtBase: .quad 0x0000000000000000
|
||||
XpaTemporaryGdtDesc: .quad 0x0000000000000000, 0x00CF9A000000FFFF, 0x00AF9A000000FFFF, 0x00CF92000000FFFF
|
||||
|
||||
.global ArEnableExtendedPhysicalAddressingEnd
|
||||
ArEnableExtendedPhysicalAddressingEnd:
|
||||
|
||||
/**
|
||||
* Handles a spurious interrupt allowing it to end up.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.global ArHandleSpuriousInterrupt
|
||||
ArHandleSpuriousInterrupt:
|
||||
iretq
|
||||
|
||||
/**
|
||||
* Starts an application processor (AP). This is just a stub.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.global ArStartApplicationProcessor
|
||||
ArStartApplicationProcessor:
|
||||
|
||||
.global ArStartApplicationProcessorEnd
|
||||
ArStartApplicationProcessorEnd:
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
|
||||
@@ -26,9 +26,3 @@ KPROCESSOR_BLOCK AR::ProcSup::InitialProcessorBlock;
|
||||
|
||||
/* Initial TSS */
|
||||
KTSS AR::ProcSup::InitialTss;
|
||||
|
||||
/* Initial kernel NMI stack */
|
||||
UCHAR AR::ProcSup::NmiStack[KERNEL_STACK_SIZE] = {};
|
||||
|
||||
/* Unhandled interrupt routine */
|
||||
PINTERRUPT_HANDLER AR::Traps::UnhandledInterruptRoutine = NULLPTR;
|
||||
|
||||
@@ -20,7 +20,7 @@ XTAPI
|
||||
PVOID
|
||||
AR::ProcSup::GetBootStack(VOID)
|
||||
{
|
||||
return (PVOID)((ULONG_PTR)BootStack + KERNEL_STACK_SIZE);
|
||||
return (PVOID)BootStack;
|
||||
}
|
||||
|
||||
XTAPI
|
||||
@@ -73,7 +73,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
/* Get CPU vendor by issueing CPUID instruction */
|
||||
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
CpuFunc::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU vendor in processor control block */
|
||||
Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx;
|
||||
@@ -85,7 +85,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
/* Get CPU standard features */
|
||||
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
CpuFunc::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU signature in processor control block */
|
||||
CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax;
|
||||
@@ -97,23 +97,23 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
if(Prcb->CpuId.Vendor == CPU_VENDOR_AMD)
|
||||
{
|
||||
/* AMD CPU */
|
||||
if(CpuSignature.Family == 0xF)
|
||||
if(Prcb->CpuId.Family >= 0xF)
|
||||
{
|
||||
Prcb->CpuId.Family += CpuSignature.ExtendedFamily;
|
||||
Prcb->CpuId.Model += (CpuSignature.ExtendedModel << 4);
|
||||
Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
|
||||
Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
|
||||
}
|
||||
}
|
||||
else if(Prcb->CpuId.Vendor == CPU_VENDOR_INTEL)
|
||||
{
|
||||
/* Intel CPU */
|
||||
if(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
|
||||
@@ -136,8 +136,8 @@ XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
{
|
||||
PVOID KernelBootStack, KernelFaultStack, KernelNmiStack;
|
||||
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
|
||||
PVOID KernelBootStack, KernelFaultStack;
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
PKGDTENTRY Gdt;
|
||||
PKIDTENTRY Idt;
|
||||
@@ -148,7 +148,7 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
{
|
||||
/* Assign CPU structures from provided buffer */
|
||||
InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
|
||||
&KernelBootStack, &KernelFaultStack, &KernelNmiStack);
|
||||
&KernelBootStack, &KernelFaultStack);
|
||||
|
||||
/* Use global IDT */
|
||||
Idt = InitialIdt;
|
||||
@@ -159,9 +159,8 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
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);
|
||||
KernelBootStack = &BootStack;
|
||||
KernelFaultStack = &FaultStack;
|
||||
ProcessorBlock = &InitialProcessorBlock;
|
||||
}
|
||||
|
||||
@@ -171,7 +170,7 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
/* Initialize GDT, IDT and TSS */
|
||||
InitializeGdt(ProcessorBlock);
|
||||
InitializeIdt(ProcessorBlock);
|
||||
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack, KernelNmiStack);
|
||||
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack);
|
||||
|
||||
/* Set GDT and IDT descriptors */
|
||||
GdtDescriptor.Base = Gdt;
|
||||
@@ -180,9 +179,9 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
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);
|
||||
CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
|
||||
CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
|
||||
CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS);
|
||||
|
||||
/* Enter passive IRQ level */
|
||||
HL::RunLevel::SetRunLevel(PASSIVE_LEVEL);
|
||||
@@ -191,8 +190,8 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
InitializeSegments();
|
||||
|
||||
/* Set GS base */
|
||||
AR::CpuFunc::WriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock);
|
||||
AR::CpuFunc::WriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock);
|
||||
CpuFunc::WriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock);
|
||||
CpuFunc::WriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock);
|
||||
|
||||
/* Initialize processor registers */
|
||||
InitializeProcessorRegisters();
|
||||
@@ -250,35 +249,34 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
|
||||
{
|
||||
/* Set the IDT to handle unexpected interrupts */
|
||||
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArInterruptEntry[Vector], KGDT_R0_CODE,
|
||||
KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
}
|
||||
|
||||
/* Setup IDT handlers for known interrupts and traps */
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrapEntry[0x00], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrapEntry[0x01], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrapEntry[0x02], KGDT_R0_CODE, KIDT_IST_NMI, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrapEntry[0x03], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrapEntry[0x04], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrapEntry[0x05], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrapEntry[0x06], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrapEntry[0x07], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrapEntry[0x08], KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrapEntry[0x09], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrapEntry[0x0A], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrapEntry[0x0B], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrapEntry[0x0C], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrapEntry[0x0D], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrapEntry[0x0E], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrapEntry[0x10], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrapEntry[0x11], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrapEntry[0x12], KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrapEntry[0x13], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x1F, (PVOID)ArTrapEntry[0x1F], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrapEntry[0x2C], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrapEntry[0x2D], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrapEntry[0x2F], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArInterruptEntry[0xE1], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x1F, (PVOID)ArTrap0x1F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrap0x2F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArTrap0xE1, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -357,45 +355,45 @@ AR::ProcSup::InitializeProcessorRegisters(VOID)
|
||||
ULONGLONG PatAttributes;
|
||||
|
||||
/* Enable FXSAVE restore */
|
||||
AR::CpuFunc::WriteControlRegister(4, AR::CpuFunc::ReadControlRegister(4) | CR4_FXSR);
|
||||
CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_FXSR);
|
||||
|
||||
/* Enable XMMI exceptions */
|
||||
AR::CpuFunc::WriteControlRegister(4, AR::CpuFunc::ReadControlRegister(4) | CR4_XMMEXCPT);
|
||||
CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_XMMEXCPT);
|
||||
|
||||
/* Set debugger extension */
|
||||
AR::CpuFunc::WriteControlRegister(4, AR::CpuFunc::ReadControlRegister(4) | CR4_DE);
|
||||
CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_DE);
|
||||
|
||||
/* Enable large pages */
|
||||
AR::CpuFunc::WriteControlRegister(4, AR::CpuFunc::ReadControlRegister(4) | CR4_PSE);
|
||||
CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_PSE);
|
||||
|
||||
/* Enable write-protection */
|
||||
AR::CpuFunc::WriteControlRegister(0, AR::CpuFunc::ReadControlRegister(0) | CR0_WP);
|
||||
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_WP);
|
||||
|
||||
/* Set alignment mask */
|
||||
AR::CpuFunc::WriteControlRegister(0, AR::CpuFunc::ReadControlRegister(0) | CR0_AM);
|
||||
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_AM);
|
||||
|
||||
/* 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 */
|
||||
AR::CpuFunc::WriteControlRegister(0, AR::CpuFunc::ReadControlRegister(0) & ~CR0_NE);
|
||||
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) & ~CR0_NE);
|
||||
|
||||
/* Flush the TLB */
|
||||
AR::CpuFunc::FlushTlb();
|
||||
CpuFunc::FlushTlb();
|
||||
|
||||
/* Initialize system call MSRs */
|
||||
AR::Traps::InitializeSystemCallMsrs();
|
||||
Traps::InitializeSystemCallMsrs();
|
||||
|
||||
/* 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 */
|
||||
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);
|
||||
AR::CpuFunc::WriteModelSpecificRegister(X86_MSR_PAT, PatAttributes);
|
||||
CpuFunc::WriteModelSpecificRegister(X86_MSR_PAT, PatAttributes);
|
||||
|
||||
/* Initialize MXCSR register */
|
||||
AR::CpuFunc::LoadMxcsrRegister(INITIAL_MXCSR);
|
||||
CpuFunc::LoadMxcsrRegister(INITIAL_MXCSR);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -430,8 +428,7 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
||||
OUT PKTSS *Tss,
|
||||
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
||||
OUT PVOID *KernelBootStack,
|
||||
OUT PVOID *KernelFaultStack,
|
||||
OUT PVOID *KernelNmiStack)
|
||||
OUT PVOID *KernelFaultStack)
|
||||
{
|
||||
UINT_PTR Address;
|
||||
|
||||
@@ -442,12 +439,8 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
||||
*KernelBootStack = (PVOID)Address;
|
||||
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 */
|
||||
*KernelFaultStack = (PVOID)Address;
|
||||
Address += KERNEL_STACK_SIZE;
|
||||
|
||||
/* Assign a space for kernel NMI stack, no advance needed as stack grows down */
|
||||
*KernelNmiStack = (PVOID)Address;
|
||||
|
||||
/* Assign a space for GDT and advance */
|
||||
*Gdt = (PKGDTENTRY)(PVOID)Address;
|
||||
@@ -473,12 +466,12 @@ VOID
|
||||
AR::ProcSup::InitializeSegments(VOID)
|
||||
{
|
||||
/* Initialize segments */
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);
|
||||
CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
|
||||
CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
|
||||
CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
|
||||
CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK);
|
||||
CpuFunc::LoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK);
|
||||
CpuFunc::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -498,8 +491,7 @@ XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelBootStack,
|
||||
IN PVOID KernelFaultStack,
|
||||
IN PVOID KernelNmiStack)
|
||||
IN PVOID KernelFaultStack)
|
||||
{
|
||||
/* Fill TSS with zeroes */
|
||||
RtlZeroMemory(ProcessorBlock->TssBase, sizeof(KTSS));
|
||||
@@ -509,7 +501,6 @@ AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
ProcessorBlock->TssBase->Rsp0 = (ULONG_PTR)KernelBootStack;
|
||||
ProcessorBlock->TssBase->Ist[KIDT_IST_PANIC] = (ULONG_PTR)KernelFaultStack;
|
||||
ProcessorBlock->TssBase->Ist[KIDT_IST_MCA] = (ULONG_PTR)KernelFaultStack;
|
||||
ProcessorBlock->TssBase->Ist[KIDT_IST_NMI] = (ULONG_PTR)KernelNmiStack;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,44 +9,6 @@
|
||||
#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.
|
||||
*
|
||||
@@ -265,6 +227,7 @@ VOID
|
||||
AR::Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
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
|
||||
* Supplies the pointer to the interrupt handler routine.
|
||||
* @param TrapFrame
|
||||
* Supplies a kernel trap frame pushed by common trap handler on the stack.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::Traps::SetUnhandledInterruptRoutine(PINTERRUPT_HANDLER Handler)
|
||||
ArDispatchTrap(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
/* Set the unhandled interrupt routine */
|
||||
UnhandledInterruptRoutine = Handler;
|
||||
AR::Traps::DispatchTrap(TrapFrame);
|
||||
}
|
||||
|
||||
@@ -4,244 +4,132 @@
|
||||
* FILE: xtoskrnl/ar/i686/archsup.S
|
||||
* DESCRIPTION: Provides i686 architecture features not implementable in C.
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtkmapi.h>
|
||||
#include <xtadk.h>
|
||||
#include <ar/i686/asmsup.h>
|
||||
|
||||
.altmacro
|
||||
.text
|
||||
|
||||
|
||||
/**
|
||||
* Creates a task, trap or interrupt handler for the specified vector.
|
||||
* This macro creates a trap handler for the specified vector.
|
||||
*
|
||||
* @param Vector
|
||||
* Supplies a vector number.
|
||||
*
|
||||
* @param Type
|
||||
* Specifies whether the handler is designed to handle an interrupt, a task or a trap.
|
||||
* Supplies a trap vector number.
|
||||
*
|
||||
* @return This macro does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.macro ArCreateHandler Vector Type
|
||||
.global _Ar\Type\Vector
|
||||
_Ar\Type\Vector:
|
||||
/* Check handler type */
|
||||
.ifc \Type,Task
|
||||
_Ar\Type\Vector\()Start:
|
||||
/* Clear the Task Switch flag */
|
||||
clts
|
||||
|
||||
/* Allocate the trap frame and inject the hardware vector for the dispatcher */
|
||||
sub $KTRAP_FRAME_SIZE, %esp
|
||||
movl $\Vector, KTRAP_FRAME_Vector(%esp)
|
||||
|
||||
/* Pass the trap frame pointer as an argument and clear the direction flag */
|
||||
push %esp
|
||||
cld
|
||||
|
||||
/* Pass control to the trap dispatcher */
|
||||
call _ArDispatchTrap
|
||||
|
||||
/* Discard the argument and deallocate the trap frame */
|
||||
add $4, %esp
|
||||
add $KTRAP_FRAME_SIZE, %esp
|
||||
|
||||
/* Hardware task return */
|
||||
iretl
|
||||
|
||||
/* Spin back to the entry point to rearm the task gate */
|
||||
jmp _Ar\Type\Vector\()Start
|
||||
.else
|
||||
/* Check handler type */
|
||||
.ifc \Type,Trap
|
||||
/* Push fake error code for non-error vector traps */
|
||||
.if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
|
||||
push $0
|
||||
.endif
|
||||
.else
|
||||
/* Push fake error code for interrupts */
|
||||
push $0
|
||||
.endif
|
||||
|
||||
/* Push vector number */
|
||||
push $\Vector
|
||||
|
||||
/* 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
|
||||
.macro ArCreateTrapHandler Vector
|
||||
.global _ArTrap\Vector
|
||||
_ArTrap\Vector:
|
||||
/* Push fake error code for non-error vectors */
|
||||
.if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
|
||||
push $0
|
||||
.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
|
||||
|
||||
/* 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 j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
ArCreateHandler 0x\i\j Interrupt
|
||||
.if 0x\i\j == 0x02 || 0x\i\j == 0x08
|
||||
ArCreateHandler 0x\i\j Task
|
||||
.else
|
||||
ArCreateHandler 0x\i\j Trap
|
||||
.endif
|
||||
ArCreateTrapHandler 0x\i\j
|
||||
.endr
|
||||
.endr
|
||||
|
||||
/* Define array of pointers to the interrupt handlers */
|
||||
.global _ArInterruptEntry
|
||||
_ArInterruptEntry:
|
||||
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.long _ArInterrupt0x\i\j
|
||||
.endr
|
||||
.endr
|
||||
|
||||
/* Define array of pointers to the trap handlers */
|
||||
.global _ArTrapEntry
|
||||
_ArTrapEntry:
|
||||
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.if 0x\i\j == 0x02 || 0x\i\j == 0x08
|
||||
.long _ArTask0x\i\j
|
||||
.else
|
||||
.long _ArTrap0x\i\j
|
||||
.endif
|
||||
.endr
|
||||
.endr
|
||||
|
||||
/**
|
||||
* Enables eXtended Physical Addressing (XPA). On i386, this is just a stub.
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page map to be used.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.global ArEnableExtendedPhysicalAddressing
|
||||
ArEnableExtendedPhysicalAddressing:
|
||||
|
||||
.global ArEnableExtendedPhysicalAddressingEnd
|
||||
ArEnableExtendedPhysicalAddressingEnd:
|
||||
|
||||
/**
|
||||
* Handles a spurious interrupt allowing it to end up.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.global _ArHandleSpuriousInterrupt
|
||||
_ArHandleSpuriousInterrupt:
|
||||
iret
|
||||
|
||||
/**
|
||||
* Starts an application processor (AP). This is just a stub.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.global _ArStartApplicationProcessor
|
||||
_ArStartApplicationProcessor:
|
||||
|
||||
.global _ArStartApplicationProcessorEnd
|
||||
_ArStartApplicationProcessorEnd:
|
||||
|
||||
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
|
||||
VOID
|
||||
AR::CpuFunc::LoadSegment(IN USHORT Segment,
|
||||
IN ULONG Source)
|
||||
IN ULONG Source)
|
||||
{
|
||||
switch(Segment)
|
||||
{
|
||||
@@ -543,33 +543,6 @@ AR::CpuFunc::ReadTimeStampCounter(VOID)
|
||||
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.
|
||||
*
|
||||
@@ -677,7 +650,7 @@ AR::CpuFunc::StoreLocalDescriptorTable(OUT PVOID Destination)
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::StoreSegment(IN USHORT Segment,
|
||||
OUT PVOID Destination)
|
||||
OUT PVOID Destination)
|
||||
{
|
||||
switch(Segment)
|
||||
{
|
||||
|
||||
@@ -30,11 +30,5 @@ KPROCESSOR_BLOCK AR::ProcSup::InitialProcessorBlock;
|
||||
/* Initial TSS */
|
||||
KTSS AR::ProcSup::InitialTss;
|
||||
|
||||
/* Initial kernel NMI stack */
|
||||
UCHAR AR::ProcSup::NmiStack[KERNEL_STACK_SIZE] = {};
|
||||
|
||||
/* NMI task gate */
|
||||
UCHAR AR::ProcSup::NonMaskableInterruptTss[KTSS_IO_MAPS];
|
||||
|
||||
/* Unhandled interrupt routine */
|
||||
PINTERRUPT_HANDLER AR::Traps::UnhandledInterruptRoutine = NULLPTR;
|
||||
|
||||
@@ -20,7 +20,7 @@ XTAPI
|
||||
PVOID
|
||||
AR::ProcSup::GetBootStack(VOID)
|
||||
{
|
||||
return (PVOID)((ULONG_PTR)BootStack + KERNEL_STACK_SIZE);
|
||||
return (PVOID)BootStack;
|
||||
}
|
||||
|
||||
XTAPI
|
||||
@@ -68,7 +68,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
/* Get CPU vendor by issueing CPUID instruction */
|
||||
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
CpuFunc::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU vendor in processor control block */
|
||||
Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx;
|
||||
@@ -80,7 +80,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
/* Get CPU standard features */
|
||||
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
CpuFunc::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU signature in processor control block */
|
||||
CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax;
|
||||
@@ -92,23 +92,23 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
if(Prcb->CpuId.Vendor == CPU_VENDOR_AMD)
|
||||
{
|
||||
/* AMD CPU */
|
||||
if(CpuSignature.Family == 0xF)
|
||||
if(Prcb->CpuId.Family >= 0xF)
|
||||
{
|
||||
Prcb->CpuId.Family += CpuSignature.ExtendedFamily;
|
||||
Prcb->CpuId.Model += (CpuSignature.ExtendedModel << 4);
|
||||
Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
|
||||
Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
|
||||
}
|
||||
}
|
||||
else if(Prcb->CpuId.Vendor == CPU_VENDOR_INTEL)
|
||||
{
|
||||
/* Intel CPU */
|
||||
if(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
|
||||
@@ -132,7 +132,7 @@ VOID
|
||||
AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
{
|
||||
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
|
||||
PVOID KernelBootStack, KernelFaultStack, KernelNmiStack;
|
||||
PVOID KernelBootStack, KernelFaultStack;
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
PKGDTENTRY Gdt;
|
||||
PKIDTENTRY Idt;
|
||||
@@ -143,7 +143,7 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
{
|
||||
/* Assign CPU structures from provided buffer */
|
||||
InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
|
||||
&KernelBootStack, &KernelFaultStack, &KernelNmiStack);
|
||||
&KernelBootStack, &KernelFaultStack);
|
||||
|
||||
/* Use global IDT */
|
||||
Idt = InitialIdt;
|
||||
@@ -154,9 +154,8 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
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);
|
||||
KernelBootStack = &BootStack;
|
||||
KernelFaultStack = &FaultStack;
|
||||
ProcessorBlock = &InitialProcessorBlock;
|
||||
}
|
||||
|
||||
@@ -166,7 +165,7 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
/* Initialize GDT, IDT and TSS */
|
||||
InitializeGdt(ProcessorBlock);
|
||||
InitializeIdt(ProcessorBlock);
|
||||
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack, KernelNmiStack);
|
||||
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack);
|
||||
|
||||
/* Set GDT and IDT descriptors */
|
||||
GdtDescriptor.Base = Gdt;
|
||||
@@ -175,9 +174,9 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
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);
|
||||
CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
|
||||
CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
|
||||
CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS);
|
||||
|
||||
/* Enter passive IRQ level */
|
||||
HL::RunLevel::SetRunLevel(PASSIVE_LEVEL);
|
||||
@@ -216,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_R3_TEB, 0x0, 0xFFF, KGDT_TYPE_DATA | KGDT_DESCRIPTOR_ACCESSED, KGDT_DPL_USER, 2);
|
||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDM_TILE, 0x0400, 0xFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 0);
|
||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0x0, 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_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_ALIAS, (ULONG_PTR)ProcessorBlock->GdtBase, (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0);
|
||||
}
|
||||
@@ -243,35 +242,34 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
|
||||
{
|
||||
/* Set the IDT to handle unexpected interrupts */
|
||||
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArInterruptEntry[Vector],
|
||||
KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
}
|
||||
|
||||
/* 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, 0x01, (PVOID)ArTrapEntry[0x01], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrapEntry[0x02], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TASK_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrapEntry[0x03], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrapEntry[0x04], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrapEntry[0x05], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrapEntry[0x06], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrapEntry[0x07], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrapEntry[0x08], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TASK_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrapEntry[0x09], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrapEntry[0x0A], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrapEntry[0x0B], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrapEntry[0x0C], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrapEntry[0x0D], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrapEntry[0x0E], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrapEntry[0x10], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrapEntry[0x11], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrapEntry[0x12], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrapEntry[0x13], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrapEntry[0x2A], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrapEntry[0x2B], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrapEntry[0x2C], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrapEntry[0x2D], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrapEntry[0x2E], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrap0x2A, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrap0x2B, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrap0x2E, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -344,10 +342,10 @@ VOID
|
||||
AR::ProcSup::InitializeProcessorRegisters(VOID)
|
||||
{
|
||||
/* Clear EFLAGS register */
|
||||
AR::CpuFunc::WriteEflagsRegister(0);
|
||||
CpuFunc::WriteEflagsRegister(0);
|
||||
|
||||
/* Enable write-protection */
|
||||
AR::CpuFunc::WriteControlRegister(0, AR::CpuFunc::ReadControlRegister(0) | CR0_WP);
|
||||
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_WP);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -382,8 +380,7 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
||||
OUT PKTSS *Tss,
|
||||
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
||||
OUT PVOID *KernelBootStack,
|
||||
OUT PVOID *KernelFaultStack,
|
||||
OUT PVOID *KernelNmiStack)
|
||||
OUT PVOID *KernelFaultStack)
|
||||
{
|
||||
UINT_PTR Address;
|
||||
|
||||
@@ -394,12 +391,8 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
||||
*KernelBootStack = (PVOID)Address;
|
||||
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 */
|
||||
*KernelFaultStack = (PVOID)Address;
|
||||
Address += KERNEL_STACK_SIZE;
|
||||
|
||||
/* Assign a space for kernel NMI stack, no advance needed as stack grows down */
|
||||
*KernelNmiStack = (PVOID)Address;
|
||||
|
||||
/* Assign a space for GDT and advance */
|
||||
*Gdt = (PKGDTENTRY)(PVOID)Address;
|
||||
@@ -425,12 +418,10 @@ VOID
|
||||
AR::ProcSup::InitializeSegments(VOID)
|
||||
{
|
||||
/* Initialize segments */
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R0_PB);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_GS, 0);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);
|
||||
CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
|
||||
CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
|
||||
CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
|
||||
CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R0_PB);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -447,19 +438,8 @@ XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelBootStack,
|
||||
IN PVOID KernelFaultStack,
|
||||
IN PVOID KernelNmiStack)
|
||||
IN PVOID KernelFaultStack)
|
||||
{
|
||||
PKGDTENTRY TssEntry;
|
||||
|
||||
/* Setup System TSS entry in Global Descriptor Table */
|
||||
TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_SYS_TSS / sizeof(KGDTENTRY)]));
|
||||
TssEntry->LimitLow = sizeof(KTSS) - 1;
|
||||
TssEntry->Bits.LimitHigh = 0;
|
||||
TssEntry->Bits.Dpl = 0;
|
||||
TssEntry->Bits.Present = 1;
|
||||
TssEntry->Bits.Type = I686_TSS;
|
||||
|
||||
/* Clear I/O map */
|
||||
RtlSetMemory(ProcessorBlock->TssBase->IoMaps[0].IoMap, 0xFF, IOPM_FULL_SIZE);
|
||||
|
||||
@@ -481,16 +461,16 @@ AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
|
||||
/* Set I/O map base and disable traps */
|
||||
ProcessorBlock->TssBase->IoMapBase = sizeof(KTSS);
|
||||
ProcessorBlock->TssBase->Esp0 = (ULONG_PTR)KernelBootStack;
|
||||
ProcessorBlock->TssBase->Flags = 0;
|
||||
|
||||
/* Set CR3, LDT and SS */
|
||||
ProcessorBlock->TssBase->CR3 = AR::CpuFunc::ReadControlRegister(3);
|
||||
ProcessorBlock->TssBase->LDT = 0;
|
||||
/* Set LDT and SS */
|
||||
ProcessorBlock->TssBase->LDT = KGDT_R0_LDT;
|
||||
ProcessorBlock->TssBase->Ss0 = KGDT_R0_DATA;
|
||||
|
||||
/* Initialize task gates for DoubleFault and NMI traps */
|
||||
SetDoubleFaultTssEntry(ProcessorBlock, KernelFaultStack);
|
||||
SetNonMaskableInterruptTssEntry(ProcessorBlock, KernelNmiStack);
|
||||
SetNonMaskableInterruptTssEntry(ProcessorBlock, KernelFaultStack);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -522,24 +502,24 @@ AR::ProcSup::SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
Tss = (PKTSS)DoubleFaultTss;
|
||||
Tss->IoMapBase = sizeof(KTSS);
|
||||
Tss->Flags = 0;
|
||||
Tss->LDT = 0;
|
||||
Tss->CR3 = AR::CpuFunc::ReadControlRegister(3);
|
||||
Tss->LDT = KGDT_R0_LDT;
|
||||
Tss->CR3 = CpuFunc::ReadControlRegister(3);
|
||||
Tss->Esp = (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->Ds = KGDT_R3_DATA | RPL_MASK;
|
||||
Tss->Es = KGDT_R3_DATA | RPL_MASK;
|
||||
Tss->Fs = KGDT_R0_PB;
|
||||
Tss->Ss = KGDT_R0_DATA;
|
||||
Tss->Ss0 = KGDT_R0_DATA;
|
||||
CpuFunc::StoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss);
|
||||
|
||||
/* Setup DoubleFault TSS entry in Global Descriptor Table */
|
||||
TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_DF_TSS / sizeof(KGDTENTRY)]));
|
||||
TssEntry->BaseLow = ((ULONG_PTR)Tss & 0xFFFF);
|
||||
TssEntry->Bytes.BaseMiddle = ((ULONG_PTR)Tss >> 16);
|
||||
TssEntry->Bytes.BaseHigh = ((ULONG_PTR)Tss >> 24);
|
||||
TssEntry->LimitLow = 0x68;
|
||||
TssEntry->LimitLow = sizeof(KTSS) - 1;
|
||||
TssEntry->Bits.LimitHigh = 0;
|
||||
TssEntry->Bits.Dpl = 0;
|
||||
TssEntry->Bits.Present = 1;
|
||||
@@ -720,7 +700,7 @@ AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelNmiStack)
|
||||
IN PVOID KernelFaultStack)
|
||||
{
|
||||
PKGDTENTRY TaskGateEntry, TssEntry;
|
||||
PKTSS Tss;
|
||||
@@ -736,24 +716,23 @@ AR::ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock
|
||||
Tss = (PKTSS)NonMaskableInterruptTss;
|
||||
Tss->IoMapBase = sizeof(KTSS);
|
||||
Tss->Flags = 0;
|
||||
Tss->LDT = 0;
|
||||
Tss->CR3 = AR::CpuFunc::ReadControlRegister(3);
|
||||
Tss->Esp = (ULONG_PTR)KernelNmiStack;
|
||||
Tss->Esp0 = (ULONG_PTR)KernelNmiStack;
|
||||
Tss->Eip = (ULONG)(ULONG_PTR)ArTrapEntry[0x02];
|
||||
Tss->LDT = KGDT_R0_LDT;
|
||||
Tss->CR3 = CpuFunc::ReadControlRegister(3);
|
||||
Tss->Esp = (ULONG_PTR)KernelFaultStack;
|
||||
Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
|
||||
Tss->Eip = PtrToUlong(ArTrap0x02);
|
||||
Tss->Cs = KGDT_R0_CODE;
|
||||
Tss->Ds = KGDT_R3_DATA | RPL_MASK;
|
||||
Tss->Es = KGDT_R3_DATA | RPL_MASK;
|
||||
Tss->Fs = KGDT_R0_PB;
|
||||
Tss->Ss = KGDT_R0_DATA;
|
||||
Tss->Ss0 = KGDT_R0_DATA;
|
||||
CpuFunc::StoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss);
|
||||
|
||||
/* Setup NMI TSS entry in Global Descriptor Table */
|
||||
TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_NMI_TSS / sizeof(KGDTENTRY)]));
|
||||
TssEntry->BaseLow = ((ULONG_PTR)Tss & 0xFFFF);
|
||||
TssEntry->Bytes.BaseMiddle = ((ULONG_PTR)Tss >> 16);
|
||||
TssEntry->Bytes.BaseHigh = ((ULONG_PTR)Tss >> 24);
|
||||
TssEntry->LimitLow = 0x68;
|
||||
TssEntry->LimitLow = sizeof(KTSS) - 1;
|
||||
TssEntry->Bits.LimitHigh = 0;
|
||||
TssEntry->Bits.Dpl = 0;
|
||||
TssEntry->Bits.Present = 1;
|
||||
|
||||
@@ -9,44 +9,6 @@
|
||||
#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.
|
||||
*
|
||||
@@ -233,6 +195,7 @@ VOID
|
||||
AR::Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
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
|
||||
* Supplies the pointer to the interrupt handler routine.
|
||||
* @param TrapFrame
|
||||
* Supplies a kernel trap frame pushed by common trap handler on the stack.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::Traps::SetUnhandledInterruptRoutine(PINTERRUPT_HANDLER Handler)
|
||||
ArDispatchTrap(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
/* Set the unhandled interrupt routine */
|
||||
UnhandledInterruptRoutine = Handler;
|
||||
AR::Traps::DispatchTrap(TrapFrame);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
* FILE: xtoskrnl/hl/x86/acpi.cc
|
||||
* DESCRIPTION: Advanced Configuration and Power Interface (ACPI) support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
@@ -26,21 +25,8 @@ HL::Acpi::CacheAcpiTable(IN PACPI_DESCRIPTION_HEADER AcpiTable)
|
||||
{
|
||||
PACPI_CACHE_LIST AcpiCache;
|
||||
|
||||
/* Check if there are free slots in static early-boot cache array */
|
||||
if(CacheCount >= ACPI_MAX_CACHED_TABLES)
|
||||
{
|
||||
/* Cache is full, the table is mapped but not cached */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the next available static cache entry */
|
||||
AcpiCache = &CacheEntries[CacheCount];
|
||||
CacheCount++;
|
||||
|
||||
/* Store the pointer to the mapped ACPI table */
|
||||
AcpiCache->Table = AcpiTable;
|
||||
|
||||
/* Insert entry into the global ACPI cache list */
|
||||
/* Create new ACPI table cache entry */
|
||||
AcpiCache = CONTAIN_RECORD(AcpiTable, ACPI_CACHE_LIST, Header);
|
||||
RTL::LinkedList::InsertTailList(&CacheList, &AcpiCache->ListEntry);
|
||||
}
|
||||
|
||||
@@ -105,28 +91,6 @@ HL::Acpi::GetAcpiTable(IN ULONG Signature,
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an initialization of the ACPI subsystem.
|
||||
*
|
||||
@@ -232,23 +196,14 @@ HL::Acpi::InitializeAcpiSystemDescriptionTable(OUT PACPI_DESCRIPTION_HEADER *Acp
|
||||
AcpiResource = (PSYSTEM_RESOURCE_ACPI)ResourceHeader;
|
||||
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);
|
||||
if(Status != STATUS_SUCCESS)
|
||||
{
|
||||
/* Failed to map RSDP, return error */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Mark RSDP as CD/WT to avoid delays in write-back cache */
|
||||
MM::HardwarePool::MarkHardwareMemoryWriteThrough(RsdpStructure, 1);
|
||||
|
||||
/* Validate RSDP signature */
|
||||
if(RsdpStructure->Signature != ACPI_RSDP_SIGNATURE)
|
||||
if(Status != STATUS_SUCCESS || RsdpStructure->Signature != ACPI_RSDP_SIGNATURE)
|
||||
{
|
||||
/* Invalid RSDP signature, unmap and return error */
|
||||
MM::HardwarePool::UnmapHardwareMemory(RsdpStructure, 1, TRUE);
|
||||
RsdpStructure = NULLPTR;
|
||||
/* Not mapped correctly or invalid RSDP signature, return error */
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
@@ -264,40 +219,34 @@ HL::Acpi::InitializeAcpiSystemDescriptionTable(OUT PACPI_DESCRIPTION_HEADER *Acp
|
||||
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);
|
||||
if(Status != STATUS_SUCCESS)
|
||||
{
|
||||
/* Failed to map RSDT/XSDT, return error */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Mark RSDT/XSDT as CD/WT */
|
||||
MM::HardwarePool::MarkHardwareMemoryWriteThrough(Rsdt, 2);
|
||||
|
||||
/* Validate RSDT/XSDT signature */
|
||||
if(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 */
|
||||
MM::HardwarePool::UnmapHardwareMemory(Rsdt, 2, TRUE);
|
||||
/* Not mapped correctly or invalid RSDT/XSDT signature, return error */
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Calculate the length of all available ACPI tables and remap it if needed */
|
||||
RsdtPages = (((RsdtAddress.LowPart & (MM_PAGE_SIZE - 1)) + Rsdt->Header.Length + (MM_PAGE_SIZE - 1)) >> MM_PAGE_SHIFT);
|
||||
RsdtPages = ((RsdtAddress.LowPart & (MM_PAGE_SIZE - 1)) + Rsdt->Header.Length + (MM_PAGE_SIZE - 1)) >> MM_PAGE_SHIFT;
|
||||
if(RsdtPages != 2)
|
||||
{
|
||||
/* RSDT/XSDT needs less or more than 2 pages, remap it */
|
||||
MM::HardwarePool::UnmapHardwareMemory(Rsdt, 2, TRUE);
|
||||
Status = MM::HardwarePool::MapHardwareMemory(RsdtAddress, RsdtPages, TRUE, (PVOID *)&Rsdt);
|
||||
MM::HardwarePool::MarkHardwareMemoryWriteThrough(Rsdt, RsdtPages);
|
||||
|
||||
/* Make sure remapping was successful */
|
||||
if(Status != STATUS_SUCCESS)
|
||||
{
|
||||
/* Remapping failed, return error */
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* Mark remapped RSDT/XSDT as CD/WT */
|
||||
MM::HardwarePool::MarkHardwareMemoryWriteThrough(Rsdt, RsdtPages);
|
||||
}
|
||||
|
||||
/* Get ACPI table header and return success */
|
||||
@@ -318,7 +267,6 @@ HL::Acpi::InitializeAcpiSystemInformation(VOID)
|
||||
{
|
||||
PACPI_MADT_LOCAL_X2APIC LocalX2Apic;
|
||||
PACPI_MADT_LOCAL_APIC LocalApic;
|
||||
PACPI_SUBTABLE_HEADER SubTable;
|
||||
ULONG_PTR MadtTable;
|
||||
PACPI_MADT Madt;
|
||||
XTSTATUS Status;
|
||||
@@ -345,20 +293,11 @@ HL::Acpi::InitializeAcpiSystemInformation(VOID)
|
||||
CpuCount = 0;
|
||||
|
||||
/* Traverse all MADT tables to get system information */
|
||||
while(MadtTable < ((ULONG_PTR)Madt + Madt->Header.Length))
|
||||
while(MadtTable <= ((ULONG_PTR)Madt + Madt->Header.Length))
|
||||
{
|
||||
/* Get current MADT subtable header */
|
||||
SubTable = (PACPI_SUBTABLE_HEADER)MadtTable;
|
||||
|
||||
/* Prevent infinite loops if BIOS provides 0 length */
|
||||
if(SubTable->Length == 0)
|
||||
{
|
||||
/* Broken ACPI table, abort traversal */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if this is a local APIC subtable */
|
||||
if(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 */
|
||||
LocalApic = (PACPI_MADT_LOCAL_APIC)MadtTable;
|
||||
@@ -374,8 +313,12 @@ HL::Acpi::InitializeAcpiSystemInformation(VOID)
|
||||
/* Increment number of CPUs */
|
||||
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 */
|
||||
LocalX2Apic = (PACPI_MADT_LOCAL_X2APIC)MadtTable;
|
||||
@@ -391,10 +334,15 @@ HL::Acpi::InitializeAcpiSystemInformation(VOID)
|
||||
/* Increment number of CPUs */
|
||||
CpuCount++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Safely advance pointer using proper subtable length */
|
||||
MadtTable += SubTable->Length;
|
||||
/* Go to the next MADT table */
|
||||
MadtTable += ((PACPI_SUBTABLE_HEADER)MadtTable)->Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Any other MADT table, try to go to the next one byte-by-byte */
|
||||
MadtTable += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Store number of CPUs */
|
||||
@@ -416,7 +364,6 @@ XTSTATUS
|
||||
HL::Acpi::InitializeAcpiSystemStructure(VOID)
|
||||
{
|
||||
PHYSICAL_ADDRESS PhysicalAddress;
|
||||
PACPI_SUBTABLE_HEADER SubTable;
|
||||
PFN_NUMBER PageCount;
|
||||
ULONG_PTR MadtTable;
|
||||
PACPI_MADT Madt;
|
||||
@@ -436,19 +383,11 @@ HL::Acpi::InitializeAcpiSystemStructure(VOID)
|
||||
CpuCount = 0;
|
||||
|
||||
/* 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 */
|
||||
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 */
|
||||
if(((PACPI_MADT_LOCAL_APIC)MadtTable)->Flags & ACPI_MADT_PLAOC_ENABLED)
|
||||
@@ -456,8 +395,12 @@ HL::Acpi::InitializeAcpiSystemStructure(VOID)
|
||||
/* Increment number of CPUs */
|
||||
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 */
|
||||
if(((PACPI_MADT_LOCAL_X2APIC)MadtTable)->Flags & ACPI_MADT_PLAOC_ENABLED)
|
||||
@@ -465,10 +408,15 @@ HL::Acpi::InitializeAcpiSystemStructure(VOID)
|
||||
/* Increment number of CPUs */
|
||||
CpuCount++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Safely advance pointer using proper subtable length */
|
||||
MadtTable += SubTable->Length;
|
||||
/* Go to the next MADT table */
|
||||
MadtTable += ((PACPI_SUBTABLE_HEADER)MadtTable)->Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Any other MADT table, try to go to the next one byte-by-byte */
|
||||
MadtTable += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Zero the ACPI system information structure */
|
||||
@@ -574,10 +522,10 @@ HL::Acpi::QueryAcpiCache(IN ULONG Signature,
|
||||
AcpiCache = CONTAIN_RECORD(ListEntry, ACPI_CACHE_LIST, ListEntry);
|
||||
|
||||
/* Check if ACPI table signature matches */
|
||||
if(AcpiCache->Table->Signature == Signature)
|
||||
if(AcpiCache->Header.Signature == Signature)
|
||||
{
|
||||
/* ACPI table found in cache, return it */
|
||||
TableHeader = AcpiCache->Table;
|
||||
TableHeader = &AcpiCache->Header;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -648,31 +596,18 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
|
||||
/* Check if DSDT or FACS table requested */
|
||||
if(Signature == ACPI_DSDT_SIGNATURE)
|
||||
{
|
||||
/* Prefer 64-bit address on ACPI 2.0+ */
|
||||
if(Fadt->Header.Revision >= 2 && Fadt->XDsdt.QuadPart != 0)
|
||||
{
|
||||
TableAddress.QuadPart = Fadt->XDsdt.QuadPart;
|
||||
}
|
||||
else
|
||||
{
|
||||
TableAddress.LowPart = Fadt->Dsdt;
|
||||
TableAddress.HighPart = 0;
|
||||
}
|
||||
/* Get DSDT address */
|
||||
TableAddress.LowPart = Fadt->Dsdt;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Prefer 64-bit address on ACPI 2.0+ */
|
||||
if(Fadt->Header.Revision >= 2 && Fadt->XFirmwareCtrl.QuadPart != 0)
|
||||
{
|
||||
TableAddress.QuadPart = Fadt->XFirmwareCtrl.QuadPart;
|
||||
}
|
||||
else
|
||||
{
|
||||
TableAddress.LowPart = Fadt->FirmwareCtrl;
|
||||
TableAddress.HighPart = 0;
|
||||
}
|
||||
/* Get FACS address */
|
||||
TableAddress.LowPart = Fadt->FirmwareCtrl;
|
||||
}
|
||||
|
||||
/* Fill in high part of ACPI table address */
|
||||
TableAddress.HighPart = 0;
|
||||
|
||||
/* Map table using hardware memory pool */
|
||||
Status = MM::HardwarePool::MapHardwareMemory(TableAddress, 2, TRUE, (PVOID*)&TableHeader);
|
||||
if(Status != STATUS_SUCCESS)
|
||||
@@ -683,12 +618,11 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Query cache for XSDT table */
|
||||
/* Query cache for XSDP table */
|
||||
Status = QueryAcpiCache(ACPI_XSDT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Xsdt);
|
||||
if(Status != STATUS_SUCCESS)
|
||||
{
|
||||
/* XSDT not found, query cache for RSDT table */
|
||||
Xsdt = NULLPTR;
|
||||
/* XSDP not found, query cache for RSDP table */
|
||||
Status = QueryAcpiCache(ACPI_RSDT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Rsdt);
|
||||
}
|
||||
|
||||
@@ -699,22 +633,22 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Get table count depending on root table type securely */
|
||||
/* Get table count depending on root table type */
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
/* Iterate over all ACPI tables */
|
||||
for(TableIndex = 0; TableIndex < TableCount; TableIndex++)
|
||||
{
|
||||
/* Check if XSDT or RSDT is used */
|
||||
/* Check if XSDP or RSDT is used */
|
||||
if(Xsdt != NULLPTR)
|
||||
{
|
||||
/* Get table header physical address from XSDT */
|
||||
@@ -727,6 +661,13 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
|
||||
TableAddress.HighPart = 0;
|
||||
}
|
||||
|
||||
/* Check whether some table is already mapped */
|
||||
if(TableHeader != NULLPTR)
|
||||
{
|
||||
/* Unmap previous table */
|
||||
MM::HardwarePool::UnmapHardwareMemory(TableHeader, 2, TRUE);
|
||||
}
|
||||
|
||||
/* Map table using hardware memory pool */
|
||||
Status = MM::HardwarePool::MapHardwareMemory(TableAddress, 2, TRUE, (PVOID*)&TableHeader);
|
||||
if(Status != STATUS_SUCCESS)
|
||||
@@ -741,31 +682,25 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
|
||||
/* Found requested ACPI table */
|
||||
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 */
|
||||
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) */
|
||||
/* Make sure table was found */
|
||||
if(TableHeader->Signature != Signature)
|
||||
{
|
||||
/* Unmap non-matching ACPI table and return error */
|
||||
MM::HardwarePool::UnmapHardwareMemory(TableHeader, 2, TRUE);
|
||||
/* ACPI table not found, check if cleanup is needed */
|
||||
if(TableHeader != NULLPTR)
|
||||
{
|
||||
/* Unmap non-matching ACPI table */
|
||||
MM::HardwarePool::UnmapHardwareMemory(TableHeader, 2, TRUE);
|
||||
}
|
||||
|
||||
/* Return error */
|
||||
return STATUS_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* Don't validate FACS and FADT on old, broken firmwares with ACPI 2.0 or older */
|
||||
if((TableHeader->Signature != ACPI_FADT_SIGNATURE || TableHeader->Revision > 2) &&
|
||||
(TableHeader->Signature != ACPI_FACS_SIGNATURE))
|
||||
/* Don't validate FADT on old, broken firmwares with ACPI 2.0 or older */
|
||||
if(TableHeader->Signature != ACPI_FADT_SIGNATURE || TableHeader->Revision > 2)
|
||||
{
|
||||
/* Validate table checksum */
|
||||
if(!ValidateAcpiTable(TableHeader, TableHeader->Length))
|
||||
@@ -777,7 +712,7 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
/* 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
|
||||
HL::RunLevel::GetRunLevel(VOID)
|
||||
{
|
||||
/* Read current run level */
|
||||
return (KRUNLEVEL)AR::CpuFunc::ReadControlRegister(8);
|
||||
}
|
||||
|
||||
@@ -38,7 +37,6 @@ XTFASTCALL
|
||||
VOID
|
||||
HL::RunLevel::SetRunLevel(IN KRUNLEVEL RunLevel)
|
||||
{
|
||||
/* Set new run level */
|
||||
AR::CpuFunc::WriteControlRegister(8, RunLevel);
|
||||
}
|
||||
|
||||
@@ -56,7 +54,6 @@ XTFASTCALL
|
||||
KRUNLEVEL
|
||||
HL::RunLevel::TransformApicTprToRunLevel(IN UCHAR Tpr)
|
||||
{
|
||||
/* Transform APIC TPR to run level */
|
||||
return (KRUNLEVEL)(Tpr >> 4);
|
||||
}
|
||||
|
||||
@@ -74,25 +71,5 @@ XTFASTCALL
|
||||
UCHAR
|
||||
HL::RunLevel::TransformRunLevelToApicTpr(IN KRUNLEVEL RunLevel)
|
||||
{
|
||||
/* Transform run level to APIC TPR */
|
||||
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: APIC Timer for AMD64 support
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Include common Timer interface */
|
||||
#include ARCH_COMMON(timer.cc)
|
||||
@@ -9,12 +9,6 @@
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* ACPI tables cache count */
|
||||
ULONG HL::Acpi::CacheCount = 0;
|
||||
|
||||
/* ACPI tables cache entries */
|
||||
ACPI_CACHE_LIST HL::Acpi::CacheEntries[ACPI_MAX_CACHED_TABLES];
|
||||
|
||||
/* ACPI tables cache list */
|
||||
LIST_ENTRY HL::Acpi::CacheList;
|
||||
|
||||
@@ -33,35 +27,8 @@ KAFFINITY HL::Cpu::ActiveProcessors;
|
||||
/* FrameBuffer information */
|
||||
HL_FRAMEBUFFER_DATA HL::FrameBuffer::FrameBufferData;
|
||||
|
||||
/* Pointer to the RAM shadow buffer used for double-buffered rendering */
|
||||
PVOID HL::FrameBuffer::ScreenShadowBuffer;
|
||||
|
||||
/* Scroll region information */
|
||||
HL_SCROLL_REGION_DATA HL::FrameBuffer::ScrollRegionData;
|
||||
|
||||
/* APIC mode */
|
||||
APIC_MODE HL::Pic::ApicMode;
|
||||
|
||||
/* Number of I/O APIC controllers */
|
||||
ULONG HL::Pic::ControllerCount;
|
||||
|
||||
/* I/O APIC controllers information */
|
||||
IOAPIC_DATA HL::Pic::Controllers[IOAPIC_MAX_CONTROLLERS];
|
||||
|
||||
/* Number of I/O APIC overrides */
|
||||
ULONG HL::Pic::IrqOverrideCount;
|
||||
|
||||
/* I/O APIC overrides information */
|
||||
ACPI_MADT_INTERRUPT_OVERRIDE HL::Pic::IrqOverrides[IOAPIC_MAX_OVERRIDES];
|
||||
|
||||
/* Mapped interrupt vectors */
|
||||
UCHAR HL::Pic::MappedVectors[256];
|
||||
|
||||
/* Kernel profiling interval */
|
||||
ULONG HL::Timer::ProfilingInterval;
|
||||
|
||||
/* Timer capabilities */
|
||||
TIMER_CAPABILITIES HL::Timer::TimerCapabilities = {0};
|
||||
|
||||
/* APIC timer frequency */
|
||||
ULONG HL::Timer::TimerFrequency;
|
||||
|
||||
@@ -25,9 +25,10 @@ XTAPI
|
||||
VOID
|
||||
HL::FrameBuffer::ClearScreen(IN ULONG Color)
|
||||
{
|
||||
ULONG BackgroundColor, PositionY;
|
||||
PCHAR CurrentLine, TargetBuffer;
|
||||
UCHAR FillByte;
|
||||
ULONG PositionX, PositionY;
|
||||
ULONG BackgroundColor;
|
||||
PCHAR CurrentLine;
|
||||
PULONG Pixel;
|
||||
|
||||
/* Make sure frame buffer is already initialized */
|
||||
if(FrameBufferData.Initialized == FALSE)
|
||||
@@ -36,29 +37,20 @@ HL::FrameBuffer::ClearScreen(IN ULONG Color)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Convert background color */
|
||||
/* Convert background color and get pointer to frame buffer */
|
||||
BackgroundColor = GetRGBColor(Color);
|
||||
|
||||
/* Extract the lower byte for SetMemory */
|
||||
FillByte = (UCHAR)(BackgroundColor & 0xFF);
|
||||
|
||||
/* Determine target buffer */
|
||||
TargetBuffer = (ScreenShadowBuffer != NULLPTR) ? (PCHAR)ScreenShadowBuffer : (PCHAR)FrameBufferData.Address;
|
||||
CurrentLine = TargetBuffer;
|
||||
CurrentLine = (PCHAR)FrameBufferData.Address;
|
||||
|
||||
/* Fill the screen with the specified color */
|
||||
for(PositionY = 0; PositionY < FrameBufferData.Height; PositionY++, CurrentLine += FrameBufferData.Pitch)
|
||||
{
|
||||
/* Fill the current scanline with the background color byte */
|
||||
RTL::Memory::SetMemory(CurrentLine, FillByte, FrameBufferData.Width * FrameBufferData.BytesPerPixel);
|
||||
}
|
||||
|
||||
/* Check if Shadow Buffer is active */
|
||||
if(ScreenShadowBuffer != NULLPTR)
|
||||
{
|
||||
/* Flush changes to VRAM */
|
||||
RTL::Memory::CopyMemory(FrameBufferData.Address, ScreenShadowBuffer,
|
||||
FrameBufferData.Pitch * FrameBufferData.Height);
|
||||
/* Fill the current line with the specified color */
|
||||
Pixel = (PULONG)CurrentLine;
|
||||
for(PositionX = 0; PositionX < FrameBufferData.Width; PositionX++)
|
||||
{
|
||||
/* Set the color of the pixel */
|
||||
Pixel[PositionX] = BackgroundColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,9 +68,7 @@ XTCDECL
|
||||
XTSTATUS
|
||||
HL::FrameBuffer::DisplayCharacter(IN WCHAR Character)
|
||||
{
|
||||
ULONG CharacterX, CharacterY;
|
||||
PSSFN_FONT_HEADER FbFont;
|
||||
BOOLEAN VisibleCharacter;
|
||||
|
||||
/* Make sure frame buffer is already initialized */
|
||||
if(FrameBufferData.Initialized == FALSE)
|
||||
@@ -90,9 +80,6 @@ HL::FrameBuffer::DisplayCharacter(IN WCHAR Character)
|
||||
/* Get font information */
|
||||
FbFont = (PSSFN_FONT_HEADER)FrameBufferData.Font;
|
||||
|
||||
/* Assume invisible character */
|
||||
VisibleCharacter = FALSE;
|
||||
|
||||
/* Handle special characters */
|
||||
switch(Character)
|
||||
{
|
||||
@@ -104,20 +91,15 @@ HL::FrameBuffer::DisplayCharacter(IN WCHAR Character)
|
||||
case L'\t':
|
||||
/* Move cursor to the next tab stop */
|
||||
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.CursorY += FbFont->Height;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* Save cursor position */
|
||||
CharacterX = ScrollRegionData.CursorX;
|
||||
CharacterY = ScrollRegionData.CursorY;
|
||||
|
||||
/* Draw the character to RAM and mark it as visible */
|
||||
DrawCharacter(CharacterX, CharacterY, ScrollRegionData.TextColor, Character);
|
||||
VisibleCharacter = TRUE;
|
||||
/* Draw the character */
|
||||
DrawCharacter(ScrollRegionData.CursorX, ScrollRegionData.CursorY, ScrollRegionData.TextColor, Character);
|
||||
|
||||
/* Advance cursor */
|
||||
ScrollRegionData.CursorX += FbFont->Width;
|
||||
@@ -125,7 +107,6 @@ HL::FrameBuffer::DisplayCharacter(IN WCHAR Character)
|
||||
/* Check if cursor reached end of line */
|
||||
if(ScrollRegionData.CursorX >= ScrollRegionData.Right)
|
||||
{
|
||||
/* Reset cursor to the left margin and advance to the next line */
|
||||
ScrollRegionData.CursorX = ScrollRegionData.Left;
|
||||
ScrollRegionData.CursorY += FbFont->Height;
|
||||
}
|
||||
@@ -139,13 +120,6 @@ HL::FrameBuffer::DisplayCharacter(IN WCHAR Character)
|
||||
ScrollRegion();
|
||||
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 STATUS_SUCCESS;
|
||||
@@ -179,8 +153,9 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
|
||||
{
|
||||
UINT CurrentFragment, Glyph, GlyphLimit, Index, Line, Mapping;
|
||||
PUCHAR Character, CharacterMapping, Fragment;
|
||||
ULONG FontColor, GlyphOffset, PixelOffset;
|
||||
UINT_PTR GlyphPixel, Pixel;
|
||||
PSSFN_FONT_HEADER FbFont;
|
||||
ULONG FontColor;
|
||||
|
||||
/* Make sure frame buffer is already initialized */
|
||||
if(FrameBufferData.Initialized == FALSE)
|
||||
@@ -217,7 +192,7 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
|
||||
}
|
||||
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)
|
||||
{
|
||||
/* 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 */
|
||||
GlyphOffset = (PositionY * FrameBufferData.Pitch) + (PositionX * FrameBufferData.BytesPerPixel);
|
||||
GlyphPixel = (UINT_PTR)FrameBufferData.Address + PositionY * FrameBufferData.Pitch +
|
||||
PositionX * FrameBufferData.BytesPerPixel;
|
||||
FontColor = GetRGBColor(Color);
|
||||
|
||||
/* Check all kerning fragments */
|
||||
@@ -267,7 +243,7 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
|
||||
}
|
||||
|
||||
/* Get initial glyph line */
|
||||
GlyphOffset += (CharacterMapping[1] - Mapping) * FrameBufferData.Pitch;
|
||||
GlyphPixel += (CharacterMapping[1] - Mapping) * FrameBufferData.Pitch;
|
||||
Mapping = CharacterMapping[1];
|
||||
|
||||
/* Extract glyph data from fragments table and advance */
|
||||
@@ -279,8 +255,7 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
|
||||
CurrentFragment = 1;
|
||||
while(GlyphLimit--)
|
||||
{
|
||||
/* Set the initial pixel offset for the current glyph fragment */
|
||||
PixelOffset = GlyphOffset;
|
||||
Pixel = GlyphPixel;
|
||||
for(Line = 0; Line < Glyph; Line++)
|
||||
{
|
||||
/* Decode compressed offsets */
|
||||
@@ -294,26 +269,17 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
|
||||
/* Check if pixel should be drawn */
|
||||
if(*Fragment & CurrentFragment)
|
||||
{
|
||||
/* Route the pixel draw operation to the active buffer */
|
||||
if(ScreenShadowBuffer != NULLPTR)
|
||||
{
|
||||
/* Draw glyph pixel to Shadow Buffer */
|
||||
*((PULONG)((PCHAR)ScreenShadowBuffer + PixelOffset)) = FontColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Draw glyph pixel directly to VRAM */
|
||||
*((PULONG)((PCHAR)FrameBufferData.Address + PixelOffset)) = FontColor;
|
||||
}
|
||||
/* Draw glyph pixel */
|
||||
*((PULONG)Pixel) = FontColor;
|
||||
}
|
||||
|
||||
/* Advance pixel pointer */
|
||||
PixelOffset += FrameBufferData.BytesPerPixel;
|
||||
Pixel += FrameBufferData.BytesPerPixel;
|
||||
CurrentFragment <<= 1;
|
||||
}
|
||||
|
||||
/* Advance to next line and increase mapping */
|
||||
GlyphOffset += FrameBufferData.Pitch;
|
||||
GlyphPixel += FrameBufferData.Pitch;
|
||||
Mapping++;
|
||||
}
|
||||
|
||||
@@ -344,7 +310,7 @@ HL::FrameBuffer::DrawPixel(IN ULONG PositionX,
|
||||
IN ULONG PositionY,
|
||||
IN ULONG Color)
|
||||
{
|
||||
ULONG Offset;
|
||||
PCHAR PixelAddress;
|
||||
|
||||
/* Make sure frame buffer is already initialized */
|
||||
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 */
|
||||
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 */
|
||||
if(ScreenShadowBuffer != NULLPTR)
|
||||
{
|
||||
/* 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;
|
||||
/* Set the color of the pixel by writing to the corresponding memory location */
|
||||
*((PULONG)PixelAddress) = GetRGBColor(Color);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -634,9 +544,10 @@ XTAPI
|
||||
VOID
|
||||
HL::FrameBuffer::ScrollRegion(VOID)
|
||||
{
|
||||
PCHAR TargetBuffer, Destination, Source;
|
||||
ULONG Line, PositionX, LineBytes;
|
||||
PCHAR Destination, Source;
|
||||
PSSFN_FONT_HEADER FbFont;
|
||||
ULONG Line, PositionX;
|
||||
ULONG LineBytes;
|
||||
PULONG Pixel;
|
||||
|
||||
/* Make sure frame buffer is already initialized */
|
||||
@@ -646,132 +557,37 @@ HL::FrameBuffer::ScrollRegion(VOID)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Retrieve font metrics and calculate line properties for the scroll operation */
|
||||
/* Get font information */
|
||||
FbFont = (PSSFN_FONT_HEADER)FrameBufferData.Font;
|
||||
|
||||
/* Calculate bytes per line in the scroll region */
|
||||
LineBytes = (ScrollRegionData.Right - ScrollRegionData.Left) * FrameBufferData.BytesPerPixel;
|
||||
TargetBuffer = (ScreenShadowBuffer != NULLPTR) ? (PCHAR)ScreenShadowBuffer : (PCHAR)FrameBufferData.Address;
|
||||
|
||||
/* Process every line in the scroll region */
|
||||
for(Line = ScrollRegionData.Top; Line < ScrollRegionData.Bottom; Line++)
|
||||
/* Scroll up each scan line in the scroll region */
|
||||
for(Line = ScrollRegionData.Top; Line < ScrollRegionData.Bottom - FbFont->Height; Line++)
|
||||
{
|
||||
/* Calculate destination address for the current line */
|
||||
Destination = TargetBuffer + (Line * FrameBufferData.Pitch) +
|
||||
(ScrollRegionData.Left * FrameBufferData.BytesPerPixel);
|
||||
Destination = (PCHAR)FrameBufferData.Address + Line * FrameBufferData.Pitch +
|
||||
ScrollRegionData.Left * FrameBufferData.BytesPerPixel;
|
||||
|
||||
/* Check if the current line needs to be copied from below or cleared */
|
||||
if(Line < ScrollRegionData.Bottom - FbFont->Height)
|
||||
/* The source is one full text line (FbFont->Height) below the destination */
|
||||
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 */
|
||||
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;
|
||||
}
|
||||
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
|
||||
HL::RunLevel::GetRunLevel(VOID)
|
||||
{
|
||||
/* Read current run level */
|
||||
return TransformApicTprToRunLevel(HL::Pic::ReadApicRegister(APIC_TPR));
|
||||
}
|
||||
|
||||
@@ -38,7 +37,6 @@ XTFASTCALL
|
||||
VOID
|
||||
HL::RunLevel::SetRunLevel(IN KRUNLEVEL RunLevel)
|
||||
{
|
||||
/* Set new run level */
|
||||
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 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: APIC Timer for i686 support
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Include common Timer interface */
|
||||
#include ARCH_COMMON(timer.cc)
|
||||
@@ -23,22 +23,19 @@ HL::Init::InitializeSystem(VOID)
|
||||
XTSTATUS Status;
|
||||
|
||||
/* Initialize ACPI */
|
||||
Status = HL::Acpi::InitializeAcpi();
|
||||
Status = Acpi::InitializeAcpi();
|
||||
if(Status != STATUS_SUCCESS)
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Get system information from ACPI */
|
||||
Status = HL::Acpi::InitializeAcpiSystemInformation();
|
||||
Status = Acpi::InitializeAcpiSystemInformation();
|
||||
if(Status != STATUS_SUCCESS)
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Initialize I/O APIC */
|
||||
HL::Pic::InitializeIOApic();
|
||||
|
||||
/* Return success */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -40,11 +40,8 @@ HL::Cpu::InitializeProcessor(VOID)
|
||||
ActiveProcessors |= Affinity;
|
||||
|
||||
/* Initialize APIC for this processor */
|
||||
HL::Pic::InitializePic();
|
||||
Pic::InitializePic();
|
||||
|
||||
/* Set the APIC running level */
|
||||
HL::RunLevel::SetRunLevel(KE::Processor::GetCurrentProcessorBlock()->RunLevel);
|
||||
|
||||
/* Initialize timer */
|
||||
HL::Timer::InitializeTimer();
|
||||
}
|
||||
|
||||
@@ -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,103 +4,11 @@
|
||||
* FILE: xtoskrnl/hl/x86/pic.cc
|
||||
* DESCRIPTION: Programmable Interrupt Controller (PIC) for x86 (i686/AMD64) support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#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.DeliveryMode = APIC_DM_FIXED;
|
||||
Register.DeliveryStatus = 0;
|
||||
Register.Destination = HL::Pic::ReadApicRegister(APIC_ID) >> 24;
|
||||
Register.DestinationMode = APIC_DM_Physical;
|
||||
Register.Mask = 1;
|
||||
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)
|
||||
{
|
||||
CPUID_REGISTERS CpuRegisters;
|
||||
|
||||
/* Prepare CPUID registers */
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||
CpuRegisters.SubLeaf = 0;
|
||||
CpuRegisters.Eax = 0;
|
||||
CpuRegisters.Ebx = 0;
|
||||
CpuRegisters.Ecx = 0;
|
||||
CpuRegisters.Edx = 0;
|
||||
|
||||
/* Get CPUID */
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
|
||||
/* Check APIC status from the CPUID results */
|
||||
if(!(CpuRegisters.Edx & CPUID_FEATURES_EDX_APIC))
|
||||
{
|
||||
/* APIC is not supported */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* APIC is supported */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the x2APIC extension is supported by the processor.
|
||||
*
|
||||
@@ -154,105 +62,6 @@ HL::Pic::ClearApicErrors(VOID)
|
||||
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.
|
||||
*
|
||||
@@ -274,52 +83,7 @@ HL::Pic::GetCpuApicId(VOID)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the I/O APIC controller information for the specified GSI.
|
||||
*
|
||||
* @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.
|
||||
* Allows an APIC spurious interrupts to end up.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
@@ -327,19 +91,21 @@ HL::Pic::GetIoApicController(IN ULONG Gsi,
|
||||
*/
|
||||
XTCDECL
|
||||
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);
|
||||
ErrorStatus = (ULONG)ReadApicRegister(APIC_ESR);
|
||||
|
||||
/* Log the detected hardware error */
|
||||
DebugPrint(L"Caught APIC Error interrupt with ESR = 0x%08X\n", ErrorStatus);
|
||||
|
||||
/* Acknowledge the interrupt to allow further interrupt delivery */
|
||||
SendEoi();
|
||||
/**
|
||||
* Allows a PIC spurious interrupts to end up.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
HL::Pic::HandlePicSpuriousService(VOID)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -358,14 +124,6 @@ HL::Pic::InitializeApic(VOID)
|
||||
APIC_LVT_REGISTER LvtRegister;
|
||||
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) */
|
||||
if(CheckX2ApicSupport())
|
||||
{
|
||||
@@ -411,9 +169,13 @@ HL::Pic::InitializeApic(VOID)
|
||||
/* Setup the LVT Error entry to deliver APIC errors on a dedicated vector */
|
||||
WriteApicRegister(APIC_ERRLVTR, APIC_VECTOR_ERROR);
|
||||
|
||||
/* Mask the APIC Timer */
|
||||
/* Program the APIC timer for periodic mode */
|
||||
LvtRegister.Long = 0;
|
||||
LvtRegister.Mask = 1;
|
||||
LvtRegister.DeliveryMode = APIC_DM_FIXED;
|
||||
LvtRegister.TimerMode = 1;
|
||||
LvtRegister.TriggerMode = APIC_TGM_EDGE;
|
||||
LvtRegister.Vector = APIC_VECTOR_PROFILE;
|
||||
WriteApicRegister(APIC_TMRLVTR, LvtRegister.Long);
|
||||
|
||||
/* Configure the performance counter overflow */
|
||||
@@ -444,9 +206,8 @@ HL::Pic::InitializeApic(VOID)
|
||||
WriteApicRegister(APIC_LINT1, LvtRegister.Long);
|
||||
|
||||
/* Register interrupt handlers */
|
||||
HL::Irq::RegisterSystemInterruptHandler(APIC_VECTOR_ERROR, HandleApicErrorInterrupt);
|
||||
HL::Irq::RegisterSystemInterruptHandler(APIC_VECTOR_PROFILE, HL::Irq::HandleProfileInterrupt);
|
||||
HL::Irq::RegisterInterruptHandler(APIC_VECTOR_SPURIOUS, (PVOID)ArHandleSpuriousInterrupt);
|
||||
KE::Irq::SetInterruptHandler(APIC_VECTOR_SPURIOUS, (PVOID)HandleApicSpuriousService);
|
||||
KE::Irq::SetInterruptHandler(PIC1_VECTOR_SPURIOUS, (PVOID)HandlePicSpuriousService);
|
||||
|
||||
/* Clear any pre-existing errors */
|
||||
WriteApicRegister(APIC_ESR, 0);
|
||||
@@ -455,84 +216,6 @@ HL::Pic::InitializeApic(VOID)
|
||||
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 */
|
||||
MM::HardwarePool::MapHardwareMemory(Controllers[ControllerIndex].PhysicalAddress,
|
||||
1,
|
||||
FALSE,
|
||||
(PVOID*)&Controllers[ControllerIndex].VirtualAddress);
|
||||
|
||||
/* 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.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.
|
||||
*
|
||||
@@ -606,9 +289,6 @@ HL::Pic::InitializeLegacyPic(VOID)
|
||||
|
||||
/* Mask all interrupts on PIC2 port */
|
||||
HL::IoPort::WritePort8(PIC2_DATA_PORT, 0xFF);
|
||||
|
||||
/* Register interrupt handler */
|
||||
HL::Irq::RegisterInterruptHandler(PIC1_VECTOR_SPURIOUS, (PVOID)ArHandleSpuriousInterrupt);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -653,186 +333,7 @@ HL::Pic::ReadApicRegister(IN APIC_REGISTER Register)
|
||||
else
|
||||
{
|
||||
/* Read from xAPIC */
|
||||
return HL::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)
|
||||
{
|
||||
APIC_COMMAND_REGISTER Register;
|
||||
BOOLEAN Interrupts;
|
||||
|
||||
/* SMP not implemented */
|
||||
if(TRUE)
|
||||
{
|
||||
/* Check if IPI is addressed to the current CPU */
|
||||
if(Self)
|
||||
{
|
||||
/* Send IPI to the current CPU */
|
||||
SendSelfIpi(Vector);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Nothing to do */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check whether interrupts are enabled */
|
||||
Interrupts = AR::CpuFunc::InterruptsEnabled();
|
||||
|
||||
/* Disable interrupts */
|
||||
AR::CpuFunc::ClearInterruptFlag();
|
||||
|
||||
/* Prepare the APIC command register */
|
||||
Register.LongLong = 0;
|
||||
Register.DeliveryMode = APIC_DM_FIXED;
|
||||
Register.DestinationShortHand = Self ? APIC_DSH_AllIncludingSelf : APIC_DSH_AllExclusingSelf;
|
||||
Register.Level = 1;
|
||||
Register.TriggerMode = APIC_TGM_EDGE;
|
||||
Register.Vector = Vector;
|
||||
|
||||
/* Check current APIC mode */
|
||||
if(ApicMode == APIC_MODE_X2APIC)
|
||||
{
|
||||
/* In x2APIC mode, writing the full 64-bit value to the ICR MSR is sufficient */
|
||||
WriteApicRegister(APIC_ICR0, Register.LongLong);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Wait for the APIC to clear the delivery status */
|
||||
while((ReadApicRegister(APIC_ICR0) & 0x1000) != 0)
|
||||
{
|
||||
/* Yield the processor */
|
||||
AR::CpuFunc::YieldProcessor();
|
||||
}
|
||||
|
||||
/* In xAPIC compatibility mode, write the command to the ICR registers */
|
||||
WriteApicRegister(APIC_ICR1, Register.Long1);
|
||||
WriteApicRegister(APIC_ICR0, Register.Long0);
|
||||
}
|
||||
|
||||
/* Check whether interrupts need to be re-enabled */
|
||||
if(Interrupts)
|
||||
{
|
||||
/* Re-enable interrupts */
|
||||
AR::CpuFunc::SetInterruptFlag();
|
||||
return IoRegister::ReadRegister32((PULONG)(APIC_BASE + (Register << 4)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -866,8 +367,8 @@ HL::Pic::SendEoi(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Pic::SendIpi(IN ULONG ApicId,
|
||||
IN ULONG Vector)
|
||||
HL::Pic::SendIpi(ULONG ApicId,
|
||||
ULONG Vector)
|
||||
{
|
||||
/* Check current APIC mode */
|
||||
if(ApicMode == APIC_MODE_X2APIC)
|
||||
@@ -883,105 +384,6 @@ HL::Pic::SendIpi(IN ULONG ApicId,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a Self-IPI (Inter-Processor Interrupt) to the current CPU.
|
||||
*
|
||||
* @param Vector
|
||||
* Supplies the IPI vector to send.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Pic::SendSelfIpi(IN ULONG Vector)
|
||||
{
|
||||
APIC_COMMAND_REGISTER Register;
|
||||
BOOLEAN Interrupts;
|
||||
|
||||
/* Check whether interrupts are enabled */
|
||||
Interrupts = AR::CpuFunc::InterruptsEnabled();
|
||||
|
||||
/* Disable interrupts */
|
||||
AR::CpuFunc::ClearInterruptFlag();
|
||||
|
||||
/* Check current APIC mode */
|
||||
if(ApicMode == APIC_MODE_X2APIC)
|
||||
{
|
||||
/* In x2APIC mode, a dedicated Self-IPI register is used */
|
||||
WriteApicRegister(APIC_SIPI, Vector);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Prepare APIC command register */
|
||||
Register.LongLong = 0;
|
||||
Register.DeliveryMode = APIC_DM_FIXED;
|
||||
Register.DestinationShortHand = APIC_DSH_Self;
|
||||
Register.TriggerMode = APIC_TGM_EDGE;
|
||||
Register.Vector = Vector;
|
||||
|
||||
/* Wait for the APIC to clear the delivery status */
|
||||
while((ReadApicRegister(APIC_ICR0) & 0x1000) != 0)
|
||||
{
|
||||
/* Yield the processor */
|
||||
AR::CpuFunc::YieldProcessor();
|
||||
}
|
||||
|
||||
/* In xAPIC compatibility mode, write the command to the ICR registers */
|
||||
WriteApicRegister(APIC_ICR1, Register.Long1);
|
||||
WriteApicRegister(APIC_ICR0, Register.Long0);
|
||||
|
||||
/* 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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes to the APIC register.
|
||||
*
|
||||
@@ -1008,70 +410,6 @@ HL::Pic::WriteApicRegister(IN APIC_REGISTER Register,
|
||||
else
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
@@ -1,439 +0,0 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/hl/x86/timer.cc
|
||||
* DESCRIPTION: APIC Timer support for x86 (i686/AMD64) support
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Calibrates the Local APIC timer frequency.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
HL::Timer::CalibrateApicTimer()
|
||||
{
|
||||
ULONG CurrentCount, Frequency, InitialCount;
|
||||
|
||||
/* Get APIC timer frequency from the Core Crystal Clock */
|
||||
if(TimerCapabilities.Art && TimerCapabilities.TimerFrequency != 0)
|
||||
{
|
||||
/* CCC available, use it as the source of APIC timer frequency */
|
||||
Frequency = TimerCapabilities.TimerFrequency;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* CCC unavailable, fallback to PIT calibration */
|
||||
InitialCount = 0xFFFFFFFF;
|
||||
|
||||
/* Load the initial count into the APIC Timer and begin the countdown */
|
||||
HL::Pic::WriteApicRegister(APIC_TICR, InitialCount);
|
||||
|
||||
/* Wait for 10ms */
|
||||
StallExecution(10000);
|
||||
|
||||
/* Read current tick count from APIC timer and clear APIC timer */
|
||||
CurrentCount = HL::Pic::ReadApicRegister(APIC_TCCR);
|
||||
HL::Pic::WriteApicRegister(APIC_TICR, 0);
|
||||
|
||||
/* Calculate APIC timer frequency based on ticks passed */
|
||||
Frequency = (InitialCount - CurrentCount) * 100;
|
||||
|
||||
/* Verify APIC timer frequency */
|
||||
if(Frequency == 0)
|
||||
{
|
||||
/* Unable to calibrate APIC timer, return error */
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Save APIC timer frequency */
|
||||
TimerFrequency = Frequency;
|
||||
|
||||
/* Print APIC timer frequency and return success */
|
||||
DebugPrint(L"APIC Timer calibrated: %u Ticks/s\n", TimerFrequency);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes and calibrates the Local APIC Timer.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Timer::InitializeApicTimer(VOID)
|
||||
{
|
||||
XTSTATUS Status;
|
||||
|
||||
/* Set APIC timer to divide by 1 */
|
||||
HL::Pic::WriteApicRegister(APIC_TDCR, TIMER_DivideBy1);
|
||||
|
||||
/* Calibrate the APIC timer */
|
||||
Status = CalibrateApicTimer();
|
||||
if(Status != STATUS_SUCCESS)
|
||||
{
|
||||
/* System cannot operate without a calibrated system timer, raise kernel panic */
|
||||
KE::Crash::Panic(0);
|
||||
}
|
||||
|
||||
/* Set the default system profile interval */
|
||||
HL::Timer::SetProfileInterval(1000);
|
||||
|
||||
/* Program the APIC timer for periodic mode */
|
||||
StopProfileInterrupt(ProfileXtKernel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a basic Timer initialization.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Timer::InitializeTimer(VOID)
|
||||
{
|
||||
/* Query timer capabilities */
|
||||
QueryTimerCapabilities();
|
||||
|
||||
/* Initialize the APIC timer */
|
||||
InitializeApicTimer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stalls the CPU execution for a specified duration (maximum 3 seconds) using the legacy PIT timer.
|
||||
*
|
||||
* @param MicroSeconds
|
||||
* Specifies the number of microseconds to stall execution.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Timer::PitStallExecution(IN ULONG MicroSeconds)
|
||||
{
|
||||
USHORT CurrentCount, PreviousCount;
|
||||
ULONG TargetTicks, TickCounter;
|
||||
|
||||
/* Validate input parameter */
|
||||
if(MicroSeconds == 0)
|
||||
{
|
||||
/* Nothing to do */
|
||||
return;
|
||||
}
|
||||
else if(MicroSeconds > 3000000)
|
||||
{
|
||||
/* Cap execution stall to 3 seconds */
|
||||
MicroSeconds = 3000000;
|
||||
}
|
||||
|
||||
/* Convert us to PIT ticks and initialize tick counter */
|
||||
TargetTicks = (MicroSeconds * 1193) / 1000;
|
||||
TickCounter = 0;
|
||||
|
||||
/* Configure PIT Channel 0: Read/Write LSB then MSB, Mode 0 (Interrupt on Terminal Count) */
|
||||
HL::IoPort::WritePort8(PIT_COMMAND_PORT, 0x30);
|
||||
|
||||
/* Initialize the PIT counter with the maximum possible value (0xFFFF) */
|
||||
HL::IoPort::WritePort8(PIT_DATA_PORT0, 0xFF);
|
||||
HL::IoPort::WritePort8(PIT_DATA_PORT0, 0xFF);
|
||||
|
||||
/* Latch and read the initial counter value */
|
||||
HL::IoPort::WritePort8(PIT_COMMAND_PORT, 0x00);
|
||||
PreviousCount = HL::IoPort::ReadPort8(PIT_DATA_PORT0);
|
||||
PreviousCount |= (HL::IoPort::ReadPort8(PIT_DATA_PORT0) << 8);
|
||||
|
||||
/* Poll the PIT */
|
||||
while(TickCounter < TargetTicks)
|
||||
{
|
||||
/* Latch the current counter value without stopping the timer */
|
||||
HL::IoPort::WritePort8(PIT_COMMAND_PORT, 0x00);
|
||||
CurrentCount = HL::IoPort::ReadPort8(PIT_DATA_PORT0);
|
||||
CurrentCount |= (HL::IoPort::ReadPort8(PIT_DATA_PORT0) << 8);
|
||||
|
||||
/* Calculate elapsed ticks since the last read */
|
||||
TickCounter += (PreviousCount - CurrentCount) & 0xFFFF;
|
||||
|
||||
/* Update the tracking variable */
|
||||
PreviousCount = CurrentCount;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Probes the processor via CPUID to detect available modern timing and clock generation features.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Timer::QueryTimerCapabilities(VOID)
|
||||
{
|
||||
CPUID_REGISTERS CpuRegisters;
|
||||
ULONG MaxStandardLeaf;
|
||||
ULONG MaxExtendedLeaf;
|
||||
|
||||
/* Query maximum standard CPUID leaf */
|
||||
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
|
||||
CpuRegisters.SubLeaf = 0;
|
||||
CpuRegisters.Eax = 0;
|
||||
CpuRegisters.Ebx = 0;
|
||||
CpuRegisters.Ecx = 0;
|
||||
CpuRegisters.Edx = 0;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
|
||||
/* Save maximum supported standard CPUID leaf */
|
||||
MaxStandardLeaf = CpuRegisters.Eax;
|
||||
|
||||
/* Query maximum extended CPUID leaf */
|
||||
CpuRegisters.Leaf = CPUID_GET_EXTENDED_MAX;
|
||||
CpuRegisters.SubLeaf = 0;
|
||||
CpuRegisters.Eax = 0;
|
||||
CpuRegisters.Ebx = 0;
|
||||
CpuRegisters.Ecx = 0;
|
||||
CpuRegisters.Edx = 0;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
|
||||
/* Save maximum supported extended CPUID leaf */
|
||||
MaxExtendedLeaf = CpuRegisters.Eax;
|
||||
|
||||
/* Check TSC-Deadline mode if leaf supported */
|
||||
if(MaxStandardLeaf >= CPUID_GET_STANDARD1_FEATURES)
|
||||
{
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||
CpuRegisters.SubLeaf = 0;
|
||||
CpuRegisters.Eax = 0;
|
||||
CpuRegisters.Ebx = 0;
|
||||
CpuRegisters.Ecx = 0;
|
||||
CpuRegisters.Edx = 0;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
|
||||
/* Verify TSC-Deadline support */
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_TSC_DEADLINE)
|
||||
{
|
||||
TimerCapabilities.TscDeadline = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check Always Running APIC Timer - ARAT if leaf supported */
|
||||
if(MaxStandardLeaf >= CPUID_GET_POWER_MANAGEMENT)
|
||||
{
|
||||
CpuRegisters.Leaf = CPUID_GET_POWER_MANAGEMENT;
|
||||
CpuRegisters.SubLeaf = 0;
|
||||
CpuRegisters.Eax = 0;
|
||||
CpuRegisters.Ebx = 0;
|
||||
CpuRegisters.Ecx = 0;
|
||||
CpuRegisters.Edx = 0;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
|
||||
/* Verify ARAT support */
|
||||
if(CpuRegisters.Eax & CPUID_FEATURES_EAX_ARAT)
|
||||
{
|
||||
TimerCapabilities.Arat = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check Always Running Timer - ART if leaf supported */
|
||||
if(MaxStandardLeaf >= CPUID_GET_TSC_CRYSTAL_CLOCK)
|
||||
{
|
||||
CpuRegisters.Leaf = CPUID_GET_TSC_CRYSTAL_CLOCK;
|
||||
CpuRegisters.SubLeaf = 0;
|
||||
CpuRegisters.Eax = 0;
|
||||
CpuRegisters.Ebx = 0;
|
||||
CpuRegisters.Ecx = 0;
|
||||
CpuRegisters.Edx = 0;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
|
||||
/* Verify ART support */
|
||||
if(CpuRegisters.Eax != 0 && CpuRegisters.Ebx != 0)
|
||||
{
|
||||
TimerCapabilities.Art = TRUE;
|
||||
|
||||
/* Save the TSC scaling ratios */
|
||||
TimerCapabilities.TscDenominator = CpuRegisters.Eax;
|
||||
TimerCapabilities.TscNumerator = CpuRegisters.Ebx;
|
||||
|
||||
/* Check if ECX contains the nominal frequency of the core crystal clock */
|
||||
if(CpuRegisters.Ecx != 0)
|
||||
{
|
||||
/* Save the base frequency for the APIC Timer */
|
||||
TimerCapabilities.TimerFrequency = CpuRegisters.Ecx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check RDTSCP instruction support if leaf supported */
|
||||
if(MaxExtendedLeaf >= CPUID_GET_EXTENDED_FEATURES)
|
||||
{
|
||||
CpuRegisters.Leaf = CPUID_GET_EXTENDED_FEATURES;
|
||||
CpuRegisters.SubLeaf = 0;
|
||||
CpuRegisters.Eax = 0;
|
||||
CpuRegisters.Ebx = 0;
|
||||
CpuRegisters.Ecx = 0;
|
||||
CpuRegisters.Edx = 0;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
|
||||
/* Verify RDTSCP support */
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_RDTSCP)
|
||||
{
|
||||
TimerCapabilities.RDTSCP = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check Invariant TSC if leaf supported */
|
||||
if(MaxExtendedLeaf >= CPUID_GET_ADVANCED_POWER_MANAGEMENT)
|
||||
{
|
||||
CpuRegisters.Leaf = CPUID_GET_ADVANCED_POWER_MANAGEMENT;
|
||||
CpuRegisters.SubLeaf = 0;
|
||||
CpuRegisters.Eax = 0;
|
||||
CpuRegisters.Ebx = 0;
|
||||
CpuRegisters.Ecx = 0;
|
||||
CpuRegisters.Edx = 0;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
|
||||
/* Verify Invariant TSC support */
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSCI)
|
||||
{
|
||||
TimerCapabilities.InvariantTsc = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the profile interrupt interval. The interval may be bounded by hardware capabilities.
|
||||
*
|
||||
* @param Interval
|
||||
* Supplies the requested profile interval in 100-nanosecond units.
|
||||
*
|
||||
* @return This routine returns the actual profile interval that was set.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
ULONG_PTR
|
||||
HL::Timer::SetProfileInterval(IN ULONG_PTR Interval)
|
||||
{
|
||||
/* Validate and bound the requested profile interval against hardware limits */
|
||||
if(Interval < MIN_PROFILE_INTERVAL)
|
||||
{
|
||||
/* Enforce the minimum profile interval limit */
|
||||
Interval = MIN_PROFILE_INTERVAL;
|
||||
}
|
||||
else if(Interval > MAX_PROFILE_INTERVAL)
|
||||
{
|
||||
/* Enforce the maximum profile interval limit */
|
||||
Interval = MAX_PROFILE_INTERVAL;
|
||||
}
|
||||
|
||||
/* Calculate the number of APIC timer ticks required for the requested interval */
|
||||
ProfilingInterval = (TimerFrequency / 10000) * (Interval / 1000);
|
||||
|
||||
/* Update the APIC Timer Initial Count Register (TICR) to apply the new interval immediately */
|
||||
HL::Pic::WriteApicRegister(APIC_TICR, ProfilingInterval);
|
||||
|
||||
/* Return the actual interval */
|
||||
return Interval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stalls the CPU execution for a specified duration.
|
||||
*
|
||||
* @param MicroSeconds
|
||||
* Supplies the number of microseconds to stall execution.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Timer::StallExecution(IN ULONG MicroSeconds)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
|
||||
/* ACPI PM Timer not supported, fall back to PIT */
|
||||
PitStallExecution(MicroSeconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the profile interrupt for the specified profile source.
|
||||
*
|
||||
* @param ProfileSource
|
||||
* Supplies the source of the profile interrupt to start.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Timer::StartProfileInterrupt(IN KPROFILE_SOURCE ProfileSource)
|
||||
{
|
||||
APIC_LVT_REGISTER LvtRegister;
|
||||
|
||||
/* Handle only ProfileTime and ProfileXtKernel */
|
||||
if(ProfileSource != ProfileTime && ProfileSource != ProfileXtKernel)
|
||||
{
|
||||
/* Invalid profile source, do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the interval */
|
||||
HL::Pic::WriteApicRegister(APIC_TICR, ProfilingInterval);
|
||||
|
||||
/* Unmask interrupt */
|
||||
LvtRegister.Long = 0;
|
||||
LvtRegister.Mask = 0;
|
||||
LvtRegister.DeliveryMode = APIC_DM_FIXED;
|
||||
LvtRegister.TimerMode = 1;
|
||||
LvtRegister.TriggerMode = APIC_TGM_EDGE;
|
||||
LvtRegister.Vector = APIC_VECTOR_PROFILE;
|
||||
HL::Pic::WriteApicRegister(APIC_TMRLVTR, LvtRegister.Long);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the profile interrupt for the specified profile source.
|
||||
*
|
||||
* @param ProfileSource
|
||||
* Supplies the source of the profile interrupt to stop.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Timer::StopProfileInterrupt(IN KPROFILE_SOURCE ProfileSource)
|
||||
{
|
||||
APIC_LVT_REGISTER LvtRegister;
|
||||
|
||||
/* Handle only ProfileTime and ProfileXtKernel */
|
||||
if(ProfileSource != ProfileTime && ProfileSource != ProfileXtKernel)
|
||||
{
|
||||
/* Invalid profile source, do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Mask interrupt */
|
||||
LvtRegister.Long = 0;
|
||||
LvtRegister.Mask = 1;
|
||||
LvtRegister.DeliveryMode = APIC_DM_FIXED;
|
||||
LvtRegister.TimerMode = 1;
|
||||
LvtRegister.TriggerMode = APIC_TGM_EDGE;
|
||||
LvtRegister.Vector = APIC_VECTOR_PROFILE;
|
||||
HL::Pic::WriteApicRegister(APIC_TMRLVTR, LvtRegister.Long);
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
#include XTOS_ARCH_HEADER(ar, asmsup.hh)
|
||||
#include XTOS_ARCH_HEADER(ar, assembly.hh)
|
||||
#include XTOS_ARCH_HEADER(ar, cpufunc.hh)
|
||||
#include XTOS_ARCH_HEADER(ar, procsup.hh)
|
||||
#include XTOS_ARCH_HEADER(ar, traps.hh)
|
||||
|
||||
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 UINT ReadMxCsrRegister(VOID);
|
||||
STATIC XTCDECL ULONGLONG ReadTimeStampCounter(VOID);
|
||||
STATIC XTCDECL ULONGLONG ReadTimeStampCounterProcessor(OUT PULONG TscAux);
|
||||
STATIC XTCDECL VOID ReadWriteBarrier(VOID);
|
||||
STATIC XTCDECL VOID SetInterruptFlag(VOID);
|
||||
STATIC XTCDECL VOID StoreGlobalDescriptorTable(OUT PVOID Destination);
|
||||
|
||||
@@ -24,7 +24,6 @@ namespace AR
|
||||
STATIC KIDTENTRY InitialIdt[IDT_ENTRIES];
|
||||
STATIC KPROCESSOR_BLOCK InitialProcessorBlock;
|
||||
STATIC KTSS InitialTss;
|
||||
STATIC UCHAR NmiStack[KERNEL_STACK_SIZE];
|
||||
|
||||
public:
|
||||
STATIC XTAPI PVOID GetBootStack(VOID);
|
||||
@@ -32,13 +31,6 @@ namespace AR
|
||||
OUT PVOID *TrampolineCode,
|
||||
OUT PULONG_PTR TrampolineSize);
|
||||
STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures);
|
||||
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
|
||||
IN USHORT Vector,
|
||||
IN PVOID Handler,
|
||||
IN USHORT Selector,
|
||||
IN USHORT Ist,
|
||||
IN USHORT Dpl,
|
||||
IN USHORT Type);
|
||||
|
||||
private:
|
||||
STATIC XTAPI VOID IdentifyProcessor(VOID);
|
||||
@@ -55,13 +47,11 @@ namespace AR
|
||||
OUT PKTSS *Tss,
|
||||
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
||||
OUT PVOID *KernelBootStack,
|
||||
OUT PVOID *KernelFaultStack,
|
||||
OUT PVOID *KernelNmiStack);
|
||||
OUT PVOID *KernelFaultStack);
|
||||
STATIC XTAPI VOID InitializeSegments(VOID);
|
||||
STATIC XTAPI VOID InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelBootStack,
|
||||
IN PVOID KernelFaultStack,
|
||||
IN PVOID KernelNmiStack);
|
||||
IN PVOID KernelFaultStack);
|
||||
STATIC XTAPI VOID SetGdtEntry(IN PKGDTENTRY Gdt,
|
||||
IN USHORT Selector,
|
||||
IN ULONG_PTR Base,
|
||||
@@ -72,6 +62,13 @@ namespace AR
|
||||
STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
||||
IN USHORT Selector,
|
||||
IN ULONG_PTR Base);
|
||||
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
|
||||
IN USHORT Vector,
|
||||
IN PVOID Handler,
|
||||
IN USHORT Selector,
|
||||
IN USHORT Ist,
|
||||
IN USHORT Dpl,
|
||||
IN USHORT Type);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -17,14 +17,9 @@ namespace AR
|
||||
{
|
||||
class Traps
|
||||
{
|
||||
private:
|
||||
STATIC PINTERRUPT_HANDLER UnhandledInterruptRoutine;
|
||||
|
||||
public:
|
||||
STATIC XTCDECL VOID DispatchInterrupt(IN PKTRAP_FRAME TrapFrame) XTSYMBOL("ArDispatchInterrupt");
|
||||
STATIC XTCDECL VOID DispatchTrap(IN PKTRAP_FRAME TrapFrame) XTSYMBOL("ArDispatchTrap");
|
||||
STATIC XTCDECL VOID DispatchTrap(IN PKTRAP_FRAME TrapFrame);
|
||||
STATIC XTCDECL VOID InitializeSystemCallMsrs(VOID);
|
||||
STATIC XTCDECL VOID SetUnhandledInterruptRoutine(PINTERRUPT_HANDLER Handler);
|
||||
|
||||
private:
|
||||
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 */
|
||||
@@ -39,7 +39,6 @@ namespace AR
|
||||
STATIC XTCDECL ULONGLONG ReadModelSpecificRegister(IN ULONG Register);
|
||||
STATIC XTCDECL UINT ReadMxCsrRegister(VOID);
|
||||
STATIC XTCDECL ULONGLONG ReadTimeStampCounter(VOID);
|
||||
STATIC XTCDECL ULONGLONG ReadTimeStampCounterProcessor(OUT PULONG TscAux);
|
||||
STATIC XTCDECL VOID ReadWriteBarrier(VOID);
|
||||
STATIC XTCDECL VOID SetInterruptFlag(VOID);
|
||||
STATIC XTCDECL VOID StoreGlobalDescriptorTable(OUT PVOID Destination);
|
||||
|
||||
@@ -25,7 +25,6 @@ namespace AR
|
||||
STATIC KIDTENTRY InitialIdt[IDT_ENTRIES];
|
||||
STATIC KPROCESSOR_BLOCK InitialProcessorBlock;
|
||||
STATIC KTSS InitialTss;
|
||||
STATIC UCHAR NmiStack[KERNEL_STACK_SIZE];
|
||||
STATIC UCHAR NonMaskableInterruptTss[KTSS_IO_MAPS];
|
||||
|
||||
|
||||
@@ -35,13 +34,6 @@ namespace AR
|
||||
OUT PVOID *TrampolineCode,
|
||||
OUT PULONG_PTR TrampolineSize);
|
||||
STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures);
|
||||
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
|
||||
IN USHORT Vector,
|
||||
IN PVOID Handler,
|
||||
IN USHORT Selector,
|
||||
IN USHORT Ist,
|
||||
IN USHORT Dpl,
|
||||
IN USHORT Type);
|
||||
|
||||
private:
|
||||
STATIC XTAPI VOID IdentifyProcessor(VOID);
|
||||
@@ -58,13 +50,11 @@ namespace AR
|
||||
OUT PKTSS *Tss,
|
||||
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
||||
OUT PVOID *KernelBootStack,
|
||||
OUT PVOID *KernelFaultStack,
|
||||
OUT PVOID *KernelNmiStack);
|
||||
OUT PVOID *KernelFaultStack);
|
||||
STATIC XTAPI VOID InitializeSegments(VOID);
|
||||
STATIC XTAPI VOID InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelBootStack,
|
||||
IN PVOID KernelFaultStack,
|
||||
IN PVOID KernelNmiStack);
|
||||
IN PVOID KernelFaultStack);
|
||||
STATIC XTAPI VOID SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelFaultStack);
|
||||
STATIC XTAPI VOID SetGdtEntry(IN PKGDTENTRY Gdt,
|
||||
@@ -77,8 +67,15 @@ namespace AR
|
||||
STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
||||
IN USHORT Selector,
|
||||
IN ULONG_PTR Base);
|
||||
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
|
||||
IN USHORT Vector,
|
||||
IN PVOID Handler,
|
||||
IN USHORT Selector,
|
||||
IN USHORT Ist,
|
||||
IN USHORT Dpl,
|
||||
IN USHORT Type);
|
||||
STATIC XTAPI VOID SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelNmiStack);
|
||||
IN PVOID KernelFaultStack);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/**
|
||||
/**@s
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/includes/ar/i686/traps.hh
|
||||
@@ -17,13 +17,8 @@ namespace AR
|
||||
{
|
||||
class Traps
|
||||
{
|
||||
private:
|
||||
STATIC PINTERRUPT_HANDLER UnhandledInterruptRoutine;
|
||||
|
||||
public:
|
||||
STATIC XTCDECL VOID DispatchInterrupt(IN PKTRAP_FRAME TrapFrame) XTSYMBOL("_ArDispatchInterrupt");
|
||||
STATIC XTCDECL VOID DispatchTrap(IN PKTRAP_FRAME TrapFrame) XTSYMBOL("_ArDispatchTrap");
|
||||
STATIC XTCDECL VOID SetUnhandledInterruptRoutine(PINTERRUPT_HANDLER Handler);
|
||||
STATIC XTCDECL VOID DispatchTrap(IN PKTRAP_FRAME TrapFrame);
|
||||
|
||||
private:
|
||||
STATIC XTCDECL VOID HandleTrap00(IN PKTRAP_FRAME TrapFrame);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user