Compare commits
348 Commits
40d54743e0
...
threads
| Author | SHA1 | Date | |
|---|---|---|---|
|
e5cf62cbfb
|
|||
|
10aaac59e4
|
|||
|
e3081c0cf5
|
|||
|
a0e707d35f
|
|||
|
042bf8520c
|
|||
|
30a6517109
|
|||
|
cba4c6fffb
|
|||
|
66f74be947
|
|||
|
0ccf20f0c9
|
|||
|
a2801bab2a
|
|||
|
9fcd81a507
|
|||
|
46fb492032
|
|||
|
b2e3a6afe0
|
|||
|
2389bcbed1
|
|||
|
213713b6d2
|
|||
|
c1bc4e4940
|
|||
|
b76a240fd8
|
|||
|
d164495d48
|
|||
|
2b7fc5b41d
|
|||
|
5cd52a4a12
|
|||
|
c58305022f
|
|||
|
d8f4f6bfd0
|
|||
|
ef4f9ba74d
|
|||
|
f9cbe78f84
|
|||
|
91946ae88f
|
|||
|
84d35e3c97
|
|||
|
9ef8c569d5
|
|||
|
7d9c338e2a
|
|||
|
2868db63ca
|
|||
|
9d5466594a
|
|||
|
119480382b
|
|||
|
3011df6f3c
|
|||
|
6e4f9dd5b1
|
|||
|
42d6426318
|
|||
|
757acb732e
|
|||
|
a54c4b48fb
|
|||
|
314012cad9
|
|||
|
b3ce1a8be8
|
|||
|
d6f925ebfd
|
|||
|
53a8b57a96
|
|||
|
77c1138f7d
|
|||
|
03f97d94ae
|
|||
|
8c6e06c973
|
|||
|
f2168e8c55
|
|||
|
6184e9e73d
|
|||
|
3d42ecf3d3
|
|||
|
c309bd769d
|
|||
|
79c9b2abef
|
|||
|
d9a4217f8b
|
|||
|
7b27b09748
|
|||
|
195c4a34ad
|
|||
|
e266b30e24
|
|||
|
28daa1718c
|
|||
|
b016ffd0d7
|
|||
|
8479c95e82
|
|||
|
f66e27cf83
|
|||
|
cf846d5abe
|
|||
|
08f26c6762
|
|||
|
19a1b11236
|
|||
|
d10b2cc2a1
|
|||
|
5475d970c4
|
|||
|
18d36b9f23
|
|||
|
fe02bb9214
|
|||
|
76b1807eee
|
|||
|
e431bccd44
|
|||
|
7526f90759
|
|||
|
c45b81d345
|
|||
|
95ec18a1de
|
|||
|
9faf19b57e
|
|||
|
bae43034a6
|
|||
|
156ae3efab
|
|||
|
854a8c8eef
|
|||
|
1fca2400a4
|
|||
|
ea1ad3c6b1
|
|||
|
cea860b008
|
|||
|
6560ca9b96
|
|||
|
ffcb2dbeda
|
|||
|
780bf92b40
|
|||
|
cc288f5417
|
|||
|
55eb3047e3
|
|||
|
8597e37650
|
|||
|
1c90218042
|
|||
|
f6f37494cd
|
|||
|
d1aa3cf481
|
|||
|
208684c3b4
|
|||
|
89681897d7
|
|||
|
e035666f7a
|
|||
|
df35bf8601
|
|||
|
15523e7d71
|
|||
|
f79c9023d8
|
|||
|
97703c7932
|
|||
|
2f5902119d
|
|||
|
7a10135731
|
|||
|
b0074637f8
|
|||
|
1a062ca05f
|
|||
|
c702152cca
|
|||
|
81c799e590
|
|||
|
cf0d7f0a40
|
|||
|
b0d2868f82
|
|||
|
32f0b747a1
|
|||
|
c57aa98923
|
|||
|
429e4ef6f1
|
|||
|
39928f2ef4
|
|||
|
51ec7e3bab
|
|||
|
f3ae70573c
|
|||
|
830f84ab26
|
|||
|
5a9df7ca86
|
|||
|
4bcdcda3a0
|
|||
|
7a27912dac
|
|||
|
cf4b91ac83
|
|||
|
36c3d92399
|
|||
|
6a2a35c008
|
|||
|
a9202f5b57
|
|||
|
4cbefe3a22
|
|||
|
3841ceaf5b
|
|||
|
e2eb784eef
|
|||
|
6078a5ba29
|
|||
|
663f5cd048
|
|||
|
5999906bf0
|
|||
|
1e0c1490fb
|
|||
|
5b0eebdb43
|
|||
|
9e64939de4
|
|||
|
b911670121
|
|||
|
d175a817a5
|
|||
|
b285bc7312
|
|||
|
c8cd198c4e
|
|||
|
95d45f5a0a
|
|||
|
766e4d9603
|
|||
|
a601fd0afa
|
|||
|
cc23e459e0
|
|||
|
d36b678ba1
|
|||
|
43265bcddb
|
|||
|
47d4069d6f
|
|||
|
904df63198
|
|||
|
1df971a71e
|
|||
|
2a413d5717
|
|||
|
9c2357dfe6
|
|||
|
f82562f450
|
|||
|
a33b63842a
|
|||
|
4256a312ae
|
|||
|
678a0f4f48
|
|||
|
7344c5ed4a
|
|||
|
537fbc8af4
|
|||
|
cf25af23d1
|
|||
|
f680830b53
|
|||
|
53a239958f
|
|||
|
f13326ffaf
|
|||
|
75e7760d04
|
|||
|
02d0f3f538
|
|||
|
e2a78389f2
|
|||
|
81fdf1f77a
|
|||
|
631f58bf72
|
|||
|
1d2d66fc83
|
|||
|
34aba8c7c7
|
|||
|
5e764a0d17
|
|||
|
65e86db731
|
|||
|
615d253bb4
|
|||
|
2fcbc7bee8
|
|||
|
2c14da997d
|
|||
|
a7c2182d4a
|
|||
|
0aabc206a1
|
|||
|
7d8b33390a
|
|||
|
5a5604c35d
|
|||
|
addf9addab
|
|||
|
f562aa0874
|
|||
|
19a9dfe7c6
|
|||
|
46594f1fc3
|
|||
|
a93ebbfb5b
|
|||
|
53726b5743
|
|||
|
71870cd178
|
|||
|
6f3b5b5e51
|
|||
|
6b689baa7a
|
|||
|
9ac64605d3
|
|||
|
102b357a75
|
|||
|
6eb0b4d982
|
|||
|
d8cb7c9242
|
|||
|
9002ac8b5c
|
|||
|
72a03f641d
|
|||
|
fe2e78f3c7
|
|||
|
6e4f0ba6e4
|
|||
|
19092eda2e
|
|||
|
b03cca65d8
|
|||
|
fec5bf65f1
|
|||
|
7836dbe147
|
|||
|
297aba248b
|
|||
|
d41c90f541
|
|||
|
f2c70d582a
|
|||
|
24c9ae321c
|
|||
|
7a18a2602f
|
|||
|
a39835493a
|
|||
|
4e7113a079
|
|||
|
8080e07281
|
|||
|
fc0e1384c4
|
|||
|
9603453334
|
|||
|
29368a0dd8
|
|||
|
8ee97ac0ae
|
|||
|
6bbeb657ea
|
|||
|
c824e15cdb
|
|||
|
38b2e7a1ed
|
|||
|
efff262fb5
|
|||
|
8da6fefdc0
|
|||
|
14cbd63b01
|
|||
|
63d18aad1e
|
|||
|
ed52d421ea
|
|||
|
6df6a012d2
|
|||
|
ac675b037e
|
|||
|
ca4f3acc0e
|
|||
|
5b7761fe7d
|
|||
|
7a2a27b1b9
|
|||
|
1cff58c106
|
|||
|
9185ceade6
|
|||
|
908bc87b06
|
|||
|
6b852556a5
|
|||
|
ae18468bad
|
|||
|
42bbdc9b26
|
|||
|
b1ecdc3439
|
|||
|
fd7e18989d
|
|||
|
757eac08c6
|
|||
|
760e58f993
|
|||
|
c8868ead47
|
|||
|
58981e0087
|
|||
|
06635ed014
|
|||
|
5a92173586
|
|||
|
897d9d4099
|
|||
|
6b14f31107
|
|||
|
976eee9ce3
|
|||
|
689951cfde
|
|||
|
4cb5b12e68
|
|||
|
9761569e06
|
|||
|
100b58312f
|
|||
|
c5b0d15830
|
|||
|
8107692d83
|
|||
|
3262ad78c1
|
|||
|
85fb08b3d4
|
|||
|
0952dd80b2
|
|||
|
a3178e94bd
|
|||
|
f7554e0e24
|
|||
|
27440aefc4
|
|||
|
ba85c88544
|
|||
|
b417f84492
|
|||
|
48ef4bcdca
|
|||
|
7a28cf1c0a
|
|||
|
1050ddea8a
|
|||
|
a7151dbc89
|
|||
|
d532303b7f
|
|||
|
7017985682
|
|||
|
7aba8aa4ec
|
|||
|
d1eed619a7
|
|||
|
6cbda52d6b
|
|||
|
f03515b0eb
|
|||
|
03a9907bee
|
|||
|
49fde5adbd
|
|||
|
165e82f78b
|
|||
|
3ad10b8b07
|
|||
|
e2e2b05bc6
|
|||
|
98733aa62b
|
|||
|
58deafb1d8
|
|||
|
88d1f6f2ae
|
|||
|
6a983fe33c
|
|||
|
8d58a7fcc1
|
|||
|
13cf7b5fe7
|
|||
|
6a46dad9c5
|
|||
|
534aaba27e
|
|||
|
119679c996
|
|||
|
b1d013977f
|
|||
|
4d12f7ac01
|
|||
|
439ea891ca
|
|||
|
8ab3ddb8eb
|
|||
|
4afe678667
|
|||
|
3b76146d53
|
|||
|
341759a325
|
|||
|
122bae21a2
|
|||
|
5dc782ca24
|
|||
|
f2baa765b4
|
|||
|
2dd1fdf869
|
|||
|
b1e849a251
|
|||
|
58010c27f4
|
|||
|
98f2f449f9
|
|||
|
76ee56c762
|
|||
|
ba41ad8f0b
|
|||
|
a217391338
|
|||
|
5824e9d366
|
|||
|
57bd3d505e
|
|||
|
d6c2dabcbb
|
|||
|
1f733c120c
|
|||
|
735ccd96a6
|
|||
|
cd4e905054
|
|||
|
715419abe7
|
|||
|
d37f2e3827
|
|||
|
cec5e8b16b
|
|||
|
a08e07e515
|
|||
|
d7f390b236
|
|||
|
55cb12c978
|
|||
|
7d8bfa8f0a
|
|||
|
d00e96baa4
|
|||
|
17f044cb3f
|
|||
|
1fa6e90439
|
|||
|
f15790e25b
|
|||
|
53c5946c04
|
|||
|
9ffb03217a
|
|||
|
4f65773aa9
|
|||
|
f1476912f3
|
|||
|
adb591f8c7
|
|||
|
4ef068dadc
|
|||
|
a0d5ee17c2
|
|||
|
9935d2d26b
|
|||
|
9eff9874c5
|
|||
|
09516835d0
|
|||
|
2a24ce9a35
|
|||
|
9ea79c92a6
|
|||
|
c30df8e5b5
|
|||
|
397d0a9f29
|
|||
|
0fa23ccf40
|
|||
|
87a91bfeb1
|
|||
|
232b92fd7e
|
|||
|
d88f9f0a15
|
|||
|
154b2062ba
|
|||
|
38d49eece4
|
|||
|
d00577ac8d
|
|||
|
620fc24cd2
|
|||
|
494b615dc2
|
|||
|
d834b7e0c8
|
|||
|
987b8f45d7
|
|||
|
52ecbdeaff
|
|||
|
121f461491
|
|||
|
f4b189adef
|
|||
|
40c4860548
|
|||
|
d2a7ae46ac
|
|||
|
8a02a5aca3
|
|||
|
96df5a80b8
|
|||
|
489ef8a514
|
|||
|
8c6c63465f
|
|||
|
e9aaeab982
|
|||
|
a608b26fde
|
|||
|
3ce009db41
|
|||
|
a0b0938099
|
|||
|
32d3672a51
|
|||
|
0c17337388
|
|||
|
9c449bed43
|
|||
|
a64aa83eb8
|
|||
|
64b5de98c8
|
|||
|
4e02664977
|
|||
|
bad3aaf6e0
|
|||
|
9b19bc94b3
|
|||
|
9479f3d364
|
|||
|
8d97ea4112
|
|||
|
576a2b7f1b
|
|||
|
916d124c9b
|
@@ -55,6 +55,9 @@ add_definitions(-D__XTOS__)
|
||||
add_definitions(-DXTOS_SOURCE_DIR="${EXECTOS_SOURCE_DIR}")
|
||||
add_definitions(-DXTOS_BINARY_DIR="${EXECTOS_BINARY_DIR}")
|
||||
|
||||
# Add assembler flags
|
||||
add_compiler_asmflags(-D__XTOS_ASSEMBLER__)
|
||||
|
||||
# Compute __FILE__ definition
|
||||
file(RELATIVE_PATH _PATH_PREFIX ${EXECTOS_BINARY_DIR} ${EXECTOS_SOURCE_DIR})
|
||||
add_compiler_flags(-D__RELFILE__="&__FILE__[__FILE__[0] == '.' ? sizeof \\\"${_PATH_PREFIX}\\\" - 1 : sizeof XTOS_SOURCE_DIR]")
|
||||
|
||||
@@ -221,10 +221,15 @@ Console::QueryMode(OUT PUINT_PTR ResX,
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
EFI_STATUS
|
||||
Console::ReadKeyStroke(OUT PEFI_INPUT_KEY Key)
|
||||
{
|
||||
XtLoader::GetEfiSystemTable()->ConIn->ReadKeyStroke(XtLoader::GetEfiSystemTable()->ConIn, 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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -56,6 +56,21 @@ 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;
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
/* Minimal forward references for AR classes used by XTLDR */
|
||||
namespace AR
|
||||
{
|
||||
class CpuFunc
|
||||
class CpuFunctions
|
||||
{
|
||||
public:
|
||||
STATIC XTCDECL BOOLEAN CpuId(IN OUT PCPUID_REGISTERS Registers);
|
||||
@@ -25,12 +25,12 @@ namespace AR
|
||||
IN UINT_PTR Value);
|
||||
};
|
||||
|
||||
class ProcSup
|
||||
class ProcessorSupport
|
||||
{
|
||||
public:
|
||||
STATIC XTAPI VOID GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
|
||||
OUT PVOID *TrampolineCode,
|
||||
OUT PULONG_PTR TrampolineSize);
|
||||
OUT PULONG TrampolineSize);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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 VOID ReadKeyStroke(OUT PEFI_INPUT_KEY Key);
|
||||
STATIC XTCDECL EFI_STATUS 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,11 +253,47 @@ 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
|
||||
|
||||
@@ -116,7 +116,7 @@ Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
EFI_STATUS Status;
|
||||
EFI_PHYSICAL_ADDRESS TrampolineAddress;
|
||||
PXT_TRAMPOLINE_ENTRY TrampolineEntry;
|
||||
ULONG_PTR TrampolineSize;
|
||||
ULONG TrampolineSize;
|
||||
PVOID TrampolineCode;
|
||||
|
||||
/* Check the configured page map level to set the LA57 state accordingly */
|
||||
|
||||
@@ -302,6 +302,7 @@ 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;
|
||||
@@ -328,8 +329,11 @@ 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, (RTL::WideString::WideStringLength(ModuleName, 0) + 1) * sizeof(WCHAR));
|
||||
RTL::Memory::CopyMemory(ModuleFileName, ModuleName, ModuleNameLength * sizeof(WCHAR));
|
||||
RTL::WideString::ConcatenateWideString(ModuleFileName, (PWCHAR)L".EFI", 0);
|
||||
|
||||
/* Open EFI volume */
|
||||
@@ -438,7 +442,8 @@ 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;
|
||||
}
|
||||
|
||||
@@ -501,8 +506,19 @@ 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;
|
||||
@@ -1016,7 +1032,7 @@ Protocol::InstallXtLoaderProtocol()
|
||||
LoaderProtocol.Boot.RegisterMenu = XtLoader::RegisterBootMenu;
|
||||
LoaderProtocol.Boot.RegisterProtocol = RegisterBootProtocol;
|
||||
LoaderProtocol.BootUtils.GetBooleanParameter = BootUtils::GetBooleanParameter;
|
||||
LoaderProtocol.BootUtils.GetTrampolineInformation = AR::ProcSup::GetTrampolineInformation;
|
||||
LoaderProtocol.BootUtils.GetTrampolineInformation = AR::ProcessorSupport::GetTrampolineInformation;
|
||||
LoaderProtocol.Config.GetBooleanValue = Configuration::GetBooleanValue;
|
||||
LoaderProtocol.Config.GetBootOptionValue = Configuration::GetBootOptionValue;
|
||||
LoaderProtocol.Config.GetEditableOptions = Configuration::GetEditableOptions;
|
||||
@@ -1033,10 +1049,10 @@ Protocol::InstallXtLoaderProtocol()
|
||||
LoaderProtocol.Console.SetAttributes = Console::SetAttributes;
|
||||
LoaderProtocol.Console.SetCursorPosition = Console::SetCursorPosition;
|
||||
LoaderProtocol.Console.Write = Console::Write;
|
||||
LoaderProtocol.Cpu.CpuId = AR::CpuFunc::CpuId;
|
||||
LoaderProtocol.Cpu.ReadControlRegister = AR::CpuFunc::ReadControlRegister;
|
||||
LoaderProtocol.Cpu.ReadModelSpecificRegister = AR::CpuFunc::ReadModelSpecificRegister;
|
||||
LoaderProtocol.Cpu.WriteControlRegister = AR::CpuFunc::WriteControlRegister;
|
||||
LoaderProtocol.Cpu.CpuId = AR::CpuFunctions::CpuId;
|
||||
LoaderProtocol.Cpu.ReadControlRegister = AR::CpuFunctions::ReadControlRegister;
|
||||
LoaderProtocol.Cpu.ReadModelSpecificRegister = AR::CpuFunctions::ReadModelSpecificRegister;
|
||||
LoaderProtocol.Cpu.WriteControlRegister = AR::CpuFunctions::WriteControlRegister;
|
||||
LoaderProtocol.Debug.Print = Debug::Print;
|
||||
LoaderProtocol.Disk.CloseVolume = Volume::CloseVolume;
|
||||
LoaderProtocol.Disk.OpenVolume = Volume::OpenVolume;
|
||||
@@ -1077,6 +1093,7 @@ 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,13 +4,21 @@
|
||||
* FILE: xtldr/shell.cc
|
||||
* DESCRIPTION: XT Boot Loader shell
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtldr.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Starts XTLDR shell.
|
||||
* 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.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
@@ -18,14 +26,410 @@
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
Shell::StartLoaderShell()
|
||||
Shell::CommandExit(IN ULONG Argc,
|
||||
IN PWCHAR *Argv)
|
||||
{
|
||||
/* Initialize console */
|
||||
Console::InitializeConsole();
|
||||
/* Signal the main shell loop to stop and return to the boot menu */
|
||||
ExitRequest = TRUE;
|
||||
}
|
||||
|
||||
/* Print prompt */
|
||||
PrintPrompt();
|
||||
for(;;);
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,9 +446,486 @@ Shell::PrintPrompt()
|
||||
/* Set prompt color */
|
||||
Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_YELLOW);
|
||||
|
||||
/* Print prompt */
|
||||
Console::Print(L"XTLDR> ");
|
||||
/* Print prompt at the start of the line */
|
||||
Console::Print(L"\rXTLDR> ");
|
||||
|
||||
/* 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.UnicodeChar == 0x02)
|
||||
else if(Key.ScanCode == 0x14)
|
||||
{
|
||||
/* CTRL-B key pressed, boot the OS */
|
||||
/* F10 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 CTRL-B to boot.\n");
|
||||
L" option, ESC to return to the main boot menu or F10 to boot.\n");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
add_subdirectory("xtadk")
|
||||
|
||||
set_sdk_target("xtdk/" "include")
|
||||
|
||||
@@ -59,6 +59,86 @@ function(add_module_linker_flags MODULE FLAGS)
|
||||
set_module_property(${MODULE} LINK_FLAGS ${FLAGS})
|
||||
endfunction()
|
||||
|
||||
# This function compiles XT Assembly Development Kit
|
||||
function(generate_xtadk TARGET_NAME SOURCE_FILES)
|
||||
# Define the absolute destination path for the generated header file
|
||||
set(HEADER_OUTPUT "${EXECTOS_BINARY_DIR}/sdk/includes/${TARGET_NAME}.h")
|
||||
get_filename_component(HEADER_OUTPUT_DIRECTORY "${HEADER_OUTPUT}" DIRECTORY)
|
||||
|
||||
# Tokenize global CXX flags into a list to ensure correct argument expansion
|
||||
separate_arguments(COMPILER_FLAGS NATIVE_COMMAND "${CMAKE_CXX_FLAGS}")
|
||||
|
||||
# Resolve and tokenize build-configuration specific flags
|
||||
string(TOUPPER "${CMAKE_BUILD_TYPE}" BUILD_TYPE)
|
||||
if(BUILD_TYPE)
|
||||
separate_arguments(BUILD_TYPE_SPECIFIC_FLAGS NATIVE_COMMAND "${CMAKE_CXX_FLAGS_${BUILD_TYPE}}")
|
||||
endif()
|
||||
|
||||
# Retrieve compiler definitions, include paths, and options
|
||||
get_directory_property(COMPILE_DEFINITIONS COMPILE_DEFINITIONS)
|
||||
get_directory_property(INCLUDE_DIRECTORIES INCLUDE_DIRECTORIES)
|
||||
get_directory_property(COMPILE_OPTIONS COMPILE_OPTIONS)
|
||||
|
||||
# Initialize the final compiler argument list
|
||||
set(COMPILER_ARGUMENTS "")
|
||||
list(APPEND COMPILER_ARGUMENTS ${COMPILER_FLAGS} ${BUILD_TYPE_SPECIFIC_FLAGS})
|
||||
|
||||
# Transform definitions into MSVC-style
|
||||
foreach(DEFINITION ${COMPILE_DEFINITIONS})
|
||||
list(APPEND COMPILER_ARGUMENTS "/D${DEFINITION}")
|
||||
endforeach()
|
||||
|
||||
# Transform include paths into MSVC-style
|
||||
foreach(INCLUDE_PATH ${INCLUDE_DIRECTORIES})
|
||||
list(APPEND COMPILER_ARGUMENTS "/I${INCLUDE_PATH}")
|
||||
endforeach()
|
||||
|
||||
# Append all supplemental compiler options
|
||||
list(APPEND COMPILER_ARGUMENTS ${COMPILE_OPTIONS})
|
||||
set(COLLECTED_ASSEMBLY_OUTPUTS "")
|
||||
|
||||
# Iterate through each source file to create individual assembly generation rules
|
||||
foreach(SOURCE_FILE_PATH ${SOURCE_FILES})
|
||||
# Extract the base filename
|
||||
get_filename_component(FILENAME_WITHOUT_EXTENSION "${SOURCE_FILE_PATH}" NAME_WE)
|
||||
|
||||
# Define the unique output path for the intermediate assembly file
|
||||
set(CURRENT_ASSEMBLY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FILENAME_WITHOUT_EXTENSION}.S")
|
||||
list(APPEND COLLECTED_ASSEMBLY_OUTPUTS "${CURRENT_ASSEMBLY_OUTPUT}")
|
||||
get_filename_component(CURRENT_ASSEMBLY_DIRECTORY "${CURRENT_ASSEMBLY_OUTPUT}" DIRECTORY)
|
||||
|
||||
# Execute the compiler to generate assembly code
|
||||
add_custom_command(
|
||||
OUTPUT "${CURRENT_ASSEMBLY_OUTPUT}"
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${CURRENT_ASSEMBLY_DIRECTORY}"
|
||||
COMMAND ${CMAKE_CXX_COMPILER}
|
||||
${COMPILER_ARGUMENTS}
|
||||
/c /FAs /Fa${CURRENT_ASSEMBLY_OUTPUT}
|
||||
-- ${SOURCE_FILE_PATH}
|
||||
DEPENDS "${SOURCE_FILE_PATH}"
|
||||
COMMENT "Generating XTADK Assembly: ${FILENAME_WITHOUT_EXTENSION}"
|
||||
VERBATIM
|
||||
COMMAND_EXPAND_LISTS
|
||||
)
|
||||
endforeach()
|
||||
|
||||
# Aggregate all generated assembly units into a single consolidated XTADK header
|
||||
add_custom_command(
|
||||
OUTPUT "${HEADER_OUTPUT}"
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${HEADER_OUTPUT_DIRECTORY}"
|
||||
COMMAND xtadkgen ${COLLECTED_ASSEMBLY_OUTPUTS} -O "${HEADER_OUTPUT}"
|
||||
DEPENDS ${COLLECTED_ASSEMBLY_OUTPUTS}
|
||||
COMMENT "Generating XTADK header: ${TARGET_NAME}"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# Establish the generation target and expose the header directory via an interface library
|
||||
add_custom_target(${TARGET_NAME}_gen DEPENDS "${HEADER_OUTPUT}")
|
||||
add_library(${TARGET_NAME} INTERFACE)
|
||||
add_dependencies(${TARGET_NAME} ${TARGET_NAME}_gen)
|
||||
target_include_directories(${TARGET_NAME} INTERFACE "${EXECTOS_BINARY_DIR}/sdk/includes")
|
||||
endfunction()
|
||||
|
||||
# This function compiles an assembly bootsector file into a flat binary
|
||||
function(compile_bootsector NAME SOURCE BASEADDR ENTRYPOINT)
|
||||
set(BINARY_NAME "${NAME}.bin")
|
||||
|
||||
@@ -13,6 +13,10 @@ The ovmf_vars files, store UEFI variables, which are used to store and retrieve
|
||||
boot options, device settings, and system preferences. The ovmf_vars file contains the persistent variables specific to
|
||||
a virtual machine, allowing it to maintain its configuration across multiple boot sessions.
|
||||
|
||||
## BOCHS ROM BIOS
|
||||
The rombios.bin file contains the ROM BIOS image for Bochs. This image is distributed under the GNU Lesser General Public
|
||||
License (LGPL).
|
||||
|
||||
## Video BIOS (LGPL'd VGABios)
|
||||
The vgabios.bin file contains the Video Bios for Bochs and QEMU. This VGA Bios is very specific to the emulated VGA card.
|
||||
It is NOT meant to drive a physical vga card. It also implements support for VBE version 2.0.
|
||||
|
||||
14
sdk/xtadk/CMakeLists.txt
Normal file
14
sdk/xtadk/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
# XT Assembly Development Kit
|
||||
PROJECT(XTADK)
|
||||
|
||||
# Specify include directories
|
||||
include_directories(
|
||||
${EXECTOS_SOURCE_DIR}/sdk/xtdk
|
||||
${XTADK_SOURCE_DIR}/includes)
|
||||
|
||||
# Specify list of XTADK source code files
|
||||
list(APPEND XTADK_SOURCE
|
||||
${XTADK_SOURCE_DIR}/${ARCH}/ke.cc)
|
||||
|
||||
# Generate assembly header from XTADK sources
|
||||
generate_xtadk(xtadk "${XTADK_SOURCE}")
|
||||
92
sdk/xtadk/amd64/ke.cc
Normal file
92
sdk/xtadk/amd64/ke.cc
Normal file
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: sdk/xtadk/amd64/ke.cc
|
||||
* DESCRIPTION: ADK generator for AMD64 version of Kernel Library
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtkmapi.h>
|
||||
#include <adkdefs.h>
|
||||
|
||||
|
||||
/**
|
||||
* Generates a definitions file for the Kernel Library used by the XTOS kernel assembly code
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCLINK
|
||||
XTAPI
|
||||
VOID
|
||||
GenerateAssemblyDefinitions(VOID)
|
||||
{
|
||||
/* Generate KTRAP_FRAME offsets */
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm0);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm1);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm2);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm3);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm4);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm5);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm6);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm7);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm8);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm9);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm10);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm11);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm12);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm13);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm14);
|
||||
ADK_OFFSET(KTRAP_FRAME, Xmm15);
|
||||
ADK_OFFSET(KTRAP_FRAME, MxCsr);
|
||||
ADK_OFFSET(KTRAP_FRAME, PreviousMode);
|
||||
ADK_OFFSET(KTRAP_FRAME, Cr2);
|
||||
ADK_OFFSET(KTRAP_FRAME, Cr3);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr0);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr1);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr2);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr3);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr6);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr7);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegDs);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegEs);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegFs);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegGs);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rax);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rbx);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rcx);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rdx);
|
||||
ADK_OFFSET(KTRAP_FRAME, R8);
|
||||
ADK_OFFSET(KTRAP_FRAME, R9);
|
||||
ADK_OFFSET(KTRAP_FRAME, R10);
|
||||
ADK_OFFSET(KTRAP_FRAME, R11);
|
||||
ADK_OFFSET(KTRAP_FRAME, R12);
|
||||
ADK_OFFSET(KTRAP_FRAME, R13);
|
||||
ADK_OFFSET(KTRAP_FRAME, R14);
|
||||
ADK_OFFSET(KTRAP_FRAME, R15);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rsi);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rdi);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rbp);
|
||||
ADK_OFFSET(KTRAP_FRAME, Vector);
|
||||
ADK_OFFSET(KTRAP_FRAME, ErrorCode);
|
||||
ADK_OFFSET(KTRAP_FRAME, ExceptionFrame);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rip);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegCs);
|
||||
ADK_OFFSET(KTRAP_FRAME, Flags);
|
||||
ADK_OFFSET(KTRAP_FRAME, Rsp);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegSs);
|
||||
|
||||
/* Generate KTRAP_FRAME size and REGISTERS_SIZE */
|
||||
ADK_SIZE(KTRAP_FRAME);
|
||||
ADK_SIZE_FROM(REGISTERS_SIZE, KTRAP_FRAME, Rax);
|
||||
|
||||
/* Generate PROCESSOR_START_BLOCK offsets */
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr3);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr4);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, EntryPoint);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, InitialStack);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, ProcessorStructures);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Stack);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Started);
|
||||
}
|
||||
66
sdk/xtadk/i686/ke.cc
Normal file
66
sdk/xtadk/i686/ke.cc
Normal file
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: sdk/xtadk/i686/ke.cc
|
||||
* DESCRIPTION: ADK generator for i686 version of Kernel Library
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtkmapi.h>
|
||||
#include <adkdefs.h>
|
||||
|
||||
|
||||
/**
|
||||
* Generates a definitions file for the Kernel Library used by the XTOS kernel assembly code
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCLINK
|
||||
XTAPI
|
||||
VOID
|
||||
GenerateAssemblyDefinitions(VOID)
|
||||
{
|
||||
/* Generate KTRAP_FRAME offsets */
|
||||
ADK_OFFSET(KTRAP_FRAME, PreviousMode);
|
||||
ADK_OFFSET(KTRAP_FRAME, Cr2);
|
||||
ADK_OFFSET(KTRAP_FRAME, Cr3);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr0);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr1);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr2);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr3);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr6);
|
||||
ADK_OFFSET(KTRAP_FRAME, Dr7);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegDs);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegEs);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegFs);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegGs);
|
||||
ADK_OFFSET(KTRAP_FRAME, Eax);
|
||||
ADK_OFFSET(KTRAP_FRAME, Ebx);
|
||||
ADK_OFFSET(KTRAP_FRAME, Ecx);
|
||||
ADK_OFFSET(KTRAP_FRAME, Edx);
|
||||
ADK_OFFSET(KTRAP_FRAME, Esi);
|
||||
ADK_OFFSET(KTRAP_FRAME, Edi);
|
||||
ADK_OFFSET(KTRAP_FRAME, Ebp);
|
||||
ADK_OFFSET(KTRAP_FRAME, Vector);
|
||||
ADK_OFFSET(KTRAP_FRAME, ErrorCode);
|
||||
ADK_OFFSET(KTRAP_FRAME, Eip);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegCs);
|
||||
ADK_OFFSET(KTRAP_FRAME, Flags);
|
||||
ADK_OFFSET(KTRAP_FRAME, Esp);
|
||||
ADK_OFFSET(KTRAP_FRAME, SegSs);
|
||||
|
||||
/* Generate KTRAP_FRAME size and REGISTERS_SIZE */
|
||||
ADK_SIZE(KTRAP_FRAME);
|
||||
ADK_SIZE_FROM(REGISTERS_SIZE, KTRAP_FRAME, Eax);
|
||||
|
||||
/* Generate PROCESSOR_START_BLOCK offsets */
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr3);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr4);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, EntryPoint);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, InitialStack);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, ProcessorStructures);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Stack);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Started);
|
||||
}
|
||||
19
sdk/xtadk/includes/adkdefs.h
Normal file
19
sdk/xtadk/includes/adkdefs.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: sdk/xtadk/adkdefs.h
|
||||
* DESCRIPTION: Definitions for XTADK
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTADK_ADKDEFS_H
|
||||
#define __XTADK_ADKDEFS_H
|
||||
|
||||
|
||||
/* Macros for calculating structure size and offsets for assembler code */
|
||||
#define ADK_DEFINE(Symbol, Value) __asm__ volatile("\n\t# ==> " #Symbol " %c0" : : "i" ((SIZE_T)(Value)))
|
||||
#define ADK_OFFSET(Structure, Member) ADK_DEFINE(Structure ## _ ## Member, FIELD_OFFSET(Structure, Member))
|
||||
#define ADK_SIZE(Structure) ADK_DEFINE(Structure ## _SIZE, sizeof(Structure))
|
||||
#define ADK_SIZE_FROM(Name, Structure, Member) ADK_DEFINE(Structure ## _ ## Name, sizeof(Structure) - FIELD_OFFSET(Structure, Member))
|
||||
|
||||
#endif /* __XTADK_ADKDEFS_H */
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <xtdefs.h>
|
||||
#include <xtstruct.h>
|
||||
#include <xttypes.h>
|
||||
#include ARCH_HEADER(xtstruct.h)
|
||||
|
||||
|
||||
/* Control Register 0 constants */
|
||||
@@ -127,6 +128,10 @@
|
||||
#define X86_EFLAGS_VIP_MASK 0x00100000 /* Virtual Interrupt Pending */
|
||||
#define X86_EFLAGS_ID_MASK 0x00200000 /* Identification */
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* CPU vendor enumeration list */
|
||||
typedef enum _CPU_VENDOR
|
||||
{
|
||||
@@ -135,6 +140,18 @@ typedef enum _CPU_VENDOR
|
||||
CPU_VENDOR_UNKNOWN = 0xFFFFFFFF
|
||||
} CPU_VENDOR, *PCPU_VENDOR;
|
||||
|
||||
/* CPUID advanced power management features (0x80000007) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT
|
||||
{
|
||||
CPUID_FEATURES_EDX_TS = 1 << 0, /* Temperature Sensor */
|
||||
CPUID_FEATURES_EDX_FIS = 1 << 1, /* Frequency ID Selection */
|
||||
CPUID_FEATURES_EDX_VIS = 1 << 2, /* Voltage ID Selection */
|
||||
CPUID_FEATURES_EDX_TTS = 1 << 3, /* ThermaTrip Support */
|
||||
CPUID_FEATURES_EDX_HTC = 1 << 4, /* Hardware Thermal Throttling */
|
||||
CPUID_FEATURES_EDX_STC = 1 << 5, /* Software Thermal Throttling */
|
||||
CPUID_FEATURES_EDX_TSCI = 1 << 8 /* TSC Invariant */
|
||||
} CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT, *PCPUID_FEATURES_ADVANCED_POWER_MANAGEMENT;
|
||||
|
||||
/* CPUID extended features (0x80000001) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_EXTENDED
|
||||
{
|
||||
@@ -176,6 +193,23 @@ typedef enum _CPUID_FEATURES_EXTENDED
|
||||
CPUID_FEATURES_EDX_3DNOW = 1 << 31
|
||||
} CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
|
||||
|
||||
/* CPUID Thermal and Power Management features (0x00000006) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_POWER_MANAGEMENT
|
||||
{
|
||||
CPUID_FEATURES_EAX_DTHERM = 1 << 0,
|
||||
CPUID_FEATURES_EAX_IDA = 1 << 1,
|
||||
CPUID_FEATURES_EAX_ARAT = 1 << 2,
|
||||
CPUID_FEATURES_EAX_PLN = 1 << 4,
|
||||
CPUID_FEATURES_EAX_PTS = 1 << 6,
|
||||
CPUID_FEATURES_EAX_HWP = 1 << 7,
|
||||
CPUID_FEATURES_EAX_HWP_NOTIFY = 1 << 8,
|
||||
CPUID_FEATURES_EAX_HWP_ACT_WINDOW = 1 << 9,
|
||||
CPUID_FEATURES_EAX_HWP_EPP = 1 << 10,
|
||||
CPUID_FEATURES_EAX_HWP_PKG_REQ = 1 << 11,
|
||||
CPUID_FEATURES_EAX_HWP_HIGHEST_PERF_CHANGE = 1 << 15,
|
||||
CPUID_FEATURES_EAX_HFI = 1 << 19
|
||||
} CPUID_FEATURES_LEAF6, *PCPUID_FEATURES_LEAF6;
|
||||
|
||||
/* CPUID STD1 features (0x00000001) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_STANDARD1
|
||||
{
|
||||
@@ -202,7 +236,7 @@ typedef enum _CPUID_FEATURES_STANDARD1
|
||||
CPUID_FEATURES_ECX_X2APIC = 1 << 21,
|
||||
CPUID_FEATURES_ECX_MOVBE = 1 << 22,
|
||||
CPUID_FEATURES_ECX_POPCNT = 1 << 23,
|
||||
CPUID_FEATURES_ECX_TSC = 1 << 24,
|
||||
CPUID_FEATURES_ECX_TSC_DEADLINE = 1 << 24,
|
||||
CPUID_FEATURES_ECX_AES = 1 << 25,
|
||||
CPUID_FEATURES_ECX_XSAVE = 1 << 26,
|
||||
CPUID_FEATURES_ECX_OSXSAVE = 1 << 27,
|
||||
@@ -376,20 +410,29 @@ typedef enum _CPUID_FEATURES_STANDARD7_LEAF1
|
||||
/* CPUID requests */
|
||||
typedef enum _CPUID_REQUESTS
|
||||
{
|
||||
CPUID_GET_VENDOR_STRING,
|
||||
CPUID_GET_STANDARD1_FEATURES,
|
||||
CPUID_GET_TLB_CACHE,
|
||||
CPUID_GET_SERIAL,
|
||||
CPUID_GET_CACHE_TOPOLOGY,
|
||||
CPUID_GET_MONITOR_MWAIT,
|
||||
CPUID_GET_POWER_MANAGEMENT,
|
||||
CPUID_GET_STANDARD7_FEATURES
|
||||
CPUID_GET_VENDOR_STRING = 0x00000000,
|
||||
CPUID_GET_STANDARD1_FEATURES = 0x00000001,
|
||||
CPUID_GET_TLB_CACHE = 0x00000002,
|
||||
CPUID_GET_SERIAL = 0x00000003,
|
||||
CPUID_GET_CACHE_TOPOLOGY = 0x00000004,
|
||||
CPUID_GET_MONITOR_MWAIT = 0x00000005,
|
||||
CPUID_GET_POWER_MANAGEMENT = 0x00000006,
|
||||
CPUID_GET_STANDARD7_FEATURES = 0x00000007,
|
||||
CPUID_GET_TSC_CRYSTAL_CLOCK = 0x00000015,
|
||||
CPUID_GET_EXTENDED_MAX = 0x80000000,
|
||||
CPUID_GET_EXTENDED_FEATURES = 0x80000001,
|
||||
CPUID_GET_ADVANCED_POWER_MANAGEMENT = 0x80000007
|
||||
} CPUID_REQUESTS, *PCPUID_REQUESTS;
|
||||
|
||||
/* Interrupt handler */
|
||||
typedef VOID (*PINTERRUPT_HANDLER)(PKTRAP_FRAME TrapFrame);
|
||||
|
||||
/* Processor identification information */
|
||||
typedef struct _CPU_IDENTIFICATION
|
||||
{
|
||||
ULONGLONG ExtendedFeatureBits;
|
||||
USHORT Family;
|
||||
ULONGLONG FeatureBits;
|
||||
USHORT Model;
|
||||
USHORT Stepping;
|
||||
CPU_VENDOR Vendor;
|
||||
@@ -426,4 +469,5 @@ typedef enum _TRAMPOLINE_TYPE
|
||||
TrampolineEnableXpa
|
||||
} TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_AMD64_ARTYPES_H */
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
#include <amd64/xtstruct.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Hardware layer routines forward references */
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
@@ -49,4 +52,5 @@ VOID
|
||||
HlWritePort32(IN USHORT Port,
|
||||
IN ULONG Value);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_AMD64_HLFUNCS_H */
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#ifndef __XTDK_AMD64_HLTYPES_H
|
||||
#define __XTDK_AMD64_HLTYPES_H
|
||||
|
||||
#include <xtbase.h>
|
||||
#include <xtdefs.h>
|
||||
#include <xtstruct.h>
|
||||
#include <xttypes.h>
|
||||
@@ -38,6 +39,9 @@
|
||||
#define APIC_VECTOR_PERF 0xFE
|
||||
#define APIC_VECTOR_NMI 0xFF
|
||||
|
||||
/* APIC SIPI vector shift */
|
||||
#define APIC_VECTOR_SIPI_SHIFT 12
|
||||
|
||||
/* APIC destination formats */
|
||||
#define APIC_DF_FLAT 0xFFFFFFFF
|
||||
#define APIC_DF_CLUSTER 0x0FFFFFFF
|
||||
@@ -53,6 +57,27 @@
|
||||
/* 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
|
||||
@@ -62,6 +87,87 @@
|
||||
/* 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
|
||||
@@ -69,6 +175,17 @@
|
||||
/* 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
|
||||
{
|
||||
@@ -126,6 +243,7 @@ typedef enum _APIC_REGISTER
|
||||
APIC_TICR = 0x38, /* Initial Count Register for Timer */
|
||||
APIC_TCCR = 0x39, /* Current Count Register for Timer */
|
||||
APIC_TDCR = 0x3E, /* Timer Divide Configuration Register */
|
||||
APIC_SIPI = 0x3F, /* Self-IPI Register */
|
||||
APIC_EAFR = 0x40, /* extended APIC Feature register */
|
||||
APIC_EACR = 0x41, /* Extended APIC Control Register */
|
||||
APIC_SEOI = 0x42, /* Specific End Of Interrupt Register */
|
||||
@@ -135,6 +253,19 @@ typedef enum _APIC_REGISTER
|
||||
APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */
|
||||
} APIC_REGISTER, *PAPIC_REGISTER;
|
||||
|
||||
/* APIC Timer Divide enumeration list */
|
||||
typedef enum _APIC_TIMER_DIVISOR
|
||||
{
|
||||
TIMER_DivideBy2 = 0,
|
||||
TIMER_DivideBy4 = 1,
|
||||
TIMER_DivideBy8 = 2,
|
||||
TIMER_DivideBy16 = 3,
|
||||
TIMER_DivideBy32 = 8,
|
||||
TIMER_DivideBy64 = 9,
|
||||
TIMER_DivideBy128 = 10,
|
||||
TIMER_DivideBy1 = 11,
|
||||
} APIC_TIMER_DIVISOR, *PAPIC_TIMER_DIVISOR;
|
||||
|
||||
/* I8259 PIC interrupt mode enumeration list */
|
||||
typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE
|
||||
{
|
||||
@@ -179,6 +310,17 @@ typedef enum _PIC_I8259_ICW4_SYSTEM_MODE
|
||||
New8086Mode
|
||||
} PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;
|
||||
|
||||
/* Supported hardware timer backends */
|
||||
typedef enum _TIMER_TYPE
|
||||
{
|
||||
TimerNone,
|
||||
TimerAcpiPm,
|
||||
TimerHpet,
|
||||
TimerLapic,
|
||||
TimerPit,
|
||||
TimerTsc
|
||||
} TIMER_TYPE, *PTIMER_TYPE;
|
||||
|
||||
/* APIC Base Register */
|
||||
typedef union _APIC_BASE_REGISTER
|
||||
{
|
||||
@@ -252,6 +394,40 @@ 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
|
||||
{
|
||||
@@ -317,4 +493,39 @@ 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;
|
||||
|
||||
/* Hardware timer capabilities and CPU clock features */
|
||||
typedef struct _TIMER_CAPABILITIES
|
||||
{
|
||||
BOOLEAN Arat;
|
||||
BOOLEAN Art;
|
||||
BOOLEAN InvariantTsc;
|
||||
BOOLEAN RDTSCP;
|
||||
ULONG TimerFrequency;
|
||||
BOOLEAN TscDeadline;
|
||||
ULONG TscDenominator;
|
||||
ULONG TscNumerator;
|
||||
} TIMER_CAPABILITIES, *PTIMER_CAPABILITIES;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_AMD64_HLTYPES_H */
|
||||
|
||||
@@ -12,89 +12,160 @@
|
||||
#include <xtbase.h>
|
||||
#include <xtstruct.h>
|
||||
#include <xttypes.h>
|
||||
#include <extypes.h>
|
||||
#include <potypes.h>
|
||||
#include ARCH_HEADER(xtstruct.h)
|
||||
#include ARCH_HEADER(artypes.h)
|
||||
|
||||
|
||||
/* Selector masks */
|
||||
#define MODE_MASK 0x0001
|
||||
#define RPL_MASK 0x0003
|
||||
#define MODE_MASK 0x0001
|
||||
#define RPL_MASK 0x0003
|
||||
|
||||
/* GDT selector names */
|
||||
#define KGDT_NULL 0x0000
|
||||
#define KGDT_R0_CODE 0x0010
|
||||
#define KGDT_R0_DATA 0x0018
|
||||
#define KGDT_R3_CMCODE 0x0020
|
||||
#define KGDT_R3_DATA 0x0028
|
||||
#define KGDT_R3_CODE 0x0030
|
||||
#define KGDT_SYS_TSS 0x0040
|
||||
#define KGDT_R3_CMTEB 0x0050
|
||||
#define KGDT_R0_LDT 0x0060
|
||||
#define KGDT_ALIAS 0x0070
|
||||
#define KGDT_NULL 0x0000
|
||||
#define KGDT_R0_CMCODE 0x0008
|
||||
#define KGDT_R0_CODE 0x0010
|
||||
#define KGDT_R0_DATA 0x0018
|
||||
#define KGDT_R3_CMCODE 0x0020
|
||||
#define KGDT_R3_DATA 0x0028
|
||||
#define KGDT_R3_CODE 0x0030
|
||||
#define KGDT_SYS_TSS 0x0040
|
||||
#define KGDT_R3_CMTEB 0x0050
|
||||
#define KGDT_R0_LDT 0x0060
|
||||
#define KGDT_ALIAS 0x0070
|
||||
|
||||
/* GDT descriptor privilege levels */
|
||||
#define KGDT_DPL_SYSTEM 0
|
||||
#define KGDT_DPL_USER 3
|
||||
#define KGDT_DPL_SYSTEM 0
|
||||
#define KGDT_DPL_USER 3
|
||||
|
||||
/* GDT descriptor properties */
|
||||
#define KGDT_DESCRIPTOR_ACCESSED 0x01
|
||||
#define KGDT_DESCRIPTOR_READ_WRITE 0x02
|
||||
#define KGDT_DESCRIPTOR_EXECUTE_READ 0x02
|
||||
#define KGDT_DESCRIPTOR_EXPAND_DOWN 0x04
|
||||
#define KGDT_DESCRIPTOR_CONFORMING 0x04
|
||||
#define KGDT_DESCRIPTOR_CODE 0x08
|
||||
#define KGDT_DESCRIPTOR_ACCESSED 0x01
|
||||
#define KGDT_DESCRIPTOR_READ_WRITE 0x02
|
||||
#define KGDT_DESCRIPTOR_EXECUTE_READ 0x02
|
||||
#define KGDT_DESCRIPTOR_EXPAND_DOWN 0x04
|
||||
#define KGDT_DESCRIPTOR_CONFORMING 0x04
|
||||
#define KGDT_DESCRIPTOR_CODE 0x08
|
||||
|
||||
/* GDT descriptor type codes */
|
||||
#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)
|
||||
#define KGDT_TYPE_NONE 0x00
|
||||
#define KGDT_TYPE_CODE (0x10 | KGDT_DESCRIPTOR_CODE | KGDT_DESCRIPTOR_EXECUTE_READ)
|
||||
#define KGDT_TYPE_DATA (0x10 | KGDT_DESCRIPTOR_READ_WRITE)
|
||||
|
||||
/* IDT access levels */
|
||||
#define KIDT_ACCESS_RING0 0x0
|
||||
#define KIDT_ACCESS_RING3 0x3
|
||||
#define KIDT_ACCESS_RING0 0x0
|
||||
#define KIDT_ACCESS_RING3 0x3
|
||||
|
||||
/* IDT Interrupt Stack Table entries */
|
||||
#define KIDT_IST_RESERVED 0
|
||||
#define KIDT_IST_PANIC 1
|
||||
#define KIDT_IST_MCA 2
|
||||
#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
|
||||
#define AMD64_TSS 0x9
|
||||
#define AMD64_ACTIVE_TSS 0xB
|
||||
#define AMD64_CALL_GATE 0xC
|
||||
#define AMD64_INTERRUPT_GATE 0xE
|
||||
#define AMD64_TRAP_GATE 0xF
|
||||
#define AMD64_TASK_GATE 0x5
|
||||
#define AMD64_TSS 0x9
|
||||
#define AMD64_ACTIVE_TSS 0xB
|
||||
#define AMD64_CALL_GATE 0xC
|
||||
#define AMD64_INTERRUPT_GATE 0xE
|
||||
#define AMD64_TRAP_GATE 0xF
|
||||
|
||||
/* Kernel CPU Standard Features */
|
||||
#define KCF_VME (1ULL << 0) /* Virtual 8086 Mode Enhancements */
|
||||
#define KCF_LARGE_PAGE (1ULL << 1) /* Page Size Extensions */
|
||||
#define KCF_RDTSC (1ULL << 2) /* Time Stamp Counter */
|
||||
#define KCF_PAE (1ULL << 3) /* Physical Address Extension */
|
||||
#define KCF_MCE (1ULL << 4) /* Machine Check Exception */
|
||||
#define KCF_CMPXCHG8B (1ULL << 5) /* CMPXCHG8B Instruction */
|
||||
#define KCF_APIC (1ULL << 6) /* APIC On-Chip */
|
||||
#define KCF_FAST_SYSCALL (1ULL << 7) /* SYSENTER/SYSEXIT Instructions */
|
||||
#define KCF_MTRR (1ULL << 8) /* Memory Type Range Registers */
|
||||
#define KCF_GLOBAL_PAGE (1ULL << 9) /* Page Global Enable */
|
||||
#define KCF_MCA (1ULL << 10) /* Machine Check Architecture */
|
||||
#define KCF_CMOV (1ULL << 11) /* Conditional Move Instructions */
|
||||
#define KCF_PAT (1ULL << 12) /* Page Attribute Table */
|
||||
#define KCF_PSE36 (1ULL << 13) /* 36-bit Page Size Extension */
|
||||
#define KCF_CLFLUSH (1ULL << 14) /* CLFLUSH Instruction */
|
||||
#define KCF_FXSR (1ULL << 15) /* FXSAVE/FXRSTOR Instructions */
|
||||
#define KCF_ACPI (1ULL << 16) /* Thermal Monitor and Software Controlled Clock */
|
||||
#define KCF_MMX (1ULL << 17) /* MMX Technology */
|
||||
#define KCF_SSE (1ULL << 18) /* Streaming SIMD Extensions */
|
||||
#define KCF_SSE2 (1ULL << 19) /* Streaming SIMD Extensions 2 */
|
||||
#define KCF_SMT (1ULL << 20) /* Hyper-Threading Technology */
|
||||
#define KCF_SSE3 (1ULL << 21) /* Streaming SIMD Extensions 3 */
|
||||
#define KCF_VMX (1ULL << 22) /* Intel Virtual Machine Extensions */
|
||||
#define KCF_SSSE3 (1ULL << 23) /* Supplemental SSE3 Instructions */
|
||||
#define KCF_SSE41 (1ULL << 24) /* SSE4.1 Instructions */
|
||||
#define KCF_SSE42 (1ULL << 25) /* SSE4.2 Instructions */
|
||||
#define KCF_X2APIC (1ULL << 26) /* x2APIC Support */
|
||||
#define KCF_POPCNT (1ULL << 27) /* POPCNT Instruction */
|
||||
#define KCF_TSC_DEADLINE (1ULL << 28) /* TSC Deadline Timer */
|
||||
#define KCF_AES (1ULL << 29) /* AES-NI Instruction Set */
|
||||
#define KCF_XSAVE (1ULL << 30) /* XSAVE/XRSTOR Instructions */
|
||||
#define KCF_AVX (1ULL << 31) /* Advanced Vector Extensions */
|
||||
#define KCF_RDRAND (1ULL << 32) /* RDRAND Instruction */
|
||||
#define KCF_FSGSBASE (1ULL << 33) /* RDFSBASE/WRFSBASE Instructions */
|
||||
#define KCF_AVX2 (1ULL << 34) /* AVX2 Instructions */
|
||||
#define KCF_SMEP (1ULL << 35) /* Supervisor Mode Execution Prevention */
|
||||
#define KCF_RDSEED (1ULL << 36) /* RDSEED Instruction */
|
||||
#define KCF_SMAP (1ULL << 37) /* Supervisor Mode Access Prevention */
|
||||
#define KCF_SHA (1ULL << 38) /* SHA Extensions */
|
||||
#define KCF_LA57 (1ULL << 39) /* 57-bit Linear Addresses */
|
||||
#define KCF_ARAT (1ULL << 40) /* Always Running APIC Timer */
|
||||
|
||||
/* Kernel CPU Extended Features */
|
||||
#define KCF_SVM (1ULL << 0) /* AMD Secure Virtual Machine */
|
||||
#define KCF_SSE4A (1ULL << 1) /* SSE4A Instructions */
|
||||
#define KCF_FMA4 (1ULL << 2) /* FMA4 Instructions */
|
||||
#define KCF_TOPOEXT (1ULL << 3) /* AMD Topology Extensions */
|
||||
#define KCF_SYSCALL (1ULL << 4) /* SYSCALL/SYSRET Instructions */
|
||||
#define KCF_NX_BIT (1ULL << 5) /* No-Execute Page Protection */
|
||||
#define KCF_RDTSCP (1ULL << 6) /* RDTSCP Instruction */
|
||||
#define KCF_64BIT (1ULL << 7) /* Long Mode Support */
|
||||
#define KCF_3DNOW_EXT (1ULL << 8) /* 3DNow! Extensions */
|
||||
#define KCF_3DNOW (1ULL << 9) /* 3DNow! Instructions */
|
||||
#define KCF_INVARIANT_TSC (1ULL << 10) /* Invariant Time Stamp Counter */
|
||||
|
||||
/* Context control flags */
|
||||
#define CONTEXT_ARCHITECTURE 0x00100000
|
||||
#define CONTEXT_CONTROL (CONTEXT_ARCHITECTURE | 0x01)
|
||||
#define CONTEXT_INTEGER (CONTEXT_ARCHITECTURE | 0x02)
|
||||
#define CONTEXT_SEGMENTS (CONTEXT_ARCHITECTURE | 0x04)
|
||||
#define CONTEXT_FLOATING_POINT (CONTEXT_ARCHITECTURE | 0x08)
|
||||
#define CONTEXT_DEBUG_REGISTERS (CONTEXT_ARCHITECTURE | 0x10)
|
||||
#define CONTEXT_ARCHITECTURE 0x00100000
|
||||
#define CONTEXT_CONTROL (CONTEXT_ARCHITECTURE | 0x01)
|
||||
#define CONTEXT_INTEGER (CONTEXT_ARCHITECTURE | 0x02)
|
||||
#define CONTEXT_SEGMENTS (CONTEXT_ARCHITECTURE | 0x04)
|
||||
#define CONTEXT_FLOATING_POINT (CONTEXT_ARCHITECTURE | 0x08)
|
||||
#define CONTEXT_DEBUG_REGISTERS (CONTEXT_ARCHITECTURE | 0x10)
|
||||
#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT)
|
||||
#define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | \
|
||||
CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS)
|
||||
|
||||
/* Clock control flags */
|
||||
#define CLOCK_QUANTUM_DECREMENT 3
|
||||
|
||||
/* DPC definitions */
|
||||
#define DPC_ADJUST_THRESHOLD 20
|
||||
#define DPC_IDEAL_RATE 20
|
||||
#define DPC_MAXIMUM_QUEUE_DEPTH 4
|
||||
#define DPC_MINIMUM_RATE 3
|
||||
|
||||
/* Interrupt request levels definitions */
|
||||
#define PASSIVE_LEVEL 0
|
||||
#define LOW_LEVEL 0
|
||||
#define APC_LEVEL 1
|
||||
#define DISPATCH_LEVEL 2
|
||||
#define CMC_LEVEL 5
|
||||
#define DEVICE1_LEVEL 6
|
||||
#define DEVICE2_LEVEL 7
|
||||
#define DEVICE3_LEVEL 8
|
||||
#define DEVICE4_LEVEL 9
|
||||
#define DEVICE5_LEVEL 10
|
||||
#define DEVICE6_LEVEL 11
|
||||
#define DEVICE7_LEVEL 12
|
||||
#define SYNC_LEVEL 12
|
||||
#define CLOCK_LEVEL 13
|
||||
#define IPI_LEVEL 14
|
||||
#define DRS_LEVEL 14
|
||||
#define POWER_LEVEL 14
|
||||
#define PROFILE_LEVEL 15
|
||||
#define HIGH_LEVEL 15
|
||||
#define PASSIVE_LEVEL 0
|
||||
#define LOW_LEVEL 0
|
||||
#define APC_LEVEL 1
|
||||
#define DISPATCH_LEVEL 2
|
||||
#define CMC_LEVEL 5
|
||||
#define DEVICE1_LEVEL 6
|
||||
#define DEVICE2_LEVEL 7
|
||||
#define DEVICE3_LEVEL 8
|
||||
#define DEVICE4_LEVEL 9
|
||||
#define DEVICE5_LEVEL 10
|
||||
#define DEVICE6_LEVEL 11
|
||||
#define DEVICE7_LEVEL 12
|
||||
#define SYNC_LEVEL 12
|
||||
#define CLOCK_LEVEL 13
|
||||
#define IPI_LEVEL 14
|
||||
#define DRS_LEVEL 14
|
||||
#define POWER_LEVEL 14
|
||||
#define PROFILE_LEVEL 15
|
||||
#define HIGH_LEVEL 15
|
||||
|
||||
/* Size of the exception area */
|
||||
#define EXCEPTION_AREA_SIZE 64
|
||||
@@ -110,13 +181,14 @@
|
||||
|
||||
/* XTOS Kernel stack size */
|
||||
#define KERNEL_STACK_SIZE 0x8000
|
||||
#define KERNEL_STACKS 3
|
||||
|
||||
/* XTOS Kernel stack guard pages */
|
||||
#define KERNEL_STACK_GUARD_PAGES 1
|
||||
|
||||
/* Processor structures size */
|
||||
#define KPROCESSOR_STRUCTURES_SIZE ((2 * KERNEL_STACK_SIZE) + (GDT_ENTRIES * sizeof(KGDTENTRY)) + sizeof(KTSS) + \
|
||||
sizeof(KPROCESSOR_BLOCK) + MM_PAGE_SIZE)
|
||||
#define KPROCESSOR_STRUCTURES_SIZE ((KERNEL_STACKS * KERNEL_STACK_SIZE) + (GDT_ENTRIES * sizeof(KGDTENTRY)) + \
|
||||
sizeof(KTSS) + sizeof(KPROCESSOR_BLOCK) + MM_PAGE_SIZE)
|
||||
|
||||
/* Kernel frames */
|
||||
#define KEXCEPTION_FRAME_SIZE sizeof(KEXCEPTION_FRAME)
|
||||
@@ -124,6 +196,9 @@
|
||||
#define KTRAP_FRAME_ALIGN 0x10
|
||||
#define KTRAP_FRAME_SIZE sizeof(KTRAP_FRAME)
|
||||
|
||||
/* Initial stack reservation size */
|
||||
#define KTHREAD_STACK_OFFSET ((sizeof(KTHREAD_INIT_FRAME) + STACK_ALIGNMENT - 1) & ~(STACK_ALIGNMENT - 1))
|
||||
|
||||
/* Return address size pushed by 'call' instruction */
|
||||
#define KRETURN_ADDRESS_SIZE 0x8
|
||||
|
||||
@@ -135,6 +210,10 @@
|
||||
#define NPX_STATE_SCRUB 0x1
|
||||
#define NPX_STATE_SWITCH 0x2
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Floating point state storing structure */
|
||||
typedef struct _FLOATING_SAVE_AREA
|
||||
{
|
||||
@@ -166,7 +245,7 @@ typedef struct _CONTEXT
|
||||
USHORT SegFs;
|
||||
USHORT SegGs;
|
||||
USHORT SegSs;
|
||||
ULONG EFlags;
|
||||
ULONG Flags;
|
||||
ULONG64 Dr0;
|
||||
ULONG64 Dr1;
|
||||
ULONG64 Dr2;
|
||||
@@ -232,6 +311,24 @@ typedef struct _KDESCRIPTOR
|
||||
PVOID Base;
|
||||
} KDESCRIPTOR, *PKDESCRIPTOR;
|
||||
|
||||
/* Device Queue structure definition */
|
||||
typedef struct _KDEVICE_QUEUE
|
||||
{
|
||||
CSHORT Type;
|
||||
CSHORT Size;
|
||||
LIST_ENTRY DeviceListHead;
|
||||
KSPIN_LOCK Lock;
|
||||
union
|
||||
{
|
||||
BOOLEAN Busy;
|
||||
struct
|
||||
{
|
||||
LONGLONG Reserved:8;
|
||||
LONGLONG Hint:56;
|
||||
};
|
||||
};
|
||||
} KDEVICE_QUEUE, *PKDEVICE_QUEUE;
|
||||
|
||||
/* Global Descriptor Table (GDT) entry union definition */
|
||||
typedef struct _KGDTENTRY
|
||||
{
|
||||
@@ -463,11 +560,23 @@ typedef struct _KSPECIAL_REGISTERS
|
||||
ULONG64 MsrSyscallMask;
|
||||
} KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS;
|
||||
|
||||
/* Processor start block structure definition */
|
||||
typedef struct _PROCESSOR_START_BLOCK
|
||||
{
|
||||
ULONG_PTR Cr3;
|
||||
ULONG_PTR Cr4;
|
||||
PVOID EntryPoint;
|
||||
PVOID InitialStack;
|
||||
PVOID ProcessorStructures;
|
||||
PVOID Stack;
|
||||
BOOLEAN Started;
|
||||
} PROCESSOR_START_BLOCK, *PPROCESSOR_START_BLOCK;
|
||||
|
||||
/* Processor state frame structure definition */
|
||||
typedef struct _KPROCESSOR_STATE
|
||||
{
|
||||
KSPECIAL_REGISTERS SpecialRegisters;
|
||||
CONTEXT ContextFrame;
|
||||
KSPECIAL_REGISTERS SpecialRegisters;
|
||||
} KPROCESSOR_STATE, *PKPROCESSOR_STATE;
|
||||
|
||||
/* Processor Control Block (PRCB) structure definition */
|
||||
@@ -482,14 +591,32 @@ typedef struct _KPROCESSOR_CONTROL_BLOCK
|
||||
ULONG_PTR SetMember;
|
||||
CPU_IDENTIFICATION CpuId;
|
||||
KPROCESSOR_STATE ProcessorState;
|
||||
KSPIN_LOCK PrcbLock;
|
||||
KSPIN_LOCK_QUEUE LockQueue[MaximumLock];
|
||||
LOOKASIDE_LIST LookasideList[16];
|
||||
LOOKASIDE_LIST NonPagedLookasideList[POOL_LOOKASIDE_LISTS];
|
||||
LOOKASIDE_LIST PagedLookasideList[POOL_LOOKASIDE_LISTS];
|
||||
VOLATILE ULONG IpiFrozen;
|
||||
VOLATILE LONG_PTR RequestSummary;
|
||||
KDPC_DATA DpcData[2];
|
||||
PVOID DpcStack;
|
||||
LONG MaximumDpcQueueDepth;
|
||||
ULONG DpcRequestRate;
|
||||
BOOLEAN DpcInterruptRequested;
|
||||
VOLATILE BOOLEAN DpcRoutineActive;
|
||||
ULONG DpcLastCount;
|
||||
VOLATILE ULONG_PTR TimerHand;
|
||||
VOLATILE ULONG_PTR TimerRequest;
|
||||
ULONG_PTR MultiThreadProcessorSet;
|
||||
SINGLE_LIST_ENTRY DeferredReadyListHead;
|
||||
ULONG InterruptCount;
|
||||
ULONG KernelTime;
|
||||
ULONG UserTime;
|
||||
ULONG DpcTime;
|
||||
ULONG InterruptTime;
|
||||
ULONG AdjustDpcThreshold;
|
||||
PROCESSOR_POWER_STATE PowerState;
|
||||
ULONG ProfilingCountdown;
|
||||
} KPROCESSOR_CONTROL_BLOCK, *PKPROCESSOR_CONTROL_BLOCK;
|
||||
|
||||
/* Processor Block structure definition */
|
||||
@@ -516,6 +643,9 @@ typedef struct _KPROCESSOR_BLOCK
|
||||
KAFFINITY SetMember;
|
||||
ULONG StallScaleFactor;
|
||||
UCHAR CpuNumber;
|
||||
ULONG HardwareId;
|
||||
VOLATILE BOOLEAN Started;
|
||||
PINTERRUPT_HANDLER InterruptDispatchTable[256];
|
||||
} KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK;
|
||||
|
||||
/* Thread Environment Block (TEB) structure definition */
|
||||
@@ -524,4 +654,5 @@ typedef struct _THREAD_ENVIRONMENT_BLOCK
|
||||
THREAD_INFORMATION_BLOCK InformationBlock;
|
||||
} THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_AMD64_KETYPES_H */
|
||||
|
||||
@@ -101,12 +101,19 @@
|
||||
/* 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
|
||||
|
||||
/* Highest system address */
|
||||
#define MM_HIGHEST_SYSTEM_ADDRESS 0xFFFFFFFFFFFFFFFFULL
|
||||
|
||||
/* User probe address */
|
||||
#define MM_USER_PROBE_ADDRESS 0x00007FFFFFFF0000ULL
|
||||
#define MM_USER_PROBE_LA57_ADDRESS 0x00FFFFFFFFFF0000ULL
|
||||
|
||||
/* Trampoline code address */
|
||||
#define MM_TRAMPOLINE_ADDRESS 0x80000
|
||||
|
||||
@@ -116,8 +123,9 @@
|
||||
/* Number of pool lists per page */
|
||||
#define MM_POOL_LISTS_PER_PAGE (MM_PAGE_SIZE / MM_POOL_BLOCK_SIZE)
|
||||
|
||||
/* Number of pool tracking tables */
|
||||
#define MM_POOL_TRACKING_TABLES 64
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Page size enumeration list */
|
||||
typedef enum _PAGE_SIZE
|
||||
@@ -344,4 +352,5 @@ typedef struct _POOL_DESCRIPTOR
|
||||
SIZE_T Reserved;
|
||||
} POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_AMD64_MMTYPES_H */
|
||||
|
||||
57
sdk/xtdk/amd64/rtltypes.h
Normal file
57
sdk/xtdk/amd64/rtltypes.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: sdk/xtdk/amd64/rtltypes.h
|
||||
* DESCRIPTION: Runtime library structures definitions for AMD64 architecture
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTDK_AMD64_RTLTYPES_H
|
||||
#define __XTDK_AMD64_RTLTYPES_H
|
||||
|
||||
#include <xtbase.h>
|
||||
#include <rtltypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Header for a sequenced single linked list union definition */
|
||||
typedef union _SINGLE_LIST_HEADER
|
||||
{
|
||||
struct
|
||||
{
|
||||
ULONGLONG Alignment;
|
||||
ULONGLONG Region;
|
||||
};
|
||||
struct
|
||||
{
|
||||
ULONGLONG Depth:16;
|
||||
ULONGLONG Sequence:9;
|
||||
ULONGLONG NextEntry:39;
|
||||
ULONGLONG HeaderType:1;
|
||||
ULONGLONG Init:1;
|
||||
ULONGLONG Reserved:59;
|
||||
ULONGLONG Region:3;
|
||||
} Header8;
|
||||
struct
|
||||
{
|
||||
ULONGLONG Depth:16;
|
||||
ULONGLONG Sequence:48;
|
||||
ULONGLONG HeaderType:1;
|
||||
ULONGLONG Init:1;
|
||||
ULONGLONG Reserved:2;
|
||||
ULONGLONG NextEntry:60;
|
||||
} Header16;
|
||||
struct
|
||||
{
|
||||
ULONGLONG Depth:16;
|
||||
ULONGLONG Sequence:48;
|
||||
ULONGLONG HeaderType:1;
|
||||
ULONGLONG Reserved:3;
|
||||
ULONGLONG NextEntry:60;
|
||||
} Header64;
|
||||
} SINGLE_LIST_HEADER, *PSINGLE_LIST_HEADER;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_AMD64_RTLTYPES_H */
|
||||
@@ -12,13 +12,20 @@
|
||||
#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;
|
||||
@@ -30,6 +37,7 @@ typedef enum _PIC_I8259_ICW1_OPERATING_MODE PIC_I8259_ICW1_OPERATING_MODE, *PPIC
|
||||
typedef enum _PIC_I8259_ICW4_BUFFERED_MODE PIC_I8259_ICW4_BUFFERED_MODE, *PPIC_I8259_ICW4_BUFFERED_MODE;
|
||||
typedef enum _PIC_I8259_ICW4_EOI_MODE PIC_I8259_ICW4_EOI_MODE, *PPIC_I8259_ICW4_EOI_MODE;
|
||||
typedef enum _PIC_I8259_ICW4_SYSTEM_MODE PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;
|
||||
typedef enum _TIMER_TYPE TIMER_TYPE, *PTIMER_TYPE;
|
||||
typedef enum _TRAMPOLINE_TYPE TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;
|
||||
|
||||
/* Architecture-specific structures forward references */
|
||||
@@ -39,7 +47,10 @@ 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 _KDEVICE_QUEUE KDEVICE_QUEUE, *PKDEVICE_QUEUE;
|
||||
typedef struct _KEXCEPTION_FRAME KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;
|
||||
typedef struct _KGDTENTRY KGDTENTRY, *PKGDTENTRY;
|
||||
typedef struct _KIDTENTRY KIDTENTRY, *PKIDTENTRY;
|
||||
@@ -63,12 +74,14 @@ 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;
|
||||
@@ -78,5 +91,7 @@ typedef union _PIC_I8259_ICW1 PIC_I8259_ICW1, *PPIC_I8259_ICW1;
|
||||
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;
|
||||
typedef union _SINGLE_LIST_HEADER SINGLE_LIST_HEADER, *PSINGLE_LIST_HEADER;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_AMD64_XTSTRUCT_H */
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
#include <xtuefi.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef D__XTOS_ASSEMBLER__
|
||||
|
||||
/* XT BootLoader routines forward references */
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
@@ -21,4 +24,5 @@ BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable,
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
OUT PXTBL_LOADER_PROTOCOL *ProtocolHandler);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_BLFUNCS_H */
|
||||
|
||||
@@ -29,6 +29,10 @@
|
||||
#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
|
||||
@@ -41,6 +45,10 @@
|
||||
/* TUI dialog box maximum width */
|
||||
#define XTBL_TUI_MAX_DIALOG_WIDTH 100
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef D__XTOS_ASSEMBLER__
|
||||
|
||||
/* XTLDR Routine pointers */
|
||||
typedef LOADER_MEMORY_TYPE (XTCDECL *PBL_GET_MEMTYPE_ROUTINE)(IN EFI_MEMORY_TYPE EfiMemoryType);
|
||||
|
||||
@@ -49,7 +57,7 @@ typedef EFI_STATUS (XTCDECL *PBL_ALLOCATE_PAGES)(IN EFI_ALLOCATE_TYPE Allocation
|
||||
typedef EFI_STATUS (XTCDECL *PBL_ALLOCATE_POOL)(IN UINT_PTR Size, OUT PVOID *Memory);
|
||||
typedef EFI_STATUS (XTCDECL *PBL_BOOTMENU_INITIALIZE_OS_LIST)(IN ULONG MaxNameLength, OUT PXTBL_BOOTMENU_ITEM *MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId);
|
||||
typedef BOOLEAN (XTCDECL *PBL_BOOTUTILS_GET_BOOLEAN_PARAMETER)(IN PCWSTR Parameters, IN PCWSTR Needle);
|
||||
typedef VOID (XTAPI *PBL_BOOTUTILS_GET_TRAMPOLINE_INFORMATION)(IN TRAMPOLINE_TYPE TrampolineType, OUT PVOID *TrampolineCode, OUT PULONG_PTR TrampolineSize);
|
||||
typedef VOID (XTAPI *PBL_BOOTUTILS_GET_TRAMPOLINE_INFORMATION)(IN TRAMPOLINE_TYPE TrampolineType, OUT PVOID *TrampolineCode, OUT PULONG TrampolineSize);
|
||||
typedef EFI_STATUS (XTCDECL *PBL_BUILD_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR SelfMapAddress);
|
||||
typedef EFI_STATUS (XTCDECL *PBL_COMMIT_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap);
|
||||
typedef EFI_STATUS (XTCDECL *PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle);
|
||||
@@ -69,7 +77,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 VOID (XTCDECL *PBL_CONSOLE_READ_KEY_STROKE)(OUT PEFI_INPUT_KEY Key);
|
||||
typedef EFI_STATUS (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);
|
||||
@@ -139,6 +147,8 @@ 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);
|
||||
|
||||
@@ -229,6 +239,15 @@ 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
|
||||
{
|
||||
@@ -478,6 +497,10 @@ 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;
|
||||
@@ -520,4 +543,5 @@ typedef struct _XTBL_LOADER_PROTOCOL
|
||||
} WideString;
|
||||
} XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_BLTYPES_H */
|
||||
|
||||
135
sdk/xtdk/cmtypes.h
Normal file
135
sdk/xtdk/cmtypes.h
Normal file
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: sdk/xtdk/cmtypes.h
|
||||
* DESCRIPTION: Configuration Manager structures definitions
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTDK_CMTYPES_H
|
||||
#define __XTDK_CMTYPES_H
|
||||
|
||||
#include <xttypes.h>
|
||||
#include <xtstruct.h>
|
||||
#include <mmtypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Partial resource descriptor */
|
||||
typedef struct _CM_PARTIAL_RESOURCE_DESCRIPTOR
|
||||
{
|
||||
UCHAR Type;
|
||||
UCHAR ShareDisposition;
|
||||
USHORT Flags;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
PHYSICAL_ADDRESS Start;
|
||||
ULONG Length;
|
||||
} Generic;
|
||||
struct
|
||||
{
|
||||
PHYSICAL_ADDRESS Start;
|
||||
ULONG Length;
|
||||
} Port;
|
||||
struct
|
||||
{
|
||||
USHORT Level;
|
||||
USHORT Group;
|
||||
ULONG Vector;
|
||||
PKAFFINITY_MAP Affinity;
|
||||
} Interrupt;
|
||||
struct
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
USHORT Group;
|
||||
USHORT MessageCount;
|
||||
ULONG Vector;
|
||||
PKAFFINITY_MAP Affinity;
|
||||
} Raw;
|
||||
struct
|
||||
{
|
||||
USHORT Level;
|
||||
USHORT Group;
|
||||
ULONG Vector;
|
||||
PKAFFINITY_MAP Affinity;
|
||||
} Translated;
|
||||
};
|
||||
} MessageInterrupt;
|
||||
struct
|
||||
{
|
||||
PHYSICAL_ADDRESS Start;
|
||||
ULONG Length;
|
||||
} Memory;
|
||||
struct
|
||||
{
|
||||
ULONG Channel;
|
||||
ULONG Port;
|
||||
ULONG Reserved1;
|
||||
} Dma;
|
||||
struct
|
||||
{
|
||||
ULONG Data[3];
|
||||
} DevicePrivate;
|
||||
struct
|
||||
{
|
||||
ULONG Start;
|
||||
ULONG Length;
|
||||
ULONG Reserved;
|
||||
} BusNumber;
|
||||
struct
|
||||
{
|
||||
ULONG DataSize;
|
||||
ULONG Reserved1;
|
||||
ULONG Reserved2;
|
||||
} DeviceSpecificData;
|
||||
struct
|
||||
{
|
||||
PHYSICAL_ADDRESS Start;
|
||||
ULONG Length40;
|
||||
} Memory40;
|
||||
struct
|
||||
{
|
||||
PHYSICAL_ADDRESS Start;
|
||||
ULONG Length48;
|
||||
} Memory48;
|
||||
struct
|
||||
{
|
||||
PHYSICAL_ADDRESS Start;
|
||||
ULONG Length64;
|
||||
} Memory64;
|
||||
} u;
|
||||
} CM_PARTIAL_RESOURCE_DESCRIPTOR, *PCM_PARTIAL_RESOURCE_DESCRIPTOR;
|
||||
|
||||
/* Partial resource list */
|
||||
typedef struct _CM_PARTIAL_RESOURCE_LIST
|
||||
{
|
||||
USHORT Version;
|
||||
USHORT Revision;
|
||||
ULONG Count;
|
||||
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1];
|
||||
} CM_PARTIAL_RESOURCE_LIST, *PCM_PARTIAL_RESOURCE_LIST;
|
||||
|
||||
/* Full resource descriptor */
|
||||
typedef struct _CM_FULL_RESOURCE_DESCRIPTOR
|
||||
{
|
||||
INTERFACE_TYPE InterfaceType;
|
||||
ULONG BusNumber;
|
||||
CM_PARTIAL_RESOURCE_LIST PartialResourceList;
|
||||
} CM_FULL_RESOURCE_DESCRIPTOR, *PCM_FULL_RESOURCE_DESCRIPTOR;
|
||||
|
||||
/* Full resource list */
|
||||
typedef struct _CM_RESOURCE_LIST
|
||||
{
|
||||
ULONG Count;
|
||||
CM_FULL_RESOURCE_DESCRIPTOR List[1];
|
||||
} CM_RESOURCE_LIST, *PCM_RESOURCE_LIST;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_CMTYPES_H */
|
||||
@@ -13,6 +13,9 @@
|
||||
#include <xttypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Kernel Executive routines forward references */
|
||||
XTCLINK
|
||||
XTFASTCALL
|
||||
@@ -44,4 +47,5 @@ XTFASTCALL
|
||||
VOID
|
||||
ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_EXFUNCS_H */
|
||||
|
||||
@@ -17,14 +17,75 @@
|
||||
/* Rundown protection flags */
|
||||
#define EX_RUNDOWN_ACTIVE 0x1
|
||||
|
||||
/* Executive rundown protection structure definition */
|
||||
typedef struct _EX_RUNDOWN_REFERENCE
|
||||
/* Number of lookaside lists */
|
||||
#define POOL_LOOKASIDE_LISTS 32
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Kernel routine callbacks */
|
||||
typedef XTSTATUS (XTAPI *PALLOCATE_FUNCTION)(IN MMPOOL_TYPE PoolType, IN SIZE_T Bytes, OUT PVOID *Memory, IN ULONG Tag);
|
||||
typedef XTSTATUS (XTAPI *PALLOCATE_FUNCTION_EX)(IN MMPOOL_TYPE PoolType, IN SIZE_T Bytes, OUT PVOID *Memory, IN ULONG Tag, IN PLOOKASIDE_LIST_EX Lookaside);
|
||||
typedef XTSTATUS (XTAPI *PFREE_FUNCTION)(IN PVOID Buffer);
|
||||
typedef XTSTATUS (XTAPI *PFREE_FUNCTION_EX)(IN PVOID Buffer, IN OUT PLOOKASIDE_LIST_EX Lookaside);
|
||||
typedef VOID (XTAPI *PWORKER_THREAD_ROUTINE)(IN PVOID Parameter);
|
||||
|
||||
/* Work queue types */
|
||||
typedef enum _WORK_QUEUE_TYPE
|
||||
{
|
||||
CriticalWorkQueue,
|
||||
DelayedWorkQueue,
|
||||
HyperCriticalWorkQueue,
|
||||
NormalWorkQueue,
|
||||
BackgroundWorkQueue,
|
||||
RealTimeWorkQueue,
|
||||
SuperCriticalWorkQueue,
|
||||
MaximumWorkQueue,
|
||||
} WORK_QUEUE_TYPE, *PWORK_QUEUE_TYPE;
|
||||
|
||||
/* Owner entry structure definition */
|
||||
typedef struct _OWNER_ENTRY
|
||||
{
|
||||
ULONG_PTR OwnerThread;
|
||||
union
|
||||
{
|
||||
ULONG_PTR Count;
|
||||
PVOID Ptr;
|
||||
struct
|
||||
{
|
||||
ULONG IoPriorityBoosted:1;
|
||||
ULONG OwnerReferenced:1;
|
||||
ULONG OwnerCount:30;
|
||||
};
|
||||
ULONG TableSize;
|
||||
};
|
||||
} OWNER_ENTRY, *POWNER_ENTRY;
|
||||
|
||||
/* Exclusive resource structure definition */
|
||||
typedef struct _ERESOURCE
|
||||
{
|
||||
LIST_ENTRY SystemResourcesList;
|
||||
POWNER_ENTRY OwnerTable;
|
||||
SHORT ActiveCount;
|
||||
USHORT Flag;
|
||||
VOLATILE PKSEMAPHORE SharedWaiters;
|
||||
VOLATILE PKEVENT ExclusiveWaiters;
|
||||
OWNER_ENTRY OwnerEntry;
|
||||
ULONG ActiveEntries;
|
||||
ULONG ContentionCount;
|
||||
ULONG NumberOfSharedWaiters;
|
||||
ULONG NumberOfExclusiveWaiters;
|
||||
union
|
||||
{
|
||||
PVOID Address;
|
||||
ULONG_PTR CreatorBackTraceIndex;
|
||||
};
|
||||
KSPIN_LOCK SpinLock;
|
||||
} ERESOURCE, *PERESOURCE;
|
||||
|
||||
/* Executive rundown protection structure definition */
|
||||
typedef union _EX_RUNDOWN_REFERENCE
|
||||
{
|
||||
ULONG_PTR Count;
|
||||
PVOID Ptr;
|
||||
} EX_RUNDOWN_REFERENCE, *PEX_RUNDOWN_REFERENCE;
|
||||
|
||||
/* Executive rundown wait block definition */
|
||||
@@ -34,4 +95,82 @@ typedef struct _EX_RUNDOWN_WAIT_BLOCK
|
||||
KEVENT WakeEvent;
|
||||
} EX_RUNDOWN_WAIT_BLOCK, *PEX_RUNDOWN_WAIT_BLOCK;
|
||||
|
||||
/* Lookaside list structure definition */
|
||||
typedef struct _GENERAL_LOOKASIDE
|
||||
{
|
||||
union
|
||||
{
|
||||
SINGLE_LIST_HEADER ListHead;
|
||||
SINGLE_LIST_ENTRY SingleListHead;
|
||||
};
|
||||
USHORT Depth;
|
||||
USHORT MaximumDepth;
|
||||
ULONG TotalAllocates;
|
||||
union
|
||||
{
|
||||
ULONG AllocateMisses;
|
||||
ULONG AllocateHits;
|
||||
};
|
||||
ULONG TotalFrees;
|
||||
union {
|
||||
ULONG FreeMisses;
|
||||
ULONG FreeHits;
|
||||
};
|
||||
MMPOOL_TYPE Type;
|
||||
ULONG Tag;
|
||||
ULONG Size;
|
||||
union
|
||||
{
|
||||
PALLOCATE_FUNCTION_EX AllocateEx;
|
||||
PALLOCATE_FUNCTION Allocate;
|
||||
};
|
||||
union
|
||||
{
|
||||
PFREE_FUNCTION_EX FreeEx;
|
||||
PFREE_FUNCTION Free;
|
||||
};
|
||||
LIST_ENTRY ListEntry;
|
||||
ULONG LastTotalAllocates;
|
||||
union
|
||||
{
|
||||
ULONG LastAllocateMisses;
|
||||
ULONG LastAllocateHits;
|
||||
};
|
||||
ULONG Future[2];
|
||||
} GENERAL_LOOKASIDE, *PGENERAL_LOOKASIDE;
|
||||
|
||||
/* Lookaside list pointers structure definition */
|
||||
typedef struct _LOOKASIDE_LIST
|
||||
{
|
||||
PGENERAL_LOOKASIDE Local;
|
||||
PGENERAL_LOOKASIDE Global;
|
||||
} LOOKASIDE_LIST, *PLOOKASIDE_LIST;
|
||||
|
||||
/* Lookaside list extended structure definition */
|
||||
typedef struct _LOOKASIDE_LIST_EX
|
||||
{
|
||||
GENERAL_LOOKASIDE Global;
|
||||
} LOOKASIDE_LIST_EX, *PLOOKASIDE_LIST_EX;
|
||||
|
||||
/* Non-paged lookaside list structure definition */
|
||||
typedef struct _NONPAGED_LOOKASIDE_LIST
|
||||
{
|
||||
GENERAL_LOOKASIDE Global;
|
||||
} NONPAGED_LOOKASIDE_LIST, *PNONPAGED_LOOKASIDE_LIST;
|
||||
|
||||
/* Paged lookaside list structure definition */
|
||||
typedef struct _PAGED_LOOKASIDE_LIST
|
||||
{
|
||||
GENERAL_LOOKASIDE Global;
|
||||
} PAGED_LOOKASIDE_LIST, *PPAGED_LOOKASIDE_LIST;
|
||||
|
||||
/* Work queue item structure definition */
|
||||
typedef struct _WORK_QUEUE_ITEM
|
||||
{
|
||||
LIST_ENTRY List;
|
||||
PWORKER_THREAD_ROUTINE WorkerRoutine;
|
||||
VOLATILE PVOID Parameter;
|
||||
} WORK_QUEUE_ITEM, *PWORK_QUEUE_ITEM;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_EXTYPES_H */
|
||||
|
||||
@@ -14,7 +14,15 @@
|
||||
#include <xttypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Hardware layer routines forward references */
|
||||
XTCLINK
|
||||
XTAPI
|
||||
LARGE_INTEGER
|
||||
HlQueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceFrequency);
|
||||
|
||||
XTCLINK
|
||||
XTAPI
|
||||
UCHAR
|
||||
@@ -30,6 +38,11 @@ XTAPI
|
||||
ULONG
|
||||
HlReadRegister32(IN PVOID Register);
|
||||
|
||||
XTCLINK
|
||||
XTAPI
|
||||
ULONG
|
||||
HlSetClockRate(IN ULONG Rate);
|
||||
|
||||
XTCLINK
|
||||
XTAPI
|
||||
VOID
|
||||
@@ -48,4 +61,5 @@ 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 0x80000000
|
||||
#define ACPI_FADT_TIMER_24BIT 0x00800000
|
||||
#define ACPI_FADT_TIMER_32BIT 0xFFFFFFFF
|
||||
#define ACPI_FADT_TIMER_24BIT 0x00FFFFFF
|
||||
|
||||
/* ACPI MADT subtable type definitions */
|
||||
#define ACPI_MADT_TYPE_LOCAL_APIC 0
|
||||
@@ -101,6 +101,15 @@
|
||||
#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
|
||||
@@ -179,6 +188,57 @@
|
||||
#define COMPORT_REG_MSR 0x06 /* Modem Status Register */
|
||||
#define COMPORT_REG_SR 0x07 /* Scratch Register */
|
||||
|
||||
/* Standard system clock rates (in 100-nanosecond units)*/
|
||||
#define HL_CLOCK_RATE_1000HZ 10000 /* 1 ms (1000 Hz) - Best Performance */
|
||||
#define HL_CLOCK_RATE_500HZ 20000 /* 2 ms (500 Hz) - High Responsiveness */
|
||||
#define HL_CLOCK_RATE_300HZ 33333 /* 3.33ms (300 Hz) - Multimedia Sync */
|
||||
#define HL_CLOCK_RATE_250HZ 40000 /* 4 ms (250 Hz) - Optimal Balance */
|
||||
#define HL_CLOCK_RATE_100HZ 100000 /* 10 ms (100 Hz) - Power Saving */
|
||||
#define HL_CLOCK_RATE_50HZ 200000 /* 20 ms (50 Hz) - Deep Power Saving */
|
||||
|
||||
/* Minimum and maximum system clock rate definitions */
|
||||
#define HL_MINIMUM_CLOCK_RATE HL_CLOCK_RATE_1000HZ
|
||||
#define HL_MAXIMUM_CLOCK_RATE HL_CLOCK_RATE_50HZ
|
||||
|
||||
/* Minimum and maximum profile intervals */
|
||||
#define MIN_PROFILE_INTERVAL 10000
|
||||
#define MAX_PROFILE_INTERVAL 10000000
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Hardware Layer routine callbacks */
|
||||
typedef XTSTATUS (XTAPI *PHALP_INITIALIZE_CLOCK)(VOID);
|
||||
typedef ULONGLONG (XTAPI *PHALP_QUERY_PERF_COUNTER)(VOID);
|
||||
typedef ULONG (XTAPI *PHALP_QUERY_TIME_DELTA)(VOID);
|
||||
typedef ULONG (XTAPI *PHALP_SET_CLOCK_RATE)(IN ULONG Increment);
|
||||
typedef VOID (XTAPI *PHALP_STALL_EXECUTION)(IN ULONG MicroSeconds);
|
||||
|
||||
/* Interface types */
|
||||
typedef enum _INTERFACE_TYPE
|
||||
{
|
||||
InterfaceTypeUndefined = -1,
|
||||
Internal,
|
||||
Isa,
|
||||
Eisa,
|
||||
MicroChannel,
|
||||
TurboChannel,
|
||||
PCIBus,
|
||||
VMEBus,
|
||||
NuBus,
|
||||
PCMCIABus,
|
||||
CBus,
|
||||
MPIBus,
|
||||
MPSABus,
|
||||
ProcessorInternal,
|
||||
InternalPowerBus,
|
||||
PNPISABus,
|
||||
PNPBus,
|
||||
Vmcs,
|
||||
MaximumInterfaceType
|
||||
} INTERFACE_TYPE, *PINTERFACE_TYPE;
|
||||
|
||||
/* Generic Address structure */
|
||||
typedef struct _GENERIC_ADDRESS
|
||||
{
|
||||
@@ -214,7 +274,7 @@ typedef struct _ACPI_SUBTABLE_HEADER
|
||||
typedef struct _ACPI_CACHE_LIST
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
ACPI_DESCRIPTION_HEADER Header;
|
||||
PACPI_DESCRIPTION_HEADER Table;
|
||||
} ACPI_CACHE_LIST, *PACPI_CACHE_LIST;
|
||||
|
||||
/* ACPI Root System Description Table Pointer (RSDP) structure */
|
||||
@@ -305,6 +365,17 @@ 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
|
||||
{
|
||||
@@ -314,6 +385,26 @@ 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
|
||||
{
|
||||
@@ -450,4 +541,15 @@ typedef struct _SMBIOS3_TABLE_HEADER
|
||||
ULONGLONG TableAddress;
|
||||
} SMBIOS3_TABLE_HEADER, *PSMBIOS3_TABLE_HEADER;
|
||||
|
||||
/* Timer dispatch table */
|
||||
typedef struct _TIMER_ROUTINES
|
||||
{
|
||||
PHALP_INITIALIZE_CLOCK InitializeClock;
|
||||
PHALP_QUERY_PERF_COUNTER QueryPerformanceCounter;
|
||||
PHALP_QUERY_TIME_DELTA QueryTimeDelta;
|
||||
PHALP_SET_CLOCK_RATE SetClockRate;
|
||||
PHALP_STALL_EXECUTION StallExecution;
|
||||
} TIMER_ROUTINES, *PTIMER_ROUTINES;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_HLTYPES_H */
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <xtdefs.h>
|
||||
#include <xtstruct.h>
|
||||
#include <xttypes.h>
|
||||
#include ARCH_HEADER(xtstruct.h)
|
||||
|
||||
|
||||
/* Control Register 0 constants */
|
||||
@@ -92,6 +93,10 @@
|
||||
#define X86_EFLAGS_VIP_MASK 0x00100000 /* Virtual Interrupt Pending */
|
||||
#define X86_EFLAGS_ID_MASK 0x00200000 /* Identification */
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* CPU vendor enumeration list */
|
||||
typedef enum _CPU_VENDOR
|
||||
{
|
||||
@@ -100,6 +105,18 @@ typedef enum _CPU_VENDOR
|
||||
CPU_VENDOR_UNKNOWN = 0xFFFFFFFF
|
||||
} CPU_VENDOR, *PCPU_VENDOR;
|
||||
|
||||
/* CPUID advanced power management features (0x80000007) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT
|
||||
{
|
||||
CPUID_FEATURES_EDX_TS = 1 << 0, /* Temperature Sensor */
|
||||
CPUID_FEATURES_EDX_FIS = 1 << 1, /* Frequency ID Selection */
|
||||
CPUID_FEATURES_EDX_VIS = 1 << 2, /* Voltage ID Selection */
|
||||
CPUID_FEATURES_EDX_TTS = 1 << 3, /* ThermaTrip Support */
|
||||
CPUID_FEATURES_EDX_HTC = 1 << 4, /* Hardware Thermal Throttling */
|
||||
CPUID_FEATURES_EDX_STC = 1 << 5, /* Software Thermal Throttling */
|
||||
CPUID_FEATURES_EDX_TSCI = 1 << 8 /* TSC Invariant */
|
||||
} CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT, *PCPUID_FEATURES_ADVANCED_POWER_MANAGEMENT;
|
||||
|
||||
/* CPUID extended features (0x80000001) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_EXTENDED
|
||||
{
|
||||
@@ -141,6 +158,23 @@ typedef enum _CPUID_FEATURES_EXTENDED
|
||||
CPUID_FEATURES_EDX_3DNOW = 1 << 31
|
||||
} CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;
|
||||
|
||||
/* CPUID Thermal and Power Management features (0x00000006) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_POWER_MANAGEMENT
|
||||
{
|
||||
CPUID_FEATURES_EAX_DTHERM = 1 << 0,
|
||||
CPUID_FEATURES_EAX_IDA = 1 << 1,
|
||||
CPUID_FEATURES_EAX_ARAT = 1 << 2,
|
||||
CPUID_FEATURES_EAX_PLN = 1 << 4,
|
||||
CPUID_FEATURES_EAX_PTS = 1 << 6,
|
||||
CPUID_FEATURES_EAX_HWP = 1 << 7,
|
||||
CPUID_FEATURES_EAX_HWP_NOTIFY = 1 << 8,
|
||||
CPUID_FEATURES_EAX_HWP_ACT_WINDOW = 1 << 9,
|
||||
CPUID_FEATURES_EAX_HWP_EPP = 1 << 10,
|
||||
CPUID_FEATURES_EAX_HWP_PKG_REQ = 1 << 11,
|
||||
CPUID_FEATURES_EAX_HWP_HIGHEST_PERF_CHANGE = 1 << 15,
|
||||
CPUID_FEATURES_EAX_HFI = 1 << 19
|
||||
} CPUID_FEATURES_LEAF6, *PCPUID_FEATURES_LEAF6;
|
||||
|
||||
/* CPUID STD1 features (0x00000001) enumeration list */
|
||||
typedef enum _CPUID_FEATURES_STANDARD1
|
||||
{
|
||||
@@ -167,7 +201,7 @@ typedef enum _CPUID_FEATURES_STANDARD1
|
||||
CPUID_FEATURES_ECX_X2APIC = 1 << 21,
|
||||
CPUID_FEATURES_ECX_MOVBE = 1 << 22,
|
||||
CPUID_FEATURES_ECX_POPCNT = 1 << 23,
|
||||
CPUID_FEATURES_ECX_TSC = 1 << 24,
|
||||
CPUID_FEATURES_ECX_TSC_DEADLINE = 1 << 24,
|
||||
CPUID_FEATURES_ECX_AES = 1 << 25,
|
||||
CPUID_FEATURES_ECX_XSAVE = 1 << 26,
|
||||
CPUID_FEATURES_ECX_OSXSAVE = 1 << 27,
|
||||
@@ -341,20 +375,29 @@ typedef enum _CPUID_FEATURES_STANDARD7_LEAF1
|
||||
/* CPUID requests */
|
||||
typedef enum _CPUID_REQUESTS
|
||||
{
|
||||
CPUID_GET_VENDOR_STRING,
|
||||
CPUID_GET_STANDARD1_FEATURES,
|
||||
CPUID_GET_TLB_CACHE,
|
||||
CPUID_GET_SERIAL,
|
||||
CPUID_GET_CACHE_TOPOLOGY,
|
||||
CPUID_GET_MONITOR_MWAIT,
|
||||
CPUID_GET_POWER_MANAGEMENT,
|
||||
CPUID_GET_STANDARD7_FEATURES
|
||||
CPUID_GET_VENDOR_STRING = 0x00000000,
|
||||
CPUID_GET_STANDARD1_FEATURES = 0x00000001,
|
||||
CPUID_GET_TLB_CACHE = 0x00000002,
|
||||
CPUID_GET_SERIAL = 0x00000003,
|
||||
CPUID_GET_CACHE_TOPOLOGY = 0x00000004,
|
||||
CPUID_GET_MONITOR_MWAIT = 0x00000005,
|
||||
CPUID_GET_POWER_MANAGEMENT = 0x00000006,
|
||||
CPUID_GET_STANDARD7_FEATURES = 0x00000007,
|
||||
CPUID_GET_TSC_CRYSTAL_CLOCK = 0x00000015,
|
||||
CPUID_GET_EXTENDED_MAX = 0x80000000,
|
||||
CPUID_GET_EXTENDED_FEATURES = 0x80000001,
|
||||
CPUID_GET_ADVANCED_POWER_MANAGEMENT = 0x80000007
|
||||
} CPUID_REQUESTS, *PCPUID_REQUESTS;
|
||||
|
||||
/* Interrupt handler */
|
||||
typedef VOID (*PINTERRUPT_HANDLER)(PKTRAP_FRAME TrapFrame);
|
||||
|
||||
/* Processor identification information */
|
||||
typedef struct _CPU_IDENTIFICATION
|
||||
{
|
||||
ULONGLONG ExtendedFeatureBits;
|
||||
USHORT Family;
|
||||
ULONGLONG FeatureBits;
|
||||
USHORT Model;
|
||||
USHORT Stepping;
|
||||
CPU_VENDOR Vendor;
|
||||
@@ -390,4 +433,5 @@ typedef enum _TRAMPOLINE_TYPE
|
||||
TrampolineApStartup
|
||||
} TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_I686_ARTYPES_H */
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
#include <i686/xtstruct.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Hardware layer routines forward references */
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
@@ -49,4 +52,5 @@ VOID
|
||||
HlWritePort32(IN USHORT Port,
|
||||
IN ULONG Value);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_I686_HLFUNCS_H */
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#ifndef __XTDK_I686_HLTYPES_H
|
||||
#define __XTDK_I686_HLTYPES_H
|
||||
|
||||
#include <xtbase.h>
|
||||
#include <xtdefs.h>
|
||||
#include <xtstruct.h>
|
||||
#include <xttypes.h>
|
||||
@@ -36,6 +37,7 @@
|
||||
#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
|
||||
@@ -43,6 +45,9 @@
|
||||
#define APIC_VECTOR_PERF 0xFE
|
||||
#define APIC_VECTOR_NMI 0xFF
|
||||
|
||||
/* APIC SIPI vector shift */
|
||||
#define APIC_VECTOR_SIPI_SHIFT 12
|
||||
|
||||
/* APIC destination formats */
|
||||
#define APIC_DF_FLAT 0xFFFFFFFF
|
||||
#define APIC_DF_CLUSTER 0x0FFFFFFF
|
||||
@@ -58,6 +63,27 @@
|
||||
/* 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
|
||||
@@ -69,6 +95,87 @@
|
||||
/* 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
|
||||
@@ -76,6 +183,17 @@
|
||||
/* 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
|
||||
{
|
||||
@@ -133,6 +251,7 @@ typedef enum _APIC_REGISTER
|
||||
APIC_TICR = 0x38, /* Initial Count Register for Timer */
|
||||
APIC_TCCR = 0x39, /* Current Count Register for Timer */
|
||||
APIC_TDCR = 0x3E, /* Timer Divide Configuration Register */
|
||||
APIC_SIPI = 0x3F, /* Self-IPI Register */
|
||||
APIC_EAFR = 0x40, /* extended APIC Feature register */
|
||||
APIC_EACR = 0x41, /* Extended APIC Control Register */
|
||||
APIC_SEOI = 0x42, /* Specific End Of Interrupt Register */
|
||||
@@ -142,6 +261,19 @@ typedef enum _APIC_REGISTER
|
||||
APIC_EXT3LVTR = 0x53 /* Extended Interrupt 3 Local Vector Table */
|
||||
} APIC_REGISTER, *PAPIC_REGISTER;
|
||||
|
||||
/* APIC Timer Divide enumeration list */
|
||||
typedef enum _APIC_TIMER_DIVISOR
|
||||
{
|
||||
TIMER_DivideBy2 = 0,
|
||||
TIMER_DivideBy4 = 1,
|
||||
TIMER_DivideBy8 = 2,
|
||||
TIMER_DivideBy16 = 3,
|
||||
TIMER_DivideBy32 = 8,
|
||||
TIMER_DivideBy64 = 9,
|
||||
TIMER_DivideBy128 = 10,
|
||||
TIMER_DivideBy1 = 11,
|
||||
} APIC_TIMER_DIVISOR, *PAPIC_TIMER_DIVISOR;
|
||||
|
||||
/* I8259 PIC interrupt mode enumeration list */
|
||||
typedef enum _PIC_I8259_ICW1_INTERRUPT_MODE
|
||||
{
|
||||
@@ -186,6 +318,17 @@ typedef enum _PIC_I8259_ICW4_SYSTEM_MODE
|
||||
New8086Mode
|
||||
} PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;
|
||||
|
||||
/* Supported hardware timer backends */
|
||||
typedef enum _TIMER_TYPE
|
||||
{
|
||||
TimerNone,
|
||||
TimerAcpiPm,
|
||||
TimerHpet,
|
||||
TimerLapic,
|
||||
TimerPit,
|
||||
TimerTsc
|
||||
} TIMER_TYPE, *PTIMER_TYPE;
|
||||
|
||||
/* APIC Base Register */
|
||||
typedef union _APIC_BASE_REGISTER
|
||||
{
|
||||
@@ -259,6 +402,40 @@ 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
|
||||
{
|
||||
@@ -324,4 +501,39 @@ 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;
|
||||
|
||||
/* Hardware timer capabilities and CPU clock features */
|
||||
typedef struct _TIMER_CAPABILITIES
|
||||
{
|
||||
BOOLEAN Arat;
|
||||
BOOLEAN Art;
|
||||
BOOLEAN InvariantTsc;
|
||||
BOOLEAN RDTSCP;
|
||||
ULONG TimerFrequency;
|
||||
BOOLEAN TscDeadline;
|
||||
ULONG TscDenominator;
|
||||
ULONG TscNumerator;
|
||||
} TIMER_CAPABILITIES, *PTIMER_CAPABILITIES;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_I686_HLTYPES_H */
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <xtbase.h>
|
||||
#include <xtstruct.h>
|
||||
#include <xttypes.h>
|
||||
#include <extypes.h>
|
||||
#include <potypes.h>
|
||||
#include ARCH_HEADER(xtstruct.h)
|
||||
#include ARCH_HEADER(artypes.h)
|
||||
@@ -50,7 +51,7 @@
|
||||
#define KGDT_DESCRIPTOR_CODE 0x08
|
||||
|
||||
/* GDT descriptor type codes */
|
||||
#define KGDT_TYPE_NONE 0x0
|
||||
#define KGDT_TYPE_NONE 0x00
|
||||
#define KGDT_TYPE_CODE (0x10 | KGDT_DESCRIPTOR_CODE | KGDT_DESCRIPTOR_EXECUTE_READ)
|
||||
#define KGDT_TYPE_DATA (0x10 | KGDT_DESCRIPTOR_READ_WRITE)
|
||||
|
||||
@@ -82,6 +83,7 @@
|
||||
#define KTSS_IO_MAPS 0x68
|
||||
|
||||
/* I686 Segment Types */
|
||||
#define I686_LDT 0x2
|
||||
#define I686_TASK_GATE 0x5
|
||||
#define I686_TSS 0x9
|
||||
#define I686_ACTIVE_TSS 0xB
|
||||
@@ -89,6 +91,62 @@
|
||||
#define I686_INTERRUPT_GATE 0xE
|
||||
#define I686_TRAP_GATE 0xF
|
||||
|
||||
/* Kernel CPU Standard Features */
|
||||
#define KCF_VME (1ULL << 0) /* Virtual 8086 Mode Enhancements */
|
||||
#define KCF_LARGE_PAGE (1ULL << 1) /* Page Size Extensions */
|
||||
#define KCF_RDTSC (1ULL << 2) /* Time Stamp Counter */
|
||||
#define KCF_PAE (1ULL << 3) /* Physical Address Extension */
|
||||
#define KCF_MCE (1ULL << 4) /* Machine Check Exception */
|
||||
#define KCF_CMPXCHG8B (1ULL << 5) /* CMPXCHG8B Instruction */
|
||||
#define KCF_APIC (1ULL << 6) /* APIC On-Chip */
|
||||
#define KCF_FAST_SYSCALL (1ULL << 7) /* SYSENTER/SYSEXIT Instructions */
|
||||
#define KCF_MTRR (1ULL << 8) /* Memory Type Range Registers */
|
||||
#define KCF_GLOBAL_PAGE (1ULL << 9) /* Page Global Enable */
|
||||
#define KCF_MCA (1ULL << 10) /* Machine Check Architecture */
|
||||
#define KCF_CMOV (1ULL << 11) /* Conditional Move Instructions */
|
||||
#define KCF_PAT (1ULL << 12) /* Page Attribute Table */
|
||||
#define KCF_PSE36 (1ULL << 13) /* 36-bit Page Size Extension */
|
||||
#define KCF_CLFLUSH (1ULL << 14) /* CLFLUSH Instruction */
|
||||
#define KCF_FXSR (1ULL << 15) /* FXSAVE/FXRSTOR Instructions */
|
||||
#define KCF_ACPI (1ULL << 16) /* Thermal Monitor and Software Controlled Clock */
|
||||
#define KCF_MMX (1ULL << 17) /* MMX Technology */
|
||||
#define KCF_SSE (1ULL << 18) /* Streaming SIMD Extensions */
|
||||
#define KCF_SSE2 (1ULL << 19) /* Streaming SIMD Extensions 2 */
|
||||
#define KCF_SMT (1ULL << 20) /* Hyper-Threading Technology */
|
||||
#define KCF_SSE3 (1ULL << 21) /* Streaming SIMD Extensions 3 */
|
||||
#define KCF_VMX (1ULL << 22) /* Intel Virtual Machine Extensions */
|
||||
#define KCF_SSSE3 (1ULL << 23) /* Supplemental SSE3 Instructions */
|
||||
#define KCF_SSE41 (1ULL << 24) /* SSE4.1 Instructions */
|
||||
#define KCF_SSE42 (1ULL << 25) /* SSE4.2 Instructions */
|
||||
#define KCF_X2APIC (1ULL << 26) /* x2APIC Support */
|
||||
#define KCF_POPCNT (1ULL << 27) /* POPCNT Instruction */
|
||||
#define KCF_TSC_DEADLINE (1ULL << 28) /* TSC Deadline Timer */
|
||||
#define KCF_AES (1ULL << 29) /* AES-NI Instruction Set */
|
||||
#define KCF_XSAVE (1ULL << 30) /* XSAVE/XRSTOR Instructions */
|
||||
#define KCF_AVX (1ULL << 31) /* Advanced Vector Extensions */
|
||||
#define KCF_RDRAND (1ULL << 32) /* RDRAND Instruction */
|
||||
#define KCF_FSGSBASE (1ULL << 33) /* RDFSBASE/WRFSBASE Instructions */
|
||||
#define KCF_AVX2 (1ULL << 34) /* AVX2 Instructions */
|
||||
#define KCF_SMEP (1ULL << 35) /* Supervisor Mode Execution Prevention */
|
||||
#define KCF_RDSEED (1ULL << 36) /* RDSEED Instruction */
|
||||
#define KCF_SMAP (1ULL << 37) /* Supervisor Mode Access Prevention */
|
||||
#define KCF_SHA (1ULL << 38) /* SHA Extensions */
|
||||
#define KCF_LA57 (1ULL << 39) /* 57-bit Linear Addresses */
|
||||
#define KCF_ARAT (1ULL << 40) /* Always Running APIC Timer */
|
||||
|
||||
/* Kernel CPU Extended Features */
|
||||
#define KCF_SVM (1ULL << 0) /* AMD Secure Virtual Machine */
|
||||
#define KCF_SSE4A (1ULL << 1) /* SSE4A Instructions */
|
||||
#define KCF_FMA4 (1ULL << 2) /* FMA4 Instructions */
|
||||
#define KCF_TOPOEXT (1ULL << 3) /* AMD Topology Extensions */
|
||||
#define KCF_SYSCALL (1ULL << 4) /* SYSCALL/SYSRET Instructions */
|
||||
#define KCF_NX_BIT (1ULL << 5) /* No-Execute Page Protection */
|
||||
#define KCF_RDTSCP (1ULL << 6) /* RDTSCP Instruction */
|
||||
#define KCF_64BIT (1ULL << 7) /* Long Mode Support */
|
||||
#define KCF_3DNOW_EXT (1ULL << 8) /* 3DNow! Extensions */
|
||||
#define KCF_3DNOW (1ULL << 9) /* 3DNow! Instructions */
|
||||
#define KCF_INVARIANT_TSC (1ULL << 10) /* Invariant Time Stamp Counter */
|
||||
|
||||
/* Context control flags */
|
||||
#define CONTEXT_ARCHITECTURE 0x00010000
|
||||
#define CONTEXT_CONTROL (CONTEXT_ARCHITECTURE | 0x01)
|
||||
@@ -97,6 +155,19 @@
|
||||
#define CONTEXT_FLOATING_POINT (CONTEXT_ARCHITECTURE | 0x08)
|
||||
#define CONTEXT_DEBUG_REGISTERS (CONTEXT_ARCHITECTURE | 0x10)
|
||||
#define CONTEXT_EXTENDED_REGISTERS (CONTEXT_ARCHITECTURE | 0x20)
|
||||
#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS)
|
||||
#define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | \
|
||||
CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | \
|
||||
CONTEXT_EXTENDED_REGISTERS)
|
||||
|
||||
/* Clock control flags */
|
||||
#define CLOCK_QUANTUM_DECREMENT 3
|
||||
|
||||
/* DPC definitions */
|
||||
#define DPC_ADJUST_THRESHOLD 20
|
||||
#define DPC_IDEAL_RATE 20
|
||||
#define DPC_MAXIMUM_QUEUE_DEPTH 4
|
||||
#define DPC_MINIMUM_RATE 3
|
||||
|
||||
/* Interrupt request levels definitions */
|
||||
#define PASSIVE_LEVEL 0
|
||||
@@ -130,19 +201,23 @@
|
||||
|
||||
/* XTOS Kernel stack size */
|
||||
#define KERNEL_STACK_SIZE 0x4000
|
||||
#define KERNEL_STACKS 3
|
||||
|
||||
/* XTOS Kernel stack guard pages */
|
||||
#define KERNEL_STACK_GUARD_PAGES 1
|
||||
|
||||
/* Processor structures size */
|
||||
#define KPROCESSOR_STRUCTURES_SIZE ((2 * KERNEL_STACK_SIZE) + (GDT_ENTRIES * sizeof(KGDTENTRY)) + sizeof(KTSS) + \
|
||||
sizeof(KPROCESSOR_BLOCK) + MM_PAGE_SIZE)
|
||||
#define KPROCESSOR_STRUCTURES_SIZE ((KERNEL_STACKS * KERNEL_STACK_SIZE) + (GDT_ENTRIES * sizeof(KGDTENTRY)) + \
|
||||
sizeof(KTSS) + sizeof(KPROCESSOR_BLOCK) + MM_PAGE_SIZE)
|
||||
|
||||
/* Kernel frames */
|
||||
#define KTRAP_FRAME_ALIGN 0x08
|
||||
#define KTRAP_FRAME_SIZE sizeof(KTRAP_FRAME)
|
||||
#define NPX_FRAME_SIZE 0x210
|
||||
|
||||
/* Initial stack reservation size */
|
||||
#define KTHREAD_STACK_OFFSET ((sizeof(KTHREAD_INIT_FRAME) + STACK_ALIGNMENT - 1) & ~(STACK_ALIGNMENT - 1))
|
||||
|
||||
/* Number of supported extensions */
|
||||
#define MAXIMUM_SUPPORTED_EXTENSION 512
|
||||
|
||||
@@ -157,6 +232,10 @@
|
||||
#define NPX_STATE_LOADED 0x0
|
||||
#define NPX_STATE_UNLOADED 0xA
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Floating point state storing structure */
|
||||
typedef struct _FN_SAVE_FORMAT
|
||||
{
|
||||
@@ -226,7 +305,7 @@ typedef struct _CONTEXT
|
||||
ULONG Ebp;
|
||||
ULONG Eip;
|
||||
ULONG SegCs;
|
||||
ULONG EFlags;
|
||||
ULONG Flags;
|
||||
ULONG Esp;
|
||||
ULONG SegSs;
|
||||
UCHAR ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];
|
||||
@@ -240,6 +319,16 @@ typedef struct _KDESCRIPTOR
|
||||
PVOID Base;
|
||||
} KDESCRIPTOR, *PKDESCRIPTOR;
|
||||
|
||||
/* Device Queue structure definition */
|
||||
typedef struct _KDEVICE_QUEUE
|
||||
{
|
||||
CSHORT Type;
|
||||
CSHORT Size;
|
||||
LIST_ENTRY DeviceListHead;
|
||||
KSPIN_LOCK Lock;
|
||||
BOOLEAN Busy;
|
||||
} KDEVICE_QUEUE, *PKDEVICE_QUEUE;
|
||||
|
||||
/* Global Descriptor Table (GDT) entry structure definition */
|
||||
typedef struct _KGDTENTRY
|
||||
{
|
||||
@@ -337,27 +426,32 @@ typedef struct _KTSS
|
||||
UCHAR IntDirectionMap[IOPM_DIRECTION_MAP_SIZE];
|
||||
} KTSS, *PKTSS;
|
||||
|
||||
/* Exception frame definition (not available on ia32) */
|
||||
/* Exception frame definition (not available on i686) */
|
||||
typedef struct _KEXCEPTION_FRAME
|
||||
{
|
||||
ULONG PlaceHolder;
|
||||
ULONG Ebp;
|
||||
ULONG Ebx;
|
||||
ULONG Edi;
|
||||
ULONG Esi;
|
||||
ULONG Return;
|
||||
} KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;
|
||||
|
||||
/* Thread start frame definition */
|
||||
typedef struct _KSTART_FRAME
|
||||
{
|
||||
PKSYSTEM_ROUTINE SystemRoutine;
|
||||
PKSTART_ROUTINE StartRoutine;
|
||||
PVOID StartContext;
|
||||
ULONG P1Home;
|
||||
ULONG P2Home;
|
||||
ULONG P3Home;
|
||||
BOOLEAN UserMode;
|
||||
ULONG Return;
|
||||
} KSTART_FRAME, *PKSTART_FRAME;
|
||||
|
||||
/* Switch frame definition */
|
||||
typedef struct _KSWITCH_FRAME
|
||||
{
|
||||
PVOID ExceptionList;
|
||||
BOOLEAN ApcBypassDisabled;
|
||||
PVOID Return;
|
||||
KRUNLEVEL ApcBypass;
|
||||
ULONG Return;
|
||||
} KSWITCH_FRAME, *PKSWITCH_FRAME;
|
||||
|
||||
/* Trap frame definition */
|
||||
@@ -421,6 +515,18 @@ typedef struct _KSPECIAL_REGISTERS
|
||||
ULONG Reserved[6];
|
||||
} KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS;
|
||||
|
||||
/* Processor start block structure definition */
|
||||
typedef struct _PROCESSOR_START_BLOCK
|
||||
{
|
||||
ULONG_PTR Cr3;
|
||||
ULONG_PTR Cr4;
|
||||
PVOID EntryPoint;
|
||||
PVOID InitialStack;
|
||||
PVOID ProcessorStructures;
|
||||
PVOID Stack;
|
||||
BOOLEAN Started;
|
||||
} PROCESSOR_START_BLOCK, *PPROCESSOR_START_BLOCK;
|
||||
|
||||
/* Processor state frame structure definition */
|
||||
typedef struct _KPROCESSOR_STATE
|
||||
{
|
||||
@@ -438,14 +544,32 @@ typedef struct _KPROCESSOR_CONTROL_BLOCK
|
||||
ULONG_PTR SetMember;
|
||||
CPU_IDENTIFICATION CpuId;
|
||||
KPROCESSOR_STATE ProcessorState;
|
||||
KSPIN_LOCK PrcbLock;
|
||||
KSPIN_LOCK_QUEUE LockQueue[MaximumLock];
|
||||
LOOKASIDE_LIST LookasideList[16];
|
||||
LOOKASIDE_LIST NonPagedLookasideList[POOL_LOOKASIDE_LISTS];
|
||||
LOOKASIDE_LIST PagedLookasideList[POOL_LOOKASIDE_LISTS];
|
||||
ULONG_PTR MultiThreadProcessorSet;
|
||||
VOLATILE ULONG IpiFrozen;
|
||||
VOLATILE LONG_PTR RequestSummary;
|
||||
KDPC_DATA DpcData[2];
|
||||
PVOID DpcStack;
|
||||
LONG MaximumDpcQueueDepth;
|
||||
ULONG DpcRequestRate;
|
||||
BOOLEAN DpcInterruptRequested;
|
||||
VOLATILE BOOLEAN DpcRoutineActive;
|
||||
ULONG DpcLastCount;
|
||||
VOLATILE ULONG_PTR TimerHand;
|
||||
VOLATILE ULONG_PTR TimerRequest;
|
||||
SINGLE_LIST_ENTRY DeferredReadyListHead;
|
||||
ULONG InterruptCount;
|
||||
ULONG KernelTime;
|
||||
ULONG UserTime;
|
||||
ULONG DpcTime;
|
||||
ULONG InterruptTime;
|
||||
ULONG AdjustDpcThreshold;
|
||||
PROCESSOR_POWER_STATE PowerState;
|
||||
ULONG ProfilingCountdown;
|
||||
} KPROCESSOR_CONTROL_BLOCK, *PKPROCESSOR_CONTROL_BLOCK;
|
||||
|
||||
/* Processor Block structure definition */
|
||||
@@ -472,6 +596,9 @@ typedef struct _KPROCESSOR_BLOCK
|
||||
KAFFINITY SetMember;
|
||||
ULONG StallScaleFactor;
|
||||
UCHAR CpuNumber;
|
||||
ULONG HardwareId;
|
||||
VOLATILE BOOLEAN Started;
|
||||
PINTERRUPT_HANDLER InterruptDispatchTable[256];
|
||||
} KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK;
|
||||
|
||||
/* Thread Environment Block (TEB) structure definition */
|
||||
@@ -480,4 +607,5 @@ typedef struct _THREAD_ENVIRONMENT_BLOCK
|
||||
THREAD_INFORMATION_BLOCK InformationBlock;
|
||||
} THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_I686_KETYPES_H */
|
||||
|
||||
@@ -99,12 +99,18 @@
|
||||
/* 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
|
||||
|
||||
/* Highest system address */
|
||||
#define MM_HIGHEST_SYSTEM_ADDRESS 0xFFFFFFFF
|
||||
|
||||
/* User probe address */
|
||||
#define MM_USER_PROBE_ADDRESS 0x7FFF0000
|
||||
|
||||
/* Trampoline code address */
|
||||
#define MM_TRAMPOLINE_ADDRESS 0x80000
|
||||
|
||||
@@ -114,8 +120,9 @@
|
||||
/* Number of pool lists per page */
|
||||
#define MM_POOL_LISTS_PER_PAGE (MM_PAGE_SIZE / MM_POOL_BLOCK_SIZE)
|
||||
|
||||
/* Number of pool tracking tables */
|
||||
#define MM_POOL_TRACKING_TABLES 32
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Page size enumeration list */
|
||||
typedef enum _PAGE_SIZE
|
||||
@@ -437,4 +444,5 @@ typedef struct _POOL_DESCRIPTOR
|
||||
SIZE_T Reserved;
|
||||
} POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_I686_MMTYPES_H */
|
||||
|
||||
32
sdk/xtdk/i686/rtltypes.h
Normal file
32
sdk/xtdk/i686/rtltypes.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: sdk/xtdk/amd64/rtltypes.h
|
||||
* DESCRIPTION: Runtime library structures definitions for i686 architecture
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTDK_I686_RTLTYPES_H
|
||||
#define __XTDK_I686_RTLTYPES_H
|
||||
|
||||
#include <xtbase.h>
|
||||
#include <rtltypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Header for a sequenced single linked list union definition */
|
||||
typedef union _SINGLE_LIST_HEADER
|
||||
{
|
||||
ULONGLONG Alignment;
|
||||
struct
|
||||
{
|
||||
SINGLE_LIST_ENTRY Next;
|
||||
USHORT Depth;
|
||||
USHORT Sequence;
|
||||
};
|
||||
} SINGLE_LIST_HEADER, *PSINGLE_LIST_HEADER;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_I686_RTLTYPES_H */
|
||||
@@ -12,13 +12,20 @@
|
||||
#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;
|
||||
@@ -30,6 +37,7 @@ typedef enum _PIC_I8259_ICW1_OPERATING_MODE PIC_I8259_ICW1_OPERATING_MODE, *PPIC
|
||||
typedef enum _PIC_I8259_ICW4_BUFFERED_MODE PIC_I8259_ICW4_BUFFERED_MODE, *PPIC_I8259_ICW4_BUFFERED_MODE;
|
||||
typedef enum _PIC_I8259_ICW4_EOI_MODE PIC_I8259_ICW4_EOI_MODE, *PPIC_I8259_ICW4_EOI_MODE;
|
||||
typedef enum _PIC_I8259_ICW4_SYSTEM_MODE PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;
|
||||
typedef enum _TIMER_TYPE TIMER_TYPE, *PTIMER_TYPE;
|
||||
typedef enum _TRAMPOLINE_TYPE TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;
|
||||
|
||||
/* Architecture-specific structures forward references */
|
||||
@@ -42,7 +50,10 @@ 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 _KDEVICE_QUEUE KDEVICE_QUEUE, *PKDEVICE_QUEUE;
|
||||
typedef struct _KEXCEPTION_FRAME KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;
|
||||
typedef struct _KGDTENTRY KGDTENTRY, *PKGDTENTRY;
|
||||
typedef struct _KIDTENTRY KIDTENTRY, *PKIDTENTRY;
|
||||
@@ -72,6 +83,7 @@ typedef struct _MMPML3_PTE_SUBSECTION MMPML3_PTE_SUBSECTION, *PMMPML3_PTE_SUBSEC
|
||||
typedef struct _MMPML3_PTE_TRANSITION MMPML3_PTE_TRANSITION, *PMMPML3_PTE_TRANSITION;
|
||||
typedef struct _POOL_DESCRIPTOR POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
|
||||
typedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;
|
||||
typedef struct _TIMER_CAPABILITIES TIMER_CAPABILITIES, *PTIMER_CAPABILITIES;
|
||||
|
||||
/* Unions forward references */
|
||||
typedef union _APIC_BASE_REGISTER APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER;
|
||||
@@ -79,6 +91,7 @@ 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;
|
||||
@@ -88,5 +101,7 @@ typedef union _PIC_I8259_ICW1 PIC_I8259_ICW1, *PPIC_I8259_ICW1;
|
||||
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;
|
||||
typedef union _SINGLE_LIST_HEADER SINGLE_LIST_HEADER, *PSINGLE_LIST_HEADER;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_I686_XTSTRUCT_H */
|
||||
|
||||
1044
sdk/xtdk/iotypes.h
1044
sdk/xtdk/iotypes.h
File diff suppressed because it is too large
Load Diff
@@ -13,6 +13,9 @@
|
||||
#include <xttypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Kernel debugger routines forward references */
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
@@ -20,4 +23,5 @@ VOID
|
||||
DbgPrint(PCWSTR Format,
|
||||
...);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_KDFUNCS_H */
|
||||
|
||||
@@ -21,6 +21,10 @@
|
||||
#define DEBUG_PROVIDER_COMPORT 0x00000001
|
||||
#define DEBUG_PROVIDER_FRAMEBUFFER 0x00000002
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Kernel routine callbacks */
|
||||
typedef XTSTATUS (XTAPI *PKD_INIT_ROUTINE)();
|
||||
typedef VOID (*PKD_PRINT_ROUTINE)(IN PCWSTR Format, IN ...);
|
||||
@@ -42,4 +46,5 @@ typedef struct _KD_DISPATCH_TABLE
|
||||
RTL_PRINT_CONTEXT PrintContext;
|
||||
} KD_DISPATCH_TABLE, *PKD_DISPATCH_TABLE;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_KDTYPES_H */
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
#include <ketypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Kernel services routines forward references */
|
||||
XTCLINK
|
||||
XTFASTCALL
|
||||
@@ -141,6 +144,12 @@ VOID
|
||||
KeSetTargetProcessorDpc(IN PKDPC Dpc,
|
||||
IN CCHAR Number);
|
||||
|
||||
XTCLINK
|
||||
XTAPI
|
||||
VOID
|
||||
KeSetTimeIncrement(IN ULONG MaxIncrement,
|
||||
IN ULONG MinIncrement);
|
||||
|
||||
XTCLINK
|
||||
XTAPI
|
||||
VOID
|
||||
@@ -159,4 +168,5 @@ XTAPI
|
||||
BOOLEAN
|
||||
KeSignalCallDpcSynchronize(IN PVOID SystemArgument);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_KEFUNCS_H */
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <xttarget.h>
|
||||
#include <xttypes.h>
|
||||
#include ARCH_HEADER(xtstruct.h)
|
||||
#include ARCH_HEADER(rtltypes.h)
|
||||
|
||||
|
||||
/* Exception types and handling mechanisms */
|
||||
@@ -24,14 +25,49 @@
|
||||
/* Maximum number of exception parameters */
|
||||
#define EXCEPTION_MAXIMUM_PARAMETERS 15
|
||||
|
||||
/* IPI types */
|
||||
#define IPI_APC 1
|
||||
#define IPI_DPC 2
|
||||
#define IPI_FREEZE 4
|
||||
#define IPI_PACKET_READY 8
|
||||
#define IPI_SYNC_REQUEST 16
|
||||
|
||||
/* IPI frozen states */
|
||||
#define IPI_FROZEN_STATE_RUNNING 0x00
|
||||
#define IPI_FROZEN_STATE_FROZEN 0x02
|
||||
#define IPI_FROZEN_STATE_THAW 0x03
|
||||
#define IPI_FROZEN_STATE_OWNER 0x04
|
||||
#define IPI_FROZEN_STATE_FREEZE 0x05
|
||||
#define IPI_FROZEN_STATE_ACTIVE 0x20
|
||||
|
||||
/* Lock queue states */
|
||||
#define LOCK_QUEUE_WAIT 1
|
||||
#define LOCK_QUEUE_OWNER 2
|
||||
|
||||
/* APC pending state length */
|
||||
#define KAPC_STATE_LENGTH (FIELD_OFFSET(KAPC_STATE, UserApcPending) + sizeof(BOOLEAN))
|
||||
|
||||
/* Indices used to access the PushLock data structure */
|
||||
#define KPUSHLOCK_INDEX ((ULONG_PTR)0x00)
|
||||
#define KPUSHLOCK_LOCK ((ULONG_PTR)0x01)
|
||||
#define KPUSHLOCK_WAITING ((ULONG_PTR)0x02)
|
||||
#define KPUSHLOCK_WAKING ((ULONG_PTR)0x04)
|
||||
#define KPUSHLOCK_MULTIPLE_SHARED ((ULONG_PTR)0x08)
|
||||
#define KPUSHLOCK_INCREMENT_SHARED ((ULONG_PTR)0x10)
|
||||
|
||||
/* Mask for the pointer bits */
|
||||
#define KPUSHLOCK_PTR_BITS ((ULONG_PTR)0x0F)
|
||||
|
||||
/* PushLock related definitions */
|
||||
#define KPUSH_LOCK_TOTAL_BITS (sizeof(ULONG_PTR) * 8)
|
||||
#define KPUSH_LOCK_SPIN_COUNT 1024
|
||||
|
||||
/* Kernel service descriptor tables count */
|
||||
#define KSERVICE_TABLES_COUNT 4
|
||||
|
||||
/* Timer length */
|
||||
/* Timer related definitions */
|
||||
#define KTIMER_LENGTH (FIELD_OFFSET(KTIMER, Period) + sizeof(LONG))
|
||||
#define KTIMER_TABLE_SIZE 512
|
||||
|
||||
/* Kernel builtin wait blocks */
|
||||
#define EVENT_WAIT_BLOCK 2
|
||||
@@ -43,12 +79,19 @@
|
||||
#define READY_SKIP_QUANTUM 2
|
||||
#define THREAD_QUANTUM 6
|
||||
|
||||
/* Dispatcher object type mask */
|
||||
#define DISPATCHER_OBJECT_TYPE_MASK 0x7L
|
||||
|
||||
/* Thread priority levels */
|
||||
#define THREAD_LOW_PRIORITY 0
|
||||
#define THREAD_LOW_REALTIME_PRIORITY 16
|
||||
#define THREAD_HIGH_PRIORITY 31
|
||||
#define THREAD_MAXIMUM_PRIORITY 32
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Adjust reason */
|
||||
typedef enum _ADJUST_REASON
|
||||
{
|
||||
@@ -75,6 +118,15 @@ typedef enum _KAPC_ENVIRONMENT
|
||||
InsertApcEnvironment
|
||||
} KAPC_ENVIRONMENT, *PKAPC_ENVIRONMENT;
|
||||
|
||||
/* Continue status enumeration list */
|
||||
typedef enum _KCONTINUE_STATUS
|
||||
{
|
||||
ContinueError,
|
||||
ContinueSuccess,
|
||||
ContinueProcessorReselected,
|
||||
ContinueNextProcessor
|
||||
} KCONTINUE_STATUS, *PKCONTINUE_STATUS;
|
||||
|
||||
/* DPC importance enumeration list */
|
||||
typedef enum _KDPC_IMPORTANCE
|
||||
{
|
||||
@@ -96,7 +148,7 @@ typedef enum _KOBJECTS
|
||||
{
|
||||
EventNotificationObject = 0,
|
||||
EventSynchronizationObject = 1,
|
||||
MutantObject = 2,
|
||||
MutexObject = 2,
|
||||
ProcessObject = 3,
|
||||
QueueObject = 4,
|
||||
SemaphoreObject = 5,
|
||||
@@ -133,6 +185,37 @@ typedef enum _KPROCESS_STATE
|
||||
ProcessOutSwap
|
||||
} KPROCESS_STATE, *PKPROCESS_STATE;
|
||||
|
||||
/* Kernel profiling sources */
|
||||
typedef enum _KPROFILE_SOURCE
|
||||
{
|
||||
ProfileTime,
|
||||
ProfileAlignmentFixup,
|
||||
ProfileTotalIssues,
|
||||
ProfilePipelineDry,
|
||||
ProfileLoadInstructions,
|
||||
ProfilePipelineFrozen,
|
||||
ProfileBranchInstructions,
|
||||
ProfileTotalNonissues,
|
||||
ProfileDcacheMisses,
|
||||
ProfileIcacheMisses,
|
||||
ProfileCacheMisses,
|
||||
ProfileBranchMispredictions,
|
||||
ProfileStoreInstructions,
|
||||
ProfileFpInstructions,
|
||||
ProfileIntegerInstructions,
|
||||
Profile2Issue,
|
||||
Profile3Issue,
|
||||
Profile4Issue,
|
||||
ProfileSpecialInstructions,
|
||||
ProfileTotalCycles,
|
||||
ProfileIcacheIssues,
|
||||
ProfileDcacheAccesses,
|
||||
ProfileMemoryBarrierCycles,
|
||||
ProfileLoadLinkedIssues,
|
||||
ProfileXtKernel,
|
||||
ProfileMaximum
|
||||
} KPROFILE_SOURCE, *PKPROFILE_SOURCE;
|
||||
|
||||
/* Thread state */
|
||||
typedef enum _KTHREAD_STATE
|
||||
{
|
||||
@@ -177,6 +260,55 @@ typedef enum _KTIMER_TYPE
|
||||
SynchronizationTimer
|
||||
} KTIMER_TYPE, *PKTIMER_TYPE;
|
||||
|
||||
/* Wait reason */
|
||||
typedef enum _KWAIT_REASON
|
||||
{
|
||||
Executive,
|
||||
FreePage,
|
||||
PageIn,
|
||||
PoolAllocation,
|
||||
DelayExecution,
|
||||
Suspended,
|
||||
UserRequest,
|
||||
WrExecutive,
|
||||
WrFreePage,
|
||||
WrPageIn,
|
||||
WrPoolAllocation,
|
||||
WrDelayExecution,
|
||||
WrSuspended,
|
||||
WrUserRequest,
|
||||
WrEventPair,
|
||||
WrQueue,
|
||||
WrLpcReceive,
|
||||
WrLpcReply,
|
||||
WrVirtualMemory,
|
||||
WrPageOut,
|
||||
WrRendezvous,
|
||||
WrKeyedEvent,
|
||||
WrTerminated,
|
||||
WrProcessInSwap,
|
||||
WrCpuRateControl,
|
||||
WrCalloutStack,
|
||||
WrKernel,
|
||||
WrResource,
|
||||
WrPushLock,
|
||||
WrMutex,
|
||||
WrQuantumEnd,
|
||||
WrDispatchInt,
|
||||
WrPreempted,
|
||||
WrYieldExecution,
|
||||
WrFastMutex,
|
||||
WrGuardedMutex,
|
||||
WrRundown,
|
||||
WrAlertByThreadId,
|
||||
WrDeferredPreempt,
|
||||
WrPhysicalFault,
|
||||
WrIoRing,
|
||||
WrMdlCache,
|
||||
WrRcu,
|
||||
MaximumWaitReason
|
||||
} KWAIT_REASON, *PKWAIT_REASON;
|
||||
|
||||
/* APC Types */
|
||||
typedef enum _MODE
|
||||
{
|
||||
@@ -217,6 +349,27 @@ typedef VOID (XTAPI *PKRUNDOWN_ROUTINE)(IN PKAPC Apc);
|
||||
typedef VOID (XTCDECL *PKSTART_ROUTINE)(IN PVOID StartContext);
|
||||
typedef VOID (XTCDECL *PKSYSTEM_ROUTINE)(IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext);
|
||||
|
||||
/* Dispatcher object header structure definition */
|
||||
typedef struct _DISPATCHER_HEADER
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
UCHAR Type;
|
||||
UCHAR Absolute;
|
||||
UCHAR Size;
|
||||
union {
|
||||
UCHAR Inserted;
|
||||
BOOLEAN DebugActive;
|
||||
};
|
||||
};
|
||||
VOLATILE LONG Lock;
|
||||
};
|
||||
LONG SignalState;
|
||||
LIST_ENTRY WaitListHead;
|
||||
} DISPATCHER_HEADER, *PDISPATCHER_HEADER;
|
||||
|
||||
/* Exception record structure definition */
|
||||
typedef struct _EXCEPTION_RECORD
|
||||
{
|
||||
@@ -228,6 +381,14 @@ typedef struct _EXCEPTION_RECORD
|
||||
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
|
||||
} EXCEPTION_RECORD, *PEXCEPTION_RECORD;
|
||||
|
||||
/* Extended affinity structure definition */
|
||||
typedef struct _KAFFINITY_MAP
|
||||
{
|
||||
USHORT Size;
|
||||
ULONG Reserved;
|
||||
KAFFINITY Bitmap[];
|
||||
} KAFFINITY_MAP, *PKAFFINITY_MAP;
|
||||
|
||||
/* Asynchronous Procedure Call (APC) object structure definition */
|
||||
typedef struct _KAPC
|
||||
{
|
||||
@@ -296,11 +457,49 @@ typedef struct _KAPC_STATE
|
||||
BOOLEAN UserApcPending;
|
||||
} KAPC_STATE, *PKAPC_STATE;
|
||||
|
||||
/* Event gate structure definition */
|
||||
typedef struct _KGATE
|
||||
/* Device queue entry structure definition */
|
||||
typedef struct _KDEVICE_QUEUE_ENTRY
|
||||
{
|
||||
LIST_ENTRY DeviceListEntry;
|
||||
ULONG SortKey;
|
||||
BOOLEAN Inserted;
|
||||
} KDEVICE_QUEUE_ENTRY, *PKDEVICE_QUEUE_ENTRY;
|
||||
|
||||
/* Mutex object structure definition */
|
||||
typedef struct _KMUTEX
|
||||
{
|
||||
DISPATCHER_HEADER Header;
|
||||
} KGATE, *PKGATE;
|
||||
LIST_ENTRY MutexListEntry;
|
||||
PKTHREAD OwnerThread;
|
||||
BOOLEAN Abandoned;
|
||||
UCHAR ApcDisable;
|
||||
} KMUTEX, *PKMUTEX;
|
||||
|
||||
/* Push Lock structure definition */
|
||||
typedef union _KPUSH_LOCK
|
||||
{
|
||||
struct
|
||||
{
|
||||
ULONG_PTR Locked:1;
|
||||
ULONG_PTR Waiting:1;
|
||||
ULONG_PTR Waking:1;
|
||||
ULONG_PTR MultipleShared:1;
|
||||
ULONG_PTR Shared:(KPUSH_LOCK_TOTAL_BITS - 4);
|
||||
};
|
||||
ULONG_PTR Value;
|
||||
PVOID Ptr;
|
||||
} KPUSH_LOCK, *PKPUSH_LOCK;
|
||||
|
||||
/* Push lock wait block structure definition */
|
||||
typedef struct _KPUSH_LOCK_WAIT_BLOCK
|
||||
{
|
||||
KEVENT WakeEvent;
|
||||
PKPUSH_LOCK_WAIT_BLOCK Next;
|
||||
PKPUSH_LOCK_WAIT_BLOCK Last;
|
||||
PKPUSH_LOCK_WAIT_BLOCK Previous;
|
||||
LONG ShareCount;
|
||||
LONG Flags;
|
||||
} KPUSH_LOCK_WAIT_BLOCK, *PKPUSH_LOCK_WAIT_BLOCK;
|
||||
|
||||
/* Semaphore object structure definition */
|
||||
typedef struct _KSEMAPHORE
|
||||
@@ -384,7 +583,8 @@ typedef struct _KPROCESS
|
||||
ULONG_PTR DirectoryTable[2];
|
||||
USHORT IopmOffset;
|
||||
UCHAR Iopl;
|
||||
VOLATILE KAFFINITY ActiveProcessors;
|
||||
PKAFFINITY_MAP Affinity;
|
||||
PKAFFINITY_MAP ActiveProcessors;
|
||||
ULONG KernelTime;
|
||||
ULONG UserTime;
|
||||
LIST_ENTRY ReadyListHead;
|
||||
@@ -392,7 +592,6 @@ typedef struct _KPROCESS
|
||||
PVOID VdmTrapHandler;
|
||||
LIST_ENTRY ThreadListHead;
|
||||
KSPIN_LOCK ProcessLock;
|
||||
KAFFINITY Affinity;
|
||||
union
|
||||
{
|
||||
struct
|
||||
@@ -414,17 +613,39 @@ 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;
|
||||
VOLATILE KSYSTEM_TIME TickCount;
|
||||
ULONG XtMajorVersion;
|
||||
ULONG XtMinorVersion;
|
||||
WCHAR XtBuild[8];
|
||||
WCHAR XtBuildHash[11];
|
||||
WCHAR XtArchitecture[8];
|
||||
WCHAR XtDate[9];
|
||||
WCHAR XtFullDate[25];
|
||||
} KSHARED_DATA, *PKSHARED_DATA;
|
||||
|
||||
/* Thread control block structure definition */
|
||||
typedef struct _KTHREAD
|
||||
{
|
||||
DISPATCHER_HEADER Header;
|
||||
LIST_ENTRY MutantListHead;
|
||||
LIST_ENTRY MutexListHead;
|
||||
PVOID InitialStack;
|
||||
PVOID KernelStack;
|
||||
PVOID StackBase;
|
||||
PVOID StackLimit;
|
||||
KSPIN_LOCK ThreadLock;
|
||||
|
||||
ULONG ContextSwitches;
|
||||
VOLATILE UCHAR State;
|
||||
UCHAR NpxState;
|
||||
@@ -449,7 +670,7 @@ typedef struct _KTHREAD
|
||||
PKWAIT_BLOCK WaitBlockList;
|
||||
BOOLEAN Alertable;
|
||||
BOOLEAN WaitNext;
|
||||
UCHAR WaitReason;
|
||||
KWAIT_REASON WaitReason;
|
||||
SCHAR Priority;
|
||||
UCHAR StackSwap;
|
||||
VOLATILE UCHAR SwapBusy;
|
||||
@@ -487,9 +708,9 @@ typedef struct _KTHREAD
|
||||
CHAR PreviousMode;
|
||||
UCHAR ResourceIndex;
|
||||
UCHAR DisableBoost;
|
||||
KAFFINITY UserAffinity;
|
||||
PKAFFINITY_MAP UserAffinity;
|
||||
PKPROCESS Process;
|
||||
KAFFINITY Affinity;
|
||||
PKAFFINITY_MAP Affinity;
|
||||
PVOID ServiceTable;
|
||||
PKAPC_STATE ApcStatePointer[2];
|
||||
KAPC_STATE SavedApcState;
|
||||
@@ -505,12 +726,12 @@ typedef struct _KTHREAD
|
||||
LIST_ENTRY ThreadListEntry;
|
||||
UCHAR LargeStack;
|
||||
UCHAR PowerState;
|
||||
UCHAR NpxIrql;
|
||||
UCHAR NpxRunLevel;
|
||||
UCHAR Spare5;
|
||||
BOOLEAN AutoAlignment;
|
||||
UCHAR Iopl;
|
||||
CCHAR FreezeCount;
|
||||
CCHAR SuspendCount;
|
||||
CHAR FreezeCount;
|
||||
CHAR SuspendCount;
|
||||
UCHAR Spare0[1];
|
||||
UCHAR UserIdealProcessor;
|
||||
UCHAR Spare2[3];
|
||||
@@ -647,4 +868,5 @@ typedef struct _KUBSAN_TYPE_MISMATCH_DATA_V1
|
||||
UCHAR TypeCheckKind;
|
||||
} KUBSAN_TYPE_MISMATCH_DATA_V1, *PKUBSAN_TYPE_MISMATCH_DATA_V1;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_KEFUNCS_H */
|
||||
|
||||
@@ -38,6 +38,10 @@
|
||||
#define LDR_DTE_MM_LOADED 0x40000000
|
||||
#define LDR_DTE_COMPAT_DATABASE_PROCESSED 0x80000000
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Loader data table entry */
|
||||
typedef struct _LDR_DATA_TABLE_ENTRY
|
||||
{
|
||||
@@ -70,4 +74,5 @@ typedef struct _LDR_DATA_TABLE_ENTRY
|
||||
PVOID PatchInformation;
|
||||
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_LDRTYPES_H */
|
||||
|
||||
62
sdk/xtdk/lpctypes.h
Normal file
62
sdk/xtdk/lpctypes.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: sdk/xtdk/lpctypes.h
|
||||
* DESCRIPTION: Local Procedure Call (LPC) structures and definitions
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTDK_LPCTYPES_H
|
||||
#define __XTDK_LPCTYPES_H
|
||||
|
||||
#include <xttypes.h>
|
||||
#include <xtstruct.h>
|
||||
#include <iotypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* LPC non-paged port queue structure definition */
|
||||
typedef struct _LPCP_NONPAGED_PORT_QUEUE
|
||||
{
|
||||
KSEMAPHORE Semaphore;
|
||||
struct _LPCP_PORT_OBJECT *BackPointer;
|
||||
} LPCP_NONPAGED_PORT_QUEUE, *PLPCP_NONPAGED_PORT_QUEUE;
|
||||
|
||||
/* LPC port queue structure definition */
|
||||
typedef struct _LPCP_PORT_QUEUE
|
||||
{
|
||||
PLPCP_NONPAGED_PORT_QUEUE NonPagedPortQueue;
|
||||
PKSEMAPHORE Semaphore;
|
||||
LIST_ENTRY ReceiveHead;
|
||||
} LPCP_PORT_QUEUE, *PLPCP_PORT_QUEUE;
|
||||
|
||||
/* LPC port object structure definition */
|
||||
typedef struct _LPCP_PORT_OBJECT
|
||||
{
|
||||
struct _LPCP_PORT_OBJECT *ConnectionPort;
|
||||
struct _LPCP_PORT_OBJECT *ConnectedPort;
|
||||
LPCP_PORT_QUEUE MsgQueue;
|
||||
CLIENT_ID Creator;
|
||||
PVOID ClientSectionBase;
|
||||
PVOID ServerSectionBase;
|
||||
PVOID PortContext;
|
||||
PETHREAD ClientThread;
|
||||
SECURITY_QUALITY_OF_SERVICE SecurityQos;
|
||||
SECURITY_CLIENT_CONTEXT StaticSecurity;
|
||||
LIST_ENTRY LpcReplyChainHead;
|
||||
LIST_ENTRY LpcDataInfoChainHead;
|
||||
union
|
||||
{
|
||||
PEPROCESS ServerProcess;
|
||||
PEPROCESS MappingProcess;
|
||||
};
|
||||
ULONG MaxMessageLength;
|
||||
ULONG MaxConnectionInfoLength;
|
||||
ULONG Flags;
|
||||
KEVENT WaitEvent;
|
||||
} LPCP_PORT_OBJECT, *PLPCP_PORT_OBJECT;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_LPCTYPES_H */
|
||||
44
sdk/xtdk/mmfuncs.h
Normal file
44
sdk/xtdk/mmfuncs.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: sdk/xtdk/mmfuncs.h
|
||||
* DESCRIPTION: XTOS memory manager routine definitions
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTDK_MMFUNCS_H
|
||||
#define __XTDK_MMFUNCS_H
|
||||
|
||||
#include <xtdefs.h>
|
||||
#include <xtstruct.h>
|
||||
#include <xttypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Memory manager routines forward references */
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
MmAllocatePool(IN MMPOOL_TYPE PoolType,
|
||||
IN SIZE_T Bytes,
|
||||
OUT PVOID *Memory);
|
||||
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
MmAllocatePoolWithTag(IN MMPOOL_TYPE PoolType,
|
||||
IN SIZE_T Bytes,
|
||||
OUT PVOID *Memory,
|
||||
IN ULONG Tag);
|
||||
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
MmFreePool(IN PVOID VirtualAddress);
|
||||
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
MmFreePoolWithTag(IN PVOID VirtualAddress,
|
||||
IN ULONG Tag);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_MMFUNCS_H */
|
||||
@@ -55,6 +55,13 @@
|
||||
/* Protection field shift */
|
||||
#define MM_PROTECT_FIELD_SHIFT 5
|
||||
|
||||
/* Process Quota Adjustment Thresholds */
|
||||
#define MMNONPAGED_QUOTA_INCREASE (64*1024)
|
||||
#define MMPAGED_QUOTA_INCREASE (512*1024)
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Memory manager page lists */
|
||||
typedef enum _MMPAGELISTS
|
||||
{
|
||||
@@ -103,14 +110,31 @@ typedef enum _MMSYSTEM_PTE_POOL_TYPE
|
||||
MaximumPtePoolTypes
|
||||
} MMSYSTEM_PTE_POOL_TYPE, *PMMSYSTEM_PTE_POOL_TYPE;
|
||||
|
||||
/* Page map routines structure definition */
|
||||
typedef CONST STRUCT _CMMPAGEMAP_ROUTINES
|
||||
/* Non-paged lookaside list indices */
|
||||
typedef enum _NONPAGED_LOOKASIDE_NUMBER
|
||||
{
|
||||
VOID (XTAPI *ClearPte)(PHARDWARE_PTE PtePointer);
|
||||
BOOLEAN (XTAPI *PteValid)(PHARDWARE_PTE PtePointer);
|
||||
VOID (XTAPI *SetPteCaching)(PHARDWARE_PTE PtePointer, BOOLEAN CacheDisable, BOOLEAN WriteThrough);
|
||||
VOID (XTAPI *SetPte)(PHARDWARE_PTE PtePointer, PFN_NUMBER PageFrameNumber, BOOLEAN Writable);
|
||||
} CMMPAGEMAP_ROUTINES, *PCMMPAGEMAP_ROUTINES;
|
||||
LookasideSmallIrpList,
|
||||
LookasideLargeIrpList,
|
||||
LookasideMdlList,
|
||||
LookasideCreateInfoList,
|
||||
LookasideNameBufferList,
|
||||
LookasideTwilightList,
|
||||
LookasideCompletionList,
|
||||
LookasideMaximumList
|
||||
} NONPAGED_LOOKASIDE_NUMBER, *PNONPAGED_LOOKASIDE_NUMBER;
|
||||
|
||||
/* Memory Descriptor List structure definition */
|
||||
typedef struct _MDL
|
||||
{
|
||||
PMDL Next;
|
||||
CSHORT Size;
|
||||
CSHORT MdlFlags;
|
||||
PEPROCESS Process;
|
||||
PVOID MappedSystemVa;
|
||||
PVOID StartVa;
|
||||
ULONG ByteCount;
|
||||
ULONG ByteOffset;
|
||||
} MDL, *PMDL;
|
||||
|
||||
/* Color tables structure definition */
|
||||
typedef struct _MMCOLOR_TABLES
|
||||
@@ -258,4 +282,5 @@ typedef struct _POOL_TRACKING_TABLE
|
||||
ULONG Tag;
|
||||
} POOL_TRACKING_TABLE, *PPOOL_TRACKING_TABLE;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_MMTYPES_H */
|
||||
|
||||
357
sdk/xtdk/obtypes.h
Normal file
357
sdk/xtdk/obtypes.h
Normal file
@@ -0,0 +1,357 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: sdk/xtdk/obtypes.h
|
||||
* DESCRIPTION: Object Manager structures definitions
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTDK_OBTYPES_H
|
||||
#define __XTDK_OBTYPES_H
|
||||
|
||||
#include <xtbase.h>
|
||||
#include <xttypes.h>
|
||||
#include <xtstruct.h>
|
||||
#include <iotypes.h>
|
||||
|
||||
|
||||
/* Object header information flag masks */
|
||||
#define OBJECT_FLAG_NEW_OBJECT 0x01
|
||||
#define OBJECT_FLAG_KERNEL_MODE 0x02
|
||||
#define OBJECT_FLAG_CREATOR_INFO 0x04
|
||||
#define OBJECT_FLAG_EXCLUSIVE 0x08
|
||||
#define OBJECT_FLAG_PERMANENT 0x10
|
||||
#define OBJECT_FLAG_SECURITY_QUOTA 0x20
|
||||
#define OBJECT_FLAG_SINGLE_PROCESS 0x40
|
||||
#define OBJECT_FLAG_DEFER_DELETE 0x80
|
||||
|
||||
/* Object lock states */
|
||||
#define OBJECT_LOCK_STATE_WAIT_EXCLUSIVE 0xAAAA1234
|
||||
#define OBJECT_LOCK_WAITSHARED_SIGNATURE 0xBBBB1234
|
||||
#define OBJECT_LOCK_STATE_OWNED_EXCLUSIVE 0xCCCC1234
|
||||
#define OBJECT_LOCK_OWNEDSHARED_SIGNATURE 0xDDDD1234
|
||||
#define OBJECT_LOCK_STATE_RELEASED_SIGNATURE 0xEEEE1234
|
||||
#define OBJECT_LOCK_STATE_INITIALIZED 0xFFFF1234
|
||||
|
||||
/* Object name attribute flags */
|
||||
#define OBJECT_INHERIT 0x00000002L
|
||||
#define OBJECT_PERMANENT 0x00000010L
|
||||
#define OBJECT_EXCLUSIVE 0x00000020L
|
||||
#define OBJECT_CASE_INSENSITIVE 0x00000040L
|
||||
#define OBJECT_OPENIF 0x00000080L
|
||||
#define OBJECT_OPENLINK 0x00000100L
|
||||
#define OBJECT_KERNEL_HANDLE 0x00000200L
|
||||
#define OBJECT_FORCE_ACCESS_CHECK 0x00000400L
|
||||
#define OBJECT_VALID_ATTRIBUTES 0x000007F2L
|
||||
|
||||
/* Maximum number of defined object types */
|
||||
#define OBJECT_MAX_DEFINED_OBJECT_TYPES 48
|
||||
|
||||
/* Object name buffer size */
|
||||
#define OBJECT_NAME_BUFFER_SIZE 248
|
||||
|
||||
/* Object name lock flags */
|
||||
#define OBJECT_NAME_LOCKED ((LONG)0x80000000)
|
||||
#define OBJECT_REMOVE_QUEUE_LOCKED (PVOID)1
|
||||
|
||||
/* Object name path separator */
|
||||
#define OBJECT_NAME_PATH_SEPARATOR ((WCHAR)L'\\')
|
||||
|
||||
/* Number of hash buckets */
|
||||
#define OBJECT_NUMBER_HASH_BUCKETS 37
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Object Manager routine callbacks */
|
||||
typedef VOID (XTAPI *POB_DUMP_METHOD)(IN PVOID Object, IN POBJECT_DUMP_CONTROL Control);
|
||||
typedef XTSTATUS (XTAPI *POB_OPEN_METHOD)(IN OBJECT_OPEN_REASON Reason, IN PEPROCESS Process, IN PVOID ObjectBody, IN ACCESS_MASK GrantedAccess, IN ULONG HandleCount);
|
||||
typedef VOID (XTAPI *POB_CLOSE_METHOD)(IN PEPROCESS Process, IN PVOID Object, IN ACCESS_MASK GrantedAccess, IN ULONG ProcessHandleCount, IN ULONG SystemHandleCount);
|
||||
typedef VOID (XTAPI *POB_DELETE_METHOD)(IN PVOID Object);
|
||||
typedef XTSTATUS (XTAPI *POB_PARSE_METHOD)(IN PVOID ParseObject, IN PVOID ObjectType, IN OUT PACCESS_STATE AccessState, IN KPROCESSOR_MODE ProcessorMode, IN ULONG Attributes, IN OUT PUNICODE_STRING CompleteName, IN OUT PUNICODE_STRING RemainingName, IN OUT PVOID Context, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos, OUT PVOID *Object);
|
||||
typedef XTSTATUS (XTAPI *POB_SECURITY_METHOD)(IN PVOID Object, IN SECURITY_OPERATION_CODE OperationType, IN PSECURITY_INFORMATION SecurityInformation, IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN OUT PULONG CapturedLength, IN OUT PSECURITY_DESCRIPTOR *ObjectSecurityDescriptor, IN MMPOOL_TYPE PoolType, IN PGENERIC_MAPPING GenericMapping);
|
||||
typedef XTSTATUS (XTAPI *POB_QUERYNAME_METHOD)(IN PVOID Object, IN BOOLEAN HasObjectName, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength, IN KPROCESSOR_MODE ProcessorMode);
|
||||
typedef BOOLEAN (XTAPI *POB_OKAYTOCLOSE_METHOD)(IN PEPROCESS Process, IN PVOID Object, IN HANDLE Handle, IN KPROCESSOR_MODE ProcessorMode);
|
||||
|
||||
/* Bitmasks used to identify the presence of optional object headers in memory */
|
||||
typedef enum _OBJECT_HEADER_INFO
|
||||
{
|
||||
ObjectHeaderInfoNone = 0,
|
||||
ObjectHeaderInfoCreatorInfo = 0x01,
|
||||
ObjectHeaderInfoNameInfo = 0x02,
|
||||
ObjectHeaderInfoHandleInfo = 0x04,
|
||||
ObjectHeaderInfoQuotaInfo = 0x08,
|
||||
ObjectHeaderInfoProcessInfo = 0x10
|
||||
} OBJECT_HEADER_INFO, *POBJECT_HEADER_INFO;
|
||||
|
||||
/* List of information classes used when querying or setting object attributes */
|
||||
typedef enum _OBJECT_INFORMATION_CLASS
|
||||
{
|
||||
ObjectBasicInfo,
|
||||
ObjectNameInfo,
|
||||
ObjectTypeInfo,
|
||||
ObjectAllInfo,
|
||||
ObjectHandleFlagInfo
|
||||
} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;
|
||||
|
||||
/* List of valid reasons for creating, opening, or duplicating an object handle */
|
||||
typedef enum _OBJECT_OPEN_REASON
|
||||
{
|
||||
ObCreateHandle,
|
||||
ObOpenHandle,
|
||||
ObDuplicateHandle,
|
||||
ObInheritHandle,
|
||||
ObMaxOpenReason
|
||||
} OBJECT_OPEN_REASON, *POBJECT_OPEN_REASON;
|
||||
|
||||
/* Mapping of device names to object manager devices */
|
||||
typedef struct _DEVICE_MAP
|
||||
{
|
||||
POBJECT_DIRECTORY DevicesDirectory;
|
||||
POBJECT_DIRECTORY GlobalDevicesDirectory;
|
||||
ULONG ReferenceCount;
|
||||
ULONG DriveMap;
|
||||
UCHAR DriveType[32];
|
||||
} DEVICE_MAP, *PDEVICE_MAP;
|
||||
|
||||
/* Parameters provided by a caller when creating or opening an object */
|
||||
typedef struct _OBJECT_ATTRIBUTES
|
||||
{
|
||||
ULONG Length;
|
||||
HANDLE RootDirectory;
|
||||
PUNICODE_STRING ObjectName;
|
||||
ULONG Attributes;
|
||||
PSECURITY_DESCRIPTOR SecurityDescriptor;
|
||||
PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
|
||||
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
|
||||
|
||||
/* Internal data stored during object creation */
|
||||
typedef struct _OBJECT_CREATE_INFORMATION
|
||||
{
|
||||
ULONG Attributes;
|
||||
HANDLE RootDirectory;
|
||||
PVOID ParseContext;
|
||||
KPROCESSOR_MODE ProbeMode;
|
||||
ULONG PagedPoolCharge;
|
||||
ULONG NonPagedPoolCharge;
|
||||
ULONG SecurityDescriptorCharge;
|
||||
PSECURITY_DESCRIPTOR SecurityDescriptor;
|
||||
PSECURITY_QUALITY_OF_SERVICE SecurityQos;
|
||||
SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
|
||||
} OBJECT_CREATE_INFORMATION, *POBJECT_CREATE_INFORMATION;
|
||||
|
||||
/* Optional header storing information about the object's creator */
|
||||
typedef struct _OBJECT_CREATOR_INFO
|
||||
{
|
||||
LIST_ENTRY TypeList;
|
||||
HANDLE CreatorProcessId;
|
||||
} OBJECT_CREATOR_INFO, *POBJECT_CREATOR_INFO;
|
||||
|
||||
/* Directory object used to structure the namespace hierarchy */
|
||||
typedef struct _OBJECT_DIRECTORY
|
||||
{
|
||||
POBJECT_DIRECTORY_ENTRY HashBuckets[OBJECT_NUMBER_HASH_BUCKETS];
|
||||
KPUSH_LOCK Lock;
|
||||
PDEVICE_MAP DeviceMap;
|
||||
ULONG SessionId;
|
||||
} OBJECT_DIRECTORY, *POBJECT_DIRECTORY;
|
||||
|
||||
/* Linked list entry representing an object within a directory bucket */
|
||||
typedef struct _OBJECT_DIRECTORY_ENTRY
|
||||
{
|
||||
POBJECT_DIRECTORY_ENTRY ChainLink;
|
||||
PVOID Object;
|
||||
ULONG HashValue;
|
||||
} OBJECT_DIRECTORY_ENTRY, *POBJECT_DIRECTORY_ENTRY;
|
||||
|
||||
/* Control structure used during object diagnostic dumps */
|
||||
typedef struct _OBJECT_DUMP_CONTROL
|
||||
{
|
||||
PVOID Stream;
|
||||
ULONG Detail;
|
||||
} OBJECT_DUMP_CONTROL, *POBJECT_DUMP_CONTROL;
|
||||
|
||||
/* Entry tracking the number of open handles a specific process holds */
|
||||
typedef struct _OBJECT_HANDLE_COUNT_ENTRY
|
||||
{
|
||||
PEPROCESS OwningProcess;
|
||||
ULONG HandleTableIndex;
|
||||
ULONG HandleCount;
|
||||
} OBJECT_HANDLE_COUNT_ENTRY, *POBJECT_HANDLE_COUNT_ENTRY;
|
||||
|
||||
/* Database array tracking handle counts for objects opened by processes */
|
||||
typedef struct _OBJECT_HANDLE_COUNT_DATABASE
|
||||
{
|
||||
ULONG CountEntries;
|
||||
OBJECT_HANDLE_COUNT_ENTRY HandleCountEntries[1];
|
||||
} OBJECT_HANDLE_COUNT_DATABASE, *POBJECT_HANDLE_COUNT_DATABASE;
|
||||
|
||||
/* Database tracking all handle counts across different processes */
|
||||
typedef struct _OBJECT_HANDLE_COUNT_INFORMATION
|
||||
{
|
||||
ULONG TotalHandleCount;
|
||||
ULONG EntryCount;
|
||||
POBJECT_HANDLE_COUNT_ENTRY Entries;
|
||||
} OBJECT_HANDLE_COUNT_INFORMATION, *POBJECT_HANDLE_COUNT_INFORMATION;
|
||||
|
||||
/* Optional header containing the handle count database */
|
||||
typedef struct _OBJECT_HANDLE_INFO
|
||||
{
|
||||
OBJECT_HANDLE_COUNT_INFORMATION HandleCounts;
|
||||
} OBJECT_HANDLE_INFO, *POBJECT_HANDLE_INFO;
|
||||
|
||||
/* Core object header */
|
||||
typedef struct _OBJECT_HEADER
|
||||
{
|
||||
LONG_PTR PointerCount;
|
||||
union
|
||||
{
|
||||
LONG_PTR HandleCount;
|
||||
VOLATILE PVOID NextToFree;
|
||||
};
|
||||
POBJECT_TYPE Type;
|
||||
UCHAR NameInfoOffset;
|
||||
UCHAR HandleInfoOffset;
|
||||
UCHAR QuotaInfoOffset;
|
||||
UCHAR Flags;
|
||||
union
|
||||
{
|
||||
POBJECT_CREATE_INFORMATION ObjectCreateInfo;
|
||||
PVOID QuotaBlockCharged;
|
||||
};
|
||||
PSECURITY_DESCRIPTOR SecurityDescriptor;
|
||||
QUAD Body;
|
||||
} OBJECT_HEADER, *POBJECT_HEADER;
|
||||
|
||||
/* Creator tracking information */
|
||||
typedef struct _OBJECT_HEADER_CREATOR_INFO
|
||||
{
|
||||
LIST_ENTRY TypeList;
|
||||
PVOID CreatorUniqueProcess;
|
||||
USHORT CreatorBackTraceIndex;
|
||||
USHORT Reserved;
|
||||
} OBJECT_HEADER_CREATOR_INFO, *POBJECT_HEADER_CREATOR_INFO;
|
||||
|
||||
/* Union representing either a single handle count entry or a full database */
|
||||
typedef union _OBJECT_HEADER_HANDLE_INFO
|
||||
{
|
||||
POBJECT_HANDLE_COUNT_DATABASE HandleCountDatabase;
|
||||
OBJECT_HANDLE_COUNT_ENTRY SingleEntry;
|
||||
} OBJECT_HEADER_HANDLE_INFO, *POBJECT_HEADER_HANDLE_INFO;
|
||||
|
||||
/* Name information stored in the object header */
|
||||
typedef struct _OBJECT_HEADER_NAME_INFO
|
||||
{
|
||||
POBJECT_DIRECTORY Directory;
|
||||
UNICODE_STRING Name;
|
||||
ULONG QueryReferences;
|
||||
ULONG Reserved;
|
||||
ULONG DbgReferenceCount;
|
||||
} OBJECT_HEADER_NAME_INFO, *POBJECT_HEADER_NAME_INFO;
|
||||
|
||||
/* Active quota information stored in the object header */
|
||||
typedef struct _OBJECT_HEADER_QUOTA_INFO
|
||||
{
|
||||
ULONG PagedPoolCharge;
|
||||
ULONG NonPagedPoolCharge;
|
||||
ULONG SecurityDescriptorCharge;
|
||||
PEPROCESS ExclusiveProcess;
|
||||
} OBJECT_HEADER_QUOTA_INFO, *POBJECT_HEADER_QUOTA_INFO;
|
||||
|
||||
/* Context maintained during namespace traversal and directory lookups */
|
||||
typedef struct _OBJECT_LOOKUP_CONTEXT
|
||||
{
|
||||
POBJECT_DIRECTORY Directory;
|
||||
PVOID Object;
|
||||
USHORT HashIndex;
|
||||
BOOLEAN DirectoryLocked;
|
||||
VOLATILE ULONG LockStateSignature;
|
||||
} OBJECT_LOOKUP_CONTEXT, *POBJECT_LOOKUP_CONTEXT;
|
||||
|
||||
/* Optional header storing the object's hierarchical name and directory links */
|
||||
typedef struct _OBJECT_NAME_INFO
|
||||
{
|
||||
LIST_ENTRY ObjectLinks;
|
||||
UNICODE_STRING ObjectName;
|
||||
PWSTR ObjectDirectoryPath;
|
||||
} OBJECT_NAME_INFO, *POBJECT_NAME_INFO;
|
||||
|
||||
/* Structure used to query an object's name */
|
||||
typedef struct _OBJECT_NAME_INFORMATION
|
||||
{
|
||||
UNICODE_STRING Name;
|
||||
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
|
||||
|
||||
/* Memory layout sizes for the object's optional headers */
|
||||
typedef struct _OBJECT_OPTIONAL_HEADER_LAYOUT
|
||||
{
|
||||
ULONG QuotaInfoSize;
|
||||
ULONG HandleInfoSize;
|
||||
ULONG NameInfoSize;
|
||||
ULONG CreatorInfoSize;
|
||||
ULONG TotalSize;
|
||||
} OBJECT_OPTIONAL_HEADER_LAYOUT, *POBJECT_OPTIONAL_HEADER_LAYOUT;
|
||||
|
||||
/* Information block linking an object to a specific process */
|
||||
typedef struct _OBJECT_PROCESS_INFO
|
||||
{
|
||||
LIST_ENTRY Entry;
|
||||
PEPROCESS Process;
|
||||
ULONG ReferenceCount;
|
||||
} OBJECT_PROCESS_INFO, *POBJECT_PROCESS_INFO;
|
||||
|
||||
/* Optional header tracking memory pool charges */
|
||||
typedef struct _OBJECT_QUOTA_INFO
|
||||
{
|
||||
ULONG PagedPoolCharge;
|
||||
ULONG NonPagedPoolCharge;
|
||||
ULONG SecurityDescriptorCharge;
|
||||
PEPROCESS ExclusiveProcess;
|
||||
} OBJECT_QUOTA_INFO, *POBJECT_QUOTA_INFO;
|
||||
|
||||
/* Configuration block defining the lifecycle and behavior of a specific object type */
|
||||
typedef struct _OBJECT_TYPE_INITIALIZER
|
||||
{
|
||||
USHORT Length;
|
||||
BOOLEAN UseDefaultObject;
|
||||
BOOLEAN CaseInsensitive;
|
||||
ULONG InvalidAttributes;
|
||||
GENERIC_MAPPING GenericMapping;
|
||||
ULONG ValidAccessMask;
|
||||
BOOLEAN SecurityRequired;
|
||||
BOOLEAN MaintainHandleCount;
|
||||
BOOLEAN MaintainTypeList;
|
||||
MMPOOL_TYPE PoolType;
|
||||
ULONG DefaultPagedPoolCharge;
|
||||
ULONG DefaultNonPagedPoolCharge;
|
||||
POB_DUMP_METHOD DumpProcedure;
|
||||
POB_OPEN_METHOD OpenProcedure;
|
||||
POB_CLOSE_METHOD CloseProcedure;
|
||||
POB_DELETE_METHOD DeleteProcedure;
|
||||
POB_PARSE_METHOD ParseProcedure;
|
||||
POB_SECURITY_METHOD SecurityProcedure;
|
||||
POB_QUERYNAME_METHOD QueryNameProcedure;
|
||||
POB_OKAYTOCLOSE_METHOD OkayToCloseProcedure;
|
||||
} OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;
|
||||
|
||||
|
||||
/* Descriptor representing a registered object type in the system */
|
||||
typedef struct _OBJECT_TYPE
|
||||
{
|
||||
LIST_ENTRY TypeList;
|
||||
UNICODE_STRING Name;
|
||||
PVOID DefaultObject;
|
||||
ULONG Index;
|
||||
ULONG TotalNumberOfObjects;
|
||||
ULONG TotalNumberOfHandles;
|
||||
ULONG HighWaterNumberOfObjects;
|
||||
ULONG HighWaterNumberOfHandles;
|
||||
OBJECT_TYPE_INITIALIZER TypeInfo;
|
||||
KPUSH_LOCK TypeLock;
|
||||
ULONG Key;
|
||||
LIST_ENTRY CallbackList;
|
||||
} OBJECT_TYPE;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_OBTYPES_H */
|
||||
@@ -14,10 +14,67 @@
|
||||
#include <ketypes.h>
|
||||
|
||||
|
||||
/* Processor performance scale factor */
|
||||
#define POWER_PERFORMANCE_SCALE 100
|
||||
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Device power states */
|
||||
typedef enum _DEVICE_POWER_STATE
|
||||
{
|
||||
PowerDeviceUnspecified = 0,
|
||||
PowerDeviceD0,
|
||||
PowerDeviceD1,
|
||||
PowerDeviceD2,
|
||||
PowerDeviceD3,
|
||||
PowerDeviceMaximum
|
||||
} DEVICE_POWER_STATE, *PDEVICE_POWER_STATE;
|
||||
|
||||
/* Power actions list */
|
||||
typedef enum _POWER_ACTION
|
||||
{
|
||||
PowerActionNone = 0,
|
||||
PowerActionReserved,
|
||||
PowerActionSleep,
|
||||
PowerActionHibernate,
|
||||
PowerActionShutdown,
|
||||
PowerActionShutdownReset,
|
||||
PowerActionShutdownOff,
|
||||
PowerActionWarmEject
|
||||
} POWER_ACTION, *PPOWER_ACTION;
|
||||
|
||||
typedef enum _POWER_STATE_TYPE
|
||||
{
|
||||
SystemPowerState = 0,
|
||||
DevicePowerState
|
||||
} POWER_STATE_TYPE, *PPOWER_STATE_TYPE;
|
||||
|
||||
/* System power states */
|
||||
typedef enum _SYSTEM_POWER_STATE
|
||||
{
|
||||
PowerSystemUnspecified = 0,
|
||||
PowerSystemWorking,
|
||||
PowerSystemSleeping1,
|
||||
PowerSystemSleeping2,
|
||||
PowerSystemSleeping3,
|
||||
PowerSystemHibernate,
|
||||
PowerSystemShutdown,
|
||||
PowerSystemMaximum
|
||||
} SYSTEM_POWER_STATE, *PSYSTEM_POWER_STATE;
|
||||
|
||||
/* Power state union definition */
|
||||
typedef union _POWER_STATE
|
||||
{
|
||||
SYSTEM_POWER_STATE SystemState;
|
||||
DEVICE_POWER_STATE DeviceState;
|
||||
} POWER_STATE, *PPOWER_STATE;
|
||||
|
||||
/* Processor IDLE times structure definition */
|
||||
typedef struct _PROCESSOR_IDLE_TIMES
|
||||
{
|
||||
@@ -88,4 +145,24 @@ typedef struct _PROCESSOR_POWER_STATE
|
||||
ULONG LastC3UserTime;
|
||||
} PROCESSOR_POWER_STATE, *PPROCESSOR_POWER_STATE;
|
||||
|
||||
/* System power state context structure definition */
|
||||
typedef struct _SYSTEM_POWER_STATE_CONTEXT
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
ULONG Reserved1:8;
|
||||
ULONG TargetSystemState:4;
|
||||
ULONG EffectiveSystemState:4;
|
||||
ULONG CurrentSystemState:4;
|
||||
ULONG IgnoreHibernationPath:1;
|
||||
ULONG PseudoTransition:1;
|
||||
ULONG Reserved2:10;
|
||||
};
|
||||
ULONG ContextAsUlong;
|
||||
};
|
||||
} SYSTEM_POWER_STATE_CONTEXT, *PSYSTEM_POWER_STATE_CONTEXT;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_POTYPES_H */
|
||||
|
||||
@@ -10,16 +10,56 @@
|
||||
#define __XTDK_PSTYPES_H
|
||||
|
||||
#include <xttypes.h>
|
||||
#include <ketypes.h>
|
||||
#include <xtstruct.h>
|
||||
#include <extypes.h>
|
||||
|
||||
|
||||
/* Quota bypass marker */
|
||||
#define PS_QUOTA_BYPASS_MARKER ((PEPROCESS_QUOTA_BLOCK)1)
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Process quota types */
|
||||
typedef enum _PS_QUOTA_TYPE
|
||||
{
|
||||
PsNonPagedPool,
|
||||
PsPagedPool,
|
||||
PsPageFile,
|
||||
PsQuotaTypes
|
||||
} PS_QUOTA_TYPE, *PPS_QUOTA_TYPE;
|
||||
|
||||
/* Kernel's representation of a process object */
|
||||
typedef struct _EPROCESS
|
||||
{
|
||||
KPROCESS ProcessControlBlock;
|
||||
KPUSH_LOCK ProcessLock;
|
||||
LARGE_INTEGER CreateTime;
|
||||
LARGE_INTEGER ExitTime;
|
||||
EX_RUNDOWN_REFERENCE RundownProtect;
|
||||
HANDLE UniqueProcessId;
|
||||
SIZE_T QuotaUsage[PsQuotaTypes];
|
||||
UINT Reserved0;
|
||||
} EPROCESS, *PEPROCESS;
|
||||
|
||||
/* Kernel's representation of a process quota entry*/
|
||||
typedef struct _EPROCESS_QUOTA_ENTRY
|
||||
{
|
||||
SIZE_T Usage;
|
||||
SIZE_T Limit;
|
||||
SIZE_T Peak;
|
||||
SIZE_T Return;
|
||||
} EPROCESS_QUOTA_ENTRY, *PEPROCESS_QUOTA_ENTRY;
|
||||
|
||||
/* Kernel's representation of a process quota block */
|
||||
typedef struct _EPROCESS_QUOTA_BLOCK
|
||||
{
|
||||
EPROCESS_QUOTA_ENTRY QuotaEntry[PsQuotaTypes];
|
||||
LIST_ENTRY QuotaList;
|
||||
ULONG ReferenceCount;
|
||||
ULONG ProcessCount;
|
||||
} EPROCESS_QUOTA_BLOCK, *PEPROCESS_QUOTA_BLOCK;
|
||||
|
||||
/* Kernel's representation of a thread object */
|
||||
typedef struct _ETHREAD
|
||||
{
|
||||
@@ -27,4 +67,5 @@ typedef struct _ETHREAD
|
||||
UINT Reserved0;
|
||||
} ETHREAD, *PETHREAD;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_PSTYPES_H */
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
#include <rtltypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Runtime Library routines forward references */
|
||||
XTCLINK
|
||||
XTAPI
|
||||
@@ -120,6 +123,12 @@ RtlCopyString(IN PCHAR Destination,
|
||||
IN PCSTR Source,
|
||||
IN ULONG Length);
|
||||
|
||||
XTCLINK
|
||||
XTAPI
|
||||
VOID
|
||||
RtlCopyUnicodeString(IN OUT PUNICODE_STRING Destination,
|
||||
IN PCUNICODE_STRING Source);
|
||||
|
||||
XTCLINK
|
||||
XTAPI
|
||||
VOID
|
||||
@@ -184,6 +193,18 @@ XTCDECL
|
||||
VOID
|
||||
RtlInitializeListHead(IN PLIST_ENTRY ListHead);
|
||||
|
||||
XTCLINK
|
||||
XTAPI
|
||||
VOID
|
||||
RtlInitializeUnicodeString(OUT PUNICODE_STRING Destination,
|
||||
IN PCWSTR Source);
|
||||
|
||||
XTCLINK
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
RtlInitializeUnicodeStringEx(OUT PUNICODE_STRING Destination,
|
||||
IN PCWSTR Source);
|
||||
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
@@ -294,6 +315,18 @@ 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
|
||||
@@ -370,4 +403,5 @@ VOID
|
||||
RtlZeroMemory(OUT PVOID Destination,
|
||||
IN SIZE_T Length);
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_RTLFUNCS_H */
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* FILE: sdk/xtdk/rtltypes.h
|
||||
* DESCRIPTION: Runtime library structures definitions
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTDK_RTLTYPES_H
|
||||
@@ -11,52 +12,160 @@
|
||||
|
||||
#include <xtbase.h>
|
||||
#include <xttypes.h>
|
||||
#include ARCH_HEADER(xtstruct.h)
|
||||
|
||||
|
||||
/* UUID string lengths */
|
||||
#define GUID_STRING_LENGTH 38
|
||||
#define PARTUUID_STRING_LENGTH 13
|
||||
#define GUID_STRING_LENGTH 38
|
||||
#define PARTUUID_STRING_LENGTH 13
|
||||
|
||||
/* Maximum double/integer value string length */
|
||||
#define MAX_DOUBLE_STRING_SIZE 15
|
||||
#define MAX_INTEGER_STRING_SIZE 25
|
||||
#define MAX_DOUBLE_STRING_SIZE 15
|
||||
#define MAX_INTEGER_STRING_SIZE 25
|
||||
|
||||
/* Floating point definitions */
|
||||
#define DOUBLE_EXPONENT_MASK 0x7FF0000000000000ULL
|
||||
#define DOUBLE_EXPONENT_SHIFT 0x34
|
||||
#define DOUBLE_EXPONENT_BIAS 0x3FF
|
||||
#define DOUBLE_HIGH_VALUE_MASK 0x000FFFFF
|
||||
#define DOUBLE_HIGH_VALUE_SHIFT 0x20
|
||||
#define DOUBLE_PRECISION 6
|
||||
#define DOUBLE_HEX_PRECISION 13
|
||||
#define DOUBLE_SCIENTIFIC_PRECISION -4
|
||||
#define DOUBLE_SIGN_BIT 0x8000000000000000ULL
|
||||
#define DOUBLE_EXPONENT_MASK 0x7FF0000000000000ULL
|
||||
#define DOUBLE_EXPONENT_SHIFT 0x34
|
||||
#define DOUBLE_EXPONENT_BIAS 0x3FF
|
||||
#define DOUBLE_HIGH_VALUE_MASK 0x000FFFFF
|
||||
#define DOUBLE_HIGH_VALUE_SHIFT 0x20
|
||||
#define DOUBLE_PRECISION 6
|
||||
#define DOUBLE_HEX_PRECISION 13
|
||||
#define DOUBLE_SCIENTIFIC_PRECISION -4
|
||||
#define DOUBLE_SIGN_BIT 0x8000000000000000ULL
|
||||
|
||||
/* Exception Record flags */
|
||||
#define EXCEPTION_CONTINUE_SEARCH 0x00
|
||||
#define EXCEPTION_NONCONTINUABLE 0x01
|
||||
#define EXCEPTION_UNWINDING 0x02
|
||||
#define EXCEPTION_EXIT_UNWIND 0x04
|
||||
#define EXCEPTION_STACK_INVALID 0x08
|
||||
#define EXCEPTION_NESTED_CALL 0x10
|
||||
#define EXCEPTION_TARGET_UNWIND 0x20
|
||||
#define EXCEPTION_COLLIDED_UNWIND 0x40
|
||||
|
||||
/* Exception Record accessors */
|
||||
#define EXCEPTION_CODE _exception_code()
|
||||
#define EXCEPTION_INFORMATION (PEXCEPTION_POINTERS)_exception_info()
|
||||
|
||||
/* Maximum number of lead bytes for NLS */
|
||||
#define NLS_MAXIMUM_LEADBYTES 12
|
||||
|
||||
/* Print flag definitions */
|
||||
#define PFL_ALWAYS_PRINT_SIGN 0x00000001
|
||||
#define PFL_SPACE_FOR_PLUS 0x00000002
|
||||
#define PFL_LEFT_JUSTIFIED 0x00000004
|
||||
#define PFL_LEADING_ZEROES 0x00000008
|
||||
#define PFL_LONG_INTEGER 0x00000010
|
||||
#define PFL_LONG_DOUBLE 0x00000020
|
||||
#define PFL_WIDE_CHARACTER 0x00000040
|
||||
#define PFL_SHORT_VALUE 0x00000080
|
||||
#define PFL_UNSIGNED 0x00000100
|
||||
#define PFL_UPPERCASE 0x00000200
|
||||
#define PFL_PRINT_RADIX 0x00000400
|
||||
#define PFL_FLOAT_FORMAT 0x00000800
|
||||
#define PFL_SCI_FORMAT 0x00001000
|
||||
#define PFL_DIGIT_PRECISION 0x00002000
|
||||
#define PFL_THOUSANDS_GROUPING 0x00004000
|
||||
#define PFL_ALWAYS_PRINT_SIGN 0x00000001
|
||||
#define PFL_SPACE_FOR_PLUS 0x00000002
|
||||
#define PFL_LEFT_JUSTIFIED 0x00000004
|
||||
#define PFL_LEADING_ZEROES 0x00000008
|
||||
#define PFL_LONG_INTEGER 0x00000010
|
||||
#define PFL_LONG_DOUBLE 0x00000020
|
||||
#define PFL_WIDE_CHARACTER 0x00000040
|
||||
#define PFL_SHORT_VALUE 0x00000080
|
||||
#define PFL_UNSIGNED 0x00000100
|
||||
#define PFL_UPPERCASE 0x00000200
|
||||
#define PFL_PRINT_RADIX 0x00000400
|
||||
#define PFL_FLOAT_FORMAT 0x00000800
|
||||
#define PFL_SCI_FORMAT 0x00001000
|
||||
#define PFL_DIGIT_PRECISION 0x00002000
|
||||
#define PFL_THOUSANDS_GROUPING 0x00004000
|
||||
|
||||
/* Red-black tree definitions */
|
||||
#define RTL_BALANCED_NODE_RESERVED_PARENT_MASK 3
|
||||
#define RTL_BALANCED_NODE_COLOR_MASK 1
|
||||
|
||||
/* Cryptographic related definitions */
|
||||
#define SHA1_BLOCK_SIZE 64
|
||||
#define SHA1_DIGEST_SIZE 20
|
||||
#define SHA1_BLOCK_SIZE 64
|
||||
#define SHA1_DIGEST_SIZE 20
|
||||
|
||||
/* Time related definitions */
|
||||
#define TIME_SECONDS_PER_MINUTE 60
|
||||
#define TIME_SECONDS_PER_HOUR 3600
|
||||
#define TIME_SECONDS_PER_DAY 86400
|
||||
#define TIME_TICKS_PER_SECOND 10000000
|
||||
#define TIME_TICKS_PER_MILLISECOND 10000
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Runtime Library routine callbacks */
|
||||
typedef XTSTATUS (*PWRITE_CHARACTER)(IN CHAR Character);
|
||||
typedef XTSTATUS (*PWRITE_WIDE_CHARACTER)(IN WCHAR Character);
|
||||
|
||||
/* Compressed data information structure definition */
|
||||
typedef struct _COMPRESSED_DATA_INFO
|
||||
{
|
||||
USHORT CompressionFormatAndEngine;
|
||||
UCHAR CompressionUnitShift;
|
||||
UCHAR ChunkShift;
|
||||
UCHAR ClusterShift;
|
||||
UCHAR Reserved;
|
||||
USHORT NumberOfChunks;
|
||||
ULONG CompressedChunkSizes[1];
|
||||
} COMPRESSED_DATA_INFO, *PCOMPRESSED_DATA_INFO;
|
||||
|
||||
/* Code page table structure definition */
|
||||
typedef struct _CPTABLE_INFO
|
||||
{
|
||||
USHORT CodePage;
|
||||
USHORT MaximumCharacterSize;
|
||||
USHORT DefaultChar;
|
||||
USHORT UniDefaultChar;
|
||||
USHORT TransDefaultChar;
|
||||
USHORT TransUniDefaultChar;
|
||||
USHORT DBCSCodePage;
|
||||
UCHAR LeadByte[NLS_MAXIMUM_LEADBYTES];
|
||||
PUSHORT MultiByteTable;
|
||||
PVOID WideCharTable;
|
||||
PUSHORT DBCSRanges;
|
||||
PUSHORT DBCSOffsets;
|
||||
} CPTABLE_INFO, *PCPTABLE_INFO;
|
||||
|
||||
/* Exception Pointers structure definition */
|
||||
typedef struct _EXCEPTION_POINTERS
|
||||
{
|
||||
PEXCEPTION_RECORD ExceptionRecord;
|
||||
PCONTEXT ContextRecord;
|
||||
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
|
||||
|
||||
/* 128-bit buffer containing a unique identifier value */
|
||||
typedef struct _GUID
|
||||
{
|
||||
UINT Data1;
|
||||
USHORT Data2;
|
||||
USHORT Data3;
|
||||
UCHAR Data4[8];
|
||||
} GUID, *PGUID;
|
||||
|
||||
/* 32-bit double linked list structure definition */
|
||||
typedef struct _LIST_ENTRY32
|
||||
{
|
||||
ULONG Flink;
|
||||
ULONG Blink;
|
||||
} LIST_ENTRY32, *PLIST_ENTRY32;
|
||||
|
||||
/* 64-bit double linked list structure definition */
|
||||
typedef struct _LIST_ENTRY64
|
||||
{
|
||||
ULONGLONG Flink;
|
||||
ULONGLONG Blink;
|
||||
} LIST_ENTRY64, *PLIST_ENTRY64;
|
||||
|
||||
/* NLS table structure definition */
|
||||
typedef struct _NLSTABLE_INFO
|
||||
{
|
||||
CPTABLE_INFO OemTableInfo;
|
||||
CPTABLE_INFO AnsiTableInfo;
|
||||
PUSHORT UpperCaseTable;
|
||||
PUSHORT LowerCaseTable;
|
||||
} NLSTABLE_INFO, *PNLSTABLE_INFO;
|
||||
|
||||
/* Red-black tree node color enumeration list */
|
||||
typedef enum _RTL_BALANCED_NODE_COLOR
|
||||
{
|
||||
NodeBlack,
|
||||
NodeRed
|
||||
} RTL_BALANCED_NODE_COLOR, *PRTL_BALANCED_NODE_COLOR;
|
||||
|
||||
/* Variable types enumeration list */
|
||||
typedef enum _RTL_VARIABLE_TYPE
|
||||
{
|
||||
@@ -73,6 +182,26 @@ typedef enum _RTL_VARIABLE_TYPE
|
||||
TypeWideString
|
||||
} RTL_VARIABLE_TYPE, *PRTL_VARIABLE_TYPE;
|
||||
|
||||
/* Runtime Library red-black tree balanced node structure definition */
|
||||
typedef struct _RTL_BALANCED_NODE
|
||||
{
|
||||
union
|
||||
{
|
||||
PRTL_BALANCED_NODE Children[2];
|
||||
struct
|
||||
{
|
||||
PRTL_BALANCED_NODE Left;
|
||||
PRTL_BALANCED_NODE Right;
|
||||
};
|
||||
};
|
||||
union
|
||||
{
|
||||
UCHAR Red:1;
|
||||
UCHAR Balance:2;
|
||||
ULONG_PTR ParentValue;
|
||||
};
|
||||
} RTL_BALANCED_NODE, *PRTL_BALANCED_NODE;
|
||||
|
||||
/* Bit Map structure definition */
|
||||
typedef struct _RTL_BITMAP
|
||||
{
|
||||
@@ -99,12 +228,39 @@ typedef struct _RTL_PRINT_FORMAT_PROPERTIES
|
||||
LONG Flags;
|
||||
} RTL_PRINT_FORMAT_PROPERTIES, *PRTL_PRINT_FORMAT_PROPERTIES;
|
||||
|
||||
/* Runtime Library red-black tree structure definition */
|
||||
typedef struct _RTL_RB_TREE
|
||||
{
|
||||
PRTL_BALANCED_NODE Root;
|
||||
PRTL_BALANCED_NODE Min;
|
||||
} RTL_RB_TREE, *PRTL_RB_TREE;
|
||||
|
||||
/* Runtime Library SHA-1 context structure definition */
|
||||
typedef struct _RTL_SHA1_CONTEXT
|
||||
{
|
||||
ULONG State[5];
|
||||
ULONG Count[2];
|
||||
UCHAR Buffer[SHA1_BLOCK_SIZE];
|
||||
ULONG State[5];
|
||||
ULONG Count[2];
|
||||
UCHAR Buffer[SHA1_BLOCK_SIZE];
|
||||
} RTL_SHA1_CONTEXT, *PRTL_SHA1_CONTEXT;
|
||||
|
||||
/* Single linked list structure definition */
|
||||
typedef struct _SINGLE_LIST_ENTRY
|
||||
{
|
||||
PSINGLE_LIST_ENTRY Next;
|
||||
} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;
|
||||
|
||||
/* 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 */
|
||||
|
||||
201
sdk/xtdk/setypes.h
Normal file
201
sdk/xtdk/setypes.h
Normal file
@@ -0,0 +1,201 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: sdk/xtdk/setypes.h
|
||||
* DESCRIPTION: Kernel Security structures and definitions
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTDK_SETYPES_H
|
||||
#define __XTDK_SETYPES_H
|
||||
|
||||
#include <xttypes.h>
|
||||
#include <xtstruct.h>
|
||||
#include <xtbase.h>
|
||||
|
||||
|
||||
/* Privilege LUIDs */
|
||||
#define SE_LUID_MIN_WELL_KNOWN_PRIVILEGE (LUID){2, 0}
|
||||
#define SE_LUID_CREATE_TOKEN_PRIVILEGE (LUID){2, 0}
|
||||
#define SE_LUID_ASSIGNPRIMARYTOKEN_PRIVILEGE (LUID){3, 0}
|
||||
#define SE_LUID_LOCK_MEMORY_PRIVILEGE (LUID){4, 0}
|
||||
#define SE_LUID_INCREASE_QUOTA_PRIVILEGE (LUID){5, 0}
|
||||
#define SE_LUID_MACHINE_ACCOUNT_PRIVILEGE (LUID){6, 0}
|
||||
#define SE_LUID_TCB_PRIVILEGE (LUID){7, 0}
|
||||
#define SE_LUID_SECURITY_PRIVILEGE (LUID){8, 0}
|
||||
#define SE_LUID_TAKE_OWNERSHIP_PRIVILEGE (LUID){9, 0}
|
||||
#define SE_LUID_LOAD_DRIVER_PRIVILEGE (LUID){10, 0}
|
||||
#define SE_LUID_SYSTEM_PROFILE_PRIVILEGE (LUID){11, 0}
|
||||
#define SE_LUID_SYSTEMTIME_PRIVILEGE (LUID){12, 0}
|
||||
#define SE_LUID_PROF_SINGLE_PROCESS_PRIVILEGE (LUID){13, 0}
|
||||
#define SE_LUID_INC_BASE_PRIORITY_PRIVILEGE (LUID){14, 0}
|
||||
#define SE_LUID_CREATE_PAGEFILE_PRIVILEGE (LUID){15, 0}
|
||||
#define SE_LUID_CREATE_PERMANENT_PRIVILEGE (LUID){16, 0}
|
||||
#define SE_LUID_BACKUP_PRIVILEGE (LUID){17, 0}
|
||||
#define SE_LUID_RESTORE_PRIVILEGE (LUID){18, 0}
|
||||
#define SE_LUID_SHUTDOWN_PRIVILEGE (LUID){19, 0}
|
||||
#define SE_LUID_DEBUG_PRIVILEGE (LUID){20, 0}
|
||||
#define SE_LUID_AUDIT_PRIVILEGE (LUID){21, 0}
|
||||
#define SE_LUID_SYSTEM_ENVIRONMENT_PRIVILEGE (LUID){22, 0}
|
||||
#define SE_LUID_CHANGE_NOTIFY_PRIVILEGE (LUID){23, 0}
|
||||
#define SE_LUID_REMOTE_SHUTDOWN_PRIVILEGE (LUID){24, 0}
|
||||
#define SE_LUID_UNDOCK_PRIVILEGE (LUID){25, 0}
|
||||
#define SE_LUID_SYNC_AGENT_PRIVILEGE (LUID){26, 0}
|
||||
#define SE_LUID_ENABLE_DELEGATION_PRIVILEGE (LUID){27, 0}
|
||||
#define SE_LUID_MANAGE_VOLUME_PRIVILEGE (LUID){28, 0}
|
||||
#define SE_LUID_IMPERSONATE_PRIVILEGE (LUID){29, 0}
|
||||
#define SE_LUID_CREATE_GLOBAL_PRIVILEGE (LUID){30, 0}
|
||||
#define SE_LUID_TRUSTED_CREDMAN_ACCESS_PRIVILEGE (LUID){31, 0}
|
||||
#define SE_LUID_RELABEL_PRIVILEGE (LUID){32, 0}
|
||||
#define SE_LUID_INC_WORKING_SET_PRIVILEGE (LUID){33, 0}
|
||||
#define SE_LUID_TIME_ZONE_PRIVILEGE (LUID){34, 0}
|
||||
#define SE_LUID_CREATE_SYMBOLIC_LINK_PRIVILEGE (LUID){35, 0}
|
||||
|
||||
/* Default security quota */
|
||||
#define SE_DEFAULT_SECURITY_QUOTA 2048
|
||||
|
||||
#define SE_INITIAL_PRIVILEGE_COUNT 3
|
||||
|
||||
/* Token source length */
|
||||
#define SE_TOKEN_SOURCE_LENGTH 8
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Security impersonation levels */
|
||||
typedef enum _SECURITY_IMPERSONATION_LEVEL
|
||||
{
|
||||
SecurityAnonymous,
|
||||
SecurityIdentification,
|
||||
SecurityImpersonation,
|
||||
SecurityDelegation
|
||||
} SECURITY_IMPERSONATION_LEVEL, *PSECURITY_IMPERSONATION_LEVEL;
|
||||
|
||||
/* Security operation codes */
|
||||
typedef enum _SECURITY_OPERATION_CODE
|
||||
{
|
||||
SetSecurityDescriptor,
|
||||
QuerySecurityDescriptor,
|
||||
DeleteSecurityDescriptor,
|
||||
AssignSecurityDescriptor
|
||||
} SECURITY_OPERATION_CODE, *PSECURITY_OPERATION_CODE;
|
||||
|
||||
/* Generic security mapping structure definition */
|
||||
typedef struct _GENERIC_MAPPING
|
||||
{
|
||||
ULONG GenericRead;
|
||||
ULONG GenericWrite;
|
||||
ULONG GenericExecute;
|
||||
ULONG GenericAll;
|
||||
} GENERIC_MAPPING, *PGENERIC_MAPPING;
|
||||
|
||||
/* LUID and attributes structure definition */
|
||||
typedef struct _LUID_AND_ATTRIBUTES
|
||||
{
|
||||
LUID Luid;
|
||||
ULONG Attributes;
|
||||
} LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES;
|
||||
|
||||
/* Initial privilege set structure definition */
|
||||
typedef struct _INITIAL_PRIVILEGE_SET
|
||||
{
|
||||
ULONG PrivilegeCount;
|
||||
ULONG Control;
|
||||
LUID_AND_ATTRIBUTES Privilege[SE_INITIAL_PRIVILEGE_COUNT];
|
||||
} INITIAL_PRIVILEGE_SET, * PINITIAL_PRIVILEGE_SET;
|
||||
|
||||
/* Privilege set structure definition */
|
||||
typedef struct _PRIVILEGE_SET
|
||||
{
|
||||
ULONG PrivilegeCount;
|
||||
ULONG Control;
|
||||
LUID_AND_ATTRIBUTES Privilege[1];
|
||||
} PRIVILEGE_SET, *PPRIVILEGE_SET;
|
||||
|
||||
/* Identifier authority structure definition */
|
||||
typedef struct _SID_IDENTIFIER_AUTHORITY
|
||||
{
|
||||
UCHAR Value[6];
|
||||
} SID_IDENTIFIER_AUTHORITY,*PSID_IDENTIFIER_AUTHORITY;
|
||||
|
||||
/* Security identifier structure definition */
|
||||
typedef struct _SID
|
||||
{
|
||||
UCHAR Revision;
|
||||
UCHAR SubAuthorityCount;
|
||||
SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
|
||||
ULONG SubAuthority[1];
|
||||
} SID, *PSID;
|
||||
|
||||
/* Token source structure definition */
|
||||
typedef struct _TOKEN_SOURCE
|
||||
{
|
||||
CHAR SourceName[SE_TOKEN_SOURCE_LENGTH];
|
||||
LUID SourceIdentifier;
|
||||
} TOKEN_SOURCE, *PTOKEN_SOURCE;
|
||||
|
||||
/* Token control structure definition */
|
||||
typedef struct _TOKEN_CONTROL
|
||||
{
|
||||
LUID TokenId;
|
||||
LUID AuthenticationId;
|
||||
LUID ModifiedId;
|
||||
TOKEN_SOURCE TokenSource;
|
||||
} TOKEN_CONTROL, *PTOKEN_CONTROL;
|
||||
|
||||
/* Security quality of service structure definition */
|
||||
typedef struct _SECURITY_QUALITY_OF_SERVICE
|
||||
{
|
||||
ULONG Length;
|
||||
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
|
||||
SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode;
|
||||
BOOLEAN EffectiveOnly;
|
||||
} SECURITY_QUALITY_OF_SERVICE, *PSECURITY_QUALITY_OF_SERVICE;
|
||||
|
||||
/* Security client context structure definition */
|
||||
typedef struct _SECURITY_CLIENT_CONTEXT
|
||||
{
|
||||
SECURITY_QUALITY_OF_SERVICE SecurityQos;
|
||||
PACCESS_TOKEN ClientToken;
|
||||
BOOLEAN DirectlyAccessClientToken;
|
||||
BOOLEAN DirectAccessEffectiveOnly;
|
||||
BOOLEAN ServerIsRemote;
|
||||
TOKEN_CONTROL ClientTokenControl;
|
||||
} SECURITY_CLIENT_CONTEXT, *PSECURITY_CLIENT_CONTEXT;
|
||||
|
||||
/* Security subject context structure definition */
|
||||
typedef struct _SECURITY_SUBJECT_CONTEXT
|
||||
{
|
||||
PACCESS_TOKEN ClientToken;
|
||||
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
|
||||
PACCESS_TOKEN PrimaryToken;
|
||||
PVOID ProcessAuditId;
|
||||
} SECURITY_SUBJECT_CONTEXT, *PSECURITY_SUBJECT_CONTEXT;
|
||||
|
||||
/* Access state structure definition */
|
||||
typedef struct _ACCESS_STATE
|
||||
{
|
||||
LUID OperationID;
|
||||
BOOLEAN SecurityEvaluated;
|
||||
BOOLEAN GenerateAudit;
|
||||
BOOLEAN GenerateOnClose;
|
||||
BOOLEAN PrivilegesAllocated;
|
||||
ULONG Flags;
|
||||
ACCESS_MASK RemainingDesiredAccess;
|
||||
ACCESS_MASK PreviouslyGrantedAccess;
|
||||
ACCESS_MASK OriginalDesiredAccess;
|
||||
SECURITY_SUBJECT_CONTEXT SubjectSecurityContext;
|
||||
PSECURITY_DESCRIPTOR SecurityDescriptor;
|
||||
PVOID AuxData;
|
||||
union
|
||||
{
|
||||
INITIAL_PRIVILEGE_SET InitialPrivilegeSet;
|
||||
PRIVILEGE_SET PrivilegeSet;
|
||||
} Privileges;
|
||||
BOOLEAN AuditPrivileges;
|
||||
UNICODE_STRING ObjectName;
|
||||
UNICODE_STRING ObjectTypeName;
|
||||
} ACCESS_STATE, *PACCESS_STATE;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_SETYPES_H */
|
||||
@@ -14,6 +14,15 @@
|
||||
#include <xttypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Access mask */
|
||||
typedef ULONG ACCESS_MASK, *PACCESS_MASK;
|
||||
|
||||
/* Device type */
|
||||
typedef ULONG DEVICE_TYPE;
|
||||
|
||||
/* Kernel affinity */
|
||||
typedef ULONG_PTR KAFFINITY, *PKAFFINITY;
|
||||
|
||||
@@ -29,6 +38,12 @@ typedef UCHAR KRUNLEVEL, *PKRUNLEVEL;
|
||||
/* Spin locks synchronization mechanism */
|
||||
typedef ULONG_PTR KSPIN_LOCK, *PKSPIN_LOCK;
|
||||
|
||||
/* Locale identifier */
|
||||
typedef ULONG LCID;
|
||||
|
||||
/* Access token */
|
||||
typedef PVOID PACCESS_TOKEN;
|
||||
|
||||
/* Page Frame Number count */
|
||||
typedef ULONG PFN_COUNT;
|
||||
|
||||
@@ -38,74 +53,14 @@ typedef ULONG_PTR PFN_NUMBER, *PPFN_NUMBER;
|
||||
/* Physical address */
|
||||
typedef LARGE_INTEGER PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS;
|
||||
|
||||
/* 128-bit buffer containing a unique identifier value */
|
||||
typedef struct _GUID
|
||||
{
|
||||
UINT Data1;
|
||||
USHORT Data2;
|
||||
USHORT Data3;
|
||||
UCHAR Data4[8];
|
||||
} GUID, *PGUID;
|
||||
/* Security descriptor */
|
||||
typedef PVOID PSECURITY_DESCRIPTOR;
|
||||
|
||||
/* Double linked list structure definition */
|
||||
typedef struct _LIST_ENTRY
|
||||
{
|
||||
PLIST_ENTRY Flink;
|
||||
PLIST_ENTRY Blink;
|
||||
} LIST_ENTRY, *PLIST_ENTRY;
|
||||
/* Security context tracking mode */
|
||||
typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE, *PSECURITY_CONTEXT_TRACKING_MODE;
|
||||
|
||||
/* 32-bit double linked list structure definition */
|
||||
typedef struct _LIST_ENTRY32
|
||||
{
|
||||
ULONG Flink;
|
||||
ULONG Blink;
|
||||
} LIST_ENTRY32, *PLIST_ENTRY32;
|
||||
|
||||
/* 64-bit double linked list structure definition */
|
||||
typedef struct _LIST_ENTRY64
|
||||
{
|
||||
ULONGLONG Flink;
|
||||
ULONGLONG Blink;
|
||||
} LIST_ENTRY64, *PLIST_ENTRY64;
|
||||
|
||||
/* Single linked list structure definition */
|
||||
typedef struct _SINGLE_LIST_ENTRY
|
||||
{
|
||||
PSINGLE_LIST_ENTRY Next;
|
||||
} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;
|
||||
|
||||
/* Header for a sequenced single linked list union definition */
|
||||
typedef union _SINGLE_LIST_HEADER
|
||||
{
|
||||
ULONGLONG Alignment;
|
||||
struct
|
||||
{
|
||||
SINGLE_LIST_ENTRY Next;
|
||||
USHORT Depth;
|
||||
USHORT Sequence;
|
||||
};
|
||||
} SINGLE_LIST_HEADER, *PSINGLE_LIST_HEADER;
|
||||
|
||||
/* 128-bit 16-byte aligned XMM register */
|
||||
typedef struct _M128
|
||||
{
|
||||
ULONGLONG Low;
|
||||
LONGLONG High;
|
||||
} ALIGN(16) M128, *PM128;
|
||||
|
||||
/* Dispatcher object header structure definition */
|
||||
typedef struct _DISPATCHER_HEADER
|
||||
{
|
||||
UCHAR Type;
|
||||
union
|
||||
{
|
||||
UCHAR Absolute;
|
||||
UCHAR NpxIrql;
|
||||
};
|
||||
UCHAR Inserted;
|
||||
BOOLEAN DebugActive;
|
||||
LONG SignalState;
|
||||
LIST_ENTRY WaitListHead;
|
||||
} DISPATCHER_HEADER, *PDISPATCHER_HEADER;
|
||||
/* Security information */
|
||||
typedef ULONG SECURITY_INFORMATION, *PSECURITY_INFORMATION;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER_ */
|
||||
#endif /* __XTDK_XTBASE_H */
|
||||
|
||||
@@ -10,11 +10,15 @@
|
||||
#define __XTDK_XTCOMPAT_H
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* C++ definitions */
|
||||
#define NULLPTR nullptr
|
||||
#define VIRTUAL virtual
|
||||
#define XTCLINK extern "C"
|
||||
#define XTSYMBOL(Name) __asm__(Name)
|
||||
|
||||
/* C++ boolean type */
|
||||
typedef bool BOOLEAN, *PBOOLEAN;
|
||||
@@ -28,6 +32,7 @@
|
||||
#define NULLPTR ((void *)0)
|
||||
#define VIRTUAL
|
||||
#define XTCLINK
|
||||
#define XTSYMBOL(Name)
|
||||
|
||||
/* C boolean type */
|
||||
typedef enum _BOOLEAN
|
||||
@@ -40,4 +45,5 @@
|
||||
typedef unsigned short wchar;
|
||||
#endif
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_XTCOMPAT_H */
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#define MAXCHAR 0x7F
|
||||
#define MINSHORT 0x8000
|
||||
#define MAXSHORT 0x7FFF
|
||||
#define MAXUSHORT 0xFFFF
|
||||
#define MINLONG 0x80000000
|
||||
#define MAXLONG 0x7FFFFFFF
|
||||
#define MAXULONG 0xFFFFFFFF
|
||||
@@ -58,6 +59,10 @@
|
||||
/* 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)
|
||||
@@ -111,7 +116,6 @@
|
||||
#define UNIQUE(Prefix) CONCATENATE(CONCATENATE(__UNIQUE_ID_, Prefix), __COUNTER__)
|
||||
|
||||
/* Variadic ABI functions */
|
||||
typedef __builtin_va_list VA_LIST, *PVA_LIST;
|
||||
#define VA_ARG(Marker, Type) ((sizeof(Type) < sizeof(UINT_PTR)) ? \
|
||||
(Type)(__builtin_va_arg(Marker, UINT_PTR)) : \
|
||||
(Type)(__builtin_va_arg(Marker, Type)))
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
#include <xtdefs.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef D__XTOS_ASSEMBLER__
|
||||
|
||||
/* SSF2 font header */
|
||||
typedef struct _SSFN_FONT_HEADER
|
||||
{
|
||||
@@ -3980,4 +3983,5 @@ UCHAR XtFbDefaultFont[] = {0x78, 0x74, 0x66, 0x6E, 0x3B, 0xE7, 0x00, 0x00, 0x03,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x82, 0x32, 0x4E, 0x46, 0x53};
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_XTFONT_H */
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
/* Version number of the current XTOS loader protocol */
|
||||
#define BOOT_PROTOCOL_VERSION 1
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Memory allocation structures */
|
||||
typedef enum _LOADER_MEMORY_TYPE
|
||||
{
|
||||
@@ -116,4 +120,5 @@ typedef struct _KERNEL_INITIALIZATION_BLOCK
|
||||
FIRMWARE_INFORMATION_BLOCK FirmwareInformation;
|
||||
} KERNEL_INITIALIZATION_BLOCK, *PKERNEL_INITIALIZATION_BLOCK;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER_ */
|
||||
#endif /* __XTDK_XTFW_H */
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
#include <xttypes.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef D__XTOS_ASSEMBLER__
|
||||
|
||||
CHAR XTGLYPH_EXECTOS_LOGO[] =
|
||||
{
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x25, 0x23,
|
||||
@@ -61,4 +64,5 @@ CHAR XTGLYPH_EXECTOS_LOGO[] =
|
||||
0x28, 0x0d, 0x0a
|
||||
};
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_XTGLYPH_H */
|
||||
|
||||
@@ -202,6 +202,10 @@
|
||||
#define PECOFF_IMAGE_SCN_MEM_READ 0x40000000
|
||||
#define PECOFF_IMAGE_SCN_MEM_WRITE 0x80000000
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* PE/COFF image representation structure */
|
||||
typedef struct _PECOFF_IMAGE_CONTEXT
|
||||
{
|
||||
@@ -638,4 +642,5 @@ typedef struct _PECOFF_IMAGE_RESOURCE_DATA_ENTRY
|
||||
ULONG Reserved;
|
||||
} PECOFF_IMAGE_RESOURCE_DATA_ENTRY, *PPECOFF_IMAGE_RESOURCE_DATA_ENTRY;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_XTIMAGE_H */
|
||||
|
||||
@@ -28,28 +28,34 @@
|
||||
#include <xtuefi.h>
|
||||
|
||||
/* Low level data types headers */
|
||||
#include <cmtypes.h>
|
||||
#include <extypes.h>
|
||||
#include <hltypes.h>
|
||||
#include <iotypes.h>
|
||||
#include <kdtypes.h>
|
||||
#include <ketypes.h>
|
||||
#include <ldrtypes.h>
|
||||
#include <lpctypes.h>
|
||||
#include <mmtypes.h>
|
||||
#include <obtypes.h>
|
||||
#include <potypes.h>
|
||||
#include <pstypes.h>
|
||||
#include <rtltypes.h>
|
||||
#include <setypes.h>
|
||||
|
||||
/* Architecture-specific low level data types headers */
|
||||
#include ARCH_HEADER(artypes.h)
|
||||
#include ARCH_HEADER(hltypes.h)
|
||||
#include ARCH_HEADER(ketypes.h)
|
||||
#include ARCH_HEADER(mmtypes.h)
|
||||
#include ARCH_HEADER(rtltypes.h)
|
||||
|
||||
/* XT routines */
|
||||
#include <exfuncs.h>
|
||||
#include <hlfuncs.h>
|
||||
#include <kdfuncs.h>
|
||||
#include <kefuncs.h>
|
||||
#include <mmfuncs.h>
|
||||
#include <rtlfuncs.h>
|
||||
|
||||
/* Architecture specific XT routines */
|
||||
|
||||
@@ -48,6 +48,20 @@
|
||||
|
||||
/* XT status code definitions */
|
||||
#define STATUS_SUCCESS ((XTSTATUS) 0x00000000L)
|
||||
#define STATUS_WAIT_0 ((XTSTATUS) 0x00000000L)
|
||||
#define STATUS_WAIT_1 ((XTSTATUS) 0x00000001L)
|
||||
#define STATUS_WAIT_2 ((XTSTATUS) 0x00000002L)
|
||||
#define STATUS_WAIT_3 ((XTSTATUS) 0x00000003L)
|
||||
#define STATUS_WAIT_63 ((XTSTATUS) 0x0000003FL)
|
||||
#define STATUS_ABANDONED ((XTSTATUS) 0x00000080L)
|
||||
#define STATUS_ABANDONED_WAIT_0 ((XTSTATUS) 0x00000080L)
|
||||
#define STATUS_ABANDONED_WAIT_63 ((XTSTATUS) 0x000000BFL)
|
||||
#define STATUS_ALERTED ((XTSTATUS) 0x00000101L)
|
||||
#define STATUS_TIMEOUT ((XTSTATUS) 0x00000102L)
|
||||
#define STATUS_PENDING ((XTSTATUS) 0x00000103L)
|
||||
#define STATUS_REPARSE ((XTSTATUS) 0x00000104L)
|
||||
#define STATUS_DATATYPE_MISALIGNMENT ((XTSTATUS) 0x80000002L)
|
||||
#define STATUS_WAKE_SYSTEM_DEBUGGER ((XTSTATUS) 0x80000007L)
|
||||
#define STATUS_END_OF_MEDIA ((XTSTATUS) 0x8000001EL)
|
||||
#define STATUS_RESOURCE_LOCKED ((XTSTATUS) 0xC0000000L)
|
||||
#define STATUS_UNSUCCESSFUL ((XTSTATUS) 0xC0000001L)
|
||||
@@ -59,13 +73,19 @@
|
||||
#define STATUS_INVALID_PARAMETER ((XTSTATUS) 0xC000000DL)
|
||||
#define STATUS_END_OF_FILE ((XTSTATUS) 0xC0000011L)
|
||||
#define STATUS_NO_MEMORY ((XTSTATUS) 0xC0000017L)
|
||||
#define STATUS_BUFFER_TOO_SMALL ((XTSTATUS) 0xC0000023L)
|
||||
#define STATUS_OBJECT_NAME_INVALID ((XTSTATUS) 0xC0000033L)
|
||||
#define STATUS_OBJECT_NAME_COLLISION ((XTSTATUS) 0xC0000035L)
|
||||
#define STATUS_PORT_DISCONNECTED ((XTSTATUS) 0xC0000037L)
|
||||
#define STATUS_CRC_ERROR ((XTSTATUS) 0xC000003FL)
|
||||
#define STATUS_FLOAT_OVERFLOW ((XTSTATUS) 0xC0000091L)
|
||||
#define STATUS_INTEGER_OVERFLOW ((XTSTATUS) 0xC0000095L)
|
||||
#define STATUS_INSUFFICIENT_RESOURCES ((XTSTATUS) 0xC000009AL)
|
||||
#define STATUS_DEVICE_NOT_READY ((XTSTATUS) 0xC00000A3L)
|
||||
#define STATUS_NOT_SUPPORTED ((XTSTATUS) 0xC00000BBL)
|
||||
#define STATUS_TIMEOUT ((XTSTATUS) 0x00000102L)
|
||||
#define STATUS_NAME_TOO_LONG ((XTSTATUS) 0xC0000106L)
|
||||
#define STATUS_IO_DEVICE_ERROR ((XTSTATUS) 0xC0000185L)
|
||||
#define STATUS_MUTEX_LIMIT_EXCEEDED ((XTSTATUS) 0xC0000191L)
|
||||
#define STATUS_NOT_FOUND ((XTSTATUS) 0xC0000225L)
|
||||
|
||||
#endif /* __XTDK_XTSTATUS_H */
|
||||
|
||||
@@ -12,8 +12,17 @@
|
||||
#include <xtdefs.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Enumeration lists forward references */
|
||||
typedef enum _ADJUST_REASON ADJUST_REASON, *PADJUST_REASON;
|
||||
typedef enum _BUS_QUERY_ID_TYPE BUS_QUERY_ID_TYPE, *PBUS_QUERY_ID_TYPE;
|
||||
typedef enum _DEVICE_POWER_STATE DEVICE_POWER_STATE, *PDEVICE_POWER_STATE;
|
||||
typedef enum _DEVICE_RELATION_TYPE DEVICE_RELATION_TYPE, *PDEVICE_RELATION_TYPE;
|
||||
typedef enum _DEVICE_TEXT_TYPE DEVICE_TEXT_TYPE, *PDEVICE_TEXT_TYPE;
|
||||
typedef enum _DEVICE_USAGE_NOTIFICATION_TYPE DEVICE_USAGE_NOTIFICATION_TYPE, *PDEVICE_USAGE_NOTIFICATION_TYPE;
|
||||
typedef enum _DIRECTORY_NOTIFY_INFORMATION_CLASS DIRECTORY_NOTIFY_INFORMATION_CLASS, *PDIRECTORY_NOTIFY_INFORMATION_CLASS;
|
||||
typedef enum _EXCEPTION_DISPOSITION EXCEPTION_DISPOSITION, *PEXCEPTION_DISPOSITION;
|
||||
typedef enum _EFI_ALLOCATE_TYPE EFI_ALLOCATE_TYPE, *PEFI_ALLOCATE_TYPE;
|
||||
typedef enum _EFI_FRAMEWORK_CPU_DESIGNATION EFI_FRAMEWORK_CPU_DESIGNATION, *PEFI_FRAMEWORK_CPU_DESIGNATION;
|
||||
@@ -38,32 +47,58 @@ typedef enum _EFI_TIMER_DELAY EFI_TIMER_DELAY, *PEFI_TIMER_DELAY;
|
||||
typedef enum _EFI_UART_PARITY_TYPE EFI_UART_PARITY_TYPE, *PEFI_UART_PARITY_TYPE;
|
||||
typedef enum _EFI_UART_STOP_BITS_TYPE EFI_UART_STOP_BITS_TYPE, *PEFI_UART_STOP_BITS_TYPE;
|
||||
typedef enum _EFI_UNIVERSA_GRAPHICS_BLT_OPERATION EFI_UNIVERSA_GRAPHICS_BLT_OPERATION, *PEFI_UNIVERSA_GRAPHICS_BLT_OPERATION;
|
||||
typedef enum _FILE_INFORMATION_CLASS FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
|
||||
typedef enum _FS_INFORMATION_CLASS FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS;
|
||||
typedef enum _HAL_APIC_MODE HAL_APIC_MODE, *PHAL_APIC_MODE;
|
||||
typedef enum _INTERFACE_TYPE INTERFACE_TYPE, *PINTERFACE_TYPE;
|
||||
typedef enum _IO_ALLOCATION_ACTION IO_ALLOCATION_ACTION, *PIO_ALLOCATION_ACTION;
|
||||
typedef enum _IRQ_DEVICE_POLICY IRQ_DEVICE_POLICY, *PIRQ_DEVICE_POLICY;
|
||||
typedef enum _IRQ_PRIORITY IRQ_PRIORITY, *PIRQ_PRIORITY;
|
||||
typedef enum _KAPC_ENVIRONMENT KAPC_ENVIRONMENT, *PKAPC_ENVIRONMENT;
|
||||
typedef enum _KCONTINUE_STATUS KCONTINUE_STATUS, *PKCONTINUE_STATUS;
|
||||
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;
|
||||
typedef enum _KWAIT_REASON KWAIT_REASON, *PKWAIT_REASON;
|
||||
typedef enum _LOADER_MEMORY_TYPE LOADER_MEMORY_TYPE, *PLOADER_MEMORY_TYPE;
|
||||
typedef enum _MMPAGELISTS MMPAGELISTS, *PMMPAGELISTS;
|
||||
typedef enum _MMPFN_CACHE_ATTRIBUTE MMPFN_CACHE_ATTRIBUTE, *PMMPFN_CACHE_ATTRIBUTE;
|
||||
typedef enum _MMPOOL_TYPE MMPOOL_TYPE, *PMMPOOL_TYPE;
|
||||
typedef enum _MMSYSTEM_PTE_POOL_TYPE MMSYSTEM_PTE_POOL_TYPE, *PMMSYSTEM_PTE_POOL_TYPE;
|
||||
typedef enum _MODE MODE, *PMODE;
|
||||
typedef enum _NONPAGED_LOOKASIDE_NUMBER NONPAGED_LOOKASIDE_NUMBER, *PNONPAGED_LOOKASIDE_NUMBER;
|
||||
typedef enum _OBJECT_HEADER_INFO OBJECT_HEADER_INFO, *POBJECT_HEADER_INFO;
|
||||
typedef enum _OBJECT_INFORMATION_CLASS OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;
|
||||
typedef enum _OBJECT_OPEN_REASON OBJECT_OPEN_REASON, *POBJECT_OPEN_REASON;
|
||||
typedef enum _POWER_ACTION POWER_ACTION, *PPOWER_ACTION;
|
||||
typedef enum _POWER_STATE_TYPE POWER_STATE_TYPE, *PPOWER_STATE_TYPE;
|
||||
typedef enum _PS_QUOTA_TYPE PS_QUOTA_TYPE, *PPS_QUOTA_TYPE;
|
||||
typedef enum _RTL_BALANCED_NODE_COLOR RTL_BALANCED_NODE_COLOR, *PRTL_BALANCED_NODE_COLOR;
|
||||
typedef enum _RTL_VARIABLE_TYPE RTL_VARIABLE_TYPE, *PRTL_VARIABLE_TYPE;
|
||||
typedef enum _SECURITY_IMPERSONATION_LEVEL SECURITY_IMPERSONATION_LEVEL, *PSECURITY_IMPERSONATION_LEVEL;
|
||||
typedef enum _SECURITY_OPERATION_CODE SECURITY_OPERATION_CODE, *PSECURITY_OPERATION_CODE;
|
||||
typedef enum _SYSTEM_FIRMWARE_TYPE SYSTEM_FIRMWARE_TYPE, *PSYSTEM_FIRMWARE_TYPE;
|
||||
typedef enum _SYSTEM_POWER_STATE SYSTEM_POWER_STATE, *PSYSTEM_POWER_STATE;
|
||||
typedef enum _SYSTEM_RESOURCE_TYPE SYSTEM_RESOURCE_TYPE, *PSYSTEM_RESOURCE_TYPE;
|
||||
typedef enum _WAIT_TYPE WAIT_TYPE, *PWAIT_TYPE;
|
||||
typedef enum _WORK_QUEUE_TYPE WORK_QUEUE_TYPE, *PWORK_QUEUE_TYPE;
|
||||
|
||||
/* Structures forward references */
|
||||
typedef struct _ACCESS_STATE ACCESS_STATE, *PACCESS_STATE;
|
||||
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_TABLE_LOCAL_APIC ACPI_MADT_TABLE_LOCAL_APIC, *PACPI_MADT_TABLE_LOCAL_APIC;
|
||||
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_RSDP ACPI_RSDP, *PACPI_RSDP;
|
||||
typedef struct _ACPI_RSDT ACPI_RSDT, *PACPI_RSDT;
|
||||
typedef struct _ACPI_SUBTABLE_HEADER ACPI_SUBTABLE_HEADER, *PACPI_SUBTABLE_HEADER;
|
||||
@@ -73,9 +108,21 @@ typedef struct _ACPI_XSDT ACPI_XSDT, *PACPI_XSDT;
|
||||
typedef struct _ANSI_STRING ANSI_STRING, *PANSI_STRING;
|
||||
typedef struct _ANSI_STRING32 ANSI_STRING32, *PANSI_STRING32;
|
||||
typedef struct _ANSI_STRING64 ANSI_STRING64, *PANSI_STRING64;
|
||||
typedef struct _CLIENT_ID CLIENT_ID, *PCLIENT_ID;
|
||||
typedef struct _CM_FULL_RESOURCE_DESCRIPTOR CM_FULL_RESOURCE_DESCRIPTOR, *PCM_FULL_RESOURCE_DESCRIPTOR;
|
||||
typedef struct _CM_PARTIAL_RESOURCE_DESCRIPTOR CM_PARTIAL_RESOURCE_DESCRIPTOR, *PCM_PARTIAL_RESOURCE_DESCRIPTOR;
|
||||
typedef struct _CM_PARTIAL_RESOURCE_LIST CM_PARTIAL_RESOURCE_LIST, *PCM_PARTIAL_RESOURCE_LIST;
|
||||
typedef struct _CM_RESOURCE_LIST CM_RESOURCE_LIST, *PCM_RESOURCE_LIST;
|
||||
typedef struct _COMPRESSED_DATA_INFO COMPRESSED_DATA_INFO, *PCOMPRESSED_DATA_INFO;
|
||||
typedef struct _CPPORT CPPORT, *PCPPORT;
|
||||
typedef const struct _CMMPAGEMAP_ROUTINES CMMPAGEMAP_ROUTINES, *PCMMPAGEMAP_ROUTINES;
|
||||
typedef struct _CPTABLE_INFO CPTABLE_INFO, *PCPTABLE_INFO;
|
||||
typedef struct _CSTRING CSTRING, *PCSTRING;
|
||||
typedef struct _DEVICE_CAPABILITIES DEVICE_CAPABILITIES, *PDEVICE_CAPABILITIES;
|
||||
typedef struct _DEVICE_MAP DEVICE_MAP, *PDEVICE_MAP;
|
||||
typedef struct _DEVICE_OBJECT DEVICE_OBJECT, *PDEVICE_OBJECT;
|
||||
typedef struct _DEVOBJ_EXTENSION DEVOBJ_EXTENSION, *PDEVOBJ_EXTENSION;
|
||||
typedef struct _DRIVER_EXTENSION DRIVER_EXTENSION, *PDRIVER_EXTENSION;
|
||||
typedef struct _DRIVER_OBJECT DRIVER_OBJECT, *PDRIVER_OBJECT;
|
||||
typedef struct _EFI_1394_DEVICE_PATH EFI_1394_DEVICE_PATH, *PEFI_1394_DEVICE_PATH;
|
||||
typedef struct _EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR, *PEFI_ACPI_ADDRESS_SPACE_DESCRIPTOR;
|
||||
typedef struct _EFI_ACPI_ADR_DEVICE_PATH EFI_ACPI_ADR_DEVICE_PATH, *PEFI_ACPI_ADR_DEVICE_PATH;
|
||||
@@ -231,31 +278,58 @@ typedef struct _EFI_VENDOR_DEVICE_PATH EFI_VENDOR_DEVICE_PATH, *PEFI_VENDOR_DEVI
|
||||
typedef struct _EFI_VLAN_DEVICE_PATH EFI_VLAN_DEVICE_PATH, *PEFI_VLAN_DEVICE_PATH;
|
||||
typedef struct _EFI_WORD_REGS EFI_WORD_REGS, *PEFI_WORD_REGS;
|
||||
typedef struct _EPROCESS EPROCESS, *PEPROCESS;
|
||||
typedef struct _EPROCESS_QUOTA_BLOCK EPROCESS_QUOTA_BLOCK, *PEPROCESS_QUOTA_BLOCK;
|
||||
typedef struct _EPROCESS_QUOTA_ENTRY EPROCESS_QUOTA_ENTRY, *PEPROCESS_QUOTA_ENTRY;
|
||||
typedef struct _ERESOURCE ERESOURCE, *PERESOURCE;
|
||||
typedef struct _ETHREAD ETHREAD, *PETHREAD;
|
||||
typedef struct _EX_RUNDOWN_REFERENCE EX_RUNDOWN_REFERENCE, *PEX_RUNDOWN_REFERENCE;
|
||||
typedef struct _EXCEPTION_POINTERS EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
|
||||
typedef struct _EXCEPTION_RECORD EXCEPTION_RECORD, *PEXCEPTION_RECORD;
|
||||
typedef struct _EXCEPTION_REGISTRATION_RECORD EXCEPTION_REGISTRATION_RECORD, *PEXCEPTION_REGISTRATION_RECORD;
|
||||
typedef struct _FAST_IO_DISPATCH FAST_IO_DISPATCH, *PFAST_IO_DISPATCH;
|
||||
typedef struct _FILE_BASIC_INFORMATION FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
|
||||
typedef struct _FILE_GET_QUOTA_INFORMATION FILE_GET_QUOTA_INFORMATION, *PFILE_GET_QUOTA_INFORMATION;
|
||||
typedef struct _FILE_NETWORK_OPEN_INFORMATION FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION;
|
||||
typedef struct _FILE_OBJECT FILE_OBJECT, *PFILE_OBJECT;
|
||||
typedef struct _FILE_STANDARD_INFORMATION FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;
|
||||
typedef struct _FIRMWARE_INFORMATION_BLOCK FIRMWARE_INFORMATION_BLOCK, *PFIRMWARE_INFORMATION_BLOCK;
|
||||
typedef struct _FLOAT128 FLOAT128, *PFLOAT128;
|
||||
typedef struct _GENERAL_LOOKASIDE GENERAL_LOOKASIDE, *PGENERAL_LOOKASIDE;
|
||||
typedef struct _GENERIC_ADDRESS GENERIC_ADDRESS, *PGENERIC_ADDRESS;
|
||||
typedef struct _GENERIC_MAPPING GENERIC_MAPPING, *PGENERIC_MAPPING;
|
||||
typedef struct _GUID GUID, *PGUID;
|
||||
typedef struct _HL_FRAMEBUFFER_DATA HL_FRAMEBUFFER_DATA, *PHL_FRAMEBUFFER_DATA;
|
||||
typedef struct _HL_SCROLL_REGION_DATA HL_SCROLL_REGION_DATA, *PHL_SCROLL_REGION_DATA;
|
||||
typedef struct _INITIAL_PRIVILEGE_SET INITIAL_PRIVILEGE_SET, *PINITIAL_PRIVILEGE_SET;
|
||||
typedef struct _INTERFACE INTERFACE, *PINTERFACE;
|
||||
typedef struct _IO_COMPLETION_CONTEXT IO_COMPLETION_CONTEXT, *PIO_COMPLETION_CONTEXT;
|
||||
typedef struct _IO_RESOURCE_DESCRIPTOR IO_RESOURCE_DESCRIPTOR, *PIO_RESOURCE_DESCRIPTOR;
|
||||
typedef struct _IO_RESOURCE_LIST IO_RESOURCE_LIST, *PIO_RESOURCE_LIST;
|
||||
typedef struct _IO_RESOURCE_REQUIREMENTS_LIST IO_RESOURCE_REQUIREMENTS_LIST, *PIO_RESOURCE_REQUIREMENTS_LIST;
|
||||
typedef struct _IO_SECURITY_CONTEXT IO_SECURITY_CONTEXT, *PIO_SECURITY_CONTEXT;
|
||||
typedef struct _IO_STACK_LOCATION IO_STACK_LOCATION, *PIO_STACK_LOCATION;
|
||||
typedef struct _IO_STATUS_BLOCK IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
|
||||
typedef struct _IO_TIMER IO_TIMER, *PIO_TIMER;
|
||||
typedef struct _IRP IRP, *PIRP;
|
||||
typedef struct _KAFFINITY_MAP KAFFINITY_MAP, *PKAFFINITY_MAP;
|
||||
typedef struct _KAPC KAPC, *PKAPC;
|
||||
typedef struct _KAPC_STATE KAPC_STATE, *PKAPC_STATE;
|
||||
typedef struct _KD_DEBUG_MODE KD_DEBUG_MODE, *PKD_DEBUG_MODE;
|
||||
typedef struct _KD_DISPATCH_TABLE KD_DISPATCH_TABLE, *PKD_DISPATCH_TABLE;
|
||||
typedef struct _KDPC KDPC, *PKDPC;
|
||||
typedef struct _KDPC_DATA KDPC_DATA, *PKDPC_DATA;
|
||||
typedef struct _KDEVICE_QUEUE_ENTRY KDEVICE_QUEUE_ENTRY, *PKDEVICE_QUEUE_ENTRY;
|
||||
typedef struct _KERNEL_INITIALIZATION_BLOCK KERNEL_INITIALIZATION_BLOCK, *PKERNEL_INITIALIZATION_BLOCK;
|
||||
typedef struct _KEVENT KEVENT, *PKEVENT;
|
||||
typedef struct _KGATE KGATE, *PKGATE;
|
||||
typedef struct _KLOCK_QUEUE_HANDLE KLOCK_QUEUE_HANDLE, *PKLOCK_QUEUE_HANDLE;
|
||||
typedef struct _KMUTEX KMUTEX, *PKMUTEX;
|
||||
typedef struct _KPROCESS KPROCESS, *PKPROCESS;
|
||||
typedef struct _KPUSH_LOCK_WAIT_BLOCK KPUSH_LOCK_WAIT_BLOCK, *PKPUSH_LOCK_WAIT_BLOCK;
|
||||
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;
|
||||
@@ -276,12 +350,48 @@ typedef struct _LIST_ENTRY64 LIST_ENTRY64, *PLIST_ENTRY64;
|
||||
typedef struct _LOADER_GRAPHICS_INFORMATION_BLOCK LOADER_GRAPHICS_INFORMATION_BLOCK, *PLOADER_GRAPHICS_INFORMATION_BLOCK;
|
||||
typedef struct _LOADER_INFORMATION_BLOCK LOADER_INFORMATION_BLOCK, *PLOADER_INFORMATION_BLOCK;
|
||||
typedef struct _LOADER_MEMORY_DESCRIPTOR LOADER_MEMORY_DESCRIPTOR, *PLOADER_MEMORY_DESCRIPTOR;
|
||||
typedef struct _LOOKASIDE_LIST LOOKASIDE_LIST, *PLOOKASIDE_LIST;
|
||||
typedef struct _LOOKASIDE_LIST_EX LOOKASIDE_LIST_EX, *PLOOKASIDE_LIST_EX;
|
||||
typedef struct _LPCP_NONPAGED_PORT_QUEUE LPCP_NONPAGED_PORT_QUEUE, *PLPCP_NONPAGED_PORT_QUEUE;
|
||||
typedef struct _LPCP_PORT_OBJECT LPCP_PORT_OBJECT, *PLPCP_PORT_OBJECT;
|
||||
typedef struct _LPCP_PORT_QUEUE LPCP_PORT_QUEUE, *PLPCP_PORT_QUEUE;
|
||||
typedef struct _LUID LUID, *PLUID;
|
||||
typedef struct _LUID_AND_ATTRIBUTES LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES;
|
||||
typedef struct _M128 M128, *PM128;
|
||||
typedef struct _MAILSLOT_CREATE_PARAMETERS MAILSLOT_CREATE_PARAMETERS, *PMAILSLOT_CREATE_PARAMETERS;
|
||||
typedef struct _MDL MDL, *PMDL;
|
||||
typedef struct _MMCOLOR_TABLES MMCOLOR_TABLES, *PMMCOLOR_TABLES;
|
||||
typedef struct _MMFREE_POOL_ENTRY MMFREE_POOL_ENTRY, *PMMFREE_POOL_ENTRY;
|
||||
typedef struct _MMMEMORY_LAYOUT MMMEMORY_LAYOUT, *PMMMEMORY_LAYOUT;
|
||||
typedef struct _MMPFNENTRY MMPFNENTRY, *PMMPFNENTRY;
|
||||
typedef struct _MMPFNLIST MMPFNLIST, *PMMPFNLIST;
|
||||
typedef struct _NAMED_PIPE_CREATE_PARAMETERS NAMED_PIPE_CREATE_PARAMETERS, *PNAMED_PIPE_CREATE_PARAMETERS;
|
||||
typedef struct _NLSTABLE_INFO NLSTABLE_INFO, *PNLSTABLE_INFO;
|
||||
typedef struct _NONPAGED_LOOKASIDE_LIST NONPAGED_LOOKASIDE_LIST, *PNONPAGED_LOOKASIDE_LIST;
|
||||
typedef struct _OBJECT_ATTRIBUTES OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
|
||||
typedef struct _OBJECT_CREATE_INFORMATION OBJECT_CREATE_INFORMATION, *POBJECT_CREATE_INFORMATION;
|
||||
typedef struct _OBJECT_CREATOR_INFO OBJECT_CREATOR_INFO, *POBJECT_CREATOR_INFO;
|
||||
typedef struct _OBJECT_DIRECTORY OBJECT_DIRECTORY, *POBJECT_DIRECTORY;
|
||||
typedef struct _OBJECT_DIRECTORY_ENTRY OBJECT_DIRECTORY_ENTRY, *POBJECT_DIRECTORY_ENTRY;
|
||||
typedef struct _OBJECT_DUMP_CONTROL OBJECT_DUMP_CONTROL, *POBJECT_DUMP_CONTROL;
|
||||
typedef struct _OBJECT_HANDLE_COUNT_DATABASE OBJECT_HANDLE_COUNT_DATABASE, *POBJECT_HANDLE_COUNT_DATABASE;
|
||||
typedef struct _OBJECT_HANDLE_COUNT_ENTRY OBJECT_HANDLE_COUNT_ENTRY, *POBJECT_HANDLE_COUNT_ENTRY;
|
||||
typedef struct _OBJECT_HANDLE_COUNT_INFORMATION OBJECT_HANDLE_COUNT_INFORMATION, *POBJECT_HANDLE_COUNT_INFORMATION;
|
||||
typedef struct _OBJECT_HANDLE_INFO OBJECT_HANDLE_INFO, *POBJECT_HANDLE_INFO;
|
||||
typedef struct _OBJECT_HEADER OBJECT_HEADER, *POBJECT_HEADER;
|
||||
typedef struct _OBJECT_HEADER_CREATOR_INFO OBJECT_HEADER_CREATOR_INFO, *POBJECT_HEADER_CREATOR_INFO;
|
||||
typedef struct _OBJECT_HEADER_NAME_INFO OBJECT_HEADER_NAME_INFO, *POBJECT_HEADER_NAME_INFO;
|
||||
typedef struct _OBJECT_HEADER_QUOTA_INFO OBJECT_HEADER_QUOTA_INFO, *POBJECT_HEADER_QUOTA_INFO;
|
||||
typedef struct _OBJECT_LOOKUP_CONTEXT OBJECT_LOOKUP_CONTEXT, *POBJECT_LOOKUP_CONTEXT;
|
||||
typedef struct _OBJECT_NAME_INFO OBJECT_NAME_INFO, *POBJECT_NAME_INFO;
|
||||
typedef struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
|
||||
typedef struct _OBJECT_OPTIONAL_HEADER_LAYOUT OBJECT_OPTIONAL_HEADER_LAYOUT, *POBJECT_OPTIONAL_HEADER_LAYOUT;
|
||||
typedef struct _OBJECT_PROCESS_INFO OBJECT_PROCESS_INFO, *POBJECT_PROCESS_INFO;
|
||||
typedef struct _OBJECT_QUOTA_INFO OBJECT_QUOTA_INFO, *POBJECT_QUOTA_INFO;
|
||||
typedef struct _OBJECT_TYPE OBJECT_TYPE, *POBJECT_TYPE;
|
||||
typedef struct _OBJECT_TYPE_INITIALIZER OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;
|
||||
typedef struct _OWNER_ENTRY OWNER_ENTRY, *POWNER_ENTRY;
|
||||
typedef struct _PAGED_LOOKASIDE_LIST PAGED_LOOKASIDE_LIST, *PPAGED_LOOKASIDE_LIST;
|
||||
typedef struct _PCAT_FIRMWARE_INFORMATION PCAT_FIRMWARE_INFORMATION, *PPCAT_FIRMWARE_INFORMATION;
|
||||
typedef struct _PCI_BRIDGE_CONTROL_REGISTER PCI_BRIDGE_CONTROL_REGISTER, *PPCI_BRIDGE_CONTROL_REGISTER;
|
||||
typedef struct _PCI_COMMON_CONFIG PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG;
|
||||
@@ -315,22 +425,41 @@ typedef struct _PHYSICAL_MEMORY_RUN PHYSICAL_MEMORY_RUN, *PPHYSICAL_MEMORY_RUN;
|
||||
typedef struct _POOL_HEADER POOL_HEADER, *PPOOL_HEADER;
|
||||
typedef struct _POOL_TRACKING_BIG_ALLOCATIONS POOL_TRACKING_BIG_ALLOCATIONS, *PPOOL_TRACKING_BIG_ALLOCATIONS;
|
||||
typedef struct _POOL_TRACKING_TABLE POOL_TRACKING_TABLE, *PPOOL_TRACKING_TABLE;
|
||||
typedef struct _POWER_SEQUENCE POWER_SEQUENCE, *PPOWER_SEQUENCE;
|
||||
typedef struct _PRIVILEGE_SET PRIVILEGE_SET, *PPRIVILEGE_SET;
|
||||
typedef struct _PROCESSOR_IDENTITY PROCESSOR_IDENTITY, *PPROCESSOR_IDENTITY;
|
||||
typedef struct _PROCESSOR_POWER_STATE PROCESSOR_POWER_STATE, *PPROCESSOR_POWER_STATE;
|
||||
typedef struct _QUAD QUAD, *PQUAD;
|
||||
typedef struct _RTL_BALANCED_NODE RTL_BALANCED_NODE, *PRTL_BALANCED_NODE;
|
||||
typedef struct _RTL_BITMAP RTL_BITMAP, *PRTL_BITMAP;
|
||||
typedef struct _RTL_PRINT_CONTEXT RTL_PRINT_CONTEXT, *PRTL_PRINT_CONTEXT;
|
||||
typedef struct _RTL_PRINT_FORMAT_PROPERTIES RTL_PRINT_FORMAT_PROPERTIES, *PRTL_PRINT_FORMAT_PROPERTIES;
|
||||
typedef struct _RTL_RB_TREE RTL_RB_TREE, *PRTL_RB_TREE;
|
||||
typedef struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK, *PSCSI_REQUEST_BLOCK;
|
||||
typedef struct _SECTION_OBJECT_POINTERS SECTION_OBJECT_POINTERS, *PSECTION_OBJECT_POINTERS;
|
||||
typedef struct _SECURITY_CLIENT_CONTEXT SECURITY_CLIENT_CONTEXT, *PSECURITY_CLIENT_CONTEXT;
|
||||
typedef struct _SECURITY_QUALITY_OF_SERVICE SECURITY_QUALITY_OF_SERVICE, *PSECURITY_QUALITY_OF_SERVICE;
|
||||
typedef struct _SECURITY_SUBJECT_CONTEXT SECURITY_SUBJECT_CONTEXT, *PSECURITY_SUBJECT_CONTEXT;
|
||||
typedef struct _SID SID, *PSID;
|
||||
typedef struct _SID_IDENTIFIER_AUTHORITY SID_IDENTIFIER_AUTHORITY, *PSID_IDENTIFIER_AUTHORITY;
|
||||
typedef struct _SINGLE_LIST_ENTRY SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;
|
||||
typedef struct _SMBIOS_TABLE_HEADER SMBIOS_TABLE_HEADER, *PSMBIOS_TABLE_HEADER;
|
||||
typedef struct _SMBIOS3_TABLE_HEADER SMBIOS3_TABLE_HEADER, *PSMBIOS3_TABLE_HEADER;
|
||||
typedef struct _STRING STRING, *PSTRING;
|
||||
typedef struct _STRING32 STRING32, *PSTRING32;
|
||||
typedef struct _STRING64 STRING64, *PSTRING64;
|
||||
typedef struct _SYSTEM_POWER_STATE_CONTEXT SYSTEM_POWER_STATE_CONTEXT, *PSYSTEM_POWER_STATE_CONTEXT;
|
||||
typedef struct _THREAD_INFORMATION_BLOCK THREAD_INFORMATION_BLOCK, *PTHREAD_INFORMATION_BLOCK;
|
||||
typedef struct _TIME_FIELDS TIME_FIELDS, *PTIME_FIELDS;
|
||||
typedef struct _TIMER_ROUTINES TIMER_ROUTINES, *PTIMER_ROUTINES;
|
||||
typedef struct _TOKEN_CONTROL TOKEN_CONTROL, *PTOKEN_CONTROL;
|
||||
typedef struct _TOKEN_SOURCE TOKEN_SOURCE, *PTOKEN_SOURCE;
|
||||
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;
|
||||
typedef struct _UNICODE_STRING64 UNICODE_STRING64, *PUNICODE_STRING64;
|
||||
typedef struct _VPB VPB, *PVPB;
|
||||
typedef struct _WORK_QUEUE_ITEM WORK_QUEUE_ITEM, *PWORK_QUEUE_ITEM;
|
||||
typedef struct _XTBL_BOOT_PARAMETERS XTBL_BOOT_PARAMETERS, *PXTBL_BOOT_PARAMETERS;
|
||||
typedef struct _XTBL_BOOT_PROTOCOL XTBL_BOOT_PROTOCOL, *PXTBL_BOOT_PROTOCOL;
|
||||
typedef struct _XTBL_BOOTMENU_ITEM XTBL_BOOTMENU_ITEM, *PXTBL_BOOTMENU_ITEM;
|
||||
@@ -359,8 +488,12 @@ typedef union _EFI_HASH_OUTPUT EFI_HASH_OUTPUT, *PEFI_HASH_OUTPUT;
|
||||
typedef union _EFI_IA32_REGISTER_SET EFI_IA32_REGISTER_SET, *PEFI_IA32_REGISTER_SET;
|
||||
typedef union _EFI_IP_ADDRESS EFI_IP_ADDRESS, *PEFI_IP_ADDRESS;
|
||||
typedef union _EFI_PXE_BASE_CODE_PACKET EFI_PXE_BASE_CODE_PACKET, *PEFI_PXE_BASE_CODE_PACKET;
|
||||
typedef union _EX_RUNDOWN_REFERENCE EX_RUNDOWN_REFERENCE, *PEX_RUNDOWN_REFERENCE;
|
||||
typedef union _KPUSH_LOCK KPUSH_LOCK, *PKPUSH_LOCK;
|
||||
typedef union _LARGE_INTEGER LARGE_INTEGER, *PLARGE_INTEGER;
|
||||
typedef union _SINGLE_LIST_HEADER SINGLE_LIST_HEADER, *PSINGLE_LIST_HEADER;
|
||||
typedef union _OBJECT_HEADER_HANDLE_INFO OBJECT_HEADER_HANDLE_INFO, *POBJECT_HEADER_HANDLE_INFO;
|
||||
typedef union _POWER_STATE POWER_STATE, *PPOWER_STATE;
|
||||
typedef union _ULARGE_INTEGER ULARGE_INTEGER, *PULARGE_INTEGER;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_XTSTRUCT_H */
|
||||
|
||||
@@ -11,8 +11,12 @@
|
||||
|
||||
#include <xttarget.h>
|
||||
#include <xtcompat.h>
|
||||
#include <xtstruct.h>
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Standard C types */
|
||||
typedef unsigned char BYTE, *PBYTE, *LPBYTE;
|
||||
typedef char CHAR, *PCHAR, *LPCHAR;
|
||||
@@ -150,6 +154,44 @@ typedef LPCWSTR PCTSTR, LPCTSTR;
|
||||
typedef LPUWSTR PUTSTR, LPUTSTR;
|
||||
typedef LPCUWSTR PCUTSTR, LPCUTSTR;
|
||||
|
||||
/* Variadic ABI types */
|
||||
typedef __builtin_va_list VA_LIST, *PVA_LIST;
|
||||
|
||||
/* ANSI string structure */
|
||||
typedef struct _ANSI_STRING
|
||||
{
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
PSTR Buffer;
|
||||
} ANSI_STRING, *PANSI_STRING;
|
||||
typedef const ANSI_STRING *PCANSI_STRING;
|
||||
|
||||
/* 32-bit ANSI string structure */
|
||||
typedef struct _ANSI_STRING32
|
||||
{
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
ULONG Buffer;
|
||||
} ANSI_STRING32, *PANSI_STRING32;
|
||||
typedef const ANSI_STRING32 *PCANSI_STRING32;
|
||||
|
||||
/* 64-bit ANSI string structure */
|
||||
typedef struct _ANSI_STRING64
|
||||
{
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
ULONGLONG Buffer;
|
||||
} ANSI_STRING64, *PANSI_STRING64;
|
||||
typedef const ANSI_STRING64 *PCANSI_STRING64;
|
||||
|
||||
/* Constant counted string structure */
|
||||
typedef struct _CSTRING
|
||||
{
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
PCCHAR Buffer;
|
||||
} CSTRING, *PCSTRING;
|
||||
|
||||
/* 128-bit floats structure */
|
||||
typedef struct _FLOAT128
|
||||
{
|
||||
@@ -185,21 +227,32 @@ typedef union _LARGE_INTEGER
|
||||
LONGLONG QuadPart;
|
||||
} LARGE_INTEGER, *PLARGE_INTEGER;
|
||||
|
||||
/* 64-bit unsigned integer union */
|
||||
typedef union _ULARGE_INTEGER
|
||||
/* Double linked list structure definition */
|
||||
typedef struct _LIST_ENTRY
|
||||
{
|
||||
struct
|
||||
{
|
||||
ULONG LowPart;
|
||||
ULONG HighPart;
|
||||
};
|
||||
struct
|
||||
{
|
||||
ULONG LowPart;
|
||||
ULONG HighPart;
|
||||
} u;
|
||||
ULONGLONG QuadPart;
|
||||
} ULARGE_INTEGER, *PULARGE_INTEGER;
|
||||
PLIST_ENTRY Flink;
|
||||
PLIST_ENTRY Blink;
|
||||
} LIST_ENTRY, *PLIST_ENTRY;
|
||||
|
||||
/* Locally Unique Identifier structure definition */
|
||||
typedef struct _LUID
|
||||
{
|
||||
ULONG LowPart;
|
||||
LONG HighPart;
|
||||
} LUID, *PLUID;
|
||||
|
||||
/* 128-bit 16-byte aligned XMM register */
|
||||
typedef struct _M128
|
||||
{
|
||||
ULONGLONG Low;
|
||||
LONGLONG High;
|
||||
} ALIGN(16) M128, *PM128;
|
||||
|
||||
/* Quadruple-word alignment structure definition */
|
||||
typedef struct _QUAD
|
||||
{
|
||||
unsigned long long Alignment;
|
||||
} QUAD, *PQUAD;
|
||||
|
||||
/* Counted string structure */
|
||||
typedef struct _STRING
|
||||
@@ -225,40 +278,21 @@ typedef struct _STRING64
|
||||
ULONGLONG Buffer;
|
||||
} STRING64, *PSTRING64;
|
||||
|
||||
/* Constant counted string structure */
|
||||
typedef struct _CSTRING
|
||||
/* 64-bit unsigned integer union */
|
||||
typedef union _ULARGE_INTEGER
|
||||
{
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
PCCHAR Buffer;
|
||||
} CSTRING, *PCSTRING;
|
||||
|
||||
/* ANSI string structure */
|
||||
typedef struct _ANSI_STRING
|
||||
{
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
PSTR Buffer;
|
||||
} ANSI_STRING, *PANSI_STRING;
|
||||
typedef const ANSI_STRING *PCANSI_STRING;
|
||||
|
||||
/* 32-bit ANSI string structure */
|
||||
typedef struct _ANSI_STRING32
|
||||
{
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
ULONG Buffer;
|
||||
} ANSI_STRING32, *PANSI_STRING32;
|
||||
typedef const ANSI_STRING32 *PCANSI_STRING32;
|
||||
|
||||
/* 64-bit ANSI string structure */
|
||||
typedef struct _ANSI_STRING64
|
||||
{
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
ULONGLONG Buffer;
|
||||
} ANSI_STRING64, *PANSI_STRING64;
|
||||
typedef const ANSI_STRING64 *PCANSI_STRING64;
|
||||
struct
|
||||
{
|
||||
ULONG LowPart;
|
||||
ULONG HighPart;
|
||||
};
|
||||
struct
|
||||
{
|
||||
ULONG LowPart;
|
||||
ULONG HighPart;
|
||||
} u;
|
||||
ULONGLONG QuadPart;
|
||||
} ULARGE_INTEGER, *PULARGE_INTEGER;
|
||||
|
||||
/* UNICODE string structure */
|
||||
typedef struct _UNICODE_STRING
|
||||
@@ -287,4 +321,5 @@ typedef struct _UNICODE_STRING64
|
||||
} UNICODE_STRING64, *PUNICODE_STRING64;
|
||||
typedef const UNICODE_STRING64 *PCUNICODE_STRING64;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_XTTYPES_H */
|
||||
|
||||
@@ -373,6 +373,10 @@
|
||||
#define EFI_CONFIG_TABLE_SMBIOS_TABLE_GUID {0xEB9D2D31, 0x2D88, 0x11D3, {0x9A, 0x16, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}}
|
||||
#define EFI_CONFIG_TABLE_SMBIOS3_TABLE_GUID {0xF2FD1544, 0x9794, 0x4A2C, {0x99, 0x2E, 0xE5, 0xBB, 0xCf, 0x20, 0xE3, 0x94}}
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
/* Basic UEFI types */
|
||||
typedef PVOID EFI_EVENT, *PEFI_EVENT;
|
||||
typedef PVOID EFI_HANDLE, *PEFI_HANDLE;
|
||||
@@ -2723,4 +2727,5 @@ typedef struct _EFI_PROCESSOR_INFORMATION
|
||||
EFI_PROCESSOR_PHYSICAL_LOCATION Location;
|
||||
} EFI_PROCESSOR_INFORMATION, *PEFI_PROCESSOR_INFORMATION;
|
||||
|
||||
#endif /* __XTOS_ASSEMBLER__ */
|
||||
#endif /* __XTDK_XTUEFI_H */
|
||||
|
||||
@@ -10,17 +10,23 @@ 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
|
||||
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/traps.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ex/data.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ex/exports.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ex/laslist.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ex/resource.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ex/rundown.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/cpu.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/pic.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/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}/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
|
||||
@@ -28,28 +34,39 @@ list(APPEND XTOSKRNL_SOURCE
|
||||
${XTOSKRNL_SOURCE_DIR}/hl/fbdev.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/hl/init.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/hl/ioreg.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/kd/${ARCH}/debug.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/kd/data.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/kd/dbgio.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/kd/debug.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/kd/exports.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/irq.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/dispatch.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/krnlinit.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/kthread.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/proc.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/affinity.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/apc.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/bootinfo.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/crash.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/data.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/dispatch.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/dispobj.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/dpc.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/event.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/exports.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/ipi.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/kprocess.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/krnlinit.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/kthread.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/kubsan.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/pushlock.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/runlevel.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ke/schedule.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/sysserv.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
|
||||
@@ -61,44 +78,57 @@ 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
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/paging.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/pfn.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/pool.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/probe.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/pte.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/mm/quota.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/po/idle.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ps/process.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/ps/thread.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/atomic.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/${ARCH}/slist.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/atomic.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/bitmap.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/data.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/endian.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/exports.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/exsup.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/guid.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/lifo.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/llist.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/math.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/memory.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/nls.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/rbtree.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/sha1.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/slist.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/string.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/widestr.cc)
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/time.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/unicode.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/widestr.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/se/descript.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/se/privileg.cc)
|
||||
|
||||
# Set module definition SPEC file
|
||||
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)
|
||||
|
||||
@@ -11,9 +11,23 @@ These parameters can be configured either temporarily by editing the boot entry
|
||||
permanently by modifying the XTLDR configuration file.
|
||||
|
||||
The following is a consolidated list of available kernel parameters:
|
||||
* **CLOCK**: Specifies the primary hardware source used to drive the periodic system clock interrupts and the thread
|
||||
scheduler tick. Valid values include `LAPIC` (Local APIC Timer), `HPET` (High Precision Event Timer), and `PIT`
|
||||
(Legacy Programmable Interval Timer). If this parameter is omitted, the kernel will autonomously probe the hardware
|
||||
and select the most optimal clock source for the current CPU topology, (defaulting to the Local APIC on modern systems.
|
||||
* **MAXCPUS**: Specifies the maximum number of logical processors the kernel is allowed to initialize and schedule.
|
||||
Setting `MAXCPUS=1` explicitly disables Symmetric Multiprocessing (SMP), restricting execution exclusively to the Boot
|
||||
Strap Processor (BSP) and ignoring all Application Processors (APs).
|
||||
* **NOX2APIC**: Explicitly disables x2APIC support. When specified, the kernel bypasses hardware feature detection for
|
||||
x2APIC and forces the use of the classic, memory-mapped (MMIO) xAPIC mode. This parameter is particularly useful for
|
||||
troubleshooting interrupt routing issues or ensuring compatibility with specific hypervisors and legacy emulators.
|
||||
* **NOXPA**: Disables PAE or LA57 support, depending on the CPU architecture. This parameter is handled by the
|
||||
bootloader, which configures paging and selects the appropriate Page Map Level (PML) before transferring control to
|
||||
the kernel.
|
||||
* **TIMER**: Designates the hardware counter used for high-resolution performance tracking (Query Performance Counter)
|
||||
and microsecond execution stalls. Valid values include `TSC` (Invariant Time Stamp Counter), `HPET`, `ACPI` (or `PM`)
|
||||
for the ACPI Power Management Timer, and `PIT`. If not specified, the kernel evaluates hardware capabilities and
|
||||
defaults to the most precise and reliable counter available (e.g., Invariant TSC).
|
||||
|
||||
## Source Code
|
||||
The source code of the kernel is organized into subsystem-specific directories. Each directory name also defines the
|
||||
@@ -26,6 +40,7 @@ corresponding C++ namespace in which the subsystem's classes and routines reside
|
||||
* Ke - Core Kernel Library
|
||||
* Mm - Memory Manager
|
||||
* Po - Plug&Play and Power Manager
|
||||
* Ps - Process and Thread Manager
|
||||
* Rtl - Runtime library
|
||||
|
||||
### AR: Architecture Library
|
||||
@@ -62,6 +77,12 @@ This subsystem handles power management events, such as shutdown or standby. It
|
||||
supporting device detection and installation at boot time. Furthermore, it is responsible for starting and stopping
|
||||
devices on demand.
|
||||
|
||||
### PS: Process and Thread Manager
|
||||
This subsystem is responsible for managing the lifecycle of processes and threads within the operating system. It
|
||||
handles the creation, termination, and state tracking of these execution units. Furthermore, it provides the high-level
|
||||
executive abstractions required to allocate system resources, manage process boundaries, and coordinate with the core
|
||||
kernel for thread execution.
|
||||
|
||||
### RTL: Runtime Library
|
||||
The Runtime Library provides a kernel-mode implementation of common C library functions. It includes many utility
|
||||
routines, for use by other kernel components.
|
||||
|
||||
@@ -4,29 +4,40 @@
|
||||
* FILE: xtoskrnl/ar/amd64/archsup.S
|
||||
* DESCRIPTION: Provides AMD64 architecture features not implementable in C
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <ar/amd64/asmsup.h>
|
||||
#include <xtkmapi.h>
|
||||
#include <xtadk.h>
|
||||
|
||||
.altmacro
|
||||
.text
|
||||
|
||||
|
||||
/**
|
||||
* Creates a trap handler for the specified vector.
|
||||
* Creates a trap or interrupt handler for the specified vector.
|
||||
*
|
||||
* @param Vector
|
||||
* Supplies a trap vector number.
|
||||
* Supplies a trap/interrupt vector number.
|
||||
*
|
||||
* @param Type
|
||||
* Specifies whether the handler is designed to handle an interrupt or a trap.
|
||||
*
|
||||
* @return This macro does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.macro ArCreateTrapHandler Vector
|
||||
.global ArTrap\Vector
|
||||
ArTrap\Vector:
|
||||
/* Push fake error code for non-error vectors */
|
||||
.if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
|
||||
.macro ArCreateHandler Vector Type
|
||||
.global Ar\Type\Vector
|
||||
Ar\Type\Vector:
|
||||
/* Check handler type */
|
||||
.ifc \Type,Trap
|
||||
/* Push fake error code for non-error vector traps */
|
||||
.if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
|
||||
push $0
|
||||
.endif
|
||||
.else
|
||||
/* Push fake error code for interrupts */
|
||||
push $0
|
||||
.endif
|
||||
|
||||
@@ -51,113 +62,122 @@ ArTrap\Vector:
|
||||
push %rax
|
||||
|
||||
/* Reserve space for other registers and point RBP to the trap frame */
|
||||
sub $(TRAP_FRAME_SIZE - TRAP_REGISTERS_SIZE), %rsp
|
||||
sub $(KTRAP_FRAME_SIZE - KTRAP_FRAME_REGISTERS_SIZE), %rsp
|
||||
lea (%rsp), %rbp
|
||||
|
||||
/* Store segment selectors */
|
||||
mov %gs, TrapSegGs(%rbp)
|
||||
mov %fs, TrapSegFs(%rbp)
|
||||
mov %es, TrapSegEs(%rbp)
|
||||
mov %ds, TrapSegDs(%rbp)
|
||||
mov %gs, KTRAP_FRAME_SegGs(%rbp)
|
||||
mov %fs, KTRAP_FRAME_SegFs(%rbp)
|
||||
mov %es, KTRAP_FRAME_SegEs(%rbp)
|
||||
mov %ds, KTRAP_FRAME_SegDs(%rbp)
|
||||
|
||||
/* Store debug registers */
|
||||
mov %dr7, %rax
|
||||
mov %rax, TrapDr7(%rbp)
|
||||
mov %rax, KTRAP_FRAME_Dr7(%rbp)
|
||||
mov %dr6, %rax
|
||||
mov %rax, TrapDr6(%rbp)
|
||||
mov %rax, KTRAP_FRAME_Dr6(%rbp)
|
||||
mov %dr3, %rax
|
||||
mov %rax, TrapDr3(%rbp)
|
||||
mov %rax, KTRAP_FRAME_Dr3(%rbp)
|
||||
mov %dr2, %rax
|
||||
mov %rax, TrapDr2(%rbp)
|
||||
mov %rax, KTRAP_FRAME_Dr2(%rbp)
|
||||
mov %dr1, %rax
|
||||
mov %rax, TrapDr1(%rbp)
|
||||
mov %rax, KTRAP_FRAME_Dr1(%rbp)
|
||||
mov %dr0, %rax
|
||||
mov %rax, TrapDr0(%rbp)
|
||||
mov %rax, KTRAP_FRAME_Dr0(%rbp)
|
||||
|
||||
/* Store CR2 and CR3 */
|
||||
mov %cr3, %rax
|
||||
mov %rax, TrapCr3(%rbp)
|
||||
mov %rax, KTRAP_FRAME_Cr3(%rbp)
|
||||
mov %cr2, %rax
|
||||
mov %rax, TrapCr2(%rbp)
|
||||
mov %rax, KTRAP_FRAME_Cr2(%rbp)
|
||||
|
||||
/* Store MxCsr register */
|
||||
stmxcsr TrapMxCsr(%rbp)
|
||||
stmxcsr KTRAP_FRAME_MxCsr(%rbp)
|
||||
|
||||
/* Store XMM registers */
|
||||
movdqa %xmm15, TrapXmm15(%rbp)
|
||||
movdqa %xmm14, TrapXmm14(%rbp)
|
||||
movdqa %xmm13, TrapXmm13(%rbp)
|
||||
movdqa %xmm12, TrapXmm12(%rbp)
|
||||
movdqa %xmm11, TrapXmm11(%rbp)
|
||||
movdqa %xmm10, TrapXmm10(%rbp)
|
||||
movdqa %xmm9, TrapXmm9(%rbp)
|
||||
movdqa %xmm8, TrapXmm8(%rbp)
|
||||
movdqa %xmm7, TrapXmm7(%rbp)
|
||||
movdqa %xmm6, TrapXmm6(%rbp)
|
||||
movdqa %xmm5, TrapXmm5(%rbp)
|
||||
movdqa %xmm4, TrapXmm4(%rbp)
|
||||
movdqa %xmm3, TrapXmm3(%rbp)
|
||||
movdqa %xmm2, TrapXmm2(%rbp)
|
||||
movdqa %xmm1, TrapXmm1(%rbp)
|
||||
movdqa %xmm0, TrapXmm0(%rbp)
|
||||
movdqa %xmm15, KTRAP_FRAME_Xmm15(%rbp)
|
||||
movdqa %xmm14, KTRAP_FRAME_Xmm14(%rbp)
|
||||
movdqa %xmm13, KTRAP_FRAME_Xmm13(%rbp)
|
||||
movdqa %xmm12, KTRAP_FRAME_Xmm12(%rbp)
|
||||
movdqa %xmm11, KTRAP_FRAME_Xmm11(%rbp)
|
||||
movdqa %xmm10, KTRAP_FRAME_Xmm10(%rbp)
|
||||
movdqa %xmm9, KTRAP_FRAME_Xmm9(%rbp)
|
||||
movdqa %xmm8, KTRAP_FRAME_Xmm8(%rbp)
|
||||
movdqa %xmm7, KTRAP_FRAME_Xmm7(%rbp)
|
||||
movdqa %xmm6, KTRAP_FRAME_Xmm6(%rbp)
|
||||
movdqa %xmm5, KTRAP_FRAME_Xmm5(%rbp)
|
||||
movdqa %xmm4, KTRAP_FRAME_Xmm4(%rbp)
|
||||
movdqa %xmm3, KTRAP_FRAME_Xmm3(%rbp)
|
||||
movdqa %xmm2, KTRAP_FRAME_Xmm2(%rbp)
|
||||
movdqa %xmm1, KTRAP_FRAME_Xmm1(%rbp)
|
||||
movdqa %xmm0, KTRAP_FRAME_Xmm0(%rbp)
|
||||
|
||||
/* Test previous mode and swap GS if needed */
|
||||
movl $0, TrapPreviousMode(%rbp)
|
||||
mov %cs, %ax
|
||||
movl $0, KTRAP_FRAME_PreviousMode(%rbp)
|
||||
mov KTRAP_FRAME_SegCs(%rbp), %ax
|
||||
and $3, %al
|
||||
mov %al, TrapPreviousMode(%rbp)
|
||||
jz KernelMode$\Vector
|
||||
mov %al, KTRAP_FRAME_PreviousMode(%rbp)
|
||||
|
||||
/* Skip swapgs as the interrupt originated from kernel mode */
|
||||
jz Dispatch\Type\Vector
|
||||
|
||||
swapgs
|
||||
jmp UserMode$\Vector
|
||||
|
||||
KernelMode$\Vector:
|
||||
/* Save kernel stack pointer (SS:RSP) */
|
||||
movl %ss, %eax
|
||||
mov %eax, TrapSegSs(%rbp)
|
||||
lea TRAP_FRAME_SIZE(%rbp), %rax
|
||||
mov %rax, TrapRsp(%rbp)
|
||||
|
||||
UserMode$\Vector:
|
||||
/* Push Frame Pointer, clear direction flag and pass to trap dispatcher */
|
||||
Dispatch\Type\Vector:
|
||||
/* Set up trap frame pointer for the dispatcher and clear the direction flag */
|
||||
mov %rsp, %rcx
|
||||
cld
|
||||
call ArDispatchTrap
|
||||
|
||||
/* Preserve the original stack pointer */
|
||||
mov %rsp, %rbx
|
||||
|
||||
/* Force stack alignment */
|
||||
and $-16, %rsp
|
||||
|
||||
/* Allocate 32 bytes of shadow space */
|
||||
sub $32, %rsp
|
||||
|
||||
.ifc \Type,Trap
|
||||
/* Pass to the trap dispatcher */
|
||||
call ArDispatchTrap
|
||||
.else
|
||||
/* Pass to the interrupt dispatcher */
|
||||
call ArDispatchInterrupt
|
||||
.endif
|
||||
|
||||
/* Restore the original trap frame stack pointer */
|
||||
mov %rbx, %rsp
|
||||
|
||||
/* Test previous mode and swapgs if needed */
|
||||
testb $1, TrapPreviousMode(%rbp)
|
||||
jz KernelModeReturn$\Vector
|
||||
testb $1, KTRAP_FRAME_PreviousMode(%rbp)
|
||||
jz RestoreState\Type\Vector
|
||||
cli
|
||||
swapgs
|
||||
|
||||
KernelModeReturn$\Vector:
|
||||
RestoreState\Type\Vector:
|
||||
/* Restore XMM registers */
|
||||
movdqa TrapXmm0(%rbp), %xmm0
|
||||
movdqa TrapXmm1(%rbp), %xmm1
|
||||
movdqa TrapXmm2(%rbp), %xmm2
|
||||
movdqa TrapXmm3(%rbp), %xmm3
|
||||
movdqa TrapXmm4(%rbp), %xmm4
|
||||
movdqa TrapXmm5(%rbp), %xmm5
|
||||
movdqa TrapXmm6(%rbp), %xmm6
|
||||
movdqa TrapXmm7(%rbp), %xmm7
|
||||
movdqa TrapXmm8(%rbp), %xmm8
|
||||
movdqa TrapXmm9(%rbp), %xmm9
|
||||
movdqa TrapXmm10(%rbp), %xmm10
|
||||
movdqa TrapXmm11(%rbp), %xmm11
|
||||
movdqa TrapXmm12(%rbp), %xmm12
|
||||
movdqa TrapXmm13(%rbp), %xmm13
|
||||
movdqa TrapXmm14(%rbp), %xmm14
|
||||
movdqa TrapXmm15(%rbp), %xmm15
|
||||
movdqa KTRAP_FRAME_Xmm0(%rbp), %xmm0
|
||||
movdqa KTRAP_FRAME_Xmm1(%rbp), %xmm1
|
||||
movdqa KTRAP_FRAME_Xmm2(%rbp), %xmm2
|
||||
movdqa KTRAP_FRAME_Xmm3(%rbp), %xmm3
|
||||
movdqa KTRAP_FRAME_Xmm4(%rbp), %xmm4
|
||||
movdqa KTRAP_FRAME_Xmm5(%rbp), %xmm5
|
||||
movdqa KTRAP_FRAME_Xmm6(%rbp), %xmm6
|
||||
movdqa KTRAP_FRAME_Xmm7(%rbp), %xmm7
|
||||
movdqa KTRAP_FRAME_Xmm8(%rbp), %xmm8
|
||||
movdqa KTRAP_FRAME_Xmm9(%rbp), %xmm9
|
||||
movdqa KTRAP_FRAME_Xmm10(%rbp), %xmm10
|
||||
movdqa KTRAP_FRAME_Xmm11(%rbp), %xmm11
|
||||
movdqa KTRAP_FRAME_Xmm12(%rbp), %xmm12
|
||||
movdqa KTRAP_FRAME_Xmm13(%rbp), %xmm13
|
||||
movdqa KTRAP_FRAME_Xmm14(%rbp), %xmm14
|
||||
movdqa KTRAP_FRAME_Xmm15(%rbp), %xmm15
|
||||
|
||||
/* Load MxCsr register */
|
||||
ldmxcsr TrapMxCsr(%rbp)
|
||||
|
||||
/* Restore segment selectors */
|
||||
mov TrapSegDs(%rbp), %ds
|
||||
mov TrapSegEs(%rbp), %es
|
||||
mov TrapSegFs(%rbp), %fs
|
||||
ldmxcsr KTRAP_FRAME_MxCsr(%rbp)
|
||||
|
||||
/* Free stack space */
|
||||
add $(TRAP_FRAME_SIZE - TRAP_REGISTERS_SIZE), %rsp
|
||||
add $(KTRAP_FRAME_SIZE - KTRAP_FRAME_REGISTERS_SIZE), %rsp
|
||||
|
||||
/* Pop General Purpose Registers */
|
||||
pop %rax
|
||||
@@ -181,9 +201,291 @@ KernelModeReturn$\Vector:
|
||||
iretq
|
||||
.endm
|
||||
|
||||
/* Populate common trap handlers */
|
||||
/* Populate common interrupt and trap handlers */
|
||||
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
ArCreateTrapHandler 0x\i\j
|
||||
ArCreateHandler 0x\i\j Interrupt
|
||||
ArCreateHandler 0x\i\j Trap
|
||||
.endr
|
||||
.endr
|
||||
|
||||
/* Define array of pointers to the interrupt handlers */
|
||||
.global ArInterruptEntry
|
||||
ArInterruptEntry:
|
||||
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.quad ArInterrupt0x\i\j
|
||||
.endr
|
||||
.endr
|
||||
|
||||
/* Define array of pointers to the trap handlers */
|
||||
.global ArTrapEntry
|
||||
ArTrapEntry:
|
||||
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.quad ArTrap0x\i\j
|
||||
.endr
|
||||
.endr
|
||||
|
||||
/**
|
||||
* Enables eXtended Physical Addressing (XPA).
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page map to be used.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.global ArEnableExtendedPhysicalAddressing
|
||||
ArEnableExtendedPhysicalAddressing:
|
||||
/* Save the original CR4 register */
|
||||
movq %cr4, %rax
|
||||
|
||||
/* Save the state of stack pointer and non-volatile registers */
|
||||
movq %rsp, XpaRegisterSaveArea(%rip)
|
||||
movq %rbp, XpaRegisterSaveArea+0x08(%rip)
|
||||
movq %rax, XpaRegisterSaveArea+0x10(%rip)
|
||||
movq %rbx, XpaRegisterSaveArea+0x18(%rip)
|
||||
|
||||
/* Save the original CR0 register */
|
||||
movq %cr0, %rbp
|
||||
|
||||
/* Load temporary GDT required for mode transitions */
|
||||
leaq XpaTemporaryGdtDesc(%rip), %rax
|
||||
movq %rax, XpaTemporaryGdtBase(%rip)
|
||||
lgdtq XpaTemporaryGdtSize(%rip)
|
||||
|
||||
/* Load addresses for entering compatibility mode and re-entering long mode */
|
||||
leaq XpaEnterCompatMode(%rip), %rax
|
||||
leaq XpaEnterLongMode(%rip), %rbx
|
||||
|
||||
/* Push the 32-bit code segment selector and the target address for a far jump */
|
||||
pushq $KGDT_R0_CMCODE
|
||||
pushq %rax
|
||||
|
||||
/* Perform a far return to switch to 32-bit compatibility mode */
|
||||
lretq
|
||||
|
||||
XpaEnterCompatMode:
|
||||
/* Enter 32-bit compatibility mode */
|
||||
.code32
|
||||
|
||||
/* Store the PageMap pointer on the stack for future use */
|
||||
pushl %ecx
|
||||
|
||||
/* Set the stack segment to the 32-bit data segment selector */
|
||||
movl $KGDT_R0_DATA, %eax
|
||||
movl %eax, %ss
|
||||
|
||||
/* Disable PGE and PCIDE to ensure all TLB entries will be flushed */
|
||||
movl %cr4, %eax
|
||||
andl $~(CR4_PGE | CR4_PCIDE), %eax
|
||||
movl %eax, %cr4
|
||||
|
||||
/* Temporarily disable paging */
|
||||
movl %ebp, %eax
|
||||
andl $~CR0_PG, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
/* Disable Long Mode as prerequisite for enabling 5-level paging */
|
||||
movl $X86_MSR_EFER, %ecx
|
||||
rdmsr
|
||||
andl $~X86_MSR_EFER_LME, %eax
|
||||
wrmsr
|
||||
|
||||
/* Transition to 5-level paging (PML5/LA57) */
|
||||
movl %cr4, %eax
|
||||
orl $CR4_LA57, %eax
|
||||
movl %eax, %cr4
|
||||
|
||||
/* Restore the PageMap pointer from the stack and load it into CR3 */
|
||||
popl %ecx
|
||||
movl %ecx, %cr3
|
||||
|
||||
/* Re-enable Long Mode */
|
||||
movl $X86_MSR_EFER, %ecx
|
||||
rdmsr
|
||||
orl $X86_MSR_EFER_LME, %eax
|
||||
wrmsr
|
||||
|
||||
/* Restore CR0 with paging enabled and flush the instruction pipeline */
|
||||
movl %ebp, %cr0
|
||||
call XpaFlushInstructions
|
||||
|
||||
XpaFlushInstructions:
|
||||
/* Push the 64-bit code segment selector and the target address for a far jump */
|
||||
pushl $KGDT_R0_CODE
|
||||
pushl %ebx
|
||||
|
||||
/* Perform a far return to switch to 64-bit long mode */
|
||||
lretl
|
||||
|
||||
XpaEnterLongMode:
|
||||
/* Enter 64-bit long mode */
|
||||
.code64
|
||||
|
||||
/* Restore the stack pointer and non-volatile registers */
|
||||
movq XpaRegisterSaveArea(%rip), %rsp
|
||||
movq XpaRegisterSaveArea+8(%rip), %rbp
|
||||
movq XpaRegisterSaveArea+0x10(%rip), %rax
|
||||
movq XpaRegisterSaveArea+0x18(%rip), %rbx
|
||||
|
||||
/* Restore the original CR4 register with LA57 bit set */
|
||||
orq $CR4_LA57, %rax
|
||||
movq %rax, %cr4
|
||||
|
||||
/* Return to the caller */
|
||||
retq
|
||||
|
||||
/* Data section for saving registers and temporary GDT */
|
||||
XpaRegisterSaveArea: .quad 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000
|
||||
XpaTemporaryGdtSize: .short ArEnableExtendedPhysicalAddressingEnd - XpaTemporaryGdtDesc - 1
|
||||
XpaTemporaryGdtBase: .quad 0x0000000000000000
|
||||
XpaTemporaryGdtDesc: .quad 0x0000000000000000, 0x00CF9A000000FFFF, 0x00AF9A000000FFFF, 0x00CF92000000FFFF
|
||||
|
||||
.global ArEnableExtendedPhysicalAddressingEnd
|
||||
ArEnableExtendedPhysicalAddressingEnd:
|
||||
|
||||
/**
|
||||
* Handles a spurious interrupt allowing it to end up.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.global ArHandleSpuriousInterrupt
|
||||
ArHandleSpuriousInterrupt:
|
||||
iretq
|
||||
|
||||
/**
|
||||
* Starts an application processor (AP).
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.global ArStartApplicationProcessor
|
||||
ArStartApplicationProcessor:
|
||||
/* Enter 16-bit real mode */
|
||||
.code16
|
||||
|
||||
/* Disable interrupts and clear direction flag */
|
||||
cli
|
||||
cld
|
||||
|
||||
/* Establish a flat addressing baseline */
|
||||
movw %cs, %ax
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %ss
|
||||
|
||||
/* Calculate absolute physical base address */
|
||||
xorl %ebx, %ebx
|
||||
movw %cs, %bx
|
||||
shll $4, %ebx
|
||||
|
||||
/* Set up a temporary stack for the AP initialization */
|
||||
movl %ebx, %esp
|
||||
addl $0x1000, %esp
|
||||
|
||||
/* Load the temporary Global Descriptor Table */
|
||||
leal (ApTemporaryGdtDesc - ArStartApplicationProcessor)(%ebx), %eax
|
||||
movl %eax, (ApTemporaryGdtBase - ArStartApplicationProcessor)
|
||||
lgdtl (ApTemporaryGdtSize - ArStartApplicationProcessor)
|
||||
|
||||
/* Enable Protected Mode */
|
||||
movl %cr0, %eax
|
||||
orl $0x01, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
/* Far return to enter 32-bit protected mode */
|
||||
leal (ApEnterProtectedMode - ArStartApplicationProcessor)(%ebx), %eax
|
||||
pushl $KGDT_R0_CMCODE
|
||||
pushl %eax
|
||||
lretl
|
||||
|
||||
ApEnterProtectedMode:
|
||||
/* Enter 32-bit protected mode */
|
||||
.code32
|
||||
|
||||
/* Setup all data segment registers */
|
||||
movw $KGDT_R0_DATA, %ax
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %ss
|
||||
xorw %ax, %ax
|
||||
movw %ax, %fs
|
||||
movw %ax, %gs
|
||||
|
||||
/* Locate PROCESSOR_START_BLOCK structure */
|
||||
leal (ArStartApplicationProcessorEnd - ArStartApplicationProcessor)(%ebx), %edi
|
||||
|
||||
/* Load CR4 from BSP, but mask PCIDE and PGE */
|
||||
movl PROCESSOR_START_BLOCK_Cr4(%edi), %eax
|
||||
andl $~(CR4_PGE | CR4_PCIDE), %eax
|
||||
movl %eax, %cr4
|
||||
|
||||
/* Load the Kernel Page Directory Base from BSP */
|
||||
movl PROCESSOR_START_BLOCK_Cr3(%edi), %eax
|
||||
movl %eax, %cr3
|
||||
|
||||
/* Enable Long Mode and No-Execute */
|
||||
movl $X86_MSR_EFER, %ecx
|
||||
rdmsr
|
||||
orl $(X86_MSR_EFER_LME | X86_MSR_EFER_NXE), %eax
|
||||
wrmsr
|
||||
|
||||
/* Enable Paging */
|
||||
movl %cr0, %eax
|
||||
orl $CR0_PG, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
/* Far return to enter 64-bit long mode */
|
||||
leal (ApEnterLongMode - ArStartApplicationProcessor)(%ebx), %eax
|
||||
pushl $KGDT_R0_CODE
|
||||
pushl %eax
|
||||
lretl
|
||||
|
||||
ApEnterLongMode:
|
||||
/* Enter 64-bit long mode */
|
||||
.code64
|
||||
|
||||
/* Clear all segment registers */
|
||||
xorw %ax, %ax
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %ss
|
||||
movw %ax, %fs
|
||||
movw %ax, %gs
|
||||
|
||||
/* Zero-extend EDI into RDI to ensure safe 64-bit pointer usage */
|
||||
movl %edi, %edi
|
||||
|
||||
/* Load dedicated Stack for AP */
|
||||
movq PROCESSOR_START_BLOCK_InitialStack(%rdi), %rsp
|
||||
|
||||
/* Save the pointer to PROCESSOR_START_BLOCK */
|
||||
movq %rdi, %rcx
|
||||
|
||||
/* Allocate 32 bytes of shadow space */
|
||||
subq $32, %rsp
|
||||
|
||||
/* Fetch the EntryPoint address and call the routine */
|
||||
movq PROCESSOR_START_BLOCK_EntryPoint(%rdi), %rax
|
||||
call *%rax
|
||||
|
||||
/* Fire the breakpoint and halt if the entry point returns */
|
||||
.ApNoReturnPoint:
|
||||
int $0x03
|
||||
hlt
|
||||
jmp .ApNoReturnPoint
|
||||
|
||||
/* Data section for temporary GDT */
|
||||
.align 8
|
||||
ApTemporaryGdtSize: .short ArStartApplicationProcessorEnd - ApTemporaryGdtDesc - 1
|
||||
ApTemporaryGdtBase: .quad 0x0000000000000000
|
||||
ApTemporaryGdtDesc: .quad 0x0000000000000000, 0x00CF9A000000FFFF, 0x00AF9A000000FFFF, 0x00CF92000000FFFF
|
||||
|
||||
.global ArStartApplicationProcessorEnd
|
||||
ArStartApplicationProcessorEnd:
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ar/amd64/boot.S
|
||||
* DESCRIPTION: AMD64-specific boot code for setting up the low-level CPU environment
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <ar/amd64/asmsup.h>
|
||||
|
||||
.altmacro
|
||||
.text
|
||||
|
||||
|
||||
/**
|
||||
* Enables eXtended Physical Addressing (XPA).
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page map to be used.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.global ArEnableExtendedPhysicalAddressing
|
||||
ArEnableExtendedPhysicalAddressing:
|
||||
/* Save the original CR4 register */
|
||||
movq %cr4, %rax
|
||||
|
||||
/* Save the state of stack pointer and non-volatile registers */
|
||||
movq %rsp, XpaRegisterSaveArea(%rip)
|
||||
movq %rbp, XpaRegisterSaveArea+0x08(%rip)
|
||||
movq %rax, XpaRegisterSaveArea+0x10(%rip)
|
||||
movq %rbx, XpaRegisterSaveArea+0x18(%rip)
|
||||
|
||||
/* Save the original CR0 register */
|
||||
movq %cr0, %rbp
|
||||
|
||||
/* Load temporary GDT required for mode transitions */
|
||||
leaq XpaTemporaryGdtDesc(%rip), %rax
|
||||
movq %rax, XpaTemporaryGdtBase(%rip)
|
||||
lgdtq XpaTemporaryGdtSize(%rip)
|
||||
|
||||
/* Load addresses for entering compatibility mode and re-entering long mode */
|
||||
leaq XpaEnterCompatMode(%rip), %rax
|
||||
leaq XpaEnterLongMode(%rip), %rbx
|
||||
|
||||
/* Push the 32-bit code segment selector and the target address for a far jump */
|
||||
pushq $GDT_R0_CMCODE
|
||||
pushq %rax
|
||||
|
||||
/* Perform a far return to switch to 32-bit compatibility mode */
|
||||
lretq
|
||||
|
||||
XpaEnterCompatMode:
|
||||
/* Enter 32-bit compatibility mode */
|
||||
.code32
|
||||
|
||||
/* Store the PageMap pointer on the stack for future use */
|
||||
pushl %ecx
|
||||
|
||||
/* Set the stack segment to the 32-bit data segment selector */
|
||||
movl $GDT_R0_DATA, %eax
|
||||
movl %eax, %ss
|
||||
|
||||
/* Disable PGE and PCIDE to ensure all TLB entries will be flushed */
|
||||
movl %cr4, %eax
|
||||
andl $~(CR4_PGE | CR4_PCIDE), %eax
|
||||
movl %eax, %cr4
|
||||
|
||||
/* Temporarily disable paging */
|
||||
movl %ebp, %eax
|
||||
andl $~CR0_PG, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
/* Disable Long Mode as prerequisite for enabling 5-level paging */
|
||||
movl $X86_MSR_EFER, %ecx
|
||||
rdmsr
|
||||
andl $~X86_MSR_EFER_LME, %eax
|
||||
wrmsr
|
||||
|
||||
/* Transition to 5-level paging (PML5/LA57) */
|
||||
movl %cr4, %eax
|
||||
orl $CR4_LA57, %eax
|
||||
movl %eax, %cr4
|
||||
|
||||
/* Restore the PageMap pointer from the stack and load it into CR3 */
|
||||
popl %ecx
|
||||
movl %ecx, %cr3
|
||||
|
||||
/* Re-enable Long Mode */
|
||||
movl $X86_MSR_EFER, %ecx
|
||||
rdmsr
|
||||
orl $X86_MSR_EFER_LME, %eax
|
||||
wrmsr
|
||||
|
||||
/* Restore CR0 with paging enabled and flush the instruction pipeline */
|
||||
movl %ebp, %cr0
|
||||
call XpaFlushInstructions
|
||||
|
||||
XpaFlushInstructions:
|
||||
/* Push the 64-bit code segment selector and the target address for a far jump */
|
||||
pushl $GDT_R0_CODE
|
||||
pushl %ebx
|
||||
|
||||
/* Perform a far return to switch to 64-bit long mode */
|
||||
lretl
|
||||
|
||||
XpaEnterLongMode:
|
||||
/* Enter 64-bit long mode */
|
||||
.code64
|
||||
|
||||
/* Restore the stack pointer and non-volatile registers */
|
||||
movq XpaRegisterSaveArea(%rip), %rsp
|
||||
movq XpaRegisterSaveArea+8(%rip), %rbp
|
||||
movq XpaRegisterSaveArea+0x10(%rip), %rax
|
||||
movq XpaRegisterSaveArea+0x18(%rip), %rbx
|
||||
|
||||
/* Restore the original CR4 register with LA57 bit set */
|
||||
orq $CR4_LA57, %rax
|
||||
movq %rax, %cr4
|
||||
|
||||
/* Return to the caller */
|
||||
retq
|
||||
|
||||
/* Data section for saving registers and temporary GDT */
|
||||
XpaRegisterSaveArea: .quad 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000
|
||||
XpaTemporaryGdtSize: .short ArEnableExtendedPhysicalAddressingEnd - XpaTemporaryGdtDesc - 1
|
||||
XpaTemporaryGdtBase: .quad 0x0000000000000000
|
||||
XpaTemporaryGdtDesc: .quad 0x0000000000000000, 0x00CF9A000000FFFF, 0x00AF9A000000FFFF, 0x00CF92000000FFFF
|
||||
|
||||
.global ArEnableExtendedPhysicalAddressingEnd
|
||||
ArEnableExtendedPhysicalAddressingEnd:
|
||||
|
||||
|
||||
/**
|
||||
* Starts an application processor (AP). This is just a stub.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.global ArStartApplicationProcessor
|
||||
ArStartApplicationProcessor:
|
||||
|
||||
.global ArStartApplicationProcessorEnd
|
||||
ArStartApplicationProcessorEnd:
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::ClearInterruptFlag(VOID)
|
||||
AR::CpuFunctions::ClearInterruptFlag(VOID)
|
||||
{
|
||||
__asm__ volatile("cli");
|
||||
}
|
||||
@@ -29,13 +29,13 @@ AR::CpuFunc::ClearInterruptFlag(VOID)
|
||||
* @param Registers
|
||||
* Supplies a pointer to the structure containing all the necessary registers and leafs for CPUID.
|
||||
*
|
||||
* @return TRUE if CPUID function could be executed, FALSE otherwise.
|
||||
* @return This routine returns TRUE if CPUID function could be executed, FALSE otherwise.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
BOOLEAN
|
||||
AR::CpuFunc::CpuId(IN OUT PCPUID_REGISTERS Registers)
|
||||
AR::CpuFunctions::CpuId(IN OUT PCPUID_REGISTERS Registers)
|
||||
{
|
||||
UINT32 MaxLeaf;
|
||||
|
||||
@@ -76,7 +76,7 @@ AR::CpuFunc::CpuId(IN OUT PCPUID_REGISTERS Registers)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::FlushTlb(VOID)
|
||||
AR::CpuFunctions::FlushTlb(VOID)
|
||||
{
|
||||
/* Flush the TLB by resetting the CR3 */
|
||||
WriteControlRegister(3, ReadControlRegister(3));
|
||||
@@ -91,7 +91,7 @@ AR::CpuFunc::FlushTlb(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
ULONG
|
||||
AR::CpuFunc::GetCpuFlags(VOID)
|
||||
AR::CpuFunctions::GetCpuFlags(VOID)
|
||||
{
|
||||
ULONG_PTR Flags;
|
||||
|
||||
@@ -116,7 +116,7 @@ AR::CpuFunc::GetCpuFlags(VOID)
|
||||
XTASSEMBLY
|
||||
XTCDECL
|
||||
ULONG_PTR
|
||||
AR::CpuFunc::GetStackPointer(VOID)
|
||||
AR::CpuFunctions::GetStackPointer(VOID)
|
||||
{
|
||||
/* Get current stack pointer */
|
||||
__asm__ volatile("movq %%rsp, %%rax\n"
|
||||
@@ -135,7 +135,7 @@ AR::CpuFunc::GetStackPointer(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::Halt(VOID)
|
||||
AR::CpuFunctions::Halt(VOID)
|
||||
{
|
||||
__asm__ volatile("hlt");
|
||||
}
|
||||
@@ -149,7 +149,7 @@ AR::CpuFunc::Halt(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
BOOLEAN
|
||||
AR::CpuFunc::InterruptsEnabled(VOID)
|
||||
AR::CpuFunctions::InterruptsEnabled(VOID)
|
||||
{
|
||||
ULONG_PTR Flags;
|
||||
|
||||
@@ -172,7 +172,7 @@ AR::CpuFunc::InterruptsEnabled(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::InvalidateTlbEntry(IN PVOID Address)
|
||||
AR::CpuFunctions::InvalidateTlbEntry(IN PVOID Address)
|
||||
{
|
||||
__asm__ volatile("invlpg (%0)"
|
||||
:
|
||||
@@ -192,7 +192,7 @@ AR::CpuFunc::InvalidateTlbEntry(IN PVOID Address)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::LoadGlobalDescriptorTable(IN PVOID Source)
|
||||
AR::CpuFunctions::LoadGlobalDescriptorTable(IN PVOID Source)
|
||||
{
|
||||
__asm__ volatile("lgdt %0"
|
||||
:
|
||||
@@ -212,7 +212,7 @@ AR::CpuFunc::LoadGlobalDescriptorTable(IN PVOID Source)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::LoadInterruptDescriptorTable(IN PVOID Source)
|
||||
AR::CpuFunctions::LoadInterruptDescriptorTable(IN PVOID Source)
|
||||
{
|
||||
__asm__ volatile("lidt %0"
|
||||
:
|
||||
@@ -232,7 +232,7 @@ AR::CpuFunc::LoadInterruptDescriptorTable(IN PVOID Source)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::LoadLocalDescriptorTable(IN USHORT Source)
|
||||
AR::CpuFunctions::LoadLocalDescriptorTable(IN USHORT Source)
|
||||
{
|
||||
__asm__ volatile("lldtw %0"
|
||||
:
|
||||
@@ -251,7 +251,7 @@ AR::CpuFunc::LoadLocalDescriptorTable(IN USHORT Source)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::LoadMxcsrRegister(IN ULONG Source)
|
||||
AR::CpuFunctions::LoadMxcsrRegister(IN ULONG Source)
|
||||
{
|
||||
__asm__ volatile("ldmxcsr %0"
|
||||
:
|
||||
@@ -273,7 +273,7 @@ AR::CpuFunc::LoadMxcsrRegister(IN ULONG Source)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::LoadSegment(IN USHORT Segment,
|
||||
AR::CpuFunctions::LoadSegment(IN USHORT Segment,
|
||||
IN ULONG Source)
|
||||
{
|
||||
switch(Segment)
|
||||
@@ -335,7 +335,7 @@ AR::CpuFunc::LoadSegment(IN USHORT Segment,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::LoadTaskRegister(USHORT Source)
|
||||
AR::CpuFunctions::LoadTaskRegister(USHORT Source)
|
||||
{
|
||||
__asm__ volatile("ltr %0"
|
||||
:
|
||||
@@ -351,7 +351,7 @@ AR::CpuFunc::LoadTaskRegister(USHORT Source)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::MemoryBarrier(VOID)
|
||||
AR::CpuFunctions::MemoryBarrier(VOID)
|
||||
{
|
||||
LONG Barrier;
|
||||
__asm__ volatile("lock; orl $0, %0;"
|
||||
@@ -365,13 +365,13 @@ AR::CpuFunc::MemoryBarrier(VOID)
|
||||
* @param ControlRegister
|
||||
* Supplies a number of a control register which controls the general behavior of a CPU.
|
||||
*
|
||||
* @return The value stored in the control register.
|
||||
* @return This routine returns the value stored in the control register.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
ULONG_PTR
|
||||
AR::CpuFunc::ReadControlRegister(IN USHORT ControlRegister)
|
||||
AR::CpuFunctions::ReadControlRegister(IN USHORT ControlRegister)
|
||||
{
|
||||
ULONG_PTR Value;
|
||||
|
||||
@@ -429,13 +429,13 @@ AR::CpuFunc::ReadControlRegister(IN USHORT ControlRegister)
|
||||
* @param DebugRegister
|
||||
* Supplies a number of a debug register to read from.
|
||||
*
|
||||
* @return The value stored in the specified debug register.
|
||||
* @return This routine returns the value stored in the specified debug register.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
ULONG_PTR
|
||||
AR::CpuFunc::ReadDebugRegister(IN USHORT DebugRegister)
|
||||
AR::CpuFunctions::ReadDebugRegister(IN USHORT DebugRegister)
|
||||
{
|
||||
ULONG_PTR Value;
|
||||
|
||||
@@ -498,13 +498,13 @@ AR::CpuFunc::ReadDebugRegister(IN USHORT DebugRegister)
|
||||
* @param Offset
|
||||
* Specifies the offset from the beginning of GS segment.
|
||||
*
|
||||
* @return Returns the value read from the specified memory location relative to GS segment.
|
||||
* @return This routine returns the value read from the specified memory location relative to GS segment.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
ULONGLONG
|
||||
AR::CpuFunc::ReadGSQuadWord(ULONG Offset)
|
||||
AR::CpuFunctions::ReadGSQuadWord(ULONG Offset)
|
||||
{
|
||||
ULONGLONG Value;
|
||||
|
||||
@@ -527,7 +527,7 @@ AR::CpuFunc::ReadGSQuadWord(ULONG Offset)
|
||||
*/
|
||||
XTCDECL
|
||||
ULONGLONG
|
||||
AR::CpuFunc::ReadModelSpecificRegister(IN ULONG Register)
|
||||
AR::CpuFunctions::ReadModelSpecificRegister(IN ULONG Register)
|
||||
{
|
||||
ULONG Low, High;
|
||||
|
||||
@@ -548,7 +548,7 @@ AR::CpuFunc::ReadModelSpecificRegister(IN ULONG Register)
|
||||
*/
|
||||
XTCDECL
|
||||
UINT
|
||||
AR::CpuFunc::ReadMxCsrRegister(VOID)
|
||||
AR::CpuFunctions::ReadMxCsrRegister(VOID)
|
||||
{
|
||||
return __builtin_ia32_stmxcsr();
|
||||
}
|
||||
@@ -562,7 +562,7 @@ AR::CpuFunc::ReadMxCsrRegister(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
ULONGLONG
|
||||
AR::CpuFunc::ReadTimeStampCounter(VOID)
|
||||
AR::CpuFunctions::ReadTimeStampCounter(VOID)
|
||||
{
|
||||
ULONGLONG Low, High;
|
||||
|
||||
@@ -573,6 +573,33 @@ 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::CpuFunctions::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.
|
||||
*
|
||||
@@ -582,7 +609,7 @@ AR::CpuFunc::ReadTimeStampCounter(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::ReadWriteBarrier(VOID)
|
||||
AR::CpuFunctions::ReadWriteBarrier(VOID)
|
||||
{
|
||||
__asm__ volatile(""
|
||||
:
|
||||
@@ -590,6 +617,56 @@ AR::CpuFunc::ReadWriteBarrier(VOID)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a Bit Scan Forward instruction to locate the most significant set bit.
|
||||
*
|
||||
* @param Index
|
||||
* Receives the zero-based index of the highest set bit when one is found.
|
||||
*
|
||||
* @param Mask
|
||||
* Supplies the bitmap to scan.
|
||||
*
|
||||
* @return This routine returns TRUE when a set bit was found, otherwise FALSE.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
BOOLEAN
|
||||
AR::CpuFunctions::ScanForwardBit(OUT PULONG Index,
|
||||
IN ULONG Mask)
|
||||
{
|
||||
/* Defer to the BSF instruction */
|
||||
__asm__("bsfl %[Mask], %[Index]" : [Index] "=r" (*Index) : [Mask] "mr" (Mask));
|
||||
|
||||
/* Report whether the input had any bit set */
|
||||
return Mask ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a Bit Scan Reverse instruction to locate the most significant set bit.
|
||||
*
|
||||
* @param Index
|
||||
* Receives the zero-based index of the highest set bit when one is found.
|
||||
*
|
||||
* @param Mask
|
||||
* Supplies the bitmap to scan.
|
||||
*
|
||||
* @return This routine returns TRUE when a set bit was found, otherwise FALSE.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
BOOLEAN
|
||||
AR::CpuFunctions::ScanReverseBit(OUT PULONG Index,
|
||||
IN ULONG Mask)
|
||||
{
|
||||
/* Defer to the BSR instruction */
|
||||
__asm__("bsrl %[Mask], %[Index]" : [Index] "=r" (*Index) : [Mask] "mr" (Mask));
|
||||
|
||||
/* Report whether the input had any bit set */
|
||||
return Mask ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructs the processor to set the interrupt flag.
|
||||
*
|
||||
@@ -599,7 +676,7 @@ AR::CpuFunc::ReadWriteBarrier(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::SetInterruptFlag(VOID)
|
||||
AR::CpuFunctions::SetInterruptFlag(VOID)
|
||||
{
|
||||
__asm__ volatile("sti");
|
||||
}
|
||||
@@ -616,7 +693,7 @@ AR::CpuFunc::SetInterruptFlag(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::StoreGlobalDescriptorTable(OUT PVOID Destination)
|
||||
AR::CpuFunctions::StoreGlobalDescriptorTable(OUT PVOID Destination)
|
||||
{
|
||||
__asm__ volatile("sgdt %0"
|
||||
: "=m" (*(PSHORT)Destination)
|
||||
@@ -636,7 +713,7 @@ AR::CpuFunc::StoreGlobalDescriptorTable(OUT PVOID Destination)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::StoreInterruptDescriptorTable(OUT PVOID Destination)
|
||||
AR::CpuFunctions::StoreInterruptDescriptorTable(OUT PVOID Destination)
|
||||
{
|
||||
__asm__ volatile("sidt %0"
|
||||
: "=m" (*(PSHORT)Destination)
|
||||
@@ -656,7 +733,7 @@ AR::CpuFunc::StoreInterruptDescriptorTable(OUT PVOID Destination)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::StoreLocalDescriptorTable(OUT PVOID Destination)
|
||||
AR::CpuFunctions::StoreLocalDescriptorTable(OUT PVOID Destination)
|
||||
{
|
||||
__asm__ volatile("sldt %0"
|
||||
: "=m" (*(PSHORT)Destination)
|
||||
@@ -679,8 +756,8 @@ AR::CpuFunc::StoreLocalDescriptorTable(OUT PVOID Destination)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::StoreSegment(IN USHORT Segment,
|
||||
OUT PVOID Destination)
|
||||
AR::CpuFunctions::StoreSegment(IN USHORT Segment,
|
||||
OUT PVOID Destination)
|
||||
{
|
||||
switch(Segment)
|
||||
{
|
||||
@@ -726,7 +803,7 @@ AR::CpuFunc::StoreSegment(IN USHORT Segment,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::StoreTaskRegister(OUT PVOID Destination)
|
||||
AR::CpuFunctions::StoreTaskRegister(OUT PVOID Destination)
|
||||
{
|
||||
__asm__ volatile("str %0"
|
||||
: "=m" (*(PULONG)Destination)
|
||||
@@ -749,8 +826,8 @@ AR::CpuFunc::StoreTaskRegister(OUT PVOID Destination)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::WriteControlRegister(IN USHORT ControlRegister,
|
||||
IN UINT_PTR Value)
|
||||
AR::CpuFunctions::WriteControlRegister(IN USHORT ControlRegister,
|
||||
IN UINT_PTR Value)
|
||||
{
|
||||
/* Write a value into specified control register */
|
||||
switch(ControlRegister)
|
||||
@@ -808,8 +885,8 @@ AR::CpuFunc::WriteControlRegister(IN USHORT ControlRegister,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::WriteDebugRegister(IN USHORT DebugRegister,
|
||||
IN UINT_PTR Value)
|
||||
AR::CpuFunctions::WriteDebugRegister(IN USHORT DebugRegister,
|
||||
IN UINT_PTR Value)
|
||||
{
|
||||
/* Write a value into specified debug register */
|
||||
switch(DebugRegister)
|
||||
@@ -885,7 +962,7 @@ AR::CpuFunc::WriteDebugRegister(IN USHORT DebugRegister,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::WriteEflagsRegister(IN UINT_PTR Value)
|
||||
AR::CpuFunctions::WriteEflagsRegister(IN UINT_PTR Value)
|
||||
{
|
||||
__asm__ volatile("push %0\n"
|
||||
"popf"
|
||||
@@ -908,8 +985,8 @@ AR::CpuFunc::WriteEflagsRegister(IN UINT_PTR Value)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::WriteModelSpecificRegister(IN ULONG Register,
|
||||
IN ULONGLONG Value)
|
||||
AR::CpuFunctions::WriteModelSpecificRegister(IN ULONG Register,
|
||||
IN ULONGLONG Value)
|
||||
{
|
||||
ULONG Low = Value & 0xFFFFFFFF;
|
||||
ULONG High = Value >> 32;
|
||||
@@ -930,7 +1007,7 @@ AR::CpuFunc::WriteModelSpecificRegister(IN ULONG Register,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::YieldProcessor(VOID)
|
||||
AR::CpuFunctions::YieldProcessor(VOID)
|
||||
{
|
||||
__asm__ volatile("pause"
|
||||
:
|
||||
|
||||
@@ -10,19 +10,25 @@
|
||||
|
||||
|
||||
/* Initial kernel boot stack */
|
||||
UCHAR AR::ProcSup::BootStack[KERNEL_STACK_SIZE] = {};
|
||||
UCHAR AR::ProcessorSupport::BootStack[KERNEL_STACK_SIZE] = {};
|
||||
|
||||
/* Initial kernel fault stack */
|
||||
UCHAR AR::ProcSup::FaultStack[KERNEL_STACK_SIZE] = {};
|
||||
UCHAR AR::ProcessorSupport::FaultStack[KERNEL_STACK_SIZE] = {};
|
||||
|
||||
/* Initial GDT */
|
||||
KGDTENTRY AR::ProcSup::InitialGdt[GDT_ENTRIES] = {};
|
||||
KGDTENTRY AR::ProcessorSupport::InitialGdt[GDT_ENTRIES] = {};
|
||||
|
||||
/* Initial IDT */
|
||||
KIDTENTRY AR::ProcSup::InitialIdt[IDT_ENTRIES] = {};
|
||||
KIDTENTRY AR::ProcessorSupport::InitialIdt[IDT_ENTRIES] = {};
|
||||
|
||||
/* Initial Processor Block */
|
||||
KPROCESSOR_BLOCK AR::ProcSup::InitialProcessorBlock;
|
||||
KPROCESSOR_BLOCK AR::ProcessorSupport::InitialProcessorBlock;
|
||||
|
||||
/* Initial TSS */
|
||||
KTSS AR::ProcSup::InitialTss;
|
||||
KTSS AR::ProcessorSupport::InitialTss;
|
||||
|
||||
/* Initial kernel NMI stack */
|
||||
UCHAR AR::ProcessorSupport::NmiStack[KERNEL_STACK_SIZE] = {};
|
||||
|
||||
/* Unhandled interrupt routine */
|
||||
PINTERRUPT_HANDLER AR::Traps::UnhandledInterruptRoutine = NULLPTR;
|
||||
|
||||
@@ -18,30 +18,35 @@
|
||||
*/
|
||||
XTAPI
|
||||
PVOID
|
||||
AR::ProcSup::GetBootStack(VOID)
|
||||
AR::ProcessorSupport::GetBootStack(VOID)
|
||||
{
|
||||
return (PVOID)BootStack;
|
||||
/* Return base address of kernel boot stack */
|
||||
return (PVOID)((ULONG_PTR)BootStack + KERNEL_STACK_SIZE);
|
||||
}
|
||||
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
|
||||
OUT PVOID *TrampolineCode,
|
||||
OUT PULONG_PTR TrampolineSize)
|
||||
AR::ProcessorSupport::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
|
||||
OUT PVOID *TrampolineCode,
|
||||
OUT PULONG TrampolineSize)
|
||||
{
|
||||
/* Get trampoline information */
|
||||
switch(TrampolineType)
|
||||
{
|
||||
case TrampolineApStartup:
|
||||
/* Get AP startup trampoline information */
|
||||
*TrampolineCode = (PVOID)ArStartApplicationProcessor;
|
||||
*TrampolineSize = (ULONG_PTR)ArStartApplicationProcessorEnd -
|
||||
(ULONG_PTR)ArStartApplicationProcessor;
|
||||
break;
|
||||
case TrampolineEnableXpa:
|
||||
/* Get Enable XPA trampoline information */
|
||||
*TrampolineCode = (PVOID)ArEnableExtendedPhysicalAddressing;
|
||||
*TrampolineSize = (ULONG_PTR)ArEnableExtendedPhysicalAddressingEnd -
|
||||
(ULONG_PTR)ArEnableExtendedPhysicalAddressing;
|
||||
break;
|
||||
default:
|
||||
/* Unknown trampoline type */
|
||||
*TrampolineCode = NULLPTR;
|
||||
*TrampolineSize = 0;
|
||||
break;
|
||||
@@ -58,22 +63,19 @@ AR::ProcSup::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::IdentifyProcessor(VOID)
|
||||
AR::ProcessorSupport::IdentifyProcessor(VOID)
|
||||
{
|
||||
PKPROCESSOR_CONTROL_BLOCK Prcb;
|
||||
CPUID_REGISTERS CpuRegisters;
|
||||
CPUID_SIGNATURE CpuSignature;
|
||||
|
||||
/* Not fully implemented yet */
|
||||
UNIMPLEMENTED;
|
||||
|
||||
/* Get current processor control block */
|
||||
Prcb = KE::Processor::GetCurrentProcessorControlBlock();
|
||||
|
||||
/* Get CPU vendor by issueing CPUID instruction */
|
||||
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
|
||||
CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU vendor in processor control block */
|
||||
Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx;
|
||||
@@ -85,7 +87,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
/* Get CPU standard features */
|
||||
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||
CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU signature in processor control block */
|
||||
CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax;
|
||||
@@ -97,23 +99,23 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
if(Prcb->CpuId.Vendor == CPU_VENDOR_AMD)
|
||||
{
|
||||
/* AMD CPU */
|
||||
if(Prcb->CpuId.Family >= 0xF)
|
||||
if(CpuSignature.Family == 0xF)
|
||||
{
|
||||
Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
|
||||
Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
|
||||
Prcb->CpuId.Family += CpuSignature.ExtendedFamily;
|
||||
Prcb->CpuId.Model += (CpuSignature.ExtendedModel << 4);
|
||||
}
|
||||
}
|
||||
else if(Prcb->CpuId.Vendor == CPU_VENDOR_INTEL)
|
||||
{
|
||||
/* Intel CPU */
|
||||
if(Prcb->CpuId.Family == 0xF)
|
||||
if(CpuSignature.Family == 0xF)
|
||||
{
|
||||
Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
|
||||
Prcb->CpuId.Family += CpuSignature.ExtendedFamily;
|
||||
}
|
||||
|
||||
if((Prcb->CpuId.Family == 0x6) || (Prcb->CpuId.Family == 0xF))
|
||||
if((CpuSignature.Family == 0x6) || (CpuSignature.Family == 0xF))
|
||||
{
|
||||
Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
|
||||
Prcb->CpuId.Model += (CpuSignature.ExtendedModel << 4);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -122,11 +124,12 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
Prcb->CpuId.Vendor = CPU_VENDOR_UNKNOWN;
|
||||
}
|
||||
|
||||
/* TODO: Store a list of CPU features in processor control block */
|
||||
/* Identify processor features */
|
||||
IdentifyProcessorFeatures();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes AMD64 processor specific structures.
|
||||
* Identifies processor features and stores them in Processor Control Block (PRCB).
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
@@ -134,70 +137,133 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
AR::ProcessorSupport::IdentifyProcessorFeatures(VOID)
|
||||
{
|
||||
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
|
||||
PVOID KernelBootStack, KernelFaultStack;
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
PKGDTENTRY Gdt;
|
||||
PKIDTENTRY Idt;
|
||||
PKTSS Tss;
|
||||
ULONG MaxExtendedLeaf, MaxStandardLeaf;
|
||||
PKPROCESSOR_CONTROL_BLOCK Prcb;
|
||||
CPUID_REGISTERS CpuRegisters;
|
||||
|
||||
/* Check if processor structures buffer provided */
|
||||
if(ProcessorStructures)
|
||||
{
|
||||
/* Assign CPU structures from provided buffer */
|
||||
InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
|
||||
&KernelBootStack, &KernelFaultStack);
|
||||
/* Get current processor control block */
|
||||
Prcb = KE::Processor::GetCurrentProcessorControlBlock();
|
||||
|
||||
/* Use global IDT */
|
||||
Idt = InitialIdt;
|
||||
}
|
||||
else
|
||||
/* Get maximum CPUID standard leaf */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
MaxStandardLeaf = CpuRegisters.Eax;
|
||||
|
||||
/* Get maximum CPUID extended leaf */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_EXTENDED_MAX;
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
MaxExtendedLeaf = CpuRegisters.Eax;
|
||||
|
||||
/* Check if CPU supports standard features leaf */
|
||||
if(MaxStandardLeaf >= CPUID_GET_STANDARD1_FEATURES)
|
||||
{
|
||||
/* Use initial structures */
|
||||
Gdt = InitialGdt;
|
||||
Idt = InitialIdt;
|
||||
Tss = &InitialTss;
|
||||
KernelBootStack = &BootStack;
|
||||
KernelFaultStack = &FaultStack;
|
||||
ProcessorBlock = &InitialProcessorBlock;
|
||||
/* Get CPU standard features */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU standard features in processor control block */
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE3) Prcb->CpuId.FeatureBits |= KCF_SSE3;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_VMX) Prcb->CpuId.FeatureBits |= KCF_VMX;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSSE3) Prcb->CpuId.FeatureBits |= KCF_SSSE3;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4_1) Prcb->CpuId.FeatureBits |= KCF_SSE41;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4_2) Prcb->CpuId.FeatureBits |= KCF_SSE42;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_X2APIC) Prcb->CpuId.FeatureBits |= KCF_X2APIC;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_POPCNT) Prcb->CpuId.FeatureBits |= KCF_POPCNT;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_TSC_DEADLINE) Prcb->CpuId.FeatureBits |= KCF_TSC_DEADLINE;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_AES) Prcb->CpuId.FeatureBits |= KCF_AES;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_XSAVE) Prcb->CpuId.FeatureBits |= KCF_XSAVE;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_AVX) Prcb->CpuId.FeatureBits |= KCF_AVX;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_RDRAND) Prcb->CpuId.FeatureBits |= KCF_RDRAND;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_VME) Prcb->CpuId.FeatureBits |= KCF_VME;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PSE) Prcb->CpuId.FeatureBits |= KCF_LARGE_PAGE;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSC) Prcb->CpuId.FeatureBits |= KCF_RDTSC;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PAE) Prcb->CpuId.FeatureBits |= KCF_PAE;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MCE) Prcb->CpuId.FeatureBits |= KCF_MCE;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CX8) Prcb->CpuId.FeatureBits |= KCF_CMPXCHG8B;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_APIC) Prcb->CpuId.FeatureBits |= KCF_APIC;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SEP) Prcb->CpuId.FeatureBits |= KCF_FAST_SYSCALL;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MTRR) Prcb->CpuId.FeatureBits |= KCF_MTRR;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PGE) Prcb->CpuId.FeatureBits |= KCF_GLOBAL_PAGE;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MCA) Prcb->CpuId.FeatureBits |= KCF_MCA;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CMOV) Prcb->CpuId.FeatureBits |= KCF_CMOV;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PAT) Prcb->CpuId.FeatureBits |= KCF_PAT;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PSE36) Prcb->CpuId.FeatureBits |= KCF_PSE36;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CLFLUSH) Prcb->CpuId.FeatureBits |= KCF_CLFLUSH;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_FXSR) Prcb->CpuId.FeatureBits |= KCF_FXSR;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_ACPI) Prcb->CpuId.FeatureBits |= KCF_ACPI;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MMX) Prcb->CpuId.FeatureBits |= KCF_MMX;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SSE) Prcb->CpuId.FeatureBits |= KCF_SSE;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SSE2) Prcb->CpuId.FeatureBits |= KCF_SSE2;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_HTT) Prcb->CpuId.FeatureBits |= KCF_SMT;
|
||||
}
|
||||
|
||||
/* Initialize processor block */
|
||||
InitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);
|
||||
/* Check if CPU supports standard7 features leaf */
|
||||
if(MaxStandardLeaf >= CPUID_GET_STANDARD7_FEATURES)
|
||||
{
|
||||
/* Get CPU standard features */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD7_FEATURES;
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Initialize GDT, IDT and TSS */
|
||||
InitializeGdt(ProcessorBlock);
|
||||
InitializeIdt(ProcessorBlock);
|
||||
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack);
|
||||
/* Store CPU standard7 features in processor control block */
|
||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_FSGSBASE) Prcb->CpuId.FeatureBits |= KCF_FSGSBASE;
|
||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_AVX2) Prcb->CpuId.FeatureBits |= KCF_AVX2;
|
||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SMEP) Prcb->CpuId.FeatureBits |= KCF_SMEP;
|
||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_RDSEED) Prcb->CpuId.FeatureBits |= KCF_RDSEED;
|
||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SMAP) Prcb->CpuId.FeatureBits |= KCF_SMAP;
|
||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SHA) Prcb->CpuId.FeatureBits |= KCF_SHA;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_LA57) Prcb->CpuId.FeatureBits |= KCF_LA57;
|
||||
}
|
||||
|
||||
/* Set GDT and IDT descriptors */
|
||||
GdtDescriptor.Base = Gdt;
|
||||
GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1;
|
||||
IdtDescriptor.Base = Idt;
|
||||
IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;
|
||||
/* Check if CPU supports power management leaf */
|
||||
if(MaxStandardLeaf >= CPUID_GET_POWER_MANAGEMENT)
|
||||
{
|
||||
/* Get CPU power management features */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_POWER_MANAGEMENT;
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Load GDT, IDT and TSS */
|
||||
CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
|
||||
CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
|
||||
CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS);
|
||||
/* Store CPU power management features in processor control block */
|
||||
if(CpuRegisters.Eax & CPUID_FEATURES_EAX_ARAT) Prcb->CpuId.FeatureBits |= KCF_ARAT;
|
||||
}
|
||||
|
||||
/* Enter passive IRQ level */
|
||||
HL::RunLevel::SetRunLevel(PASSIVE_LEVEL);
|
||||
/* Check if CPU supports extended features leaf */
|
||||
if(MaxExtendedLeaf >= CPUID_GET_EXTENDED_FEATURES)
|
||||
{
|
||||
/* Get CPU extended features */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_EXTENDED_FEATURES;
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Initialize segment registers */
|
||||
InitializeSegments();
|
||||
/* Store CPU extended features in processor control block */
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SVM) Prcb->CpuId.ExtendedFeatureBits |= KCF_SVM;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4A) Prcb->CpuId.ExtendedFeatureBits |= KCF_SSE4A;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_FMA4) Prcb->CpuId.ExtendedFeatureBits |= KCF_FMA4;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_TOPOLOGY_EXTENSIONS) Prcb->CpuId.ExtendedFeatureBits |= KCF_TOPOEXT;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SYSCALL_SYSRET) Prcb->CpuId.ExtendedFeatureBits |= KCF_SYSCALL;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_NX) Prcb->CpuId.ExtendedFeatureBits |= KCF_NX_BIT;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_RDTSCP) Prcb->CpuId.ExtendedFeatureBits |= KCF_RDTSCP;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_LONG_MODE) Prcb->CpuId.ExtendedFeatureBits |= KCF_64BIT;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_3DNOW_EXT) Prcb->CpuId.ExtendedFeatureBits |= KCF_3DNOW_EXT;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_3DNOW) Prcb->CpuId.ExtendedFeatureBits |= KCF_3DNOW;
|
||||
}
|
||||
|
||||
/* Set GS base */
|
||||
CpuFunc::WriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock);
|
||||
CpuFunc::WriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock);
|
||||
/* Check if CPU supports advanced power management leaf */
|
||||
if(MaxExtendedLeaf >= CPUID_GET_ADVANCED_POWER_MANAGEMENT)
|
||||
{
|
||||
/* Get CPU advanced power management features */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_ADVANCED_POWER_MANAGEMENT;
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Initialize processor registers */
|
||||
InitializeProcessorRegisters();
|
||||
|
||||
/* Identify processor */
|
||||
IdentifyProcessor();
|
||||
/* Store CPU advanced power management features in processor control block */
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSCI) Prcb->CpuId.ExtendedFeatureBits |= KCF_INVARIANT_TSC;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -212,7 +278,7 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
AR::ProcessorSupport::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
{
|
||||
/* Initialize GDT entries */
|
||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 1);
|
||||
@@ -241,7 +307,7 @@ AR::ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
AR::ProcessorSupport::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
{
|
||||
UINT Vector;
|
||||
|
||||
@@ -249,34 +315,106 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
|
||||
{
|
||||
/* Set the IDT to handle unexpected interrupts */
|
||||
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArInterruptEntry[Vector], KGDT_R0_CODE,
|
||||
KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
}
|
||||
|
||||
/* Setup IDT handlers for known interrupts and traps */
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x1F, (PVOID)ArTrap0x1F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrap0x2F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArTrap0xE1, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrapEntry[0x00], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrapEntry[0x01], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_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_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrapEntry[0x04], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrapEntry[0x05], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrapEntry[0x06], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrapEntry[0x07], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrapEntry[0x08], KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrapEntry[0x09], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrapEntry[0x0A], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrapEntry[0x0B], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrapEntry[0x0C], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrapEntry[0x0D], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrapEntry[0x0E], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrapEntry[0x10], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrapEntry[0x11], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrapEntry[0x12], KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrapEntry[0x13], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_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_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrapEntry[0x2D], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_INTERRUPT_GATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes AMD64 processor specific structures.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcessorSupport::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
{
|
||||
PVOID KernelBootStack, KernelFaultStack, KernelNmiStack;
|
||||
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
PKGDTENTRY Gdt;
|
||||
PKIDTENTRY Idt;
|
||||
PKTSS Tss;
|
||||
|
||||
/* Check if processor structures buffer provided */
|
||||
if(ProcessorStructures)
|
||||
{
|
||||
/* Assign CPU structures from provided buffer */
|
||||
InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
|
||||
&KernelBootStack, &KernelFaultStack, &KernelNmiStack);
|
||||
|
||||
/* Use global IDT */
|
||||
Idt = InitialIdt;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use initial structures */
|
||||
Gdt = InitialGdt;
|
||||
Idt = InitialIdt;
|
||||
Tss = &InitialTss;
|
||||
KernelBootStack = (PVOID)((ULONG_PTR)&BootStack + KERNEL_STACK_SIZE);
|
||||
KernelFaultStack = (PVOID)((ULONG_PTR)&FaultStack + KERNEL_STACK_SIZE);
|
||||
KernelNmiStack = (PVOID)((ULONG_PTR)&NmiStack + KERNEL_STACK_SIZE);
|
||||
ProcessorBlock = &InitialProcessorBlock;
|
||||
}
|
||||
|
||||
/* Initialize processor block */
|
||||
InitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);
|
||||
|
||||
/* Initialize GDT, IDT and TSS */
|
||||
InitializeGdt(ProcessorBlock);
|
||||
InitializeIdt(ProcessorBlock);
|
||||
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack, KernelNmiStack);
|
||||
|
||||
/* Set GDT and IDT descriptors */
|
||||
GdtDescriptor.Base = Gdt;
|
||||
GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1;
|
||||
IdtDescriptor.Base = Idt;
|
||||
IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;
|
||||
|
||||
/* Load GDT, IDT and TSS */
|
||||
AR::CpuFunctions::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
|
||||
AR::CpuFunctions::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
|
||||
AR::CpuFunctions::LoadTaskRegister((UINT)KGDT_SYS_TSS);
|
||||
|
||||
/* Initialize segment registers */
|
||||
InitializeSegments();
|
||||
|
||||
/* Set GS base */
|
||||
AR::CpuFunctions::WriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock);
|
||||
AR::CpuFunctions::WriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock);
|
||||
|
||||
/* Initialize processor registers */
|
||||
InitializeProcessorRegisters();
|
||||
|
||||
/* Identify processor */
|
||||
IdentifyProcessor();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -300,11 +438,11 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PKGDTENTRY Gdt,
|
||||
IN PKIDTENTRY Idt,
|
||||
IN PKTSS Tss,
|
||||
IN PVOID DpcStack)
|
||||
AR::ProcessorSupport::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PKGDTENTRY Gdt,
|
||||
IN PKIDTENTRY Idt,
|
||||
IN PKTSS Tss,
|
||||
IN PVOID DpcStack)
|
||||
{
|
||||
/* Set processor block and processor control block */
|
||||
ProcessorBlock->Self = ProcessorBlock;
|
||||
@@ -337,8 +475,9 @@ AR::ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
/* Set initial MXCSR register value */
|
||||
ProcessorBlock->Prcb.MxCsr = INITIAL_MXCSR;
|
||||
|
||||
/* Set initial runlevel */
|
||||
/* Set initial runlevel and mark processor as started */
|
||||
ProcessorBlock->RunLevel = PASSIVE_LEVEL;
|
||||
ProcessorBlock->Started = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -350,50 +489,51 @@ AR::ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeProcessorRegisters(VOID)
|
||||
AR::ProcessorSupport::InitializeProcessorRegisters(VOID)
|
||||
{
|
||||
ULONGLONG PatAttributes;
|
||||
|
||||
/* Enable FXSAVE restore */
|
||||
CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_FXSR);
|
||||
AR::CpuFunctions::WriteControlRegister(4, AR::CpuFunctions::ReadControlRegister(4) | CR4_FXSR);
|
||||
|
||||
/* Enable XMMI exceptions */
|
||||
CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_XMMEXCPT);
|
||||
AR::CpuFunctions::WriteControlRegister(4, AR::CpuFunctions::ReadControlRegister(4) | CR4_XMMEXCPT);
|
||||
|
||||
/* Set debugger extension */
|
||||
CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_DE);
|
||||
AR::CpuFunctions::WriteControlRegister(4, AR::CpuFunctions::ReadControlRegister(4) | CR4_DE);
|
||||
|
||||
/* Enable large pages */
|
||||
CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_PSE);
|
||||
AR::CpuFunctions::WriteControlRegister(4, AR::CpuFunctions::ReadControlRegister(4) | CR4_PSE);
|
||||
|
||||
/* Enable write-protection */
|
||||
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_WP);
|
||||
AR::CpuFunctions::WriteControlRegister(0, AR::CpuFunctions::ReadControlRegister(0) | CR0_WP);
|
||||
|
||||
/* Set alignment mask */
|
||||
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_AM);
|
||||
AR::CpuFunctions::WriteControlRegister(0, AR::CpuFunctions::ReadControlRegister(0) | CR0_AM);
|
||||
|
||||
/* Disable FPU monitoring */
|
||||
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) & ~CR0_MP);
|
||||
AR::CpuFunctions::WriteControlRegister(0, AR::CpuFunctions::ReadControlRegister(0) & ~CR0_MP);
|
||||
|
||||
/* Disable x87 FPU exceptions */
|
||||
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) & ~CR0_NE);
|
||||
AR::CpuFunctions::WriteControlRegister(0, AR::CpuFunctions::ReadControlRegister(0) & ~CR0_NE);
|
||||
|
||||
/* Flush the TLB */
|
||||
CpuFunc::FlushTlb();
|
||||
AR::CpuFunctions::FlushTlb();
|
||||
|
||||
/* Initialize system call MSRs */
|
||||
Traps::InitializeSystemCallMsrs();
|
||||
AR::Traps::InitializeSystemCallMsrs();
|
||||
|
||||
/* Enable No-Execute (NXE) in EFER MSR */
|
||||
CpuFunc::WriteModelSpecificRegister(X86_MSR_EFER, CpuFunc::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_NXE);
|
||||
AR::CpuFunctions::WriteModelSpecificRegister(X86_MSR_EFER,
|
||||
CpuFunctions::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_NXE);
|
||||
|
||||
/* Initialize Page Attribute Table */
|
||||
PatAttributes = (PAT_TYPE_WB << 0) | (PAT_TYPE_USWC << 8) | (PAT_TYPE_WEAK_UC << 16) | (PAT_TYPE_STRONG_UC << 24) |
|
||||
(PAT_TYPE_WB << 32) | (PAT_TYPE_USWC << 40) | (PAT_TYPE_WEAK_UC << 48) | (PAT_TYPE_STRONG_UC << 56);
|
||||
CpuFunc::WriteModelSpecificRegister(X86_MSR_PAT, PatAttributes);
|
||||
AR::CpuFunctions::WriteModelSpecificRegister(X86_MSR_PAT, PatAttributes);
|
||||
|
||||
/* Initialize MXCSR register */
|
||||
CpuFunc::LoadMxcsrRegister(INITIAL_MXCSR);
|
||||
AR::CpuFunctions::LoadMxcsrRegister(INITIAL_MXCSR);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -423,12 +563,13 @@ AR::ProcSup::InitializeProcessorRegisters(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
||||
OUT PKGDTENTRY *Gdt,
|
||||
OUT PKTSS *Tss,
|
||||
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
||||
OUT PVOID *KernelBootStack,
|
||||
OUT PVOID *KernelFaultStack)
|
||||
AR::ProcessorSupport::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
||||
OUT PKGDTENTRY *Gdt,
|
||||
OUT PKTSS *Tss,
|
||||
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
||||
OUT PVOID *KernelBootStack,
|
||||
OUT PVOID *KernelFaultStack,
|
||||
OUT PVOID *KernelNmiStack)
|
||||
{
|
||||
UINT_PTR Address;
|
||||
|
||||
@@ -436,22 +577,49 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
||||
Address = ROUND_UP((UINT_PTR)ProcessorStructures, MM_PAGE_SIZE) + KERNEL_STACK_SIZE;
|
||||
|
||||
/* Assign a space for kernel boot stack and advance */
|
||||
*KernelBootStack = (PVOID)Address;
|
||||
if(KernelBootStack != NULLPTR)
|
||||
{
|
||||
/* Return kernel boot stack address */
|
||||
*KernelBootStack = (PVOID)Address;
|
||||
}
|
||||
Address += KERNEL_STACK_SIZE;
|
||||
|
||||
/* Assign a space for kernel fault stack, no advance needed as stack grows down */
|
||||
*KernelFaultStack = (PVOID)Address;
|
||||
/* Assign a space for kernel fault stack and advance */
|
||||
if(KernelFaultStack != NULLPTR)
|
||||
{
|
||||
/* Return kernel fault stack address */
|
||||
*KernelFaultStack = (PVOID)Address;
|
||||
}
|
||||
Address += KERNEL_STACK_SIZE;
|
||||
|
||||
/* Assign a space for kernel NMI stack, no advance needed as stack grows down */
|
||||
if(KernelNmiStack != NULLPTR)
|
||||
{
|
||||
/* Return kernel NMI stack address */
|
||||
*KernelNmiStack = (PVOID)Address;
|
||||
}
|
||||
|
||||
/* Assign a space for GDT and advance */
|
||||
*Gdt = (PKGDTENTRY)(PVOID)Address;
|
||||
Address += sizeof(InitialGdt);
|
||||
if(Gdt != NULLPTR)
|
||||
{
|
||||
/* Return GDT base address */
|
||||
*Gdt = (PKGDTENTRY)(PVOID)Address;
|
||||
}
|
||||
Address += (GDT_ENTRIES * sizeof(KGDTENTRY));
|
||||
|
||||
/* Assign a space for TSS and advance */
|
||||
if(Tss != NULLPTR)
|
||||
{
|
||||
*Tss = (PKTSS)(PVOID)Address;
|
||||
}
|
||||
Address += sizeof(KTSS);
|
||||
|
||||
/* Assign a space for Processor Block and advance */
|
||||
*ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address;
|
||||
Address += sizeof(InitialProcessorBlock);
|
||||
|
||||
/* Assign a space for TSS */
|
||||
*Tss = (PKTSS)(PVOID)Address;
|
||||
if(ProcessorBlock != NULLPTR)
|
||||
{
|
||||
/* Return processor block address */
|
||||
*ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -463,15 +631,15 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeSegments(VOID)
|
||||
AR::ProcessorSupport::InitializeSegments(VOID)
|
||||
{
|
||||
/* Initialize segments */
|
||||
CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
|
||||
CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
|
||||
CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
|
||||
CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK);
|
||||
CpuFunc::LoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK);
|
||||
CpuFunc::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);
|
||||
AR::CpuFunctions::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
|
||||
AR::CpuFunctions::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
|
||||
AR::CpuFunctions::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
|
||||
AR::CpuFunctions::LoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK);
|
||||
AR::CpuFunctions::LoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK);
|
||||
AR::CpuFunctions::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -489,9 +657,10 @@ AR::ProcSup::InitializeSegments(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelBootStack,
|
||||
IN PVOID KernelFaultStack)
|
||||
AR::ProcessorSupport::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelBootStack,
|
||||
IN PVOID KernelFaultStack,
|
||||
IN PVOID KernelNmiStack)
|
||||
{
|
||||
/* Fill TSS with zeroes */
|
||||
RtlZeroMemory(ProcessorBlock->TssBase, sizeof(KTSS));
|
||||
@@ -501,6 +670,7 @@ AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
ProcessorBlock->TssBase->Rsp0 = (ULONG_PTR)KernelBootStack;
|
||||
ProcessorBlock->TssBase->Ist[KIDT_IST_PANIC] = (ULONG_PTR)KernelFaultStack;
|
||||
ProcessorBlock->TssBase->Ist[KIDT_IST_MCA] = (ULONG_PTR)KernelFaultStack;
|
||||
ProcessorBlock->TssBase->Ist[KIDT_IST_NMI] = (ULONG_PTR)KernelNmiStack;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -533,13 +703,13 @@ AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::SetGdtEntry(IN PKGDTENTRY Gdt,
|
||||
IN USHORT Selector,
|
||||
IN ULONG_PTR Base,
|
||||
IN ULONG Limit,
|
||||
IN UCHAR Type,
|
||||
IN UCHAR Dpl,
|
||||
IN UCHAR SegmentMode)
|
||||
AR::ProcessorSupport::SetGdtEntry(IN PKGDTENTRY Gdt,
|
||||
IN USHORT Selector,
|
||||
IN ULONG_PTR Base,
|
||||
IN ULONG Limit,
|
||||
IN UCHAR Type,
|
||||
IN UCHAR Dpl,
|
||||
IN UCHAR SegmentMode)
|
||||
{
|
||||
PKGDTENTRY GdtEntry;
|
||||
UCHAR Granularity;
|
||||
@@ -599,9 +769,9 @@ AR::ProcSup::SetGdtEntry(IN PKGDTENTRY Gdt,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
||||
IN USHORT Selector,
|
||||
IN ULONG_PTR Base)
|
||||
AR::ProcessorSupport::SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
||||
IN USHORT Selector,
|
||||
IN ULONG_PTR Base)
|
||||
{
|
||||
PKGDTENTRY GdtEntry;
|
||||
|
||||
@@ -645,13 +815,13 @@ AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
|
||||
IN USHORT Vector,
|
||||
IN PVOID Handler,
|
||||
IN USHORT Selector,
|
||||
IN USHORT Ist,
|
||||
IN USHORT Dpl,
|
||||
IN USHORT Type)
|
||||
AR::ProcessorSupport::SetIdtGate(IN PKIDTENTRY Idt,
|
||||
IN USHORT Vector,
|
||||
IN PVOID Handler,
|
||||
IN USHORT Selector,
|
||||
IN USHORT Ist,
|
||||
IN USHORT Dpl,
|
||||
IN USHORT Type)
|
||||
{
|
||||
/* Set the handler's address */
|
||||
Idt[Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF);
|
||||
|
||||
@@ -9,6 +9,44 @@
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Dispatches the interrupt provided by common interrupt handler.
|
||||
*
|
||||
* @param TrapFrame
|
||||
* Supplies a kernel trap frame pushed by common interrupt handler on the stack.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::Traps::DispatchInterrupt(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
PINTERRUPT_HANDLER Handler;
|
||||
|
||||
/* Read the handler pointer from the CPU's interrupt dispatch table */
|
||||
Handler = (PINTERRUPT_HANDLER)AR::CpuFunctions::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.
|
||||
*
|
||||
@@ -133,14 +171,6 @@ AR::Traps::DispatchTrap(IN PKTRAP_FRAME TrapFrame)
|
||||
/* Debug-Service-Request raised */
|
||||
HandleTrap2D(TrapFrame);
|
||||
break;
|
||||
case 0x2F:
|
||||
/* Software Interrupt at DISPATCH level */
|
||||
HandleTrap2F(TrapFrame);
|
||||
break;
|
||||
case 0xE1:
|
||||
/* InterProcessor Interrupt (IPI) */
|
||||
HandleTrapE1(TrapFrame);
|
||||
break;
|
||||
default:
|
||||
/* Unknown/Unexpected trap */
|
||||
HandleTrapFF(TrapFrame);
|
||||
@@ -227,7 +257,6 @@ VOID
|
||||
AR::Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n");
|
||||
KE::Crash::Panic(0x02);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -571,40 +600,6 @@ AR::Traps::HandleTrap2D(IN PKTRAP_FRAME TrapFrame)
|
||||
KE::Crash::Panic(0x2D);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the trap 0x2F when a software interrupt gets generated at DISPATCH_LEVEL.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::Traps::HandleTrap2F(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
DebugPrint(L"Unhandled software interrupt at DISPATCH level (0x2F)!\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the trap 0xE1 when InterProcessor Interrupt (IPI) occurs.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::Traps::HandleTrapE1(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
DebugPrint(L"Unhandled IPI interrupt (0xE1)!\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the trap 0xFF when Unexpected Interrupt occurs.
|
||||
*
|
||||
@@ -635,29 +630,29 @@ VOID
|
||||
AR::Traps::InitializeSystemCallMsrs(VOID)
|
||||
{
|
||||
/* Initialize system calls MSR */
|
||||
CpuFunc::WriteModelSpecificRegister(X86_MSR_STAR, (((ULONG64)KGDT_R3_CMCODE | RPL_MASK) << 48) | ((ULONG64)KGDT_R0_CODE << 32));
|
||||
CpuFunc::WriteModelSpecificRegister(X86_MSR_CSTAR, (ULONG64)&HandleSystemCall32);
|
||||
CpuFunc::WriteModelSpecificRegister(X86_MSR_LSTAR, (ULONG64)&HandleSystemCall64);
|
||||
CpuFunc::WriteModelSpecificRegister(X86_MSR_FMASK, X86_EFLAGS_IF_MASK | X86_EFLAGS_TF_MASK);
|
||||
CpuFunctions::WriteModelSpecificRegister(X86_MSR_STAR, (((ULONG64)KGDT_R3_CMCODE | RPL_MASK) << 48) | ((ULONG64)KGDT_R0_CODE << 32));
|
||||
CpuFunctions::WriteModelSpecificRegister(X86_MSR_CSTAR, (ULONG64)&HandleSystemCall32);
|
||||
CpuFunctions::WriteModelSpecificRegister(X86_MSR_LSTAR, (ULONG64)&HandleSystemCall64);
|
||||
CpuFunctions::WriteModelSpecificRegister(X86_MSR_FMASK, X86_EFLAGS_IF_MASK | X86_EFLAGS_TF_MASK);
|
||||
|
||||
/* Enable system call extensions (SCE) in EFER MSR */
|
||||
CpuFunc::WriteModelSpecificRegister(X86_MSR_EFER, CpuFunc::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_SCE);
|
||||
CpuFunctions::WriteModelSpecificRegister(X86_MSR_EFER, CpuFunctions::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_SCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* C-linkage wrapper for dispatching the trap provided by common trap handler.
|
||||
* Sets the unhandled interrupt routine used for vectors that have no handler registered.
|
||||
*
|
||||
* @param TrapFrame
|
||||
* Supplies a kernel trap frame pushed by common trap handler on the stack.
|
||||
* @param Handler
|
||||
* Supplies the pointer to the interrupt handler routine.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
XTAPI
|
||||
VOID
|
||||
ArDispatchTrap(IN PKTRAP_FRAME TrapFrame)
|
||||
AR::Traps::SetUnhandledInterruptRoutine(PINTERRUPT_HANDLER Handler)
|
||||
{
|
||||
AR::Traps::DispatchTrap(TrapFrame);
|
||||
/* Set the unhandled interrupt routine */
|
||||
UnhandledInterruptRoutine = Handler;
|
||||
}
|
||||
|
||||
@@ -4,132 +4,334 @@
|
||||
* FILE: xtoskrnl/ar/i686/archsup.S
|
||||
* DESCRIPTION: Provides i686 architecture features not implementable in C.
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <ar/i686/asmsup.h>
|
||||
#include <xtkmapi.h>
|
||||
#include <xtadk.h>
|
||||
|
||||
.altmacro
|
||||
.text
|
||||
|
||||
|
||||
/**
|
||||
* This macro creates a trap handler for the specified vector.
|
||||
* Creates a task, trap or interrupt handler for the specified vector.
|
||||
*
|
||||
* @param Vector
|
||||
* Supplies a trap vector number.
|
||||
* Supplies a vector number.
|
||||
*
|
||||
* @param Type
|
||||
* Specifies whether the handler is designed to handle an interrupt, a task or a trap.
|
||||
*
|
||||
* @return This macro does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.macro ArCreateTrapHandler Vector
|
||||
.global _ArTrap\Vector
|
||||
_ArTrap\Vector:
|
||||
/* Push fake error code for non-error vectors */
|
||||
.if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
|
||||
push $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
|
||||
.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 trap handlers */
|
||||
/* Populate common interrupt, task and trap handlers */
|
||||
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
ArCreateTrapHandler 0x\i\j
|
||||
ArCreateHandler 0x\i\j Interrupt
|
||||
.if 0x\i\j == 0x02 || 0x\i\j == 0x08
|
||||
ArCreateHandler 0x\i\j Task
|
||||
.else
|
||||
ArCreateHandler 0x\i\j Trap
|
||||
.endif
|
||||
.endr
|
||||
.endr
|
||||
|
||||
/* Define array of pointers to the interrupt handlers */
|
||||
.global _ArInterruptEntry
|
||||
_ArInterruptEntry:
|
||||
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.long _ArInterrupt0x\i\j
|
||||
.endr
|
||||
.endr
|
||||
|
||||
/* Define array of pointers to the trap handlers */
|
||||
.global _ArTrapEntry
|
||||
_ArTrapEntry:
|
||||
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
.if 0x\i\j == 0x02 || 0x\i\j == 0x08
|
||||
.long _ArTask0x\i\j
|
||||
.else
|
||||
.long _ArTrap0x\i\j
|
||||
.endif
|
||||
.endr
|
||||
.endr
|
||||
|
||||
/**
|
||||
* Enables eXtended Physical Addressing (XPA). On i386, this is just a stub.
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page map to be used.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.global ArEnableExtendedPhysicalAddressing
|
||||
ArEnableExtendedPhysicalAddressing:
|
||||
|
||||
.global ArEnableExtendedPhysicalAddressingEnd
|
||||
ArEnableExtendedPhysicalAddressingEnd:
|
||||
|
||||
/**
|
||||
* Handles a spurious interrupt allowing it to end up.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.global _ArHandleSpuriousInterrupt
|
||||
_ArHandleSpuriousInterrupt:
|
||||
iret
|
||||
|
||||
/**
|
||||
* Starts an application processor (AP).
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.global _ArStartApplicationProcessor
|
||||
_ArStartApplicationProcessor:
|
||||
/* Enter 16-bit real mode */
|
||||
.code16
|
||||
|
||||
/* Disable interrupts and clear direction flag */
|
||||
cli
|
||||
cld
|
||||
|
||||
/* Establish a flat addressing baseline */
|
||||
movw %cs, %ax
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %ss
|
||||
|
||||
/* Calculate absolute physical base address */
|
||||
xorl %ebx, %ebx
|
||||
movw %cs, %bx
|
||||
shll $4, %ebx
|
||||
|
||||
/* Set up a temporary stack for the AP initialization */
|
||||
movl %ebx, %esp
|
||||
addl $0x1000, %esp
|
||||
|
||||
/* Load the temporary Global Descriptor Table */
|
||||
leal (ApTemporaryGdtDesc - _ArStartApplicationProcessor)(%ebx), %eax
|
||||
movl %eax, (ApTemporaryGdtBase - _ArStartApplicationProcessor)
|
||||
lgdtl (ApTemporaryGdtSize - _ArStartApplicationProcessor)
|
||||
|
||||
/* Enable Protected Mode */
|
||||
movl %cr0, %eax
|
||||
orl $0x01, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
/* Far return to enter 32-bit protected mode */
|
||||
leal (ApEnterProtectedMode - _ArStartApplicationProcessor)(%ebx), %eax
|
||||
pushl $KGDT_R0_CODE
|
||||
pushl %eax
|
||||
lretl
|
||||
|
||||
ApEnterProtectedMode:
|
||||
/* Enter 32-bit protected mode */
|
||||
.code32
|
||||
|
||||
/* Setup all data segment registers */
|
||||
movw $KGDT_R0_DATA, %ax
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %ss
|
||||
xorw %ax, %ax
|
||||
movw %ax, %fs
|
||||
movw %ax, %gs
|
||||
|
||||
/* Locate PROCESSOR_START_BLOCK structure */
|
||||
leal (_ArStartApplicationProcessorEnd - _ArStartApplicationProcessor)(%ebx), %edi
|
||||
|
||||
/* Load CR4 from BSP, but mask PCIDE and PGE */
|
||||
movl PROCESSOR_START_BLOCK_Cr4(%edi), %eax
|
||||
andl $~(CR4_PGE | CR4_PCIDE), %eax
|
||||
movl %eax, %cr4
|
||||
|
||||
/* Load the Kernel Page Directory Base from BSP */
|
||||
movl PROCESSOR_START_BLOCK_Cr3(%edi), %eax
|
||||
movl %eax, %cr3
|
||||
|
||||
/* Enable Paging */
|
||||
movl %cr0, %eax
|
||||
orl $CR0_PG, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
/* Load dedicated Stack for AP */
|
||||
movl PROCESSOR_START_BLOCK_InitialStack(%edi), %esp
|
||||
|
||||
/* Save the pointer to PROCESSOR_START_BLOCK */
|
||||
movl %edi, %ecx
|
||||
pushl %edi
|
||||
|
||||
/* Call the EntryPoint routine */
|
||||
movl PROCESSOR_START_BLOCK_EntryPoint(%edi), %eax
|
||||
call *%eax
|
||||
|
||||
/* Fire the breakpoint and halt if the entry point returns */
|
||||
.ApNoReturnPoint:
|
||||
int $0x03
|
||||
hlt
|
||||
jmp .ApNoReturnPoint
|
||||
|
||||
/* Data section for temporary GDT */
|
||||
.align 8
|
||||
ApTemporaryGdtSize: .short _ArStartApplicationProcessorEnd - ApTemporaryGdtDesc - 1
|
||||
ApTemporaryGdtBase: .long 0x00000000
|
||||
ApTemporaryGdtDesc: .quad 0x0000000000000000, 0x00CF9A000000FFFF, 0x00CF92000000FFFF
|
||||
|
||||
.global _ArStartApplicationProcessorEnd
|
||||
_ArStartApplicationProcessorEnd:
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ar/i686/boot.S
|
||||
* DESCRIPTION: i686-specific boot code for setting up the low-level CPU environment
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <ar/amd64/asmsup.h>
|
||||
|
||||
.altmacro
|
||||
.text
|
||||
|
||||
|
||||
/**
|
||||
* Starts an application processor (AP). This is just a stub.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
.global _ArStartApplicationProcessor
|
||||
_ArStartApplicationProcessor:
|
||||
|
||||
.global _ArStartApplicationProcessorEnd
|
||||
_ArStartApplicationProcessorEnd:
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::ClearInterruptFlag(VOID)
|
||||
AR::CpuFunctions::ClearInterruptFlag(VOID)
|
||||
{
|
||||
__asm__ volatile("cli");
|
||||
}
|
||||
@@ -29,13 +29,13 @@ AR::CpuFunc::ClearInterruptFlag(VOID)
|
||||
* @param Registers
|
||||
* Supplies a pointer to the structure containing all the necessary registers and leafs for CPUID.
|
||||
*
|
||||
* @return TRUE if CPUID function could be executed, FALSE otherwise.
|
||||
* @return This routine returns TRUE if CPUID function could be executed, FALSE otherwise.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
BOOLEAN
|
||||
AR::CpuFunc::CpuId(IN OUT PCPUID_REGISTERS Registers)
|
||||
AR::CpuFunctions::CpuId(IN OUT PCPUID_REGISTERS Registers)
|
||||
{
|
||||
UINT32 MaxLeaf;
|
||||
|
||||
@@ -76,7 +76,7 @@ AR::CpuFunc::CpuId(IN OUT PCPUID_REGISTERS Registers)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::FlushTlb(VOID)
|
||||
AR::CpuFunctions::FlushTlb(VOID)
|
||||
{
|
||||
/* Flush the TLB by resetting the CR3 */
|
||||
WriteControlRegister(3, ReadControlRegister(3));
|
||||
@@ -91,7 +91,7 @@ AR::CpuFunc::FlushTlb(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
ULONG
|
||||
AR::CpuFunc::GetCpuFlags(VOID)
|
||||
AR::CpuFunctions::GetCpuFlags(VOID)
|
||||
{
|
||||
ULONG_PTR Flags;
|
||||
|
||||
@@ -116,7 +116,7 @@ AR::CpuFunc::GetCpuFlags(VOID)
|
||||
XTASSEMBLY
|
||||
XTCDECL
|
||||
ULONG_PTR
|
||||
AR::CpuFunc::GetStackPointer(VOID)
|
||||
AR::CpuFunctions::GetStackPointer(VOID)
|
||||
{
|
||||
/* Get current stack pointer */
|
||||
__asm__ volatile("mov %%esp, %%eax\n"
|
||||
@@ -135,7 +135,7 @@ AR::CpuFunc::GetStackPointer(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::Halt(VOID)
|
||||
AR::CpuFunctions::Halt(VOID)
|
||||
{
|
||||
__asm__ volatile("hlt");
|
||||
}
|
||||
@@ -149,7 +149,7 @@ AR::CpuFunc::Halt(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
BOOLEAN
|
||||
AR::CpuFunc::InterruptsEnabled(VOID)
|
||||
AR::CpuFunctions::InterruptsEnabled(VOID)
|
||||
{
|
||||
ULONG_PTR Flags;
|
||||
|
||||
@@ -172,7 +172,7 @@ AR::CpuFunc::InterruptsEnabled(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::InvalidateTlbEntry(PVOID Address)
|
||||
AR::CpuFunctions::InvalidateTlbEntry(PVOID Address)
|
||||
{
|
||||
__asm__ volatile("invlpg (%0)"
|
||||
:
|
||||
@@ -192,7 +192,7 @@ AR::CpuFunc::InvalidateTlbEntry(PVOID Address)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::LoadGlobalDescriptorTable(IN PVOID Source)
|
||||
AR::CpuFunctions::LoadGlobalDescriptorTable(IN PVOID Source)
|
||||
{
|
||||
__asm__ volatile("lgdt %0"
|
||||
:
|
||||
@@ -212,7 +212,7 @@ AR::CpuFunc::LoadGlobalDescriptorTable(IN PVOID Source)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::LoadInterruptDescriptorTable(IN PVOID Source)
|
||||
AR::CpuFunctions::LoadInterruptDescriptorTable(IN PVOID Source)
|
||||
{
|
||||
__asm__ volatile("lidt %0"
|
||||
:
|
||||
@@ -232,7 +232,7 @@ AR::CpuFunc::LoadInterruptDescriptorTable(IN PVOID Source)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::LoadLocalDescriptorTable(IN USHORT Source)
|
||||
AR::CpuFunctions::LoadLocalDescriptorTable(IN USHORT Source)
|
||||
{
|
||||
__asm__ volatile("lldtw %0"
|
||||
:
|
||||
@@ -254,8 +254,8 @@ AR::CpuFunc::LoadLocalDescriptorTable(IN USHORT Source)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::LoadSegment(IN USHORT Segment,
|
||||
IN ULONG Source)
|
||||
AR::CpuFunctions::LoadSegment(IN USHORT Segment,
|
||||
IN ULONG Source)
|
||||
{
|
||||
switch(Segment)
|
||||
{
|
||||
@@ -316,7 +316,7 @@ AR::CpuFunc::LoadSegment(IN USHORT Segment,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::LoadTaskRegister(USHORT Source)
|
||||
AR::CpuFunctions::LoadTaskRegister(USHORT Source)
|
||||
{
|
||||
__asm__ volatile("ltr %0"
|
||||
:
|
||||
@@ -332,7 +332,7 @@ AR::CpuFunc::LoadTaskRegister(USHORT Source)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::MemoryBarrier(VOID)
|
||||
AR::CpuFunctions::MemoryBarrier(VOID)
|
||||
{
|
||||
LONG Barrier;
|
||||
__asm__ volatile("xchg %%eax, %0"
|
||||
@@ -347,13 +347,13 @@ AR::CpuFunc::MemoryBarrier(VOID)
|
||||
* @param ControlRegister
|
||||
* Supplies a number of a control register which controls the general behavior of a CPU.
|
||||
*
|
||||
* @return The value stored in the control register.
|
||||
* @return This routine returns the value stored in the control register.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
ULONG_PTR
|
||||
AR::CpuFunc::ReadControlRegister(IN USHORT ControlRegister)
|
||||
AR::CpuFunctions::ReadControlRegister(IN USHORT ControlRegister)
|
||||
{
|
||||
ULONG_PTR Value;
|
||||
|
||||
@@ -404,13 +404,13 @@ AR::CpuFunc::ReadControlRegister(IN USHORT ControlRegister)
|
||||
* @param DebugRegister
|
||||
* Supplies a number of a debug register to read from.
|
||||
*
|
||||
* @return The value stored in the specified debug register.
|
||||
* @return This routine returns the value stored in the specified debug register.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
ULONG_PTR
|
||||
AR::CpuFunc::ReadDebugRegister(IN USHORT DebugRegister)
|
||||
AR::CpuFunctions::ReadDebugRegister(IN USHORT DebugRegister)
|
||||
{
|
||||
ULONG_PTR Value;
|
||||
|
||||
@@ -473,13 +473,13 @@ AR::CpuFunc::ReadDebugRegister(IN USHORT DebugRegister)
|
||||
* @param Offset
|
||||
* Specifies the offset from the beginning of FS segment.
|
||||
*
|
||||
* @return Returns the value read from the specified memory location relative to FS segment.
|
||||
* @return This routine returns the value read from the specified memory location relative to FS segment.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
ULONG
|
||||
AR::CpuFunc::ReadFSDualWord(ULONG Offset)
|
||||
AR::CpuFunctions::ReadFSDualWord(ULONG Offset)
|
||||
{
|
||||
ULONG Value;
|
||||
__asm__ volatile("movl %%fs:%a[Offset], %k[Value]"
|
||||
@@ -500,7 +500,7 @@ AR::CpuFunc::ReadFSDualWord(ULONG Offset)
|
||||
*/
|
||||
XTCDECL
|
||||
ULONGLONG
|
||||
AR::CpuFunc::ReadModelSpecificRegister(IN ULONG Register)
|
||||
AR::CpuFunctions::ReadModelSpecificRegister(IN ULONG Register)
|
||||
{
|
||||
ULONGLONG Value;
|
||||
|
||||
@@ -519,7 +519,7 @@ AR::CpuFunc::ReadModelSpecificRegister(IN ULONG Register)
|
||||
*/
|
||||
XTCDECL
|
||||
UINT
|
||||
AR::CpuFunc::ReadMxCsrRegister(VOID)
|
||||
AR::CpuFunctions::ReadMxCsrRegister(VOID)
|
||||
{
|
||||
return __builtin_ia32_stmxcsr();
|
||||
}
|
||||
@@ -533,7 +533,7 @@ AR::CpuFunc::ReadMxCsrRegister(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
ULONGLONG
|
||||
AR::CpuFunc::ReadTimeStampCounter(VOID)
|
||||
AR::CpuFunctions::ReadTimeStampCounter(VOID)
|
||||
{
|
||||
ULONGLONG Value;
|
||||
|
||||
@@ -543,6 +543,33 @@ 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::CpuFunctions::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.
|
||||
*
|
||||
@@ -552,7 +579,7 @@ AR::CpuFunc::ReadTimeStampCounter(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::ReadWriteBarrier(VOID)
|
||||
AR::CpuFunctions::ReadWriteBarrier(VOID)
|
||||
{
|
||||
__asm__ volatile(""
|
||||
:
|
||||
@@ -560,6 +587,56 @@ AR::CpuFunc::ReadWriteBarrier(VOID)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a Bit Scan Forward instruction to locate the most significant set bit.
|
||||
*
|
||||
* @param Index
|
||||
* Receives the zero-based index of the highest set bit when one is found.
|
||||
*
|
||||
* @param Mask
|
||||
* Supplies the bitmap to scan.
|
||||
*
|
||||
* @return This routine returns TRUE when a set bit was found, otherwise FALSE.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
BOOLEAN
|
||||
AR::CpuFunctions::ScanForwardBit(OUT PULONG Index,
|
||||
IN ULONG Mask)
|
||||
{
|
||||
/* Defer to the BSF instruction */
|
||||
__asm__("bsfl %[Mask], %[Index]" : [Index] "=r" (*Index) : [Mask] "mr" (Mask));
|
||||
|
||||
/* Report whether the input had any bit set */
|
||||
return Mask ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a Bit Scan Reverse instruction to locate the most significant set bit.
|
||||
*
|
||||
* @param Index
|
||||
* Receives the zero-based index of the highest set bit when one is found.
|
||||
*
|
||||
* @param Mask
|
||||
* Supplies the bitmap to scan.
|
||||
*
|
||||
* @return This routine returns TRUE when a set bit was found, otherwise FALSE.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
BOOLEAN
|
||||
AR::CpuFunctions::ScanReverseBit(OUT PULONG Index,
|
||||
IN ULONG Mask)
|
||||
{
|
||||
/* Defer to the BSR instruction */
|
||||
__asm__("bsrl %[Mask], %[Index]" : [Index] "=r" (*Index) : [Mask] "mr" (Mask));
|
||||
|
||||
/* Report whether the input had any bit set */
|
||||
return Mask ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructs the processor to set the interrupt flag.
|
||||
*
|
||||
@@ -569,7 +646,7 @@ AR::CpuFunc::ReadWriteBarrier(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::SetInterruptFlag(VOID)
|
||||
AR::CpuFunctions::SetInterruptFlag(VOID)
|
||||
{
|
||||
__asm__ volatile("sti");
|
||||
}
|
||||
@@ -586,7 +663,7 @@ AR::CpuFunc::SetInterruptFlag(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::StoreGlobalDescriptorTable(OUT PVOID Destination)
|
||||
AR::CpuFunctions::StoreGlobalDescriptorTable(OUT PVOID Destination)
|
||||
{
|
||||
__asm__ volatile("sgdt %0"
|
||||
: "=m" (*(PSHORT)Destination)
|
||||
@@ -606,7 +683,7 @@ AR::CpuFunc::StoreGlobalDescriptorTable(OUT PVOID Destination)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::StoreInterruptDescriptorTable(OUT PVOID Destination)
|
||||
AR::CpuFunctions::StoreInterruptDescriptorTable(OUT PVOID Destination)
|
||||
{
|
||||
__asm__ volatile("sidt %0"
|
||||
: "=m" (*(PSHORT)Destination)
|
||||
@@ -626,7 +703,7 @@ AR::CpuFunc::StoreInterruptDescriptorTable(OUT PVOID Destination)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::StoreLocalDescriptorTable(OUT PVOID Destination)
|
||||
AR::CpuFunctions::StoreLocalDescriptorTable(OUT PVOID Destination)
|
||||
{
|
||||
__asm__ volatile("sldt %0"
|
||||
: "=m" (*(PSHORT)Destination)
|
||||
@@ -649,8 +726,8 @@ AR::CpuFunc::StoreLocalDescriptorTable(OUT PVOID Destination)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::StoreSegment(IN USHORT Segment,
|
||||
OUT PVOID Destination)
|
||||
AR::CpuFunctions::StoreSegment(IN USHORT Segment,
|
||||
OUT PVOID Destination)
|
||||
{
|
||||
switch(Segment)
|
||||
{
|
||||
@@ -696,7 +773,7 @@ AR::CpuFunc::StoreSegment(IN USHORT Segment,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::StoreTaskRegister(OUT PVOID Destination)
|
||||
AR::CpuFunctions::StoreTaskRegister(OUT PVOID Destination)
|
||||
{
|
||||
__asm__ volatile("str %0"
|
||||
: "=m" (*(PULONG)Destination)
|
||||
@@ -719,8 +796,8 @@ AR::CpuFunc::StoreTaskRegister(OUT PVOID Destination)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::WriteControlRegister(IN USHORT ControlRegister,
|
||||
IN UINT_PTR Value)
|
||||
AR::CpuFunctions::WriteControlRegister(IN USHORT ControlRegister,
|
||||
IN UINT_PTR Value)
|
||||
{
|
||||
/* Write a value into specified control register */
|
||||
switch(ControlRegister)
|
||||
@@ -771,8 +848,8 @@ AR::CpuFunc::WriteControlRegister(IN USHORT ControlRegister,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::WriteDebugRegister(IN USHORT DebugRegister,
|
||||
IN UINT_PTR Value)
|
||||
AR::CpuFunctions::WriteDebugRegister(IN USHORT DebugRegister,
|
||||
IN UINT_PTR Value)
|
||||
{
|
||||
/* Write a value into specified debug register */
|
||||
switch(DebugRegister)
|
||||
@@ -840,7 +917,7 @@ AR::CpuFunc::WriteDebugRegister(IN USHORT DebugRegister,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::WriteEflagsRegister(IN UINT_PTR Value)
|
||||
AR::CpuFunctions::WriteEflagsRegister(IN UINT_PTR Value)
|
||||
{
|
||||
__asm__ volatile("push %0\n"
|
||||
"popf"
|
||||
@@ -863,8 +940,8 @@ AR::CpuFunc::WriteEflagsRegister(IN UINT_PTR Value)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::WriteModelSpecificRegister(IN ULONG Register,
|
||||
IN ULONGLONG Value)
|
||||
AR::CpuFunctions::WriteModelSpecificRegister(IN ULONG Register,
|
||||
IN ULONGLONG Value)
|
||||
{
|
||||
__asm__ volatile("wrmsr"
|
||||
:
|
||||
@@ -881,7 +958,7 @@ AR::CpuFunc::WriteModelSpecificRegister(IN ULONG Register,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::YieldProcessor(VOID)
|
||||
AR::CpuFunctions::YieldProcessor(VOID)
|
||||
{
|
||||
__asm__ volatile("pause"
|
||||
:
|
||||
|
||||
@@ -10,25 +10,31 @@
|
||||
|
||||
|
||||
/* Initial kernel boot stack */
|
||||
UCHAR AR::ProcSup::BootStack[KERNEL_STACK_SIZE] = {};
|
||||
UCHAR AR::ProcessorSupport::BootStack[KERNEL_STACK_SIZE] = {};
|
||||
|
||||
/* Double Fault gate */
|
||||
UCHAR AR::ProcSup::DoubleFaultTss[KTSS_IO_MAPS];
|
||||
UCHAR AR::ProcessorSupport::DoubleFaultTss[KTSS_IO_MAPS];
|
||||
|
||||
/* Initial kernel fault stack */
|
||||
UCHAR AR::ProcSup::FaultStack[KERNEL_STACK_SIZE] = {};
|
||||
UCHAR AR::ProcessorSupport::FaultStack[KERNEL_STACK_SIZE] = {};
|
||||
|
||||
/* Initial GDT */
|
||||
KGDTENTRY AR::ProcSup::InitialGdt[GDT_ENTRIES] = {};
|
||||
KGDTENTRY AR::ProcessorSupport::InitialGdt[GDT_ENTRIES] = {};
|
||||
|
||||
/* Initial IDT */
|
||||
KIDTENTRY AR::ProcSup::InitialIdt[IDT_ENTRIES] = {};
|
||||
KIDTENTRY AR::ProcessorSupport::InitialIdt[IDT_ENTRIES] = {};
|
||||
|
||||
/* Initial Processor Block */
|
||||
KPROCESSOR_BLOCK AR::ProcSup::InitialProcessorBlock;
|
||||
KPROCESSOR_BLOCK AR::ProcessorSupport::InitialProcessorBlock;
|
||||
|
||||
/* Initial TSS */
|
||||
KTSS AR::ProcSup::InitialTss;
|
||||
KTSS AR::ProcessorSupport::InitialTss;
|
||||
|
||||
/* Initial kernel NMI stack */
|
||||
UCHAR AR::ProcessorSupport::NmiStack[KERNEL_STACK_SIZE] = {};
|
||||
|
||||
/* NMI task gate */
|
||||
UCHAR AR::ProcSup::NonMaskableInterruptTss[KTSS_IO_MAPS];
|
||||
UCHAR AR::ProcessorSupport::NonMaskableInterruptTss[KTSS_IO_MAPS];
|
||||
|
||||
/* Unhandled interrupt routine */
|
||||
PINTERRUPT_HANDLER AR::Traps::UnhandledInterruptRoutine = NULLPTR;
|
||||
|
||||
@@ -18,25 +18,29 @@
|
||||
*/
|
||||
XTAPI
|
||||
PVOID
|
||||
AR::ProcSup::GetBootStack(VOID)
|
||||
AR::ProcessorSupport::GetBootStack(VOID)
|
||||
{
|
||||
return (PVOID)BootStack;
|
||||
/* Return base address of kernel boot stack */
|
||||
return (PVOID)((ULONG_PTR)BootStack + KERNEL_STACK_SIZE);
|
||||
}
|
||||
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
|
||||
OUT PVOID *TrampolineCode,
|
||||
OUT PULONG_PTR TrampolineSize)
|
||||
AR::ProcessorSupport::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
|
||||
OUT PVOID *TrampolineCode,
|
||||
OUT PULONG TrampolineSize)
|
||||
{
|
||||
/* Get trampoline information */
|
||||
switch(TrampolineType)
|
||||
{
|
||||
case TrampolineApStartup:
|
||||
/* Get AP startup trampoline information */
|
||||
*TrampolineCode = (PVOID)ArStartApplicationProcessor;
|
||||
*TrampolineSize = (ULONG_PTR)ArStartApplicationProcessorEnd -
|
||||
(ULONG_PTR)ArStartApplicationProcessor;
|
||||
break;
|
||||
default:
|
||||
/* Unknown trampoline type */
|
||||
*TrampolineCode = NULLPTR;
|
||||
*TrampolineSize = 0;
|
||||
break;
|
||||
@@ -44,8 +48,7 @@ AR::ProcSup::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
|
||||
}
|
||||
|
||||
/**
|
||||
* Identifies processor type (vendor, model, stepping) as well as looks for available CPU features and stores them
|
||||
* in Processor Control Block (PRCB).
|
||||
* Identifies processor type (vendor, model, stepping) and stores them in Processor Control Block (PRCB).
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
@@ -53,22 +56,19 @@ AR::ProcSup::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::IdentifyProcessor(VOID)
|
||||
AR::ProcessorSupport::IdentifyProcessor(VOID)
|
||||
{
|
||||
PKPROCESSOR_CONTROL_BLOCK Prcb;
|
||||
CPUID_REGISTERS CpuRegisters;
|
||||
CPUID_SIGNATURE CpuSignature;
|
||||
|
||||
/* Not fully implemented yet */
|
||||
UNIMPLEMENTED;
|
||||
|
||||
/* Get current processor control block */
|
||||
Prcb = KE::Processor::GetCurrentProcessorControlBlock();
|
||||
|
||||
/* Get CPU vendor by issueing CPUID instruction */
|
||||
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
|
||||
CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU vendor in processor control block */
|
||||
Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx;
|
||||
@@ -80,7 +80,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
/* Get CPU standard features */
|
||||
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||
CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU signature in processor control block */
|
||||
CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax;
|
||||
@@ -92,23 +92,23 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
if(Prcb->CpuId.Vendor == CPU_VENDOR_AMD)
|
||||
{
|
||||
/* AMD CPU */
|
||||
if(Prcb->CpuId.Family >= 0xF)
|
||||
if(CpuSignature.Family == 0xF)
|
||||
{
|
||||
Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
|
||||
Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
|
||||
Prcb->CpuId.Family += CpuSignature.ExtendedFamily;
|
||||
Prcb->CpuId.Model += (CpuSignature.ExtendedModel << 4);
|
||||
}
|
||||
}
|
||||
else if(Prcb->CpuId.Vendor == CPU_VENDOR_INTEL)
|
||||
{
|
||||
/* Intel CPU */
|
||||
if(Prcb->CpuId.Family == 0xF)
|
||||
if(CpuSignature.Family == 0xF)
|
||||
{
|
||||
Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
|
||||
Prcb->CpuId.Family += CpuSignature.ExtendedFamily;
|
||||
}
|
||||
|
||||
if((Prcb->CpuId.Family == 0x6) || (Prcb->CpuId.Family == 0xF))
|
||||
if((CpuSignature.Family == 0x6) || (CpuSignature.Family == 0xF))
|
||||
{
|
||||
Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
|
||||
Prcb->CpuId.Model += (CpuSignature.ExtendedModel << 4);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -117,11 +117,12 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
Prcb->CpuId.Vendor = CPU_VENDOR_UNKNOWN;
|
||||
}
|
||||
|
||||
/* TODO: Store a list of CPU features in processor control block */
|
||||
/* Identify processor features */
|
||||
IdentifyProcessorFeatures();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes i686 processor specific structures.
|
||||
* Identifies processor features and stores them in Processor Control Block (PRCB).
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
@@ -129,66 +130,133 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
AR::ProcessorSupport::IdentifyProcessorFeatures(VOID)
|
||||
{
|
||||
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
|
||||
PVOID KernelBootStack, KernelFaultStack;
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
PKGDTENTRY Gdt;
|
||||
PKIDTENTRY Idt;
|
||||
PKTSS Tss;
|
||||
ULONG MaxExtendedLeaf, MaxStandardLeaf;
|
||||
PKPROCESSOR_CONTROL_BLOCK Prcb;
|
||||
CPUID_REGISTERS CpuRegisters;
|
||||
|
||||
/* Check if processor structures buffer provided */
|
||||
if(ProcessorStructures)
|
||||
{
|
||||
/* Assign CPU structures from provided buffer */
|
||||
InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
|
||||
&KernelBootStack, &KernelFaultStack);
|
||||
/* Get current processor control block */
|
||||
Prcb = KE::Processor::GetCurrentProcessorControlBlock();
|
||||
|
||||
/* Use global IDT */
|
||||
Idt = InitialIdt;
|
||||
}
|
||||
else
|
||||
/* Get maximum CPUID standard leaf */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
MaxStandardLeaf = CpuRegisters.Eax;
|
||||
|
||||
/* Get maximum CPUID extended leaf */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_EXTENDED_MAX;
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
MaxExtendedLeaf = CpuRegisters.Eax;
|
||||
|
||||
/* Check if CPU supports standard features leaf */
|
||||
if(MaxStandardLeaf >= CPUID_GET_STANDARD1_FEATURES)
|
||||
{
|
||||
/* Use initial structures */
|
||||
Gdt = InitialGdt;
|
||||
Idt = InitialIdt;
|
||||
Tss = &InitialTss;
|
||||
KernelBootStack = &BootStack;
|
||||
KernelFaultStack = &FaultStack;
|
||||
ProcessorBlock = &InitialProcessorBlock;
|
||||
/* Get CPU standard features */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU standard features in processor control block */
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE3) Prcb->CpuId.FeatureBits |= KCF_SSE3;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_VMX) Prcb->CpuId.FeatureBits |= KCF_VMX;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSSE3) Prcb->CpuId.FeatureBits |= KCF_SSSE3;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4_1) Prcb->CpuId.FeatureBits |= KCF_SSE41;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4_2) Prcb->CpuId.FeatureBits |= KCF_SSE42;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_X2APIC) Prcb->CpuId.FeatureBits |= KCF_X2APIC;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_POPCNT) Prcb->CpuId.FeatureBits |= KCF_POPCNT;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_TSC_DEADLINE) Prcb->CpuId.FeatureBits |= KCF_TSC_DEADLINE;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_AES) Prcb->CpuId.FeatureBits |= KCF_AES;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_XSAVE) Prcb->CpuId.FeatureBits |= KCF_XSAVE;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_AVX) Prcb->CpuId.FeatureBits |= KCF_AVX;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_RDRAND) Prcb->CpuId.FeatureBits |= KCF_RDRAND;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_VME) Prcb->CpuId.FeatureBits |= KCF_VME;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PSE) Prcb->CpuId.FeatureBits |= KCF_LARGE_PAGE;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSC) Prcb->CpuId.FeatureBits |= KCF_RDTSC;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PAE) Prcb->CpuId.FeatureBits |= KCF_PAE;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MCE) Prcb->CpuId.FeatureBits |= KCF_MCE;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CX8) Prcb->CpuId.FeatureBits |= KCF_CMPXCHG8B;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_APIC) Prcb->CpuId.FeatureBits |= KCF_APIC;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SEP) Prcb->CpuId.FeatureBits |= KCF_FAST_SYSCALL;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MTRR) Prcb->CpuId.FeatureBits |= KCF_MTRR;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PGE) Prcb->CpuId.FeatureBits |= KCF_GLOBAL_PAGE;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MCA) Prcb->CpuId.FeatureBits |= KCF_MCA;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CMOV) Prcb->CpuId.FeatureBits |= KCF_CMOV;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PAT) Prcb->CpuId.FeatureBits |= KCF_PAT;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PSE36) Prcb->CpuId.FeatureBits |= KCF_PSE36;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CLFLUSH) Prcb->CpuId.FeatureBits |= KCF_CLFLUSH;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_FXSR) Prcb->CpuId.FeatureBits |= KCF_FXSR;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_ACPI) Prcb->CpuId.FeatureBits |= KCF_ACPI;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MMX) Prcb->CpuId.FeatureBits |= KCF_MMX;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SSE) Prcb->CpuId.FeatureBits |= KCF_SSE;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SSE2) Prcb->CpuId.FeatureBits |= KCF_SSE2;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_HTT) Prcb->CpuId.FeatureBits |= KCF_SMT;
|
||||
}
|
||||
|
||||
/* Initialize processor block */
|
||||
InitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);
|
||||
/* Check if CPU supports standard7 features leaf */
|
||||
if(MaxStandardLeaf >= CPUID_GET_STANDARD7_FEATURES)
|
||||
{
|
||||
/* Get CPU standard features */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD7_FEATURES;
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Initialize GDT, IDT and TSS */
|
||||
InitializeGdt(ProcessorBlock);
|
||||
InitializeIdt(ProcessorBlock);
|
||||
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack);
|
||||
/* Store CPU standard7 features in processor control block */
|
||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_FSGSBASE) Prcb->CpuId.FeatureBits |= KCF_FSGSBASE;
|
||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_AVX2) Prcb->CpuId.FeatureBits |= KCF_AVX2;
|
||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SMEP) Prcb->CpuId.FeatureBits |= KCF_SMEP;
|
||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_RDSEED) Prcb->CpuId.FeatureBits |= KCF_RDSEED;
|
||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SMAP) Prcb->CpuId.FeatureBits |= KCF_SMAP;
|
||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SHA) Prcb->CpuId.FeatureBits |= KCF_SHA;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_LA57) Prcb->CpuId.FeatureBits |= KCF_LA57;
|
||||
}
|
||||
|
||||
/* Set GDT and IDT descriptors */
|
||||
GdtDescriptor.Base = Gdt;
|
||||
GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1;
|
||||
IdtDescriptor.Base = Idt;
|
||||
IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;
|
||||
/* Check if CPU supports power management leaf */
|
||||
if(MaxStandardLeaf >= CPUID_GET_POWER_MANAGEMENT)
|
||||
{
|
||||
/* Get CPU power management features */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_POWER_MANAGEMENT;
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Load GDT, IDT and TSS */
|
||||
CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
|
||||
CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
|
||||
CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS);
|
||||
/* Store CPU power management features in processor control block */
|
||||
if(CpuRegisters.Eax & CPUID_FEATURES_EAX_ARAT) Prcb->CpuId.FeatureBits |= KCF_ARAT;
|
||||
}
|
||||
|
||||
/* Enter passive IRQ level */
|
||||
HL::RunLevel::SetRunLevel(PASSIVE_LEVEL);
|
||||
/* Check if CPU supports extended features leaf */
|
||||
if(MaxExtendedLeaf >= CPUID_GET_EXTENDED_FEATURES)
|
||||
{
|
||||
/* Get CPU extended features */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_EXTENDED_FEATURES;
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Initialize segment registers */
|
||||
InitializeSegments();
|
||||
/* Store CPU extended features in processor control block */
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SVM) Prcb->CpuId.ExtendedFeatureBits |= KCF_SVM;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4A) Prcb->CpuId.ExtendedFeatureBits |= KCF_SSE4A;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_FMA4) Prcb->CpuId.ExtendedFeatureBits |= KCF_FMA4;
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_TOPOLOGY_EXTENSIONS) Prcb->CpuId.ExtendedFeatureBits |= KCF_TOPOEXT;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SYSCALL_SYSRET) Prcb->CpuId.ExtendedFeatureBits |= KCF_SYSCALL;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_NX) Prcb->CpuId.ExtendedFeatureBits |= KCF_NX_BIT;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_RDTSCP) Prcb->CpuId.ExtendedFeatureBits |= KCF_RDTSCP;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_LONG_MODE) Prcb->CpuId.ExtendedFeatureBits |= KCF_64BIT;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_3DNOW_EXT) Prcb->CpuId.ExtendedFeatureBits |= KCF_3DNOW_EXT;
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_3DNOW) Prcb->CpuId.ExtendedFeatureBits |= KCF_3DNOW;
|
||||
}
|
||||
|
||||
/* Initialize processor registers */
|
||||
InitializeProcessorRegisters();
|
||||
/* Check if CPU supports advanced power management leaf */
|
||||
if(MaxExtendedLeaf >= CPUID_GET_ADVANCED_POWER_MANAGEMENT)
|
||||
{
|
||||
/* Get CPU advanced power management features */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_ADVANCED_POWER_MANAGEMENT;
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Identify processor */
|
||||
IdentifyProcessor();
|
||||
/* Store CPU advanced power management features in processor control block */
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSCI) Prcb->CpuId.ExtendedFeatureBits |= KCF_INVARIANT_TSC;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -203,7 +271,7 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
AR::ProcessorSupport::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
{
|
||||
/* Initialize GDT entries */
|
||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0);
|
||||
@@ -215,9 +283,9 @@ AR::ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_PB, (ULONG_PTR)ProcessorBlock, sizeof(KPROCESSOR_BLOCK), KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2);
|
||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_TEB, 0x0, 0xFFF, KGDT_TYPE_DATA | KGDT_DESCRIPTOR_ACCESSED, KGDT_DPL_USER, 2);
|
||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDM_TILE, 0x0400, 0xFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 0);
|
||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0);
|
||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0x0, I686_LDT, KGDT_DPL_SYSTEM, 0);
|
||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_DF_TSS, 0x20000, 0xFFFF, I686_TSS, KGDT_DPL_SYSTEM, 0);
|
||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NMI_TSS, 0x20000, 0xFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0);
|
||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NMI_TSS, 0x20000, 0xFFFF, I686_TSS, KGDT_DPL_SYSTEM, 0);
|
||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDBS, 0xB8000, 0x3FFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0);
|
||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_ALIAS, (ULONG_PTR)ProcessorBlock->GdtBase, (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0);
|
||||
}
|
||||
@@ -234,7 +302,7 @@ AR::ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
AR::ProcessorSupport::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
{
|
||||
UINT Vector;
|
||||
|
||||
@@ -242,34 +310,105 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
|
||||
{
|
||||
/* Set the IDT to handle unexpected interrupts */
|
||||
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArInterruptEntry[Vector],
|
||||
KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
}
|
||||
|
||||
/* Setup IDT handlers for known interrupts and traps */
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrap0x2A, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrap0x2B, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrap0x2E, KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrapEntry[0x00], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrapEntry[0x01], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrapEntry[0x02], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TASK_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrapEntry[0x03], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrapEntry[0x04], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrapEntry[0x05], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrapEntry[0x06], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrapEntry[0x07], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrapEntry[0x08], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TASK_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrapEntry[0x09], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrapEntry[0x0A], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrapEntry[0x0B], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrapEntry[0x0C], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrapEntry[0x0D], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrapEntry[0x0E], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrapEntry[0x10], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrapEntry[0x11], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrapEntry[0x12], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrapEntry[0x13], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrapEntry[0x2A], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrapEntry[0x2B], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrapEntry[0x2C], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrapEntry[0x2D], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrapEntry[0x2E], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializes i686 processor specific structures.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcessorSupport::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
{
|
||||
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
|
||||
PVOID KernelBootStack, KernelFaultStack, KernelNmiStack;
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
PKGDTENTRY Gdt;
|
||||
PKIDTENTRY Idt;
|
||||
PKTSS Tss;
|
||||
|
||||
/* Check if processor structures buffer provided */
|
||||
if(ProcessorStructures)
|
||||
{
|
||||
/* Assign CPU structures from provided buffer */
|
||||
InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
|
||||
&KernelBootStack, &KernelFaultStack, &KernelNmiStack);
|
||||
|
||||
/* Use global IDT */
|
||||
Idt = InitialIdt;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use initial structures */
|
||||
Gdt = InitialGdt;
|
||||
Idt = InitialIdt;
|
||||
Tss = &InitialTss;
|
||||
KernelBootStack = (PVOID)((ULONG_PTR)&BootStack + KERNEL_STACK_SIZE);
|
||||
KernelFaultStack = (PVOID)((ULONG_PTR)&FaultStack + KERNEL_STACK_SIZE);
|
||||
KernelNmiStack = (PVOID)((ULONG_PTR)&NmiStack + KERNEL_STACK_SIZE);
|
||||
ProcessorBlock = &InitialProcessorBlock;
|
||||
}
|
||||
|
||||
/* Initialize processor block */
|
||||
InitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);
|
||||
|
||||
/* Initialize GDT, IDT and TSS */
|
||||
InitializeGdt(ProcessorBlock);
|
||||
InitializeIdt(ProcessorBlock);
|
||||
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack, KernelNmiStack);
|
||||
|
||||
/* Set GDT and IDT descriptors */
|
||||
GdtDescriptor.Base = Gdt;
|
||||
GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1;
|
||||
IdtDescriptor.Base = Idt;
|
||||
IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;
|
||||
|
||||
/* Load GDT, IDT and TSS */
|
||||
AR::CpuFunctions::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
|
||||
AR::CpuFunctions::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
|
||||
AR::CpuFunctions::LoadTaskRegister((UINT)KGDT_SYS_TSS);
|
||||
|
||||
/* Initialize segment registers */
|
||||
InitializeSegments();
|
||||
|
||||
/* Initialize processor registers */
|
||||
InitializeProcessorRegisters();
|
||||
|
||||
/* Identify processor */
|
||||
IdentifyProcessor();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -293,11 +432,11 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PKGDTENTRY Gdt,
|
||||
IN PKIDTENTRY Idt,
|
||||
IN PKTSS Tss,
|
||||
IN PVOID DpcStack)
|
||||
AR::ProcessorSupport::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PKGDTENTRY Gdt,
|
||||
IN PKIDTENTRY Idt,
|
||||
IN PKTSS Tss,
|
||||
IN PVOID DpcStack)
|
||||
{
|
||||
/* Set processor block and processor control block */
|
||||
ProcessorBlock->Self = ProcessorBlock;
|
||||
@@ -326,8 +465,9 @@ AR::ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
ProcessorBlock->Prcb.IdleThread = &(KE::KThread::GetInitialThread())->ThreadControlBlock;
|
||||
ProcessorBlock->Prcb.NextThread = NULLPTR;
|
||||
|
||||
/* Set initial runlevel */
|
||||
/* Set initial runlevel and mark processor as started */
|
||||
ProcessorBlock->RunLevel = PASSIVE_LEVEL;
|
||||
ProcessorBlock->Started = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -339,13 +479,13 @@ AR::ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeProcessorRegisters(VOID)
|
||||
AR::ProcessorSupport::InitializeProcessorRegisters(VOID)
|
||||
{
|
||||
/* Clear EFLAGS register */
|
||||
CpuFunc::WriteEflagsRegister(0);
|
||||
AR::CpuFunctions::WriteEflagsRegister(0);
|
||||
|
||||
/* Enable write-protection */
|
||||
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_WP);
|
||||
AR::CpuFunctions::WriteControlRegister(0, AR::CpuFunctions::ReadControlRegister(0) | CR0_WP);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -375,12 +515,13 @@ AR::ProcSup::InitializeProcessorRegisters(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
||||
OUT PKGDTENTRY *Gdt,
|
||||
OUT PKTSS *Tss,
|
||||
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
||||
OUT PVOID *KernelBootStack,
|
||||
OUT PVOID *KernelFaultStack)
|
||||
AR::ProcessorSupport::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
||||
OUT PKGDTENTRY *Gdt,
|
||||
OUT PKTSS *Tss,
|
||||
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
||||
OUT PVOID *KernelBootStack,
|
||||
OUT PVOID *KernelFaultStack,
|
||||
OUT PVOID *KernelNmiStack)
|
||||
{
|
||||
UINT_PTR Address;
|
||||
|
||||
@@ -388,22 +529,49 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
||||
Address = ROUND_UP((UINT_PTR)ProcessorStructures, MM_PAGE_SIZE) + KERNEL_STACK_SIZE;
|
||||
|
||||
/* Assign a space for kernel boot stack and advance */
|
||||
*KernelBootStack = (PVOID)Address;
|
||||
if(KernelBootStack != NULLPTR)
|
||||
{
|
||||
/* Return kernel boot stack address */
|
||||
*KernelBootStack = (PVOID)Address;
|
||||
}
|
||||
Address += KERNEL_STACK_SIZE;
|
||||
|
||||
/* Assign a space for kernel fault stack, no advance needed as stack grows down */
|
||||
*KernelFaultStack = (PVOID)Address;
|
||||
/* Assign a space for kernel fault stack and advance */
|
||||
if(KernelFaultStack != NULLPTR)
|
||||
{
|
||||
/* Return kernel fault stack address */
|
||||
*KernelFaultStack = (PVOID)Address;
|
||||
}
|
||||
Address += KERNEL_STACK_SIZE;
|
||||
|
||||
/* Assign a space for kernel NMI stack, no advance needed as stack grows down */
|
||||
if(KernelNmiStack != NULLPTR)
|
||||
{
|
||||
/* Return kernel NMI stack address */
|
||||
*KernelNmiStack = (PVOID)Address;
|
||||
}
|
||||
|
||||
/* Assign a space for GDT and advance */
|
||||
*Gdt = (PKGDTENTRY)(PVOID)Address;
|
||||
Address += sizeof(InitialGdt);
|
||||
if(Gdt != NULLPTR)
|
||||
{
|
||||
/* Return GDT base address */
|
||||
*Gdt = (PKGDTENTRY)(PVOID)Address;
|
||||
}
|
||||
Address += (GDT_ENTRIES * sizeof(KGDTENTRY));
|
||||
|
||||
/* Assign a space for TSS and advance */
|
||||
if(Tss != NULLPTR)
|
||||
{
|
||||
*Tss = (PKTSS)(PVOID)Address;
|
||||
}
|
||||
Address += sizeof(KTSS);
|
||||
|
||||
/* Assign a space for Processor Block and advance */
|
||||
*ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address;
|
||||
Address += sizeof(InitialProcessorBlock);
|
||||
|
||||
/* Assign a space for TSS */
|
||||
*Tss = (PKTSS)(PVOID)Address;
|
||||
if(ProcessorBlock != NULLPTR)
|
||||
{
|
||||
/* Return processor block address */
|
||||
*ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -415,13 +583,15 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeSegments(VOID)
|
||||
AR::ProcessorSupport::InitializeSegments(VOID)
|
||||
{
|
||||
/* Initialize segments */
|
||||
CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
|
||||
CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
|
||||
CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
|
||||
CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R0_PB);
|
||||
AR::CpuFunctions::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
|
||||
AR::CpuFunctions::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
|
||||
AR::CpuFunctions::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
|
||||
AR::CpuFunctions::LoadSegment(SEGMENT_FS, KGDT_R0_PB);
|
||||
AR::CpuFunctions::LoadSegment(SEGMENT_GS, 0);
|
||||
AR::CpuFunctions::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -436,10 +606,21 @@ AR::ProcSup::InitializeSegments(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelBootStack,
|
||||
IN PVOID KernelFaultStack)
|
||||
AR::ProcessorSupport::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelBootStack,
|
||||
IN PVOID KernelFaultStack,
|
||||
IN PVOID KernelNmiStack)
|
||||
{
|
||||
PKGDTENTRY TssEntry;
|
||||
|
||||
/* Setup System TSS entry in Global Descriptor Table */
|
||||
TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_SYS_TSS / sizeof(KGDTENTRY)]));
|
||||
TssEntry->LimitLow = sizeof(KTSS) - 1;
|
||||
TssEntry->Bits.LimitHigh = 0;
|
||||
TssEntry->Bits.Dpl = 0;
|
||||
TssEntry->Bits.Present = 1;
|
||||
TssEntry->Bits.Type = I686_TSS;
|
||||
|
||||
/* Clear I/O map */
|
||||
RtlSetMemory(ProcessorBlock->TssBase->IoMaps[0].IoMap, 0xFF, IOPM_FULL_SIZE);
|
||||
|
||||
@@ -461,16 +642,16 @@ AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
|
||||
/* Set I/O map base and disable traps */
|
||||
ProcessorBlock->TssBase->IoMapBase = sizeof(KTSS);
|
||||
ProcessorBlock->TssBase->Esp0 = (ULONG_PTR)KernelBootStack;
|
||||
ProcessorBlock->TssBase->Flags = 0;
|
||||
|
||||
/* Set LDT and SS */
|
||||
ProcessorBlock->TssBase->LDT = KGDT_R0_LDT;
|
||||
/* Set CR3, LDT and SS */
|
||||
ProcessorBlock->TssBase->CR3 = AR::CpuFunctions::ReadControlRegister(3);
|
||||
ProcessorBlock->TssBase->LDT = 0;
|
||||
ProcessorBlock->TssBase->Ss0 = KGDT_R0_DATA;
|
||||
|
||||
/* Initialize task gates for DoubleFault and NMI traps */
|
||||
SetDoubleFaultTssEntry(ProcessorBlock, KernelFaultStack);
|
||||
SetNonMaskableInterruptTssEntry(ProcessorBlock, KernelFaultStack);
|
||||
SetNonMaskableInterruptTssEntry(ProcessorBlock, KernelNmiStack);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -485,8 +666,8 @@ AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelFaultStack)
|
||||
AR::ProcessorSupport::SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelFaultStack)
|
||||
{
|
||||
PKGDTENTRY TaskGateEntry, TssEntry;
|
||||
PKTSS Tss;
|
||||
@@ -502,24 +683,24 @@ AR::ProcSup::SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
Tss = (PKTSS)DoubleFaultTss;
|
||||
Tss->IoMapBase = sizeof(KTSS);
|
||||
Tss->Flags = 0;
|
||||
Tss->LDT = KGDT_R0_LDT;
|
||||
Tss->CR3 = CpuFunc::ReadControlRegister(3);
|
||||
Tss->LDT = 0;
|
||||
Tss->CR3 = AR::CpuFunctions::ReadControlRegister(3);
|
||||
Tss->Esp = (ULONG_PTR)KernelFaultStack;
|
||||
Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
|
||||
Tss->Eip = PtrToUlong(ArTrap0x08);
|
||||
Tss->Eip = (ULONG)(ULONG_PTR)ArTrapEntry[0x08];
|
||||
Tss->Cs = KGDT_R0_CODE;
|
||||
Tss->Ds = KGDT_R3_DATA | RPL_MASK;
|
||||
Tss->Es = KGDT_R3_DATA | RPL_MASK;
|
||||
Tss->Fs = KGDT_R0_PB;
|
||||
Tss->Ss = KGDT_R0_DATA;
|
||||
Tss->Ss0 = KGDT_R0_DATA;
|
||||
CpuFunc::StoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss);
|
||||
|
||||
/* Setup DoubleFault TSS entry in Global Descriptor Table */
|
||||
TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_DF_TSS / sizeof(KGDTENTRY)]));
|
||||
TssEntry->BaseLow = ((ULONG_PTR)Tss & 0xFFFF);
|
||||
TssEntry->Bytes.BaseMiddle = ((ULONG_PTR)Tss >> 16);
|
||||
TssEntry->Bytes.BaseHigh = ((ULONG_PTR)Tss >> 24);
|
||||
TssEntry->LimitLow = sizeof(KTSS) - 1;
|
||||
TssEntry->LimitLow = 0x68;
|
||||
TssEntry->Bits.LimitHigh = 0;
|
||||
TssEntry->Bits.Dpl = 0;
|
||||
TssEntry->Bits.Present = 1;
|
||||
@@ -556,13 +737,13 @@ AR::ProcSup::SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::SetGdtEntry(IN PKGDTENTRY Gdt,
|
||||
IN USHORT Selector,
|
||||
IN ULONG_PTR Base,
|
||||
IN ULONG Limit,
|
||||
IN UCHAR Type,
|
||||
IN UCHAR Dpl,
|
||||
IN UCHAR SegmentMode)
|
||||
AR::ProcessorSupport::SetGdtEntry(IN PKGDTENTRY Gdt,
|
||||
IN USHORT Selector,
|
||||
IN ULONG_PTR Base,
|
||||
IN ULONG Limit,
|
||||
IN UCHAR Type,
|
||||
IN UCHAR Dpl,
|
||||
IN UCHAR SegmentMode)
|
||||
{
|
||||
PKGDTENTRY GdtEntry;
|
||||
UCHAR Granularity;
|
||||
@@ -620,9 +801,9 @@ AR::ProcSup::SetGdtEntry(IN PKGDTENTRY Gdt,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
||||
IN USHORT Selector,
|
||||
IN ULONG_PTR Base)
|
||||
AR::ProcessorSupport::SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
||||
IN USHORT Selector,
|
||||
IN ULONG_PTR Base)
|
||||
{
|
||||
PKGDTENTRY GdtEntry;
|
||||
|
||||
@@ -665,13 +846,13 @@ AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
|
||||
IN USHORT Vector,
|
||||
IN PVOID Handler,
|
||||
IN USHORT Selector,
|
||||
IN USHORT Ist,
|
||||
IN USHORT Dpl,
|
||||
IN USHORT Type)
|
||||
AR::ProcessorSupport::SetIdtGate(IN PKIDTENTRY Idt,
|
||||
IN USHORT Vector,
|
||||
IN PVOID Handler,
|
||||
IN USHORT Selector,
|
||||
IN USHORT Ist,
|
||||
IN USHORT Dpl,
|
||||
IN USHORT Type)
|
||||
{
|
||||
/* Set the handler's address */
|
||||
Idt[Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF);
|
||||
@@ -699,8 +880,8 @@ AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelFaultStack)
|
||||
AR::ProcessorSupport::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelNmiStack)
|
||||
{
|
||||
PKGDTENTRY TaskGateEntry, TssEntry;
|
||||
PKTSS Tss;
|
||||
@@ -716,23 +897,24 @@ AR::ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock
|
||||
Tss = (PKTSS)NonMaskableInterruptTss;
|
||||
Tss->IoMapBase = sizeof(KTSS);
|
||||
Tss->Flags = 0;
|
||||
Tss->LDT = KGDT_R0_LDT;
|
||||
Tss->CR3 = CpuFunc::ReadControlRegister(3);
|
||||
Tss->Esp = (ULONG_PTR)KernelFaultStack;
|
||||
Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
|
||||
Tss->Eip = PtrToUlong(ArTrap0x02);
|
||||
Tss->LDT = 0;
|
||||
Tss->CR3 = AR::CpuFunctions::ReadControlRegister(3);
|
||||
Tss->Esp = (ULONG_PTR)KernelNmiStack;
|
||||
Tss->Esp0 = (ULONG_PTR)KernelNmiStack;
|
||||
Tss->Eip = (ULONG)(ULONG_PTR)ArTrapEntry[0x02];
|
||||
Tss->Cs = KGDT_R0_CODE;
|
||||
Tss->Ds = KGDT_R3_DATA | RPL_MASK;
|
||||
Tss->Es = KGDT_R3_DATA | RPL_MASK;
|
||||
Tss->Fs = KGDT_R0_PB;
|
||||
CpuFunc::StoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss);
|
||||
Tss->Ss = KGDT_R0_DATA;
|
||||
Tss->Ss0 = KGDT_R0_DATA;
|
||||
|
||||
/* Setup NMI TSS entry in Global Descriptor Table */
|
||||
TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_NMI_TSS / sizeof(KGDTENTRY)]));
|
||||
TssEntry->BaseLow = ((ULONG_PTR)Tss & 0xFFFF);
|
||||
TssEntry->Bytes.BaseMiddle = ((ULONG_PTR)Tss >> 16);
|
||||
TssEntry->Bytes.BaseHigh = ((ULONG_PTR)Tss >> 24);
|
||||
TssEntry->LimitLow = sizeof(KTSS) - 1;
|
||||
TssEntry->LimitLow = 0x68;
|
||||
TssEntry->Bits.LimitHigh = 0;
|
||||
TssEntry->Bits.Dpl = 0;
|
||||
TssEntry->Bits.Present = 1;
|
||||
|
||||
@@ -9,6 +9,44 @@
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Dispatches the interrupt provided by common interrupt handler.
|
||||
*
|
||||
* @param TrapFrame
|
||||
* Supplies a kernel trap frame pushed by common interrupt handler on the stack.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::Traps::DispatchInterrupt(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
PINTERRUPT_HANDLER Handler;
|
||||
|
||||
/* Read the handler pointer from the CPU's interrupt dispatch table */
|
||||
Handler = (PINTERRUPT_HANDLER)AR::CpuFunctions::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, InterruptDispatchTable) +
|
||||
(TrapFrame->Vector * sizeof(PINTERRUPT_HANDLER)));
|
||||
|
||||
/* Check if the interrupt has a handler registered */
|
||||
if(Handler != NULLPTR)
|
||||
{
|
||||
/* Call the handler */
|
||||
Handler(TrapFrame);
|
||||
}
|
||||
else if(UnhandledInterruptRoutine != NULLPTR)
|
||||
{
|
||||
/* Call the unhandled interrupt routine */
|
||||
UnhandledInterruptRoutine(TrapFrame);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Dispatcher not initialized, print a debug message */
|
||||
DebugPrint(L"ERROR: Caught unhandled interrupt: 0x%.2lX\n", TrapFrame->Vector);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches the trap provided by common trap handler.
|
||||
*
|
||||
@@ -195,7 +233,6 @@ VOID
|
||||
AR::Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n");
|
||||
KE::Crash::Panic(0x02);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -592,19 +629,19 @@ AR::Traps::HandleTrapFF(IN PKTRAP_FRAME TrapFrame)
|
||||
}
|
||||
|
||||
/**
|
||||
* C-linkage wrapper for dispatching the trap provided by common trap handler.
|
||||
* Sets the unhandled interrupt routine used for vectors that have no handler registered.
|
||||
*
|
||||
* @param TrapFrame
|
||||
* Supplies a kernel trap frame pushed by common trap handler on the stack.
|
||||
* @param Handler
|
||||
* Supplies the pointer to the interrupt handler routine.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
ArDispatchTrap(IN PKTRAP_FRAME TrapFrame)
|
||||
AR::Traps::SetUnhandledInterruptRoutine(PINTERRUPT_HANDLER Handler)
|
||||
{
|
||||
AR::Traps::DispatchTrap(TrapFrame);
|
||||
/* Set the unhandled interrupt routine */
|
||||
UnhandledInterruptRoutine = Handler;
|
||||
}
|
||||
|
||||
43
xtoskrnl/ex/data.cc
Normal file
43
xtoskrnl/ex/data.cc
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ex/data.cc
|
||||
* DESCRIPTION: Kernel Executive global and static data
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Tracks all active non-paged lookaside lists in the system */
|
||||
LIST_ENTRY EX::LookasideList::NonPagedLookasideListHead;
|
||||
|
||||
/* Spinlock protecting the integrity of the NonPagedLookasideListHead */
|
||||
KSPIN_LOCK EX::LookasideList::NonPagedLookasideListLock;
|
||||
|
||||
/* Array of standard system lookaside lists for non-paged pool allocations */
|
||||
GENERAL_LOOKASIDE EX::LookasideList::NonPagedPoolLookasideLists[POOL_LOOKASIDE_LISTS];
|
||||
|
||||
/* Tracks all active paged lookaside lists in the system */
|
||||
LIST_ENTRY EX::LookasideList::PagedLookasideListHead;
|
||||
|
||||
/* Spinlock protecting the integrity of the PagedLookasideListHead */
|
||||
KSPIN_LOCK EX::LookasideList::PagedLookasideListLock;
|
||||
|
||||
/* Array of standard system lookaside lists for paged pool allocations */
|
||||
GENERAL_LOOKASIDE EX::LookasideList::PagedPoolLookasideLists[POOL_LOOKASIDE_LISTS];
|
||||
|
||||
/* Tracks all standard pool lookaside lists */
|
||||
LIST_ENTRY EX::LookasideList::PoolLookasideListHead;
|
||||
|
||||
/* Tracks dynamic system lookaside lists */
|
||||
LIST_ENTRY EX::LookasideList::SystemLookasideListHead;
|
||||
|
||||
/* Specifies the default timeout interval for resource wait operations */
|
||||
LARGE_INTEGER EX::Resources::ResourcesTimeOut;
|
||||
|
||||
/* Tracks all initialized structures currently active in the system */
|
||||
LIST_ENTRY EX::Resources::SystemResourcesList;
|
||||
|
||||
/* The global spinlock that protects the system resources list */
|
||||
KSPIN_LOCK EX::Resources::SystemResourcesLock;
|
||||
453
xtoskrnl/ex/laslist.cc
Normal file
453
xtoskrnl/ex/laslist.cc
Normal file
@@ -0,0 +1,453 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ex/laslist.cc
|
||||
* DESCRIPTION: Lookaside Lists support
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Attempts to allocate a fixed-size buffer from the specified non-paged lookaside list.
|
||||
*
|
||||
* @param LookasideList
|
||||
* Supplies a pointer to the non-paged lookaside list.
|
||||
*
|
||||
* @return Returns a pointer to the allocated buffer, or NULLPTR if the allocation fails.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PVOID
|
||||
EX::LookasideList::AllocateFromLookasideList(IN PNONPAGED_LOOKASIDE_LIST LookasideList)
|
||||
{
|
||||
PVOID Buffer;
|
||||
|
||||
/* Increment the total number of allocation requests */
|
||||
LookasideList->Global.TotalAllocates++;
|
||||
|
||||
/* Attempt to pop an entry from the lookaside list */
|
||||
Buffer = RTL::Atomic::PopEntrySingleList(&LookasideList->Global.ListHead);
|
||||
if(!Buffer)
|
||||
{
|
||||
/* Increment the miss counter */
|
||||
LookasideList->Global.AllocateMisses++;
|
||||
|
||||
/* Fallback to standard pool allocator */
|
||||
(LookasideList->Global.Allocate)(LookasideList->Global.Type, LookasideList->Global.Size,
|
||||
&Buffer, LookasideList->Global.Tag);
|
||||
}
|
||||
|
||||
/* Return the allocated buffer */
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to allocate a fixed-size buffer from the specified paged lookaside list.
|
||||
*
|
||||
* @param LookasideList
|
||||
* Supplies a pointer to the paged lookaside list.
|
||||
*
|
||||
* @return Returns a pointer to the allocated buffer, or NULLPTR if the allocation fails.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PVOID
|
||||
EX::LookasideList::AllocateFromLookasideList(IN PPAGED_LOOKASIDE_LIST LookasideList)
|
||||
{
|
||||
PVOID Buffer;
|
||||
|
||||
/* Increment the total number of allocation requests */
|
||||
LookasideList->Global.TotalAllocates++;
|
||||
|
||||
/* Attempt to pop an entry from the lookaside list */
|
||||
Buffer = RTL::Atomic::PopEntrySingleList(&LookasideList->Global.ListHead);
|
||||
if(!Buffer)
|
||||
{
|
||||
/* Increment the miss counter */
|
||||
LookasideList->Global.AllocateMisses++;
|
||||
|
||||
/* Fallback to standard pool allocator */
|
||||
(LookasideList->Global.Allocate)(LookasideList->Global.Type, LookasideList->Global.Size,
|
||||
&Buffer, LookasideList->Global.Tag);
|
||||
}
|
||||
|
||||
/* Return the allocated buffer */
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates a memory block from the specified per-processor lookaside list.
|
||||
*
|
||||
* @param Number
|
||||
* Supplies the index of the lookaside list to allocate from.
|
||||
*
|
||||
* @return This routine returns a pointer to the allocated memory block, or NULLPTR if allocation fails.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PVOID
|
||||
EX::LookasideList::AllocateFromPerProcessorList(IN NONPAGED_LOOKASIDE_NUMBER Number)
|
||||
{
|
||||
PKPROCESSOR_CONTROL_BLOCK Prcb;
|
||||
PGENERAL_LOOKASIDE Lookaside;
|
||||
PVOID Entry;
|
||||
|
||||
/* Retrieve the current Processor Control Block */
|
||||
Prcb = KE::Processor::GetCurrentProcessorControlBlock();
|
||||
|
||||
/* Target the processor's local lookaside list and increment the tracking metric */
|
||||
Lookaside = Prcb->LookasideList[Number].Local;
|
||||
Lookaside->TotalAllocates++;
|
||||
|
||||
/* Attempt a pop from the local list */
|
||||
Entry = RTL::Atomic::PopEntrySingleList(&Lookaside->ListHead);
|
||||
if(Entry != NULLPTR)
|
||||
{
|
||||
/* Return the retrieved a pre-allocated block */
|
||||
return Entry;
|
||||
}
|
||||
|
||||
/* Record a local cache miss */
|
||||
Lookaside->AllocateMisses++;
|
||||
Lookaside->TotalAllocates++;
|
||||
|
||||
/* Switch the target to the shared global lookaside list */
|
||||
Lookaside = Prcb->LookasideList[Number].Global;
|
||||
|
||||
/* Attempt a pop from the global list */
|
||||
Entry = RTL::Atomic::PopEntrySingleList(&Lookaside->ListHead);
|
||||
if(Entry != NULLPTR)
|
||||
{
|
||||
/* Return the retrieved a pre-allocated block */
|
||||
return Entry;
|
||||
}
|
||||
|
||||
/* Both caches are saturated, record a miss */
|
||||
Lookaside->AllocateMisses++;
|
||||
|
||||
/* Invoke the pool allocator */
|
||||
(Lookaside->Allocate)(Lookaside->Type, Lookaside->Size, &Entry, Lookaside->Tag);
|
||||
|
||||
/* Return the newly allocated block */
|
||||
return Entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a previously allocated memory block to the specified non-paged lookaside list.
|
||||
*
|
||||
* @param LookasideList
|
||||
* Supplies a pointer to the non-paged lookaside list.
|
||||
*
|
||||
* @param Entry
|
||||
* Supplies a pointer to the memory block being freed.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
EX::LookasideList::FreeToLookasideList(IN PNONPAGED_LOOKASIDE_LIST LookasideList,
|
||||
IN PVOID Entry)
|
||||
{
|
||||
/* Increment the tracking metric */
|
||||
LookasideList->Global.TotalFrees++;
|
||||
|
||||
/* Verify if the lookaside list has reached its maximum capacity threshold */
|
||||
if(RTL::SinglyList::QueryListDepth(&LookasideList->Global.ListHead) >= LookasideList->Global.Depth)
|
||||
{
|
||||
/* The list is full, record a capacity miss */
|
||||
LookasideList->Global.FreeMisses++;
|
||||
(LookasideList->Global.Free)(Entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Push the block onto the lookaside list */
|
||||
RTL::Atomic::PushEntrySingleList(&LookasideList->Global.ListHead, (PSINGLE_LIST_ENTRY)Entry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a previously allocated memory block to the specified paged lookaside list.
|
||||
*
|
||||
* @param LookasideList
|
||||
* Supplies a pointer to the paged lookaside list.
|
||||
*
|
||||
* @param Entry
|
||||
* Supplies a pointer to the memory block being freed.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
EX::LookasideList::FreeToLookasideList(IN PPAGED_LOOKASIDE_LIST LookasideList,
|
||||
IN PVOID Entry)
|
||||
{
|
||||
/* Increment the tracking metric */
|
||||
LookasideList->Global.TotalFrees++;
|
||||
|
||||
/* Verify if the lookaside list has reached its maximum capacity threshold */
|
||||
if(RTL::SinglyList::QueryListDepth(&LookasideList->Global.ListHead) >= LookasideList->Global.Depth)
|
||||
{
|
||||
/* The list is full, record a capacity miss */
|
||||
LookasideList->Global.FreeMisses++;
|
||||
(LookasideList->Global.Free)(Entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Push the block onto the lookaside list */
|
||||
RTL::Atomic::PushEntrySingleList(&LookasideList->Global.ListHead, (PSINGLE_LIST_ENTRY)Entry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees a memory block back to the specified per-processor lookaside list.
|
||||
*
|
||||
* @param Number
|
||||
* Supplies the index of the lookaside list receiving the freed block.
|
||||
*
|
||||
* @param Entry
|
||||
* Supplies a pointer to the memory block being freed.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
EX::LookasideList::FreeToPerProcessorList(IN NONPAGED_LOOKASIDE_NUMBER Number,
|
||||
IN PVOID Entry)
|
||||
{
|
||||
PKPROCESSOR_CONTROL_BLOCK Prcb;
|
||||
PGENERAL_LOOKASIDE Lookaside;
|
||||
|
||||
/* Retrieve the current Processor Control Block */
|
||||
Prcb = KE::Processor::GetCurrentProcessorControlBlock();
|
||||
|
||||
/* Target the processor's local lookaside list and increment the tracking metric */
|
||||
Lookaside = Prcb->LookasideList[Number].Local;
|
||||
Lookaside->TotalFrees += 1;
|
||||
|
||||
/* Check if the lookaside list has reached its maximum capacity threshold */
|
||||
if(RTL::SinglyList::QueryListDepth(&Lookaside->ListHead) >= Lookaside->Depth)
|
||||
{
|
||||
/* The local list is full, record a capacity miss */
|
||||
Lookaside->FreeMisses++;
|
||||
Lookaside->TotalFrees++;
|
||||
|
||||
/* Switch the target to the shared global lookaside list */
|
||||
Lookaside = Prcb->LookasideList[Number].Global;
|
||||
|
||||
/* Check if the lookaside list has reached its maximum capacity threshold */
|
||||
if(RTL::SinglyList::QueryListDepth(&Lookaside->ListHead) >= Lookaside->Depth)
|
||||
{
|
||||
/* Both caches are saturated, record a miss */
|
||||
Lookaside->FreeMisses++;
|
||||
(Lookaside->Free)(Entry);
|
||||
|
||||
/* Exit the routine */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Push the block onto the selected lookaside list */
|
||||
RTL::Atomic::PushEntrySingleList(&Lookaside->ListHead, (PSINGLE_LIST_ENTRY)Entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a generic lookaside list and inserts it into the tracking list.
|
||||
*
|
||||
* @param LookasideList
|
||||
* Supplies a pointer to the general lookaside list structure to initialize.
|
||||
*
|
||||
* @param PoolType
|
||||
* Supplies the type of memory pool to be allocated.
|
||||
*
|
||||
* @param Size
|
||||
* Supplies the size, in bytes, of the entries to be allocated from the lookaside list.
|
||||
*
|
||||
* @param Tag
|
||||
* Supplies the pool tag to be used for allocations.
|
||||
*
|
||||
* @param MaxDepth
|
||||
* Supplies the maximum number of entries the lookaside list should hold.
|
||||
*
|
||||
* @param ListHead
|
||||
* Supplies a pointer to the linked list header used to track this lookaside list.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
EX::LookasideList::InitializeLookasideList(IN OUT PGENERAL_LOOKASIDE LookasideList,
|
||||
IN MMPOOL_TYPE PoolType,
|
||||
IN ULONG Size,
|
||||
IN ULONG Tag,
|
||||
IN USHORT MaxDepth,
|
||||
IN PLIST_ENTRY ListHead)
|
||||
{
|
||||
/* Initialize the singly linked list header and insert it into the tracking list */
|
||||
RTL::SinglyList::InitializeListHead(&LookasideList->ListHead);
|
||||
RTL::LinkedList::InsertTailList(ListHead, &LookasideList->ListEntry);
|
||||
|
||||
/* Initialize lookaside list properties */
|
||||
LookasideList->Allocate = &MM::Allocator::AllocatePool;
|
||||
LookasideList->AllocateHits = 0;
|
||||
LookasideList->Depth = 2;
|
||||
LookasideList->Free = &MM::Allocator::FreePool;
|
||||
LookasideList->FreeHits = 0;
|
||||
LookasideList->LastAllocateHits = 0;
|
||||
LookasideList->LastTotalAllocates = 0;
|
||||
LookasideList->MaximumDepth = MaxDepth;
|
||||
LookasideList->Size = Size;
|
||||
LookasideList->Tag = Tag;
|
||||
LookasideList->TotalAllocates = 0;
|
||||
LookasideList->TotalFrees = 0;
|
||||
LookasideList->Type = PoolType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the per-processor lookaside list pointers.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
EX::LookasideList::InitializePointers(VOID)
|
||||
{
|
||||
PGENERAL_LOOKASIDE LookasideList;
|
||||
PKPROCESSOR_CONTROL_BLOCK Prcb;
|
||||
ULONG Index, Offset;
|
||||
XTSTATUS Status;
|
||||
|
||||
/* Retrieve the processor control block */
|
||||
Prcb = KE::Processor::GetCurrentProcessorControlBlock();
|
||||
|
||||
/* Allocate a contiguous memory block for lookaside lists */
|
||||
Status = MM::Allocator::AllocatePool(NonPagedPool, sizeof(GENERAL_LOOKASIDE) * POOL_LOOKASIDE_LISTS * 2,
|
||||
(PVOID*)&LookasideList, TAG_MM_MEMORY_POOL);
|
||||
|
||||
/* Initialize both non-paged and paged lookaside lists for all pool indexes */
|
||||
for(Index = 0; Index < POOL_LOOKASIDE_LISTS; Index++)
|
||||
{
|
||||
/* Wire the global pointer for the non-paged lookaside list */
|
||||
Prcb->NonPagedLookasideList[Index].Global = &NonPagedPoolLookasideLists[Index];
|
||||
|
||||
/* Check if the contiguous allocation was successful */
|
||||
if(Status == STATUS_SUCCESS && LookasideList)
|
||||
{
|
||||
/* Map the pointer to the first half of the contiguous block */
|
||||
Prcb->NonPagedLookasideList[Index].Local = &LookasideList[Index];
|
||||
|
||||
/* Initialize the local non-paged list */
|
||||
EX::LookasideList::InitializeLookasideList(&LookasideList[Index], NonPagedPool,
|
||||
(Index + 1) * 8, TAG_MM_MEMORY_POOL,
|
||||
256, &PoolLookasideListHead);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Allocation failed, use shared global list */
|
||||
Prcb->NonPagedLookasideList[Index].Local = &NonPagedPoolLookasideLists[Index];
|
||||
}
|
||||
|
||||
/* Wire the global pointer for the paged lookaside list */
|
||||
Prcb->PagedLookasideList[Index].Global = &PagedPoolLookasideLists[Index];
|
||||
|
||||
/* Check if the contiguous allocation was successful */
|
||||
if(Status == STATUS_SUCCESS && LookasideList)
|
||||
{
|
||||
/* Calculate the offset into the second half of the contiguous memory block */
|
||||
Offset = POOL_LOOKASIDE_LISTS + Index;
|
||||
|
||||
/* Map the pointer to the second half of the contiguous block */
|
||||
Prcb->PagedLookasideList[Index].Local = &LookasideList[Offset];
|
||||
|
||||
/* Initialize the local paged list */
|
||||
EX::LookasideList::InitializeLookasideList(&LookasideList[Offset], PagedPool,
|
||||
(Index + 1) * 8, TAG_MM_MEMORY_POOL,
|
||||
256, &PoolLookasideListHead);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Allocation failed, use shared global list */
|
||||
Prcb->PagedLookasideList[Index].Local = &PagedPoolLookasideLists[Index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes global system lookaside lists and their synchronization primitives.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
EX::LookasideList::InitializeSystemLookasideLists(VOID)
|
||||
{
|
||||
ULONG Index;
|
||||
|
||||
/* Initialize spinlocks for protecting lookaside list operations */
|
||||
KE::SpinLock::InitializeSpinLock(&NonPagedLookasideListLock);
|
||||
KE::SpinLock::InitializeSpinLock(&PagedLookasideListLock);
|
||||
|
||||
/* Initialize global list heads for tracking various types of lookaside lists */
|
||||
RTL::LinkedList::InitializeListHead(&NonPagedLookasideListHead);
|
||||
RTL::LinkedList::InitializeListHead(&PagedLookasideListHead);
|
||||
RTL::LinkedList::InitializeListHead(&PoolLookasideListHead);
|
||||
RTL::LinkedList::InitializeListHead(&SystemLookasideListHead);
|
||||
|
||||
/* Initialize standard pool lookaside lists */
|
||||
for(Index = 0; Index < POOL_LOOKASIDE_LISTS; Index++)
|
||||
{
|
||||
/* Initialize non-paged pool lookaside list */
|
||||
InitializeLookasideList(&NonPagedPoolLookasideLists[Index], NonPagedPool, (Index + 1) * 8,
|
||||
TAG_MM_MEMORY_POOL, 256, &PoolLookasideListHead);
|
||||
|
||||
/* Initialize paged pool lookaside list */
|
||||
InitializeLookasideList(&PagedPoolLookasideLists[Index], PagedPool, (Index + 1) * 8,
|
||||
TAG_MM_MEMORY_POOL, 256, &PoolLookasideListHead);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the head of the pool lookaside list tracker.
|
||||
*
|
||||
* @return This routine returns a pointer to the global pool lookaside list head.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PLIST_ENTRY
|
||||
EX::LookasideList::GetPoolLookasideListHead(VOID)
|
||||
{
|
||||
/* Return the head of the pool lookaside list */
|
||||
return &PoolLookasideListHead;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the head of the system-wide lookaside list tracker.
|
||||
*
|
||||
* @return This routine returns a pointer to the global system lookaside list head.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PLIST_ENTRY
|
||||
EX::LookasideList::GetSystemLookasideListHead(VOID)
|
||||
{
|
||||
/* Return the head of the pool lookaside list */
|
||||
return &SystemLookasideListHead;
|
||||
}
|
||||
169
xtoskrnl/ex/resource.cc
Normal file
169
xtoskrnl/ex/resource.cc
Normal file
@@ -0,0 +1,169 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ex/resource.cc
|
||||
* DESCRIPTION: Exclusive resource synchronization support
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Deletes a system resource and frees its associated memory allocations.
|
||||
*
|
||||
* @param Resource
|
||||
* Supplies a pointer to the resource to be deleted.
|
||||
*
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
EX::Resources::DeleteResource(IN PERESOURCE Resource)
|
||||
{
|
||||
/* Start a guarded code block */
|
||||
{
|
||||
/* Raise runlevel to DISPATCH level and acquire system resources lock */
|
||||
KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);
|
||||
KE::QueuedSpinLockGuard Guard(&SystemResourcesLock);
|
||||
|
||||
/* Remove the resource from the system resource list */
|
||||
RTL::LinkedList::RemoveEntryList(&Resource->SystemResourcesList);
|
||||
}
|
||||
|
||||
/* Check if exclusive waiters event exists */
|
||||
if(Resource->ExclusiveWaiters)
|
||||
{
|
||||
/* Free the exclusive waiters event */
|
||||
MM::Allocator::FreePool(Resource->ExclusiveWaiters);
|
||||
}
|
||||
|
||||
/* Check if owner table exists */
|
||||
if(Resource->OwnerTable)
|
||||
{
|
||||
/* Free the owner table */
|
||||
MM::Allocator::FreePool(Resource->OwnerTable);
|
||||
}
|
||||
|
||||
/* Check if shared waiters semaphore exists */
|
||||
if(Resource->SharedWaiters)
|
||||
{
|
||||
/* Free the shared waiters semaphore */
|
||||
MM::Allocator::FreePool(Resource->SharedWaiters);
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a system resource object.
|
||||
*
|
||||
* @param Resource
|
||||
* Supplies a pointer to the resource structure to be initialized.
|
||||
*
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
EX::Resources::InitializeResource(IN PERESOURCE Resource)
|
||||
{
|
||||
/* Clear the entire resource structure */
|
||||
RTL::Memory::ZeroMemory(Resource, sizeof(ERESOURCE));
|
||||
|
||||
/* Initialize the spinlock used for managing this resource */
|
||||
KE::SpinLock::InitializeSpinLock(&Resource->SpinLock);
|
||||
|
||||
/* Raise runlevel to DISPATCH level and acquire the global system resources lock */
|
||||
KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);
|
||||
KE::QueuedSpinLockGuard Guard(&SystemResourcesLock);
|
||||
|
||||
/* Insert the resource into the global tracking list */
|
||||
RTL::LinkedList::InsertTailList(&SystemResourcesList, &Resource->SystemResourcesList);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the global system resource structures and synchronization primitives.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
EX::Resources::InitializeSystemResources(VOID)
|
||||
{
|
||||
/* Set the default timeout for resource operations to 4 seconds relative to now */
|
||||
ResourcesTimeOut.QuadPart = -40000000LL;
|
||||
|
||||
/* Initialize the global system resources list and its protecting spinlock */
|
||||
RTL::LinkedList::InitializeListHead(&SystemResourcesList);
|
||||
KE::SpinLock::InitializeSpinLock(&SystemResourcesLock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reinitializes an existing resource object, resetting its state and synchronization primitives.
|
||||
*
|
||||
* @param Resource
|
||||
* Supplies a pointer to the resource structure to be reinitialized.
|
||||
*
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
EX::Resources::ReinitializeResource(IN PERESOURCE Resource)
|
||||
{
|
||||
ULONG Index;
|
||||
|
||||
/* Zero the active count and flags */
|
||||
Resource->ActiveCount = 0;
|
||||
Resource->ActiveEntries = 0;
|
||||
Resource->Flag = 0;
|
||||
|
||||
/* Zero the contention count and counters */
|
||||
Resource->ContentionCount = 0;
|
||||
Resource->NumberOfSharedWaiters = 0;
|
||||
Resource->NumberOfExclusiveWaiters = 0;
|
||||
|
||||
/* Zero the owner entry */
|
||||
Resource->OwnerEntry.OwnerThread = 0;
|
||||
Resource->OwnerEntry.TableSize = 0;
|
||||
|
||||
/* Check if exclusive waiters event exists */
|
||||
if(Resource->ExclusiveWaiters)
|
||||
{
|
||||
/* Reinitialize the event */
|
||||
KE::Event::InitializeEvent(Resource->ExclusiveWaiters, SynchronizationEvent, FALSE);
|
||||
}
|
||||
|
||||
/* Check if owner table exists */
|
||||
if(Resource->OwnerTable)
|
||||
{
|
||||
/* Iterate over the owner table */
|
||||
for(Index = 1; Index < Resource->OwnerTable->TableSize; Index++)
|
||||
{
|
||||
/* Zero the owner table */
|
||||
Resource->OwnerTable[Index].OwnerCount = 0;
|
||||
Resource->OwnerTable[Index].OwnerThread = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if shared waiters semaphore exists */
|
||||
if(Resource->SharedWaiters)
|
||||
{
|
||||
/* Reinitialize the semaphore */
|
||||
KE::Semaphore::InitializeSemaphore(Resource->SharedWaiters, 0, MAXLONG);
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
* FILE: xtoskrnl/ex/rundown.cc
|
||||
* DESCRIPTION: Rundown protection mechanism
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
@@ -17,11 +18,33 @@
|
||||
*
|
||||
* @return This routine returns TRUE if protection acquired successfully, or FALSE otherwise.
|
||||
*
|
||||
* @since NT 5.1
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTFASTCALL
|
||||
BOOLEAN
|
||||
EX::Rundown::AcquireProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
|
||||
{
|
||||
/* Acquire protection */
|
||||
return AcquireProtection(Descriptor, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquires the rundown protection for given descriptor.
|
||||
*
|
||||
* @param Descriptor
|
||||
* Supplies a pointer to the rundown block descriptor.
|
||||
*
|
||||
* @param Count
|
||||
* Supplies the number of times the protection should be acquired.
|
||||
*
|
||||
* @return This routine returns TRUE if protection acquired successfully, or FALSE otherwise.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTFASTCALL
|
||||
BOOLEAN
|
||||
EX::Rundown::AcquireProtection(IN PEX_RUNDOWN_REFERENCE Descriptor,
|
||||
IN ULONG Count)
|
||||
{
|
||||
ULONG_PTR CurrentValue, NewValue;
|
||||
|
||||
@@ -39,7 +62,7 @@ EX::Rundown::AcquireProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
|
||||
}
|
||||
|
||||
/* Attempt to increment the usage count */
|
||||
NewValue = CurrentValue + 2;
|
||||
NewValue = CurrentValue + 2 * Count;
|
||||
|
||||
/* Exchange the value */
|
||||
NewValue = (ULONG_PTR)RTL::Atomic::CompareExchangePointer(&Descriptor->Ptr, (PVOID)NewValue,
|
||||
@@ -65,12 +88,13 @@ EX::Rundown::AcquireProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since NT 5.1
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTFASTCALL
|
||||
VOID
|
||||
EX::Rundown::CompleteProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
|
||||
{
|
||||
/* Mark the descriptor as completely run down */
|
||||
RTL::Atomic::ExchangePointer(&Descriptor->Ptr, (PVOID)EX_RUNDOWN_ACTIVE);
|
||||
}
|
||||
|
||||
@@ -82,7 +106,7 @@ EX::Rundown::CompleteProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since NT 5.1
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTFASTCALL
|
||||
VOID
|
||||
@@ -100,12 +124,13 @@ EX::Rundown::InitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since NT 5.1
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTFASTCALL
|
||||
VOID
|
||||
EX::Rundown::ReInitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
|
||||
{
|
||||
/* Reset the descriptor to its initial state */
|
||||
RTL::Atomic::ExchangePointer(&Descriptor->Ptr, NULLPTR);
|
||||
}
|
||||
|
||||
@@ -117,44 +142,76 @@ EX::Rundown::ReInitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since NT 5.1
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTFASTCALL
|
||||
VOID
|
||||
EX::Rundown::ReleaseProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
|
||||
{
|
||||
/* Release protection */
|
||||
ReleaseProtection(Descriptor, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases the rundown protection for given descriptor.
|
||||
*
|
||||
* @param Descriptor
|
||||
* Supplies a pointer to the descriptor to be initialized.
|
||||
*
|
||||
* @param Count
|
||||
* Supplies the number of references to release.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTFASTCALL
|
||||
VOID
|
||||
EX::Rundown::ReleaseProtection(IN PEX_RUNDOWN_REFERENCE Descriptor,
|
||||
IN ULONG Count)
|
||||
{
|
||||
ULONG_PTR CurrentValue, NewValue;
|
||||
PEX_RUNDOWN_WAIT_BLOCK WaitBlock;
|
||||
|
||||
/* Read the current state of the rundown descriptor */
|
||||
CurrentValue = Descriptor->Count;
|
||||
|
||||
/* Enter a CAS loop */
|
||||
while(TRUE)
|
||||
{
|
||||
/* Check if the rundown is currently active */
|
||||
if(CurrentValue & 0x1)
|
||||
{
|
||||
/* Extract the pointer to the wait block */
|
||||
WaitBlock = (PEX_RUNDOWN_WAIT_BLOCK)(CurrentValue & ~0x1);
|
||||
|
||||
/* Decrement the pending reference count */
|
||||
if(!RTL::Atomic::Decrement64((PLONG_PTR)&WaitBlock->Count))
|
||||
{
|
||||
/* Signal the event to wake up the teardown thread */
|
||||
KE::Event::SetEvent(&WaitBlock->WakeEvent, 0, FALSE);
|
||||
}
|
||||
|
||||
/* Break the loop */
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Attempt to decrement the usage count */
|
||||
NewValue = CurrentValue - 2;
|
||||
NewValue = CurrentValue - 2 * Count;
|
||||
|
||||
/* Exchange the value */
|
||||
NewValue = (ULONG_PTR)RTL::Atomic::CompareExchangePointer(&Descriptor->Ptr, (PVOID)NewValue,
|
||||
(PVOID)CurrentValue);
|
||||
|
||||
/* Check if the atomic swap succeeded without interference from other processors */
|
||||
if(NewValue == CurrentValue)
|
||||
{
|
||||
/* Reference count is decremented, break the loop */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Collision detected, update current state and retry */
|
||||
CurrentValue = NewValue;
|
||||
}
|
||||
}
|
||||
@@ -168,7 +225,7 @@ EX::Rundown::ReleaseProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since NT 5.1
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTFASTCALL
|
||||
VOID
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* FILE: xtoskrnl/hl/x86/acpi.cc
|
||||
* DESCRIPTION: Advanced Configuration and Power Interface (ACPI) support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
@@ -25,8 +26,21 @@ HL::Acpi::CacheAcpiTable(IN PACPI_DESCRIPTION_HEADER AcpiTable)
|
||||
{
|
||||
PACPI_CACHE_LIST AcpiCache;
|
||||
|
||||
/* Create new ACPI table cache entry */
|
||||
AcpiCache = CONTAIN_RECORD(AcpiTable, ACPI_CACHE_LIST, Header);
|
||||
/* Check if there are free slots in static early-boot cache array */
|
||||
if(CacheCount >= ACPI_MAX_CACHED_TABLES)
|
||||
{
|
||||
/* Cache is full, the table is mapped but not cached */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the next available static cache entry */
|
||||
AcpiCache = &CacheEntries[CacheCount];
|
||||
CacheCount++;
|
||||
|
||||
/* Store the pointer to the mapped ACPI table */
|
||||
AcpiCache->Table = AcpiTable;
|
||||
|
||||
/* Insert entry into the global ACPI cache list */
|
||||
RTL::LinkedList::InsertTailList(&CacheList, &AcpiCache->ListEntry);
|
||||
}
|
||||
|
||||
@@ -36,7 +50,7 @@ HL::Acpi::CacheAcpiTable(IN PACPI_DESCRIPTION_HEADER AcpiTable)
|
||||
* @param Rsdp
|
||||
* Supplies a pointer to the memory area, where RSDP virtual address will be stored.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -58,7 +72,7 @@ HL::Acpi::GetAcpiSystemDescriptionPointer(OUT PACPI_RSDP *Rsdp)
|
||||
* @param AcpiTable
|
||||
* Supplies a pointer to memory area where ACPI table virtual address will be stored.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -91,10 +105,50 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ACPI system information structure containing processor and topology data.
|
||||
*
|
||||
* @param SystemInfo
|
||||
* Supplies a pointer to the memory area where the pointer to the system information structure will be stored.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Acpi::GetSystemInformation(OUT PACPI_SYSTEM_INFO *SystemInfo)
|
||||
{
|
||||
/* Return a pointer to the ACPI system information */
|
||||
*SystemInfo = &HL::Acpi::SystemInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an initialization of the ACPI subsystem.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -131,7 +185,7 @@ HL::Acpi::InitializeAcpi(VOID)
|
||||
/**
|
||||
* Initializes the kernel's local ACPI cache storage.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -166,7 +220,7 @@ HL::Acpi::InitializeAcpiCache(VOID)
|
||||
* @param AcpiTable
|
||||
* Supplies a pointer to memory area where ACPI table virtual address will be stored.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -196,14 +250,23 @@ HL::Acpi::InitializeAcpiSystemDescriptionTable(OUT PACPI_DESCRIPTION_HEADER *Acp
|
||||
AcpiResource = (PSYSTEM_RESOURCE_ACPI)ResourceHeader;
|
||||
RsdpAddress.QuadPart = (LONGLONG)AcpiResource->Header.PhysicalAddress;
|
||||
|
||||
/* Map RSDP and mark it as CD/WT to avoid delays in write-back cache */
|
||||
/* Map RSDP using hardware memory pool */
|
||||
Status = MM::HardwarePool::MapHardwareMemory(RsdpAddress, 1, TRUE, (PVOID *)&RsdpStructure);
|
||||
if(Status != STATUS_SUCCESS)
|
||||
{
|
||||
/* Failed to map RSDP, return error */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Mark RSDP as CD/WT to avoid delays in write-back cache */
|
||||
MM::HardwarePool::MarkHardwareMemoryWriteThrough(RsdpStructure, 1);
|
||||
|
||||
/* Validate RSDP signature */
|
||||
if(Status != STATUS_SUCCESS || RsdpStructure->Signature != ACPI_RSDP_SIGNATURE)
|
||||
if(RsdpStructure->Signature != ACPI_RSDP_SIGNATURE)
|
||||
{
|
||||
/* Not mapped correctly or invalid RSDP signature, return error */
|
||||
/* Invalid RSDP signature, unmap and return error */
|
||||
MM::HardwarePool::UnmapHardwareMemory(RsdpStructure, 1, TRUE);
|
||||
RsdpStructure = NULLPTR;
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
@@ -219,34 +282,40 @@ HL::Acpi::InitializeAcpiSystemDescriptionTable(OUT PACPI_DESCRIPTION_HEADER *Acp
|
||||
RsdtAddress.QuadPart = (LONGLONG)RsdpStructure->RsdtAddress;
|
||||
}
|
||||
|
||||
/* Map RSDT/XSDT as CD/WT */
|
||||
/* Map RSDT/XSDT using hardware memory pool */
|
||||
Status = MM::HardwarePool::MapHardwareMemory(RsdtAddress, 2, TRUE, (PVOID *)&Rsdt);
|
||||
if(Status != STATUS_SUCCESS)
|
||||
{
|
||||
/* Failed to map RSDT/XSDT, return error */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Mark RSDT/XSDT as CD/WT */
|
||||
MM::HardwarePool::MarkHardwareMemoryWriteThrough(Rsdt, 2);
|
||||
|
||||
/* Validate RSDT/XSDT signature */
|
||||
if((Status != STATUS_SUCCESS) ||
|
||||
(Rsdt->Header.Signature != ACPI_RSDT_SIGNATURE &&
|
||||
Rsdt->Header.Signature != ACPI_XSDT_SIGNATURE))
|
||||
if(Rsdt->Header.Signature != ACPI_RSDT_SIGNATURE && Rsdt->Header.Signature != ACPI_XSDT_SIGNATURE)
|
||||
{
|
||||
/* Not mapped correctly or invalid RSDT/XSDT signature, return error */
|
||||
/* Not mapped correctly or invalid RSDT/XSDT signature, unmap and return error */
|
||||
MM::HardwarePool::UnmapHardwareMemory(Rsdt, 2, TRUE);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Calculate the length of all available ACPI tables and remap it if needed */
|
||||
RsdtPages = ((RsdtAddress.LowPart & (MM_PAGE_SIZE - 1)) + Rsdt->Header.Length + (MM_PAGE_SIZE - 1)) >> MM_PAGE_SHIFT;
|
||||
RsdtPages = (((RsdtAddress.LowPart & (MM_PAGE_SIZE - 1)) + Rsdt->Header.Length + (MM_PAGE_SIZE - 1)) >> MM_PAGE_SHIFT);
|
||||
if(RsdtPages != 2)
|
||||
{
|
||||
/* RSDT/XSDT needs less or more than 2 pages, remap it */
|
||||
MM::HardwarePool::UnmapHardwareMemory(Rsdt, 2, TRUE);
|
||||
Status = MM::HardwarePool::MapHardwareMemory(RsdtAddress, RsdtPages, TRUE, (PVOID *)&Rsdt);
|
||||
MM::HardwarePool::MarkHardwareMemoryWriteThrough(Rsdt, RsdtPages);
|
||||
|
||||
/* Make sure remapping was successful */
|
||||
if(Status != STATUS_SUCCESS)
|
||||
{
|
||||
/* Remapping failed, return error */
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* Mark remapped RSDT/XSDT as CD/WT */
|
||||
MM::HardwarePool::MarkHardwareMemoryWriteThrough(Rsdt, RsdtPages);
|
||||
}
|
||||
|
||||
/* Get ACPI table header and return success */
|
||||
@@ -257,7 +326,7 @@ HL::Acpi::InitializeAcpiSystemDescriptionTable(OUT PACPI_DESCRIPTION_HEADER *Acp
|
||||
/**
|
||||
* Initializes System Information structure based on the ACPI provided data.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -267,6 +336,7 @@ HL::Acpi::InitializeAcpiSystemInformation(VOID)
|
||||
{
|
||||
PACPI_MADT_LOCAL_X2APIC LocalX2Apic;
|
||||
PACPI_MADT_LOCAL_APIC LocalApic;
|
||||
PACPI_SUBTABLE_HEADER SubTable;
|
||||
ULONG_PTR MadtTable;
|
||||
PACPI_MADT Madt;
|
||||
XTSTATUS Status;
|
||||
@@ -293,11 +363,20 @@ HL::Acpi::InitializeAcpiSystemInformation(VOID)
|
||||
CpuCount = 0;
|
||||
|
||||
/* Traverse all MADT tables to get system information */
|
||||
while(MadtTable <= ((ULONG_PTR)Madt + Madt->Header.Length))
|
||||
while(MadtTable < ((ULONG_PTR)Madt + Madt->Header.Length))
|
||||
{
|
||||
/* Get current MADT subtable header */
|
||||
SubTable = (PACPI_SUBTABLE_HEADER)MadtTable;
|
||||
|
||||
/* Prevent infinite loops if BIOS provides 0 length */
|
||||
if(SubTable->Length == 0)
|
||||
{
|
||||
/* Broken ACPI table, abort traversal */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if this is a local APIC subtable */
|
||||
if((((PACPI_SUBTABLE_HEADER)MadtTable)->Type == ACPI_MADT_TYPE_LOCAL_APIC) &&
|
||||
(((PACPI_SUBTABLE_HEADER)MadtTable)->Length == sizeof(ACPI_MADT_LOCAL_APIC)))
|
||||
if(SubTable->Type == ACPI_MADT_TYPE_LOCAL_APIC && SubTable->Length >= sizeof(ACPI_MADT_LOCAL_APIC))
|
||||
{
|
||||
/* Get local APIC subtable */
|
||||
LocalApic = (PACPI_MADT_LOCAL_APIC)MadtTable;
|
||||
@@ -313,12 +392,8 @@ HL::Acpi::InitializeAcpiSystemInformation(VOID)
|
||||
/* Increment number of CPUs */
|
||||
CpuCount++;
|
||||
}
|
||||
|
||||
/* Go to the next MADT table */
|
||||
MadtTable += ((PACPI_SUBTABLE_HEADER)MadtTable)->Length;
|
||||
}
|
||||
else if((((PACPI_SUBTABLE_HEADER)MadtTable)->Type == ACPI_MADT_TYPE_LOCAL_X2APIC) &&
|
||||
(((PACPI_SUBTABLE_HEADER)MadtTable)->Length == sizeof(ACPI_MADT_LOCAL_X2APIC)))
|
||||
else if(SubTable->Type == ACPI_MADT_TYPE_LOCAL_X2APIC && SubTable->Length >= sizeof(ACPI_MADT_LOCAL_X2APIC))
|
||||
{
|
||||
/* Get local X2APIC subtable */
|
||||
LocalX2Apic = (PACPI_MADT_LOCAL_X2APIC)MadtTable;
|
||||
@@ -334,15 +409,10 @@ HL::Acpi::InitializeAcpiSystemInformation(VOID)
|
||||
/* Increment number of CPUs */
|
||||
CpuCount++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Go to the next MADT table */
|
||||
MadtTable += ((PACPI_SUBTABLE_HEADER)MadtTable)->Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Any other MADT table, try to go to the next one byte-by-byte */
|
||||
MadtTable += 1;
|
||||
}
|
||||
/* Safely advance pointer using proper subtable length */
|
||||
MadtTable += SubTable->Length;
|
||||
}
|
||||
|
||||
/* Store number of CPUs */
|
||||
@@ -355,7 +425,7 @@ HL::Acpi::InitializeAcpiSystemInformation(VOID)
|
||||
/**
|
||||
* Initializes ACPI System Information data structure based on the size of available ACPI data.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -364,6 +434,7 @@ XTSTATUS
|
||||
HL::Acpi::InitializeAcpiSystemStructure(VOID)
|
||||
{
|
||||
PHYSICAL_ADDRESS PhysicalAddress;
|
||||
PACPI_SUBTABLE_HEADER SubTable;
|
||||
PFN_NUMBER PageCount;
|
||||
ULONG_PTR MadtTable;
|
||||
PACPI_MADT Madt;
|
||||
@@ -383,11 +454,19 @@ 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((((PACPI_SUBTABLE_HEADER)MadtTable)->Type == ACPI_MADT_TYPE_LOCAL_APIC) &&
|
||||
(((PACPI_SUBTABLE_HEADER)MadtTable)->Length == sizeof(ACPI_MADT_LOCAL_APIC)))
|
||||
if(SubTable->Type == ACPI_MADT_TYPE_LOCAL_APIC && SubTable->Length >= sizeof(ACPI_MADT_LOCAL_APIC))
|
||||
{
|
||||
/* Make sure, this CPU can be enabled */
|
||||
if(((PACPI_MADT_LOCAL_APIC)MadtTable)->Flags & ACPI_MADT_PLAOC_ENABLED)
|
||||
@@ -395,12 +474,8 @@ HL::Acpi::InitializeAcpiSystemStructure(VOID)
|
||||
/* Increment number of CPUs */
|
||||
CpuCount++;
|
||||
}
|
||||
|
||||
/* Go to the next MADT table */
|
||||
MadtTable += ((PACPI_SUBTABLE_HEADER)MadtTable)->Length;
|
||||
}
|
||||
else if((((PACPI_SUBTABLE_HEADER)MadtTable)->Type == ACPI_MADT_TYPE_LOCAL_X2APIC) &&
|
||||
(((PACPI_SUBTABLE_HEADER)MadtTable)->Length == sizeof(ACPI_MADT_LOCAL_X2APIC)))
|
||||
else if(SubTable->Type == ACPI_MADT_TYPE_LOCAL_X2APIC && SubTable->Length >= sizeof(ACPI_MADT_LOCAL_X2APIC))
|
||||
{
|
||||
/* Make sure, this CPU can be enabled */
|
||||
if(((PACPI_MADT_LOCAL_X2APIC)MadtTable)->Flags & ACPI_MADT_PLAOC_ENABLED)
|
||||
@@ -408,15 +483,10 @@ HL::Acpi::InitializeAcpiSystemStructure(VOID)
|
||||
/* Increment number of CPUs */
|
||||
CpuCount++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Go to the next MADT table */
|
||||
MadtTable += ((PACPI_SUBTABLE_HEADER)MadtTable)->Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Any other MADT table, try to go to the next one byte-by-byte */
|
||||
MadtTable += 1;
|
||||
}
|
||||
/* Safely advance pointer using proper subtable length */
|
||||
MadtTable += SubTable->Length;
|
||||
}
|
||||
|
||||
/* Zero the ACPI system information structure */
|
||||
@@ -426,7 +496,7 @@ HL::Acpi::InitializeAcpiSystemStructure(VOID)
|
||||
PageCount = SIZE_TO_PAGES(CpuCount * sizeof(PROCESSOR_IDENTITY));
|
||||
|
||||
/* Allocate memory for CPU information */
|
||||
Status = MM::HardwarePool::AllocateHardwareMemory(PageCount, TRUE, &PhysicalAddress);
|
||||
Status = MM::HardwarePool::AllocateHardwareMemory(PageCount, TRUE, MM_MAXIMUM_PHYSICAL_ADDRESS, &PhysicalAddress);
|
||||
if(Status != STATUS_SUCCESS)
|
||||
{
|
||||
/* Failed to allocate memory, return error */
|
||||
@@ -451,7 +521,7 @@ HL::Acpi::InitializeAcpiSystemStructure(VOID)
|
||||
/**
|
||||
* Initializes the ACPI Timer.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -498,7 +568,7 @@ HL::Acpi::InitializeAcpiTimer(VOID)
|
||||
* @param AcpiTable
|
||||
* Supplies a pointer to memory area where ACPI table virtual address will be stored.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -522,10 +592,10 @@ HL::Acpi::QueryAcpiCache(IN ULONG Signature,
|
||||
AcpiCache = CONTAIN_RECORD(ListEntry, ACPI_CACHE_LIST, ListEntry);
|
||||
|
||||
/* Check if ACPI table signature matches */
|
||||
if(AcpiCache->Header.Signature == Signature)
|
||||
if(AcpiCache->Table->Signature == Signature)
|
||||
{
|
||||
/* ACPI table found in cache, return it */
|
||||
TableHeader = &AcpiCache->Header;
|
||||
TableHeader = AcpiCache->Table;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -555,7 +625,7 @@ HL::Acpi::QueryAcpiCache(IN ULONG Signature,
|
||||
* @param AcpiTable
|
||||
* Supplies a pointer to memory area where ACPI table virtual address will be stored.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -596,18 +666,31 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
|
||||
/* Check if DSDT or FACS table requested */
|
||||
if(Signature == ACPI_DSDT_SIGNATURE)
|
||||
{
|
||||
/* Get DSDT address */
|
||||
TableAddress.LowPart = Fadt->Dsdt;
|
||||
/* Prefer 64-bit address on ACPI 2.0+ */
|
||||
if(Fadt->Header.Revision >= 2 && Fadt->XDsdt.QuadPart != 0)
|
||||
{
|
||||
TableAddress.QuadPart = Fadt->XDsdt.QuadPart;
|
||||
}
|
||||
else
|
||||
{
|
||||
TableAddress.LowPart = Fadt->Dsdt;
|
||||
TableAddress.HighPart = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get FACS address */
|
||||
TableAddress.LowPart = Fadt->FirmwareCtrl;
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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)
|
||||
@@ -618,11 +701,12 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Query cache for XSDP table */
|
||||
/* Query cache for XSDT table */
|
||||
Status = QueryAcpiCache(ACPI_XSDT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Xsdt);
|
||||
if(Status != STATUS_SUCCESS)
|
||||
{
|
||||
/* XSDP not found, query cache for RSDP table */
|
||||
/* XSDT not found, query cache for RSDT table */
|
||||
Xsdt = NULLPTR;
|
||||
Status = QueryAcpiCache(ACPI_RSDT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Rsdt);
|
||||
}
|
||||
|
||||
@@ -633,22 +717,22 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Get table count depending on root table type */
|
||||
/* Get table count depending on root table type securely */
|
||||
if(Xsdt != NULLPTR)
|
||||
{
|
||||
/* Get table count from XSDT */
|
||||
if(Xsdt->Header.Length < sizeof(ACPI_DESCRIPTION_HEADER)) return STATUS_INVALID_PARAMETER;
|
||||
TableCount = (Xsdt->Header.Length - sizeof(ACPI_DESCRIPTION_HEADER)) / 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get table count from RSDT */
|
||||
if(Rsdt->Header.Length < sizeof(ACPI_DESCRIPTION_HEADER)) return STATUS_INVALID_PARAMETER;
|
||||
TableCount = (Rsdt->Header.Length - sizeof(ACPI_DESCRIPTION_HEADER)) / 4;
|
||||
}
|
||||
|
||||
/* Iterate over all ACPI tables */
|
||||
for(TableIndex = 0; TableIndex < TableCount; TableIndex++)
|
||||
{
|
||||
/* Check if XSDP or RSDT is used */
|
||||
/* Check if XSDT or RSDT is used */
|
||||
if(Xsdt != NULLPTR)
|
||||
{
|
||||
/* Get table header physical address from XSDT */
|
||||
@@ -661,13 +745,6 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
|
||||
TableAddress.HighPart = 0;
|
||||
}
|
||||
|
||||
/* Check whether some table is already mapped */
|
||||
if(TableHeader != NULLPTR)
|
||||
{
|
||||
/* Unmap previous table */
|
||||
MM::HardwarePool::UnmapHardwareMemory(TableHeader, 2, TRUE);
|
||||
}
|
||||
|
||||
/* Map table using hardware memory pool */
|
||||
Status = MM::HardwarePool::MapHardwareMemory(TableAddress, 2, TRUE, (PVOID*)&TableHeader);
|
||||
if(Status != STATUS_SUCCESS)
|
||||
@@ -682,25 +759,31 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure table was found */
|
||||
if(TableHeader->Signature != Signature)
|
||||
/* Ensure the table was actually found and mapped */
|
||||
if(TableHeader == NULLPTR)
|
||||
{
|
||||
/* 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 */
|
||||
/* ACPI table not found, return error */
|
||||
return STATUS_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* Don't validate FADT on old, broken firmwares with ACPI 2.0 or older */
|
||||
if(TableHeader->Signature != ACPI_FADT_SIGNATURE || TableHeader->Revision > 2)
|
||||
/* Check if we broke out of the loop with the wrong table (safety check) */
|
||||
if(TableHeader->Signature != Signature)
|
||||
{
|
||||
/* Unmap non-matching ACPI table and return error */
|
||||
MM::HardwarePool::UnmapHardwareMemory(TableHeader, 2, TRUE);
|
||||
return STATUS_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* Don't validate FACS and FADT on old, broken firmwares with ACPI 2.0 or older */
|
||||
if((TableHeader->Signature != ACPI_FADT_SIGNATURE || TableHeader->Revision > 2) &&
|
||||
(TableHeader->Signature != ACPI_FACS_SIGNATURE))
|
||||
{
|
||||
/* Validate table checksum */
|
||||
if(!ValidateAcpiTable(TableHeader, TableHeader->Length))
|
||||
@@ -712,7 +795,7 @@ HL::Acpi::QueryAcpiTables(IN ULONG Signature,
|
||||
}
|
||||
|
||||
/* Calculate the length of ACPI table and remap it if needed */
|
||||
TablePages = (((ULONG_PTR)TableHeader & (MM_PAGE_SIZE - 1)) + TableHeader->Length + (MM_PAGE_SIZE - 1)) >> MM_PAGE_SHIFT;
|
||||
TablePages = (((TableAddress.LowPart & (MM_PAGE_SIZE - 1)) + TableHeader->Length + (MM_PAGE_SIZE - 1)) >> MM_PAGE_SHIFT);
|
||||
if(TablePages != 2)
|
||||
{
|
||||
/* ACPI table needs less or more than 2 pages, remap it */
|
||||
|
||||
13
xtoskrnl/hl/amd64/firmware.cc
Normal file
13
xtoskrnl/hl/amd64/firmware.cc
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* 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)
|
||||
@@ -15,7 +15,7 @@
|
||||
* @param Port
|
||||
* Specifies the address to read from, in the range of 0-0xFFFF.
|
||||
*
|
||||
* @return The value read from the port.
|
||||
* @return This routine returns the value read from the port.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -36,7 +36,7 @@ HL::IoPort::ReadPort8(IN USHORT Port)
|
||||
* @param Port
|
||||
* Specifies the address to read from, in the range of 0-0xFFFF.
|
||||
*
|
||||
* @return The value read from the port.
|
||||
* @return This routine returns the value read from the port.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -57,7 +57,7 @@ HL::IoPort::ReadPort16(IN USHORT Port)
|
||||
* @param Port
|
||||
* Specifies the address to read from, in the range of 0-0xFFFF.
|
||||
*
|
||||
* @return The value read from the port.
|
||||
* @return This routine returns the value read from the port.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
|
||||
260
xtoskrnl/hl/amd64/irq.cc
Normal file
260
xtoskrnl/hl/amd64/irq.cc
Normal file
@@ -0,0 +1,260 @@
|
||||
/**
|
||||
* 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::CpuFunctions::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::CpuFunctions::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::CpuFunctions::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::ProcessorSupport::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));
|
||||
}
|
||||
13
xtoskrnl/hl/amd64/rtc.cc
Normal file
13
xtoskrnl/hl/amd64/rtc.cc
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* 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,8 @@ XTFASTCALL
|
||||
KRUNLEVEL
|
||||
HL::RunLevel::GetRunLevel(VOID)
|
||||
{
|
||||
return (KRUNLEVEL)AR::CpuFunc::ReadControlRegister(8);
|
||||
/* Read current run level */
|
||||
return (KRUNLEVEL)AR::CpuFunctions::ReadControlRegister(8);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,7 +38,8 @@ XTFASTCALL
|
||||
VOID
|
||||
HL::RunLevel::SetRunLevel(IN KRUNLEVEL RunLevel)
|
||||
{
|
||||
AR::CpuFunc::WriteControlRegister(8, RunLevel);
|
||||
/* Set new run level */
|
||||
AR::CpuFunctions::WriteControlRegister(8, RunLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,6 +56,7 @@ XTFASTCALL
|
||||
KRUNLEVEL
|
||||
HL::RunLevel::TransformApicTprToRunLevel(IN UCHAR Tpr)
|
||||
{
|
||||
/* Transform APIC TPR to run level */
|
||||
return (KRUNLEVEL)(Tpr >> 4);
|
||||
}
|
||||
|
||||
@@ -71,5 +74,25 @@ 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;
|
||||
}
|
||||
|
||||
13
xtoskrnl/hl/amd64/timer.cc
Normal file
13
xtoskrnl/hl/amd64/timer.cc
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/hl/amd64/timer.cc
|
||||
* DESCRIPTION: Timer support for AMD64
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Include common Timer interface */
|
||||
#include ARCH_COMMON(timer.cc)
|
||||
@@ -24,7 +24,7 @@
|
||||
* @param Poll
|
||||
* Indicates whether to only poll, not reading the data.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -98,7 +98,7 @@ HL::ComPort::ReadComPort(IN PCPPORT Port,
|
||||
* @param Byte
|
||||
* Value expected from the port.
|
||||
*
|
||||
* @return Byte read from COM port.
|
||||
* @return This routine returns a byte read from COM port.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -144,7 +144,7 @@ HL::ComPort::ReadComPortLsr(IN PCPPORT Port,
|
||||
* @param BaudRate
|
||||
* Supplies an optional port baud rate.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -240,7 +240,7 @@ HL::ComPort::InitializeComPort(IN OUT PCPPORT Port,
|
||||
* @param Byte
|
||||
* Data to be written.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
|
||||
@@ -9,26 +9,104 @@
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* ACPI tables cache list */
|
||||
/* Tracks the total number of currently cached ACPI tables */
|
||||
ULONG HL::Acpi::CacheCount = 0;
|
||||
|
||||
/* Array holding the cached ACPI tables */
|
||||
ACPI_CACHE_LIST HL::Acpi::CacheEntries[ACPI_MAX_CACHED_TABLES];
|
||||
|
||||
/* Head of the linked list tracking dynamically mapped ACPI tables */
|
||||
LIST_ENTRY HL::Acpi::CacheList;
|
||||
|
||||
/* ACPI Root System Description Pointer (RSDP) */
|
||||
/* Pointer to the ACPI Root System Description Pointer (RSDP) */
|
||||
PACPI_RSDP HL::Acpi::RsdpStructure;
|
||||
|
||||
/* System information */
|
||||
/* Global architectural system states and hardware feature flags parsed from the ACPI tables */
|
||||
ACPI_SYSTEM_INFO HL::Acpi::SystemInfo;
|
||||
|
||||
/* ACPI timer information */
|
||||
/* Hardware configuration details and port addresses for the ACPI Power Management Timer */
|
||||
ACPI_TIMER_INFO HL::Acpi::TimerInfo;
|
||||
|
||||
/* Active processors count */
|
||||
KAFFINITY HL::Cpu::ActiveProcessors;
|
||||
/* Represents the number of active processors */
|
||||
PKAFFINITY_MAP HL::Cpu::ActiveProcessors;
|
||||
|
||||
/* FrameBuffer information */
|
||||
/* Metadata detailing the linear frame buffer geometry */
|
||||
HL_FRAMEBUFFER_DATA HL::FrameBuffer::FrameBufferData;
|
||||
|
||||
/* Scroll region information */
|
||||
/* Pointer to the RAM shadow buffer used for double-buffered rendering */
|
||||
PVOID HL::FrameBuffer::ScreenShadowBuffer;
|
||||
|
||||
/* Tracks the bounding box, dimensions, and cursor position for the kernel video console */
|
||||
HL_SCROLL_REGION_DATA HL::FrameBuffer::ScrollRegionData;
|
||||
|
||||
/* APIC mode */
|
||||
/* Indicates the active hardware interrupt controller mode */
|
||||
APIC_MODE HL::Pic::ApicMode;
|
||||
|
||||
/* Total number of I/O APIC chips discovered and initialized */
|
||||
ULONG HL::Pic::ControllerCount;
|
||||
|
||||
/* Array containing MMIO bases, IDs, and line counts for all I/O APICs */
|
||||
IOAPIC_DATA HL::Pic::Controllers[IOAPIC_MAX_CONTROLLERS];
|
||||
|
||||
/* Total number of legacy ISA interrupt routing overrides */
|
||||
ULONG HL::Pic::IrqOverrideCount;
|
||||
|
||||
/* Hardware routing definitions mapping legacy ISA interrupts to Global System Interrupts (GSI) */
|
||||
ACPI_MADT_INTERRUPT_OVERRIDE HL::Pic::IrqOverrides[IOAPIC_MAX_OVERRIDES];
|
||||
|
||||
/* Lookup table mapping allocated hardware APIC vectors to their assigned Run Levels */
|
||||
UCHAR HL::Pic::MappedVectors[256];
|
||||
|
||||
/* Accumulated tick value of the ACPI Power Management Timer */
|
||||
ULONG HL::Timer::AcpiPmPerformanceCounter = 0;
|
||||
|
||||
/* Primary hardware timer driving the periodic system clock interrupt */
|
||||
TIMER_TYPE HL::Timer::ClockType;
|
||||
|
||||
/* Fractional remainder used to maintain long-term system clock accuracy */
|
||||
ULONG HL::Timer::FractionalIncrement = 0;
|
||||
|
||||
/* Virtual address mapped to the HPET hardware MMIO registers */
|
||||
PVOID HL::Timer::HpetAddress = NULLPTR;
|
||||
|
||||
/* Operating frequency of the High Precision Event Timer in ticks per second */
|
||||
ULONGLONG HL::Timer::HpetFrequency = 0;
|
||||
|
||||
/* Spinlock protecting concurrent multiprocessor access to the global performance counters */
|
||||
KSPIN_LOCK HL::Timer::PerformanceCounterLock;
|
||||
|
||||
/* The performance counter frequency in ticks per second */
|
||||
ULONGLONG HL::Timer::PerformanceFrequency = 0;
|
||||
|
||||
/* Absolute monotonic tick count driven by the legacy Programmable Interval Timer */
|
||||
ULONGLONG HL::Timer::PitPerformanceCounter;
|
||||
|
||||
/* Programmed hardware divider interval used to increment the PIT performance counter */
|
||||
ULONG HL::Timer::PitRollover;
|
||||
|
||||
/* Flag indicating whether statistical system execution profiling is currently active */
|
||||
BOOLEAN HL::Timer::ProfilingEnabled = FALSE;
|
||||
|
||||
/* Tick interval required to trigger a profile interrupt */
|
||||
ULONG HL::Timer::ProfilingTicks;
|
||||
|
||||
/* Global accumulator for fractional time drift and precision compensation */
|
||||
ULONG HL::Timer::RunningFraction = 0;
|
||||
|
||||
/* System counter driven by the highest precision available hardware */
|
||||
ULONGLONG HL::Timer::SystemPerformanceCounter;
|
||||
|
||||
/* Current base clock increment in standard 100-nanosecond intervals */
|
||||
ULONG HL::Timer::TimeIncrement = 0;
|
||||
|
||||
/* Timer capabilities */
|
||||
TIMER_CAPABILITIES HL::Timer::TimerCapabilities = {0};
|
||||
|
||||
/* APIC timer frequency */
|
||||
ULONG HL::Timer::TimerFrequency;
|
||||
|
||||
/* Function dispatch table for the active hardware timer backend */
|
||||
TIMER_ROUTINES HL::Timer::TimerRoutines = {0};
|
||||
|
||||
/* Identifies the hardware timer backing */
|
||||
TIMER_TYPE HL::Timer::TimerType;
|
||||
|
||||
@@ -9,6 +9,24 @@
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the current value of the high-resolution performance counter.
|
||||
*
|
||||
* @param PerformanceFrequency
|
||||
* Suplies an optional pointer to a variable that receives the performance counter frequency in Hz.
|
||||
*
|
||||
* @return This routine returns the current 64-bit monotonic tick count.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCLINK
|
||||
XTAPI
|
||||
LARGE_INTEGER
|
||||
HlQueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceFrequency)
|
||||
{
|
||||
return HL::Timer::QueryPerformanceCounter(PerformanceFrequency);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the 8-bit data from the specified I/O port.
|
||||
*
|
||||
@@ -117,6 +135,24 @@ HlReadRegister32(IN PVOID Register)
|
||||
return HL::IoRegister::ReadRegister32(Register);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests a dynamic adjustment of the system clock resolution.
|
||||
*
|
||||
* @param Rate
|
||||
* The requested clock rate change in 100-nanosecond units.
|
||||
*
|
||||
* @return This routine returns the actual clock rate granted by the hardware.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCLINK
|
||||
XTAPI
|
||||
ULONG
|
||||
HlSetClockRate(IN ULONG Rate)
|
||||
{
|
||||
return HL::Timer::SetClockRate(Rate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the 8-bit data to the specified I/O port.
|
||||
*
|
||||
|
||||
@@ -25,10 +25,9 @@ XTAPI
|
||||
VOID
|
||||
HL::FrameBuffer::ClearScreen(IN ULONG Color)
|
||||
{
|
||||
ULONG PositionX, PositionY;
|
||||
ULONG BackgroundColor;
|
||||
PCHAR CurrentLine;
|
||||
PULONG Pixel;
|
||||
ULONG BackgroundColor, PositionY;
|
||||
PCHAR CurrentLine, TargetBuffer;
|
||||
UCHAR FillByte;
|
||||
|
||||
/* Make sure frame buffer is already initialized */
|
||||
if(FrameBufferData.Initialized == FALSE)
|
||||
@@ -37,20 +36,29 @@ HL::FrameBuffer::ClearScreen(IN ULONG Color)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Convert background color and get pointer to frame buffer */
|
||||
/* Convert background color */
|
||||
BackgroundColor = GetRGBColor(Color);
|
||||
CurrentLine = (PCHAR)FrameBufferData.Address;
|
||||
|
||||
/* Extract the lower byte for SetMemory */
|
||||
FillByte = (UCHAR)(BackgroundColor & 0xFF);
|
||||
|
||||
/* Determine target buffer */
|
||||
TargetBuffer = (ScreenShadowBuffer != NULLPTR) ? (PCHAR)ScreenShadowBuffer : (PCHAR)FrameBufferData.Address;
|
||||
CurrentLine = TargetBuffer;
|
||||
|
||||
/* Fill the screen with the specified color */
|
||||
for(PositionY = 0; PositionY < FrameBufferData.Height; PositionY++, CurrentLine += FrameBufferData.Pitch)
|
||||
{
|
||||
/* Fill the current line with the specified color */
|
||||
Pixel = (PULONG)CurrentLine;
|
||||
for(PositionX = 0; PositionX < FrameBufferData.Width; PositionX++)
|
||||
{
|
||||
/* Set the color of the pixel */
|
||||
Pixel[PositionX] = BackgroundColor;
|
||||
}
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +76,9 @@ 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)
|
||||
@@ -80,6 +90,9 @@ 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)
|
||||
{
|
||||
@@ -91,15 +104,20 @@ 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:
|
||||
/* Draw the character */
|
||||
DrawCharacter(ScrollRegionData.CursorX, ScrollRegionData.CursorY, ScrollRegionData.TextColor, Character);
|
||||
/* 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;
|
||||
|
||||
/* Advance cursor */
|
||||
ScrollRegionData.CursorX += FbFont->Width;
|
||||
@@ -107,6 +125,7 @@ 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;
|
||||
}
|
||||
@@ -120,6 +139,13 @@ 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;
|
||||
@@ -153,9 +179,8 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
|
||||
{
|
||||
UINT CurrentFragment, Glyph, GlyphLimit, Index, Line, Mapping;
|
||||
PUCHAR Character, CharacterMapping, Fragment;
|
||||
UINT_PTR GlyphPixel, Pixel;
|
||||
ULONG FontColor, GlyphOffset, PixelOffset;
|
||||
PSSFN_FONT_HEADER FbFont;
|
||||
ULONG FontColor;
|
||||
|
||||
/* Make sure frame buffer is already initialized */
|
||||
if(FrameBufferData.Initialized == FALSE)
|
||||
@@ -192,7 +217,7 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There's a glyph for this character, check if it matches */
|
||||
/* There is a glyph for this character, check if it matches */
|
||||
if(Index == WideCharacter)
|
||||
{
|
||||
/* Found the character, break loop */
|
||||
@@ -213,8 +238,7 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
|
||||
}
|
||||
|
||||
/* Find the glyph position on the frame buffer and set font color */
|
||||
GlyphPixel = (UINT_PTR)FrameBufferData.Address + PositionY * FrameBufferData.Pitch +
|
||||
PositionX * FrameBufferData.BytesPerPixel;
|
||||
GlyphOffset = (PositionY * FrameBufferData.Pitch) + (PositionX * FrameBufferData.BytesPerPixel);
|
||||
FontColor = GetRGBColor(Color);
|
||||
|
||||
/* Check all kerning fragments */
|
||||
@@ -243,7 +267,7 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
|
||||
}
|
||||
|
||||
/* Get initial glyph line */
|
||||
GlyphPixel += (CharacterMapping[1] - Mapping) * FrameBufferData.Pitch;
|
||||
GlyphOffset += (CharacterMapping[1] - Mapping) * FrameBufferData.Pitch;
|
||||
Mapping = CharacterMapping[1];
|
||||
|
||||
/* Extract glyph data from fragments table and advance */
|
||||
@@ -255,7 +279,8 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
|
||||
CurrentFragment = 1;
|
||||
while(GlyphLimit--)
|
||||
{
|
||||
Pixel = GlyphPixel;
|
||||
/* Set the initial pixel offset for the current glyph fragment */
|
||||
PixelOffset = GlyphOffset;
|
||||
for(Line = 0; Line < Glyph; Line++)
|
||||
{
|
||||
/* Decode compressed offsets */
|
||||
@@ -269,17 +294,26 @@ HL::FrameBuffer::DrawCharacter(IN ULONG PositionX,
|
||||
/* Check if pixel should be drawn */
|
||||
if(*Fragment & CurrentFragment)
|
||||
{
|
||||
/* Draw glyph pixel */
|
||||
*((PULONG)Pixel) = FontColor;
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
/* Advance pixel pointer */
|
||||
Pixel += FrameBufferData.BytesPerPixel;
|
||||
PixelOffset += FrameBufferData.BytesPerPixel;
|
||||
CurrentFragment <<= 1;
|
||||
}
|
||||
|
||||
/* Advance to next line and increase mapping */
|
||||
GlyphPixel += FrameBufferData.Pitch;
|
||||
GlyphOffset += FrameBufferData.Pitch;
|
||||
Mapping++;
|
||||
}
|
||||
|
||||
@@ -310,7 +344,7 @@ HL::FrameBuffer::DrawPixel(IN ULONG PositionX,
|
||||
IN ULONG PositionY,
|
||||
IN ULONG Color)
|
||||
{
|
||||
PCHAR PixelAddress;
|
||||
ULONG Offset;
|
||||
|
||||
/* Make sure frame buffer is already initialized */
|
||||
if(FrameBufferData.Initialized == FALSE)
|
||||
@@ -327,11 +361,67 @@ HL::FrameBuffer::DrawPixel(IN ULONG PositionX,
|
||||
}
|
||||
|
||||
/* Calculate the address of the pixel in the frame buffer memory */
|
||||
PixelAddress = (PCHAR)FrameBufferData.Address + (PositionY * FrameBufferData.Pitch) +
|
||||
(PositionX * FrameBufferData.BytesPerPixel);
|
||||
Offset = (PositionY * FrameBufferData.Pitch) + (PositionX * FrameBufferData.BytesPerPixel);
|
||||
|
||||
/* Set the color of the pixel by writing to the corresponding memory location */
|
||||
*((PULONG)PixelAddress) = GetRGBColor(Color);
|
||||
/* 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 indicating the success or failure of the operation.
|
||||
*
|
||||
* @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, TAG_HL_FRAMEBUFFER);
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -362,7 +452,7 @@ HL::FrameBuffer::GetFrameBufferResolution(OUT PULONG Width,
|
||||
* @param Color
|
||||
* Specifies the color in (A)RGB format.
|
||||
*
|
||||
* @return Returns the color in FrameBuffer format.
|
||||
* @return This routine returns the color in FrameBuffer format.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -386,7 +476,7 @@ HL::FrameBuffer::GetRGBColor(IN ULONG Color)
|
||||
/**
|
||||
* Initializes frame buffer display.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -544,10 +634,9 @@ XTAPI
|
||||
VOID
|
||||
HL::FrameBuffer::ScrollRegion(VOID)
|
||||
{
|
||||
PCHAR Destination, Source;
|
||||
PCHAR TargetBuffer, Destination, Source;
|
||||
ULONG Line, PositionX, LineBytes;
|
||||
PSSFN_FONT_HEADER FbFont;
|
||||
ULONG Line, PositionX;
|
||||
ULONG LineBytes;
|
||||
PULONG Pixel;
|
||||
|
||||
/* Make sure frame buffer is already initialized */
|
||||
@@ -557,37 +646,132 @@ HL::FrameBuffer::ScrollRegion(VOID)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get font information */
|
||||
/* Retrieve font metrics and calculate line properties for the scroll operation */
|
||||
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;
|
||||
|
||||
/* Scroll up each scan line in the scroll region */
|
||||
for(Line = ScrollRegionData.Top; Line < ScrollRegionData.Bottom - FbFont->Height; Line++)
|
||||
/* Process every line in the scroll region */
|
||||
for(Line = ScrollRegionData.Top; Line < ScrollRegionData.Bottom; Line++)
|
||||
{
|
||||
Destination = (PCHAR)FrameBufferData.Address + Line * FrameBufferData.Pitch +
|
||||
ScrollRegionData.Left * FrameBufferData.BytesPerPixel;
|
||||
/* Calculate destination address for the current line */
|
||||
Destination = TargetBuffer + (Line * FrameBufferData.Pitch) +
|
||||
(ScrollRegionData.Left * FrameBufferData.BytesPerPixel);
|
||||
|
||||
/* 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++)
|
||||
/* Check if the current line needs to be copied from below or cleared */
|
||||
if(Line < ScrollRegionData.Bottom - FbFont->Height)
|
||||
{
|
||||
Pixel[PositionX] = ScrollRegionData.BackgroundColor;
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
13
xtoskrnl/hl/i686/firmware.cc
Normal file
13
xtoskrnl/hl/i686/firmware.cc
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* 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)
|
||||
@@ -15,7 +15,7 @@
|
||||
* @param Port
|
||||
* Specifies the address to read from, in the range of 0-0xFFFF.
|
||||
*
|
||||
* @return The value read from the port.
|
||||
* @return This routine returns the value read from the port.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -36,7 +36,7 @@ HL::IoPort::ReadPort8(IN USHORT Port)
|
||||
* @param Port
|
||||
* Specifies the address to read from, in the range of 0-0xFFFF.
|
||||
*
|
||||
* @return The value read from the port.
|
||||
* @return This routine returns the value read from the port.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -57,7 +57,7 @@ HL::IoPort::ReadPort16(IN USHORT Port)
|
||||
* @param Port
|
||||
* Specifies the address to read from, in the range of 0-0xFFFF.
|
||||
*
|
||||
* @return The value read from the port.
|
||||
* @return This routine returns the value read from the port.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
|
||||
259
xtoskrnl/hl/i686/irq.cc
Normal file
259
xtoskrnl/hl/i686/irq.cc
Normal file
@@ -0,0 +1,259 @@
|
||||
/**
|
||||
* 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::CpuFunctions::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::CpuFunctions::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::CpuFunctions::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::ProcessorSupport::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));
|
||||
}
|
||||
13
xtoskrnl/hl/i686/rtc.cc
Normal file
13
xtoskrnl/hl/i686/rtc.cc
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* 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,6 +20,7 @@ XTFASTCALL
|
||||
KRUNLEVEL
|
||||
HL::RunLevel::GetRunLevel(VOID)
|
||||
{
|
||||
/* Read current run level */
|
||||
return TransformApicTprToRunLevel(HL::Pic::ReadApicRegister(APIC_TPR));
|
||||
}
|
||||
|
||||
@@ -37,6 +38,7 @@ XTFASTCALL
|
||||
VOID
|
||||
HL::RunLevel::SetRunLevel(IN KRUNLEVEL RunLevel)
|
||||
{
|
||||
/* Set new run level */
|
||||
HL::Pic::WriteApicRegister(APIC_TPR, TransformRunLevelToApicTpr(RunLevel));
|
||||
}
|
||||
|
||||
@@ -131,3 +133,23 @@ 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);
|
||||
}
|
||||
|
||||
13
xtoskrnl/hl/i686/timer.cc
Normal file
13
xtoskrnl/hl/i686/timer.cc
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/hl/i686/timer.cc
|
||||
* DESCRIPTION: Timer support for i686
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Include common Timer interface */
|
||||
#include ARCH_COMMON(timer.cc)
|
||||
@@ -23,19 +23,25 @@ HL::Init::InitializeSystem(VOID)
|
||||
XTSTATUS Status;
|
||||
|
||||
/* Initialize ACPI */
|
||||
Status = Acpi::InitializeAcpi();
|
||||
Status = HL::Acpi::InitializeAcpi();
|
||||
if(Status != STATUS_SUCCESS)
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Get system information from ACPI */
|
||||
Status = Acpi::InitializeAcpiSystemInformation();
|
||||
Status = HL::Acpi::InitializeAcpiSystemInformation();
|
||||
if(Status != STATUS_SUCCESS)
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Initialize I/O APIC */
|
||||
HL::Pic::InitializeIOApic();
|
||||
|
||||
/* Initialize timer */
|
||||
HL::Timer::InitializeTimer();
|
||||
|
||||
/* Return success */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user